一、 基本概念
基本数据类型我们都很熟悉,但基本数据类型不具备对象的特征,不能调用方法,一般能实现的功能比较简单,为了让基本数据类型具备对象的特性,Java为每个基本数据类型提供了一个包装类,进而像操作对象一样,操作这些基本数据类型了;
包装类均位于java.lang包;为了使用方便,Java中将8种基本数据类型进行了封装:除了Integer和Character类,其它六个类的类名和基本数据类型一致,只是类名的第一个字母大写;
boolean —> Boolean
char —> Character
byte—> Byte
short—> Short
long—> Long
int —> Integer
float—> Float
double—> Double
自动装箱:基本数据类型 封装 为对象类型(包装类),符合java的面向对象的思想;
自动拆箱:将对象(包装类)转化为基本数据类型;
包装类中常量池:当包装类进行自动装箱时,装箱后的对象会存储在一个缓存区中,并且只能存储有且只有一个相同值的对象。这个缓存区就是包装类常量池;各个包装类缓存值范围 如下:即已经默认创建了数值 [-128-127] 的包装类缓存数据;
boolean:true和false
byte:-128~127
char:0~127
short:-128~127
int:-128~127
long:-128~127
特别注意:对于float和double没有缓存;
以Integer为例说明包装类常量池问题:
public class IntegerDemo {
public static void main(String[] args) {
//自动装箱
Integer n1=1;
Integer n2=1;
//比较地址值,说明n1,n2指向同一个对象
System.out.println(n1==n2);//true
Integer n3=new Integer(1);
System.out.println(n1==n3);//false
//超过常量池范围
Integer n4=128;
Integer n5=128;
System.out.println(n4==n5);//false
}
}
具体的说,Integer i1=40时,JVM会直接在对象池中找到该值的引用,也就是说这种方式声明一个Integer对象时,JVM首先会在Integer对象的常量池中查找有没有值为40的对象,如果有则直接返回该对象的引用;如果没有,则新创建一个对象,并返回该对象的引用地址;
二、 基本类型和包装类之间的转换
以Integer 和Int之间的转换为例
基本类型--->包装类:
- 使用包装类的构造器
- 使用包装类提供的方法valueOf()
//first
Integer n1=new Integer(10);
//second
Integer n2=Integer.valueOf(10);
包装类--->基本类型:
- 调用包装类提供的xxxValue()方法
Integer n2=Integer.valueOf(10);
int b=n2.intValue();
三、面试
1 基本类型和包装类型的区别:
基本类型存储在堆里,包装类型存储在栈里;
包装类是对象,拥有方法和字段,对象的调用是引用对象的地址;
基本类型是值传递,包装类是引用传递;
2 为什么使用Long时,大都推荐使用valueOf方法,而不是用parseLong()?
因为Long等其它包装类存在缓存机制,缓存了-128到127之间的Long,valueOf()方法会优先从缓存中去取,
减少资源的开销使用,parseLong()没有该机制