基本数据类型与常量池

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指向同一个地址,相等

猜你喜欢

转载自blog.csdn.net/weixin_40018934/article/details/81088049