String对象的创建是比较特殊的,普通对象创建都是在堆中创建,String对象确不一定,下面看一段代码
public class StringTest1 { public static void main(String[] args) throws Exception{ String a = "abc"; String b = "abc"; String c = "ab"; String d = new String("ab"); System.out.println("a=" + a); //a=abc System.out.println("b=" + b); //b=abc System.out.println("c=" + c); //c=ab System.out.println("d=" + d); //d=ab System.out.println("a==b is " + (a == b)); //a==b is true System.out.println("c==d is " + (c == d)); //c==d is false Field field = String.class.getDeclaredField("value"); field.setAccessible(true); char[] valueA = (char[]) field.get(a); char[] valueB = (char[]) field.get(b); char[] valueC = (char[]) field.get(c); char[] valueD = (char[]) field.get(d); System.out.println("a.value(" + valueA.hashCode() + ")=" + Arrays.toString(valueA)); //a.value([1829164700)=[a, b, c] System.out.println("b.value(" + valueB.hashCode() + ")=" + Arrays.toString(valueB)); //b.value([1829164700)=[a, b, c] System.out.println("c.value(" + valueC.hashCode() + ")=" + Arrays.toString(valueC)); //c.value([2018699554)=[a, b] System.out.println("d.value(" + valueD.hashCode() + ")=" + Arrays.toString(valueD)); //d.value([2018699554)=[a, b] valueA[0] = 'z'; valueD[0] = 'x'; System.out.println("a=" + a); //a=zbc System.out.println("b=" + b); //b=zbc System.out.println("c=" + c); //c=xb System.out.println("d=" + d); //d=xb } }
c跟d都是“ab”,但是两个引用是不相等的,d是用new创建的,这个时候才会在堆中创建对象,a,b,c三个引用都是直接指向常量池的对象的,但是下面c和d的value似乎又是同一个数组,改变d的第一位,c也变了,说明d在堆中创建的对象还是指向常量池的,所以用new的话就多创建了个对象。
还有一个经典的问题, String a = "a" + "b";创建了几个对象。
一般来说应该是3个吧,一个"a",一个"b",一个结果"ab",下面写一个简单的类
public class StringTest2 { @SuppressWarnings("unused") public static void main(String[] args){ String a = "a" + "b"; } }
javap -c StringTest2.class Compiled from "StringTest2.java" public class test.StringTest2 { public test.StringTest2(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>": ()V 4: return public static void main(java.lang.String[]); Code: 0: ldc #16 // String ab 2: astore_1 3: return }
package test; public class StringTest2 { public static void main(String[] args) { String a = "ab"; } }
原文地址:http://blog.csdn.net/tsingheng/article/details/41477369