news 2026/5/28 9:47:46

Java基础热门八股总结:八种基本数据类型 + 装箱拆箱 + 缓存机制,(90%的Java新手都搞不清的装箱拆箱问题)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java基础热门八股总结:八种基本数据类型 + 装箱拆箱 + 缓存机制,(90%的Java新手都搞不清的装箱拆箱问题)

🔥个人主页:北极的代码(欢迎来访)
🎬作者简介:java后端学习者
❄️个人专栏:苍穹外卖日记,SSM框架深入,JavaWeb
命运的结局尽可永在,不屈的挑战却不可须臾或缺!

前言:

今天在上课的时候看了一些java基础的八股,在这里总结一下,希望对大家有一点帮助。

摘要:

本文总结了Java基础数据类型的关键知识点:1. 8种基本数据类型及其特性:byte(1)、short/char(2)、int/float(4)、long/double(8),包括取值范围和默认值;2. 数据类型转换的三种方式(自动/强制/字符串)及可能出现的精度损失问题;3. 包装类的作用与自动装箱拆箱机制,解决基本类型无法用于集合、泛型等问题;4. 浮点数精度问题及BigDecimal的正确使用方法;5. Integer缓存机制(-128~127)及其对==比较的影响。文章通过代码示例详细说明了这些核心概念在实际开发中的应用场景和注意事项。

基础知识:

一、八种基本数据类型

Java中的数据类型分为两大类:基本数据类型引用数据类型。其中基本数据类型共有8种,是Java程序设计的基石。

1.1 数据类型详表
数据类型占用大小位数取值范围默认值描述
byte1字节8位-128 到 1270最小的整数类型,适合节省内存,如处理文件或网络流
short2字节16位-32768 到 327670较少使用,用于需要节省内存且数值范围有限的场景
int4字节32位-2^31 到 2^31-10最常用的整数类型,满足大多数日常编程需求
long8字节64位-2^63 到 2^63-10L表示非常大的整数,数值后需加L或l
float4字节32位1.4E-45 到 3.4028235E380.0f单精度浮点数,数值后需加F或f
double8字节64位4.9E-324 到 1.7976931348623157E3080.0d双精度浮点数,Java中浮点数的默认类型
char2字节16位'\u0000' 到 '\uffff''\u0000'表示单个字符,采用Unicode编码
boolean无明确字节大小不适用true 或 falsefalse用于逻辑判断

关键记忆点:

  • 1字节:byte、boolean

  • 2字节:short、char

  • 4字节:int、float

  • 8字节:long、double

1.2 默认类型规则
java // 整数的默认类型为int int num = 100; // ✓ 正确 long bigNum = 100L; // 需要加L后缀 // 浮点数的默认类型为double double d = 3.14; // ✓ 正确 float f = 3.14f; // 需要加f后缀
1.3 包装类对应关系

除了char对应Character、int对应Integer外,其他都是首字母大写:

  • byte → Byte

  • short → Short

  • int → Integer

  • long → Long

  • float → Float

  • double → Double

  • char → Character

  • boolean → Boolean


二、数据类型转换

2.1 转换方式

Java提供三种数据类型转换方式:

① 自动类型转换(隐式转换)

java

// 小范围 → 大范围,自动转换 int intValue = 10; long longValue = intValue; // 安全,自动转换 float floatValue = intValue; // 安全,自动转换 double doubleValue = intValue; // 安全,自动转换

② 强制类型转换(显式转换)

java

// 大范围 → 小范围,需要强制转换 long longValue = 100L; int intValue = (int) longValue; // 可能有数据丢失或溢出 double d = 3.14; int i = (int) d; // i = 3,小数部分被舍弃

③ 字符串转换

java

String str = "123"; int num = Integer.parseInt(str); double d = Double.parseDouble(str);
2.2 转换可能出现的问题

数据溢出:

java

int largeNum = 300; byte b = (byte) largeNum; // b = 44 // 300的二进制:00000001 00101100 // 强制转换为byte,只保留低8位:00101100 = 44

精度损失:

java

double d = 3.14; int i = (int) d; // i = 3,损失小数部分

三、特殊知识点

3.1 char类型的特殊性

char是无符号类型,不能为负数,取值范围从0开始:

java char c1 = 65; // 对应字符 'A' char c2 = '\u0041'; // Unicode表示,也是'A' char c3 = 'A'; // 直接字符 // char c4 = -1; // ❌ 编译错误,char不能为负数
3.2 long和int的相互转换
java // int → long:安全,自动转换 int intVal = 100; long longVal = intVal; // long → int:需要强制转换,可能溢出 long bigVal = 3000000000L; // 超出int范围 int intVal2 = (int) bigVal; // 数据丢失,结果异常 // 安全的转换方式 if (bigVal >= Integer.MIN_VALUE && bigVal <= Integer.MAX_VALUE) { int safeVal = (int) bigVal; }

