java - String 浅谈
/** * String s1 = "a"; * 编译器会先检查常量池中是否已经有"a": * 如果没有,则在常量池先创建,后引用. * 如果有,则直接引用; * 所以执行该语句,会产生0个或1个对象. * 这里,会创建1个对象. */ String s1 = "a"; /** * String s2 = new String("a"); * 编译器先在堆中创建一个对象,然后去常量池中检查是否已有"a": * 如果没有,则先在常量池创建,然后将堆中的引用指向常量池的对象; * 如果有,则直接将堆中的引用指向常量池中的对象; * 所以执行该语句,会产生1个或2个对象. * 这里,会创建1个对象. */ String s2 = new String("a"); System.out.println(s1==s2); //false
以上代码,在jvm简单内存图可简述为:
而以上==比较的会是对象的地址,所以结果为false
另外:
String hello = "Hello", lo = "lo"; System.out.print((hello == "Hello") + " "); //true. System.out.print((Other.hello == hello) + " "); //true. System.out.print((spt.common.use.str.other.Other.hello == hello) + " "); //true. //使用反编译器查看,发现编译器已将"Hel"+"lo"编译为Hello System.out.print((hello == ("Hel"+"lo")) + " "); //true. //将变量和字符串使用连接符连接,在运行期才会创建,存储在堆中. System.out.print((hello == ("Hel"+lo)) + " "); //false. //调用intern方法,首先会到字符串常量池中查找,若已有,则不再创建,直接将引用指向常量池的对象. System.out.println(hello == ("Hel"+lo).intern()); String a = "a"; //两侧都会在运行期间在堆中创建对象. System.out.println((a + "b") == (a + "b")); //false.