我知道当我们使用下面给出的String文字时,String对象是在String池中创建的(如果它不存在)。
String str1= "hello";
String str2= "hello";
在上面的情况下,只会在池中创建一个字符串对象。
但是,当我们使用new关键字时,它总是在堆内存中创建一个新的String对象(即使在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 :(得分: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));
这会打印出虚假和真实的
答案 1 :(得分:1)
我们可以用与Java相同的方式考虑Java的String对象中的内存 对于任何其他对象,除了别名对于字符串是常见的。
标准字符串
实现有四个实例变量:对character array (8 bytes)
的引用
和three int values (4 bytes each)
。第一个int值是字符数组的偏移量;
第二个是计数(字符串长度)。
就实例中的实例变量名而言
图中的图形,表示的字符串由字符组成
值[offset]到值[offset + count - 1]。 String中的第三个int值
对象是hash code
,可以在某些情况下保存重新计算。
因此,每个String对象总共使用 40个字节(16个字节) 对象开销加上3个int实例变量中的每一个的4个字节加上8个字节 数组引用加上4个字节的填充)。
此空间要求是另外的 字符本身所需的空间,它们位于数组中。需要的空间 因为char数组经常被共享,所以单独考虑字符 在字符串中。由于String对象是不可变的,因此这种安排允许实现 在String对象具有相同的基础值[]时保存内存。 字符串值和子字符串。
长度为N的字符串通常使用40个字节(对于 字符串对象)加上24个2N字节(对于包含字符的数组) 总共64 + 2N字节。但是在字符串处理中通常使用子字符串,和 Java的表示意味着我们可以这样做,而无需复制字符串的字符!
来源:算法第4版
答案 2 :(得分:0)
为您的示例创建了多少个对象?
1) 4
2) 4
3) 3
4) 4
请注意,每个String
对象都包含一个char
- 数组,其中包含字符串的内容。因此,在创建新的String
时,您实际上会创建两个对象。
1)2)和4)
示例中的每一行都在池中创建一个String
,其中包含char
- 数组(因此我们有两个对象)或创建一个新的String
- 再次 - 包含一个char
- 数组。请注意,在这些示例中,字符串都不共享任何内容。
第3)强>
此示例不同,因为我们使用第一个String
(2个对象)来创建第二个String
。在这种情况下,第二个String
将是一个新对象但它将使用与第一个完全相同的char
- 数组,因此不会创建新的对象。这导致总共只有3个对象而不是4个。
再举一个例子
String s1 = "Hello";
String s2 = "Hello";
在这种情况下,我们只有2个对象,因为s1
和s2
都指向池中具有相同String
的相同char
对象 - 数组