四、BigDecimal vs double

4.1 double的精度问题

java

System.out.println(0.05 + 0.01); // 0.060000000000000005 System.out.println(1.0 - 0.42); // 0.5800000000000001 System.out.println(4.015 * 100); // 401.49999999999994 System.out.println(123.3 / 100); // 1.2329999999999999

原因:double执行的是二进制浮点运算,某些十进制小数无法用二进制精确表示,就像十进制无法精确表示1/3一样。

4.2 使用BigDecimal解决

java

import java.math.BigDecimal; BigDecimal num1 = new BigDecimal("0.1"); BigDecimal num2 = new BigDecimal("0.2"); BigDecimal sum = num1.add(num2); // 0.3 BigDecimal product = num1.multiply(num2); // 0.02 // ⚠️ 注意:必须使用字符串构造,不要直接使用浮点数 BigDecimal wrong = new BigDecimal(0.1); // 仍然有精度问题 BigDecimal correct = new BigDecimal("0.1"); // ✓ 正确方式

结论:涉及金钱计算,必须使用BigDecimal。


重点分析:

对于初学者来说,可能搞不清拆箱和装箱,以及包装类这些到底是干嘛的,可能仅仅是知道有这个东西,不太清晰。

一 核心问题:基本类型和对象之间不能直接一起玩

问题场景

Java里有两种东西:

  • 基本类型(int, double, boolean...):简单、高效,直接存值

  • 对象(String, List, 自定义类...):功能丰富,但需要new

矛盾出现了:很多Java的"工具"只认对象,不认基本类型

java

// 集合类只能存对象 ArrayList<Integer> list = new ArrayList<>(); // ✓ 必须用Integer ArrayList<int> list = new ArrayList<>(); // ❌ 编译错误,不能这样写 // 泛型只能用于对象 List<Integer> list; // ✓ 正确 List<int> list; // ❌ 错误 // 有些方法只接受对象 Thread t = new Thread(() -> {}); t.wait(1000); // 参数是long,但有些API要求对象类型

二、装箱和拆箱就是翻译官

装箱:把基本类型 → 包装成对象
拆箱:把包装对象 → 还原成基本类型

java

// 装箱:int变成Integer对象 int num = 10; Integer obj = Integer.valueOf(num); // 手动装箱 Integer obj2 = num; // 自动装箱(Java 5+) // 拆箱:Integer对象变回int Integer obj3 = new Integer(20); int num2 = obj3.intValue(); // 手动拆箱 int num3 = obj3; // 自动拆箱(Java 5+)

三、为什么需要包装类

原因1:集合框架只能存对象

java

// 实际开发中最常见的需求:存数字到列表里 List<Integer> scores = new ArrayList<>(); scores.add(95); //这里发生了自动装箱:int → Integerscores.add(87); scores.add(92); int first = scores.get(0); // 自动拆箱:Integer → int

如果没有包装类,你就没法把数字存到ArrayList里,这在实际开发中是不可接受的。

原因2:需要处理"空值"的情况

java

// 基本类型的局限性 int score = null; // ❌ 编译错误!int不能为null // 包装类可以表示"缺失" Integer score = null; // ✓ 可以,表示还没有分数 // 实际应用:从数据库查询 public Integer getAgeFromDB(int userId) { // 如果数据库里没有这个用户的年龄,返回null if (notExist) return null; // Integer可以返回null return 25; }

业务场景:用户可能没有填写年龄,数据库里是NULL,用int无法表示这种"空"状态。

原因3:包装类提供了丰富的工具方法

java

// int本身没有任何方法 int num = 123; // num.xxx // 什么都点不出来 // Integer提供了很多实用方法 String str = Integer.toString(123); // "123" int parsed = Integer.parseInt("456"); // 456 String binary = Integer.toBinaryString(10); // "1010" int max = Integer.max(5, 10); // 10 boolean isDigit = Character.isDigit('5'); // true

四、装箱拆箱的底层原理

看看编译器在背后做了什么:

java

// 你写的代码 Integer i = 100; int n = i; // 编译后实际执行的代码 Integer i = Integer.valueOf(100); // 装箱:调用valueOf int n = i.intValue(); // 拆箱:调用intValue

五、完整的代码示例对比

没有包装类会怎样(假设场景)

java

