一、基础类型有byte short int long char boolean float double八种。优化
其中byte short int long char 的包装类型是存放在常量池(用来维护该类型所用到常量的有序集合)中的,浮点类型未实现常量池。spa
常量池存放的是>=-128和<=127中的数据,当数据不在这个范围内时,则不在常量池中维护code
Integer a=new Integer(128); Integer b=new Integer(128);
a==b?false,因为a,b超出127限制,不存在与常量池,因此引用不一样。对象
public static integer valueOf(int t){ final int offset=128; if(t>=-128&&t<=127){ return IntegerCache.cache[i+offset]; } return new Integer(i) }
由valueOf方法能够看出Integer类型在-128~127范围是取自常量池中。blog
二、String a=new String("bb");字符串
可能建立了一个对象,也可能建立了两个对象。编译器
在类编译期间,会先去常量池中查找是否有“bb”的对象,若是有则在栈中复制一份;若是没有,先在常量池中建立一份,再复制一份到堆中。以后把引用交给栈中的s。编译
String a = "a1"; String b = "a" + 1; System.out.println((a == b)); //result = true String a = "atrue"; String b = "a" + "true"; System.out.println((a == b)); //result = true String a = "a3.4"; String b = "a" + 3.4; System.out.println((a == b)); //result = true 分析:JVM对于字符串常量的"+"号链接,将程序编译期,JVM就将常量字符串的"+"链接优化为链接后的值,拿"a" + 1来讲,经编译器优化后在class中就已是a1。在编译期其字符串常量的值就肯定下来,故上面程序最终的结果都为true。
String a = "ab"; String bb = "b"; String b = "a" + bb; System.out.println((a == b)); //result = false 分析:JVM对于字符串引用,因为在字符串的"+"链接中,有字符串引用存在,而引用的值在程序编译期是没法肯定的,即"a" + bb没法被编译器优化,只有在程序运行期来动态分配并将链接后的新地址赋给b。因此上面程序的结果也就为false。
String a = "ab"; final String bb = "b"; String b = "a" + bb; System.out.println((a == b)); //result = true 分析:和[3]中惟一不一样的是bb字符串加了final修饰,对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝存储到本身的常量池中或嵌入到它的字节码流中。因此此时的"a" + bb和"a" + "b"效果是同样的。故上面程序的结果为true。
能够看出当字符串+常量时,能够在编译期优化连接的值。当字符串+引用时,编译期没法肯定,不能被优化class