数值常量池

  1. public static void main(String[] args){
  2. Integer a = 1;
  3. Integer b = 2;
  4. Integer c = 3;
  5. Integer d = 3;
  6. Integer e = 321;
  7. Integer f = 321;
  8. Long g = 3L;
  9. System.out.println(c==d);//T
  10. System.out.println(e==f);//F
  11. System.out.println(c==(a+b));//T
  12. System.out.println(c.equals(a+b));//T
  13. System.out.println(g==(a+b));//,这个是因为自动装箱吧
  14. System.out.println(g.equals(a+b));//F 这个为啥,待探究
  15. }

为什么第一个输出是true, 第二个输出是false?
JVM会缓存-128~127的integer对象,即c和d在java看来是同一个对象,所以这里是直接比较的值。
-128~127的整数会被保存在常量池中,所以c和d指向的是同一个对象,e和f是堆中的两个不同的对象。这跟自动拆箱没有关系

  1. Integer i1 = 40;
  2. Integer i2 = 40;
  3. Integer i3 = 0;
  4. Integer i4 = new Integer(40);
  5. Integer i5 = new Integer(40);
  6. Integer i6 = new Integer(0);
  7. System.out.println("i1=i2 " + (i1 == i2)); //T
  8. System.out.println("i1=i2+i3 " + (i1 == i2 + i3));//T
  9. System.out.println("i1=i4 " + (i1 == i4));//F
  10. System.out.println("i4=i5 " + (i4 == i5));//F
  11. System.out.println("i4=i5+i6 " + (i4 == i5 + i6)); //T,自动装箱
  12. 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{

  1. public static void main(String[] args){
  2. String s1 = "abc";//以这种方式新建字符串,会把“abc”放到常量池中管理
  3. String s2 = new String("abc");//不会查找
  4. String s3 = "abc";//会查找常量池中,是否已经有该常量字符串
  5. System.out.println(s1==s2);//false
  6. System.out.println(s1==s3);//true 因为abc 已经在常量池中已经存在,所以两者是同一对象
  7. }

字符串在常量池里 也在方法区中