Java中的基本类型(Primitive Types)和包装类型(Wrapper Classes)之间存在多个关键区别,这些区别主要体现在包含内容、性质、声明方式、存储位置、初始值、使用方式以及泛型适用性等方面。
1. 包含内容
- 基本类型:只包含数据本身,不包含任何方法或操作。
- 包装类型:不仅包含数据,还包含了一系列的方法(如类型转换、比较等)和属性,是对基本类型数据的封装。
2. 性质
- 基本类型:不是对象,因此它们没有对象的特性,如继承和多态。
- 包装类型:是对象,因此它们具有对象的所有特性,如继承自Object类的功能(如toString()、equals()等)。
3. 声明方式
- 基本类型:直接声明变量并赋值,不需要使用new关键字。
- 包装类型:需要使用new关键字在堆内存中分配内存空间,或者使用自动装箱(JDK 5及以上版本支持)来创建对象。
4. 存储位置
- 基本类型:直接将值保存在栈内存中,访问速度较快。
- 包装类型:将对象放在堆内存中,通过栈中的引用来调用它们,访问速度相对较慢,并且需要考虑垃圾回收等额外开销。
5. 初始值
- 基本类型:在声明时如果没有显式赋值,则会被赋予一个默认值(如int的默认值为0,boolean的默认值为false)。
- 包装类型:在声明时如果没有显式赋值,则默认值为null,因为它们是引用类型。
6. 使用方式
- 基本类型:直接用于数值计算、位运算等场景,效率较高。
- 包装类型:主要用于需要对象的地方,如集合(List、Map等)中只能存储对象,因此基本类型需要通过包装类来转换为对象才能存储在集合中。此外,包装类型还提供了丰富的操作方法和常量。
7. 泛型适用性
- 基本类型:不能直接用于泛型,因为泛型在编译时会进行类型擦除,而基本类型没有对应的类型信息可以擦除。
- 包装类型:可以用作泛型的类型参数,因为它们是对象类型,具有类型信息。
为什么说是几乎所有对象实例都存在于堆中呢? 这是因为 HotSpot 虚拟机引入了 JIT 优化之后,会对对象进行逃逸分析,如果发现某一个对象并没有逃逸到方法外部,那么就可能通过标量替换来实现栈上分配,而避免堆上分配内存
⚠️ 注意:基本数据类型存放在栈中是一个常见的误区! 基本数据类型的存储位置取决于它们的作用域和声明方式。如果它们是局部变量,那么它们会存放在栈中;如果它们是成员变量,那么它们会存放在堆中。
public class Test {
// 成员变量,存放在堆中
int a = 10;
// 被 static 修饰,也存放在堆中,但属于类,不属于对象
// JDK1.7 静态变量从永久代移动了 Java 堆中
static int b = 20;
public void method() {
// 局部变量,存放在栈中
int c = 30;
static int d = 40; // 编译错误,不能在方法中使用 static 修饰局部变量
}
}
2万+

被折叠的 条评论
为什么被折叠?