// 假设Java没有包装类,你可能需要这样写: class MyInt { int value; MyInt(int v) { value = v; } int getValue() { return value; } } List<MyInt> list = new ArrayList<>(); list.add(new MyInt(5)); // 每次都要new,麻烦且低效 MyInt obj = list.get(0); int num = obj.getValue(); // 取值也要手动调用方法
有了包装类和自动装箱拆箱

java

// 实际Java代码:简洁、高效 List<Integer> list = new ArrayList<>(); list.add(5); // 自动装箱 int num = list.get(0); // 自动拆箱

六、内存和性能角度的理解

java

int primitive = 10; // 栈内存,4字节,直接存10 Integer wrapper = 10; // 栈内存存引用(8字节),堆内存存Integer对象(16字节) // 总共占用约24字节,是int的6倍!

为什么还要用,因为有些场景必须用包装类(集合、泛型、null值),这是"用空间换功能"。

七、总结:一句话理解

概念通俗解释
装箱把"数字"装进"盒子"里,变成对象
拆箱从"盒子"里取出"数字"
为什么需要包装类因为Java的"容器"(集合、泛型)不收留基本类型,只收留对象

实际开发中的平衡:

  • 日常计算用intdouble(性能好)

  • 存集合、表示空值、调用工具方法时用IntegerDouble

面试高频考点:

java

Integer a = 100; Integer b = 100; System.out.println(a == b); // true(缓存) Integer c = 200; Integer d = 200; System.out.println(c == d); // false(超出缓存范围)
Integer c = 200会调用valueOf(200),因为200不在默认缓存范围(-128~127)内,所以会创建两个不同的对象,==比较的是对象地址,因此返回false。

Java的Integer类内部实现了⼀个静态缓存池,⽤于存储特定范围内的整数值对应的Integer对象。
默认情况下,这个范围是-128⾄127。当通过Integer.valueOf(int)⽅法创建⼀个在这个范围内的整数对象时,并不会每次都⽣成新的对象实例,⽽是复⽤缓存中的现有对象,会直接从内存中取出,不需要新建⼀个对象。

为什么Java要设计这个缓存

性能优化:-128到127是最常用的整数范围,频繁创建对象会浪费内存和时间。

java

// 常见场景:循环中使用 for (int i = 0; i < 1000; i++) { list.add(i); // i在0-127之间时,复用缓存对象,节省内存 }
// 永远安全的比较方式 System.out.println(a.equals(b)); // true System.out.println(c.equals(d)); // true

结语:如果对你有帮助,请点赞,关注,收藏,你的支持就是我最大的鼓励!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/28 9:47:27

千问 LeetCode 2547. 拆分数组的最小代价 Java实现

这道题是典型的区间DP&#xff08;动态规划&#xff09;问题&#xff0c;核心在于如何高效计算每个子数组的"重要性"。问题分析重要性的计算规则&#xff1a; - 子数组中只出现一次的数字会被移除&#xff08;不计入长度&#xff09; - 重要性 k 剩余数字的个数 - …

作者头像 李华
网站建设 2026/5/22 0:50:41

γ能谱测量分析γ能谱信息复原技术【附仿真】

✨ 长期致力于γ能谱测量分析、信息复原、反卷积、系统仿真、稳谱研究工作&#xff0c;擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流&#xff0c;点击《获取方式》 &#xff08;1&#xff09;非对称鲁棒稳谱的Huber-卡尔曼滤波器…

作者头像 李华
网站建设 2026/5/22 0:50:40

1746-NR8电阻输入模块

Allen-Bradley 1746-NR8 是一款专为 SLC 500 系列设计的 8 通道电阻温度检测器&#xff08;RTD&#xff09;输入模块&#xff0c;用于精确测量温度信号。产品特点&#xff08;15条&#xff09;&#xff1a;1746-NR8 提供 8 个独立的 RTD 输入通道&#xff0c;可同时连接 8 路温…

作者头像 李华
网站建设 2026/5/22 0:49:21

15. tsconfig.json 配置详解

15. tsconfig.json 配置详解 1. 概述 tsconfig.json 是 TypeScript 项目的核心配置文件&#xff0c;用于指定编译选项、文件包含/排除规则、项目引用等。正确配置 tsconfig.json 是 TypeScript 项目工程化的基础。 ┌────────────────────────────…

作者头像 李华
网站建设 2026/5/22 0:44:40

3步掌握中兴光猫高级管理:zteOnu工具实战指南

3步掌握中兴光猫高级管理&#xff1a;zteOnu工具实战指南 【免费下载链接】zteOnu A tool that can open ZTE onu device factory mode 项目地址: https://gitcode.com/gh_mirrors/zt/zteOnu 中兴光猫破解工具zteOnu是一款专为网络管理员和技术爱好者设计的专业级中兴ON…

作者头像 李华