Integer的127和128

有如下代码:
Integer a = 127,b = 127;
Integer c = 128,d = 128;
Sysout.out.println(a == b);//true
System.out.println(c == d);//false```

这是什么原因?
Integer i = 127;的时候会进行自动装箱的操作,就是把基本数据转换成Integer对象,而转换成Integer对象用的是ValueOf方法,看了源码如下(其中一小段):

public static Integer valueOf(int i) {
return i >= -128 || i < 128 ? new Integer(i) : SMALL_VALUES[i + 128];
}
private static final Integer[] SMALL_VALUES = new Integer[256];

在源码里,Integer把-127-127缓存了下来。认为这些小的数字用到的频率比较高,所以为了优化性能,把这些数缓存了下来。所以当声明的Integer对象值在-128-127之间时,引用的是同一个对象,所以结果是true

String s1 = “abc”;
String s2 = “abc”;
String s3 = new String(“abc”);//
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s2 == s3);//false
“`
这段代码?为什么是这个结果?false可以理解,毕竟是new了不同的对象,第一个为什么是true呢?常量池,

对于String s3 = new String(“abc”);来说,初始化一个新创建的String对象,换句话说,新创建的字符串是参数字符串的一个副本。除非确实需要一份副本,否则这种方法是不必要的,因为String是不可变的。这段话来自官方文档。
意思是:
1,在编译器编译的时候,当编译器注意到参数为字符串常量时,即将字符串作为常量放在class文件中的常量区,并在类加载时放入运行时常量池中。
2,在new操作符被调用时,在java堆中创建一个新的对象,然后对象的内容为常量池里面对应字符串的一个拷贝。
而在String s2 = “abc”被编译的时候,先检查class文件中是否包含该字符串常量,如果包含,直接返回常量池中的对象。
因此,在调用new操作时,对象始终存在于堆中,而直接字符串赋值时对象实际上是存在于常量池中的,
所以比较结果肯定是false。

猜你喜欢

转载自blog.csdn.net/u010075989/article/details/72514201