1)基本数据类型的大小
int:32位 4个字节;
short:16位 2个字节;
float:32位;
double:64位;
long:64位;
char:16位;
byte:8位;最小值是-128,最大值是127
boolean:1位
2)自动拆箱和自动装箱
自动拆箱:当计算数值时,integer会自动转为int型进行计算
自动装箱:当int型传给integer类型时,int数值又会包装为integer
基本数据类型的常量池范围是-128~127之间,在这个范围内的基本数据类型的包装类可以自动拆箱,比较时可以直接比较大小;
int型的包装类Integer在比较数值是否相等时,自动拆箱和自动装箱只在-128~127之间,超过这个范围的用==判断会产生false;
char没有负值,0~127范围内会自动拆箱和自动装箱
3)基本数据类型的存储方式
public void count(int a) {
int i=0;
int j=0;
}
方法中的i,j都是引用,存在于虚拟机栈的局部变量表里,指向局部变量表的整型值0。int a是传值引用,所以也会存在于局部变量表。
public test {
int i=0;
Demo a = new Demo();
}
i是类的成员变量。类实例化的对象存在于堆中,所以成员变量也存在于堆中,引用a存的是Demo实例的地址,引用i存的是值,这个值也会存在于堆中。
4)包装类对象怎么存储
其实,常说的常量池也可以叫做对象池,比如String s = new String("hello").intern(),创建一个引用s指向一个对象;首先会在常量池中查找是否有该对象,即让引用s在常量池中查找是否有"hello"对象,如果有的话,直接返回hello对象的地址,即让引用s指向常量hello的地址。
基本数据类型在常量池中找是否有该值,如果找不到就在常量池中new一个该值的对象。
5)常量池理解与总结
java虚拟机缓存了Integer、Byte、Short、Character、Boolean包装类在-128~127之间的值,如果取值在这个范围内,会从int常量池取出一个int并自动装箱成Integer,超出这个范围就会重新创建一个。
转载:
public class Test{
Integer i1 = new Integer(1);
Integer i2 = new Integer(1);//i1,i2位于堆中不同的内存空间
Integer i3 = 1;//this is autoboxing
Integer i4 = 1;//i3,i4位于指向常量池中同一个内存空间
Integer i5 = 300;
Integer i6 = 300;//i5,i6超出范围,分别创建新的对象
System.out.println(i1 == i2);//false
System.out.println(i3 == i4);//true
System.out.println(i5 == i6);//false
String s1 = new String("hello");
String s2 = new String("hello");
String s3 = "hello";
String s4 = "hello";
System.out.println(s1 == s2);//false
System.out.println(s3 == s4);//true
}
- 基本数据类型(boolean,char,byte,short,int,long,float,double)之间使用==,比较的是它们的数值
- 复合数据类型之间使用==,比较的是它们在内存中的存放地址,对于String对象的值的比较,可以使用equals()
Integer i1 = 10;//this is autoboxing
Integer i2 = 10;
Integer i3 = 20;
Integer i4 = new Integer(10);
Integer i5 = new Integer(10);
Integer i6 = new Integer(20);
System.out.println(i1 == i2);//true (1)
System.out.println(i3 == i1 + i2);//true (2)
System.out.println(i1 == i4);//false (3)
System.out.println(i4 == i5);//false (4)
System.out.println(i6 == i4 + i5);//true (5)
System.out.println(20 == i4 + i5);//true (6)
“+”操作符不适用于Integer对象,首先i4和i5先进行自动拆箱操作,得到40,然后i6也进行自动拆箱为int值40,相等。
String s1 = "hello";
String s2 = "hello";
String s3 = "hel" + "lo";
String s4 = "hel" + new String("lo");
String s5 = new String("hello");
String s6 = s5.intern();
String s7 = "h";
String s8 = "ello";
String s9 = s7 + s8;
System.out.println(s1 == s2);//true (1)
System.out.println(s1 == s3);//true (2)
System.out.println(s1 == s4);//false (3)
System.out.println(s1 == s9);//false (4)
System.out.println(s4 == s5);//false (5)
System.out.println(s1 == s6);//true (6)
- s1和s2中都指向常量池中的同一个内存空间,相等
- 组成s3的子字符串均在常量池中;字符串拼接在编译期间会被优化,相等
- 组成s4的子字符串通过创建新的对象而产生,运行时分配的内存空间未知,不相等
- s7和s8虽然是字符串字面量,拼接成s9时,s7和s8是作为两个变量使用的,所在内存空间不可预料,不相等
- s4和s5都被存储在堆中,地址不同,不相等
- s6通过intern()方法,将字符串“hello”添加进常量池,而常量池中已经存在“hello”字符串,所以直接返回地址,所以s1和s6指向同一个地址,相等