【Java基础面试题】数据类型
Java面试高频总结:基本数据类型深度解析
📊 八种基本数据类型详解
数据类型 | 关键字 | 字节数 | 位数 | 默认值 | 取值范围 | 核心特性 |
---|---|---|---|---|---|---|
字节型 | byte | 1 | 8 | 0 | -128 ~ 127 | 最小整数类型 |
短整型 | short | 2 | 16 | 0 | -32,768 ~ 32,767 | 较少使用 |
整型 | int | 4 | 32 | 0 | -2³¹ ~ 2³¹-1 (约±21亿) | 最常用整数类型 |
长整型 | long | 8 | 64 | 0L | -2⁶³ ~ 2⁶³-1 | 大范围整数 |
单精度 | float | 4 | 32 | 0.0f | ±3.4e-38 ~ ±3.4e38 | 需后缀f/F |
双精度 | double | 8 | 64 | 0.0d | ±1.7e-308 ~ ±1.7e308 | 默认浮点类型 |
字符型 | char | 2 | 16 | ‘\u0000’ | 0 ~ 65,535 (Unicode字符) | 存储单个字符 |
布尔型 | boolean | - | 1 | false | true/false | 条件判断专用 |
💡 关键记忆点:
int
和long
的区别不仅是范围大小,更在内存占用和处理效率上- 浮点类型默认是
double
,声明float
必须显式添加f
后缀boolean
大小未精确定义,JVM实现通常使用1字节
🔄 数据类型转换与运算
类型转换三要素
-
隐式转换(自动提升)
- 小范围类型→大范围类型自动转换
- 方向:
byte → short → int → long → float → double
char
→int
自动转换(获取Unicode值)
-
显式转换(强制类型转换)
- 语法:
(目标类型)变量名
- 风险:精度丢失(浮点→整数)或数据溢出(大整数→小整数)
- 示例:
double d = 3.14; int i = (int)d; // i=3
- 语法:
-
字符串转换桥梁
- 基本类型→String:
String.valueOf()
或"" + 基本类型
- String→基本类型:
Integer.parseInt()
等包装类方法
- 基本类型→String:
⚠️ long与int互转注意事项
转换方向 | 方式 | 风险等级 | 推荐做法 |
---|---|---|---|
int → long | 隐式自动 | ★☆☆☆☆ | 直接赋值即可 |
long → int | 强制显式 | ★★★★☆ | 必须检查范围:if(longVal >= Integer.MIN_VALUE && longVal <= Integer.MAX_VALUE) |
💰 BigDecimal vs double:金融计算的生死抉择
为什么double不适合金融计算?
// 典型精度丢失案例
System.out.println(0.1 + 0.2);
// 输出:0.30000000000000004 (而非0.3)
BigDecimal核心优势
维度 | double | BigDecimal |
---|---|---|
精度 | 15-17位有效数字 | 任意精度 |
计算原理 | 二进制浮点近似值 | 十进制精确计算 |
舍入控制 | 基本四舍五入 | 8种舍入模式 |
适用场景 | 科学计算、3D图形 | 财务系统、货币 |
性能 | 快 | 慢(约10-100倍) |
🔥 黄金法则:凡是涉及货币金额、税率计算、利息结算等场景,必须使用BigDecimal!
📦 装箱与拆箱机制揭秘
核心概念
自动装箱/拆箱原理
- 装箱:
Integer i = 100;
→ 编译为Integer.valueOf(100)
- 拆箱:
int j = i;
→ 编译为i.intValue()
使用陷阱
Integer a = 100;
Integer b = 100;
Integer c = 200;
Integer d = 200;System.out.println(a == b); // true(缓存范围-128~127)
System.out.println(c == d); // false(超出缓存,新建对象)
⚔ int vs Integer:原始与包装的博弈
存在意义对比
维度 | int(基本类型) | Integer(包装类) |
---|---|---|
内存占用 | 4字节 | 16字节(对象头+字段) |
存储位置 | 栈内存 | 堆内存 |
功能扩展 | 仅数值运算 | 提供类型转换、解析等方法 |
集合兼容 | 不可直接使用 | 可直接存入集合 |
泛型支持 | 不可用于泛型 | 可用于泛型 |
空值表示 | 无(0有歧义) | 可用null表示缺失值 |
使用场景决策树
graph TD
A[需要存储数据] --> B{是否使用集合/泛型?}
B -->|是| C[使用Integer]
B -->|否| D{是否高频计算?}
D -->|是| E[使用int]
D -->|否| F{需要空值语义?}
F -->|是| C
F -->|否| E
🎯 Integer缓存机制深度解析
缓存范围与原理
- 默认范围:-128 ~ 127(可通过JVM参数
-XX:AutoBoxCacheMax=<size>
扩展上限) - 实现原理:
Integer.valueOf()
优先返回缓存对象 - 源码关键:
public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i); }
缓存机制影响
场景 | 结果 | 原因分析 |
---|---|---|
Integer a = 127; Integer b = 127; | a == b | 命中缓存,同一对象 |
Integer c = 128; Integer d = 128; | c != d | 超出范围,新建不同对象 |
Integer e = new Integer(100); Integer f = new Integer(100); | e != f | 强制新建对象 |
⚠️ 重要建议:Integer比较始终使用
equals()
而非==
!
💎 核心知识总结
-
基本类型选择铁律:
- 整数默认用
int
,超20亿用long
- 浮点默认用
double
,精确计算用BigDecimal
- 整数默认用
-
类型转换三原则:
- 小转大自动,大转小强制
- 浮点转整数截断小数
- 字符串转换注意格式异常
-
包装类使用精髓:
- 集合存储必须用包装类
- 高频计算场景用基本类型
- 对象比较用
equals()
-
Integer缓存陷阱:
- 默认缓存-128~127
- 值比较用
equals()
- 避免用
new Integer()
创建对象