在上面的两个篇博客中,我们看到String和Integer不同的常量池的变现形式
我们再看一个例子:
public static void main(String[] args) { // TODO Auto-generated method stub String i1 = "hello"; String i2="world"; String i5=new String("helloworld"); System.out.println(i5==(i1+i2)); Integer m1=40 ; Integer m2=0; Integer m3=40; System.out.println(m1==(m2+m3)); }
结果:false true
一个是对String的操作,一个是对Integer的操作。我们仍 然用反编译的方法:javap -c test
1 public class com.study.main.javaPTest extends java.lang.Object{ 2 public com.study.main.javaPTest(); 3 Code: 4 0: aload_0 5 1: invokespecial #1; //Method java/lang/Object."<init>":()V 6 4: return 7 8 public static void main(java.lang.String[]); 9 Code: 10 0: ldc #2; //String hello 11 2: astore_1 12 3: ldc #3; //String world 13 5: astore_2 14 6: new #4; //class java/lang/String 15 9: dup 16 10: ldc #5; //String helloworld 17 12: invokespecial #6; //Method java/lang/String."<init>":(Ljava/lang/Str 18 g;)V 19 15: astore_3 20 16: getstatic #7; //Field java/lang/System.out:Ljava/io/PrintStream; 21 19: aload_3 22 20: new #8; //class java/lang/StringBuilder 23 23: dup 24 24: invokespecial #9; //Method java/lang/StringBuilder."<init>":()V 25 27: aload_1 26 28: invokevirtual #10; //Method java/lang/StringBuilder.append:(Ljava/la 27 /String;)Ljava/lang/StringBuilder; 28 31: aload_2 29 32: invokevirtual #10; //Method java/lang/StringBuilder.append:(Ljava/la 30 /String;)Ljava/lang/StringBuilder; 31 35: invokevirtual #11; //Method java/lang/StringBuilder.toString:()Ljava 32 ang/String; 33 38: if_acmpne 45 //比较两个string类型的变量的引用
34 41: iconst_1 35 42: goto 46 36 45: iconst_0 37 46: invokevirtual #12; //Method java/io/PrintStream.println:(Z)V 38 49: bipush 40 39 51: invokestatic #13; //Method java/lang/Integer.valueOf:(I)Ljava/lang/ 40 teger; 41 54: astore 4 42 56: iconst_0 43 57: invokestatic #13; //Method java/lang/Integer.valueOf:(I)Ljava/lang/ 44 teger; 45 60: astore 5 46 62: bipush 40 47 64: invokestatic #13; //Method java/lang/Integer.valueOf:(I)Ljava/lang/ 48 teger; 49 67: astore 6 50 69: getstatic #7; //Field java/lang/System.out:Ljava/io/PrintStream; 51 72: aload 4 52 74: invokevirtual #14; //Method java/lang/Integer.intValue:()I 53 77: aload 5 54 79: invokevirtual #14; //Method java/lang/Integer.intValue:()I 55 82: aload 6 56 84: invokevirtual #14; //Method java/lang/Integer.intValue:()I 57 87: iadd //上面是获取对应变量的value,相当于在基本变量的基础上进行加操作和比较大小操作
58 88: if_icmpne 95 59 91: iconst_1 60 92: goto 96 61 95: iconst_0 62 96: invokevirtual #12; //Method java/io/PrintStream.println:(Z)V 63 99: return 64 65 } View Code
正如:上面代码的33和57行所示的那样:
对于String类型的变量,他们是通过常量池的方式,记录每个独有的变量,但是在String中”+“操作只会生成另一个String类型的对象。“==”操作对于引用类型的变量是比较两者的对象是否相等
对于Integer类型而言,他们也有常量池,但是他们的常量池是在程序中用数组的方式实现的(参考上一篇),而在进行”+“操作时,通过Integer.intValue()方法,取出每对象的value,再通过==来比较值是否相等,实际上在这个时候:Integer的”+“和”== “操作是基于基本数据类型进行的