IT序号网

byte数据常量池问题

luoye 2021年05月25日 编程语言 381 0

【代码】

 1 public class BufferPoolDemo { 
 2     public static void main(String[] args) { 
 3         Integer i1=127; 
 4         Integer i2=127; 
 5         System.out.println(i1==i2); 
 6         System.out.println("------------"); 
 7  
 8         Integer i3=128; 
 9         Integer i4=128; 
10         System.out.println(i3==i4); 
11         System.out.println("------------"); 
12     } 
13 }

【运行结果】

1 true 
2 ---------------------------------- 
3 false 
4 ----------------------------------

【问题】

为什么一个为true,一个为false呢?为何不是true,true,或false,false呢?

【分析】

1、Integer在定义一个数据对象时,在直接赋值这种情况下(Integer i1=127;而不是new出来的),当赋值数据在byte数据取值范围内时,会先去方法区中的Byte常量池中去找有没有127这个值,如果有,直接将这个值得引用赋值给i1,如果没有的话就分配一个内存空间,然后再把引用赋值给i1。当然这里常量池中没有127这个值,那么久直接给127分配一个空间,然后将其引用赋值给i1;同理,Integer i2=127;时会在缓冲池中找到这个值,那么直接将这个值得引用给i2,所以i1和i2的地址值都是相同的,所以输出为true。

2、由于128没在byte数据取值范围内,Integer i3=128;Integer i4=128;等同于Integer i3=new Integer(128);Integer i4=new Integer(128);那么先去堆中各自开辟一个空间,并分别将其引用赋值给i3,i4,同时也会去常量池中找是否有128这个值,若有,直接将其引用赋值他们在堆中开辟的空间,若没有,则在常量池中开一个空间,并将其引用赋值给其在堆中开的空间,由于他们在堆中的地址是不同的,输出即为false。

------------------------------------------------------------------------------------------

【By the way】

【字符串常量池代码】

1 public class BufferPoolDemo { 
2     public static void main(String[] args) { 
3         String s1="hello"; 
4         String s2="hello"; 
5         System.out.println(s1==s2); 
6     } 
7 }

【运行结果】

1 true

【分析】

        创建字符串的时候先查找字符串常量池中有没有相同的对象,如果有相同的对象就直接返回该对象的引用,如果没有相同的对象就在常量池中创建该对象,然后将该对象的引用返回。对于String s1=”hello”;这一步而言,常量池中没有hello这个字符串对象,所以首先创建一个字符串对象,然后将对象引用返回给s1。对于String s2=”hello”;这一步而言,缓冲池中有hello这个字符串对象,直接返回这个对象的引用给s2,此时,s1与s2公用一个字符串对象“hello”,所以s1与s2的内存地址是相同的,所以输出true。

----------------------------------------------------------------------------------------------------------------------------------------

【intern()方法的使用】

1 public class BufferPoolDemo {  
2     public static void main(String[] args) {  
3         String s1=”hello”;  
4         String s2=new String(“hello”);  
5         s2=s2.intern();  
6         System.out.println(s1==s2);  
7     }  
8 }

【运行结果】

1 true

【分析】

         先来说说intern()这个方法的作用吧,这个方法的作用是返回在字符串缓冲池中的对象的引用,所以s2指向的也是字符串缓冲池中的地址,和s1是相等的。


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!