2016-03-01 163 views
1

我知道当我们使用下面给出的字符串文字时,String对象在字符串池中创建(如果它不存在)。将为String创建多少个对象?

String str1= "hello"; 
String str2= "hello"; 

在上面的例子中,只有一个字符串对象将在池中创建。

但是,当我们使用new关键字它总是在堆内存中创建一个新的String对象(即使有一个在字符串池)

String str3=new String("hello"); // here a new object will be created in heap. 

在这里,我有一个关于许多对象如何将一个混乱在下面的情况下创建(池或堆内存)。

1) String s="Hello"; 
    String s1 = new String ("Hello"); 

2) String s = new String("Hello"); 
    String s1 = new String("Hello"); 

3) String s="Hello"; 
    String s1=new String (s); 

4) String s1 = new String ("Hello"); 
    String s="Hello"; 
+0

您是否试过阅读JRE源代码? –

回答

3

每次调用新的String(...)都会创建一个新的实例。您可以使用String.intern()从池中获取实例。

String s="Hello"; 
String s1 = new String ("Hello"); 
System.out.println(System.identityHashCode(s)==System.identityHashCode(s1)); 


String si= new String ("Hello").intern(); 
String s1i = new String ("Hello").intern(); 
System.out.println(System.identityHashCode(si)==System.identityHashCode(s1i)); 

这将打印虚实

+0

是的,String x = new String(“Hello”)会在堆中创建一个新的实例,但是,如果我们不使用intern()方法,它是否会在Pool中创建一个新的String? – user3244519

1

我们可以占内存在Java中的String对象以同样的方式作为 用于任何其他目的,除了走样是字符串的常见。

标准字符串 实现有四个实例变量:对character array (8 bytes)three int values (4 bytes each)的引用。第一个int值是字符数组的偏移量; 第二个是count(字符串长度)。

String Object

在 图上绘制有关的实例变量名的术语,即所表示的字符串由字符 值[偏移]通过值的[偏移+计数 - 1]。字符串 对象中的第三个int值是hash code,可在某些情况下保存重新计算。

因此,每个字符串对象总共使用40个字节(16个字节用于 对象内务操作,再加4个字节的每个由3个int实例变量加上 数组引用8个字节加上4个字节的填充)。

此空间要求是 字符本身所需的空间,它们位于数组中。字符所需的空间 单独计算,因为char数组通常在字符串之间共享 。由于String对象是不可变的,因此当String对象具有相同的基础值[]时,这种安排允许实现 节省内存。 字符串值和子字符串。的长度N

的String通常使用用于 总共64个+ 2N字节40个字节(对于 字符串对象)加上24个2N字节(对于包含字符阵列)。但是,在字符串处理中使用子字符串是很典型的,而且 Java的表示方式允许我们在不必复制字符串字符的情况下这样做!

来源:算法第四版

+1

你的描述已经过时了,它们改变了Java 7中的字符串表示形式。没有'offset'和'count',字符串不能再共享它们的部分内容(子字符串)。 – MartinS

+0

@MartinS然后请编辑它以保持它的正确性! :) – OBX

0

多少对象正在为你的例子创造出来的?

1) 4   
2) 4   
3) 3   
4) 4 

注意,每个String对象包含char - 阵列与字符串的内容。所以当创建一个新的String时,你实际上创建了两个对象。

1)2)和4)

中的每一行的例子无论是创建其中包含char阵列(因此,我们有两个对象游泳池String),或创建一个新的String它 - 再次 - 包含一个char-阵列。请注意,在这些示例中,字符串都不会共享任何内容。

3)

这个例子是不同的,因为我们使用的第一String(2对象)来创建第二String。在这种情况下,第二个String将是一个新对象,但是它将使用与第一个相同的char阵列,因此不会创建新的对象。这导致总共只有3个对象,而不是4

再举一个例子的

String s1 = "Hello"; 
String s2 = "Hello"; 

在这种情况下,我们将只有2个对象,因为s1s2都指向同一个String与池中的对象相同char -array。