数值常量池
public static void main(String[] args){
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
System.out.println(c==d);//T
System.out.println(e==f);//F
System.out.println(c==(a+b));//T
System.out.println(c.equals(a+b));//T
System.out.println(g==(a+b));//,这个是因为自动装箱吧
System.out.println(g.equals(a+b));//F 这个为啥,待探究
}
为什么第一个输出是true, 第二个输出是false?
JVM会缓存-128~127的integer对象,即c和d在java看来是同一个对象,所以这里是直接比较的值。
-128~127的整数会被保存在常量池中,所以c和d指向的是同一个对象,e和f是堆中的两个不同的对象。这跟自动拆箱没有关系
Integer i1 = 40;
Integer i2 = 40;
Integer i3 = 0;
Integer i4 = new Integer(40);
Integer i5 = new Integer(40);
Integer i6 = new Integer(0);
System.out.println("i1=i2 " + (i1 == i2)); //T
System.out.println("i1=i2+i3 " + (i1 == i2 + i3));//T
System.out.println("i1=i4 " + (i1 == i4));//F
System.out.println("i4=i5 " + (i4 == i5));//F
System.out.println("i4=i5+i6 " + (i4 == i5 + i6)); //T,自动装箱
System.out.println("40=i5+i6 " + (40 == i5 + i6)); //T
语句 i4 == i5 + i6,因为+这个操作符不适用于 Integer 对象,首先 i5 和 i6 进行自动拆箱操作,进行数值相加,即 i4 == 40。然后 Integer 对象无法与数值进行直接比较,所以 i4 自动拆箱转为 int 值 40,最终这条语句转为 40 == 40 进行数值比较。
String 常量池
public class Demo{
public static void main(String[] args){
String s1 = "abc";//以这种方式新建字符串,会把“abc”放到常量池中管理
String s2 = new String("abc");//不会查找
String s3 = "abc";//会查找常量池中,是否已经有该常量字符串
System.out.println(s1==s2);//false
System.out.println(s1==s3);//true 因为abc 已经在常量池中已经存在,所以两者是同一对象
}
字符串在常量池里 也在方法区中