当我们使用new运算符创建一个String对象时,我读到创建了两个对象,一个Object是字符串常量池,第二个是堆内存。
我的问题是我们正在使用new运算符,因此只应在Heap中创建一个对象。为什么然后必须在String Constant池中创建另外一个对象。我知道只要我们不使用new运算符来创建String,Java就会存储String对象。例如:
String s = "abc" .
在这种情况下,它只会在String常量池中创建。
String s2 = new String("abc")
只有一个对象可以在堆中创建,而不是在常量池中创建。
请在这里解释我错的原因。
答案 0 :(得分:10)
我们正在使用new运算符,因此只应在堆中创建一个对象。
当然 - new
操作只创建一个对象。但它的参数是一个String文字,它已经代表了一个对象。每次使用String文字时,都会在类加载期间为其创建一个对象(除非在其他地方已经使用了相同的文字)。这不会被跳过,因为您随后将该对象用作new String()
操作的参数。
因此,new String()
操作在大多数情况下是不必要的,很少使用。
答案 1 :(得分:2)
请参阅http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28
String类型的编译时常量表达式总是“实例化”,以便使用String.intern方法共享唯一实例
因此,当你写
String s2 = new String("abc")
编译时常量表达式“abc”将是internd。
答案 2 :(得分:2)
它将创建两个对象,一个对象进入池区域,另一个对象在非池区域中,因为您使用new和string字符串作为参数。
String s = new String("abs");
答案 3 :(得分:1)
java中的字符串是不可变的,一旦创建它就无法更改。此外,任何字符串文字都将存储在字符串池中,以便以后再次使用相同的文字时使用,例如:
String name = "my name"; // one intern object is created in pool
String otherName = "my name"; // the old intern object is reused
System.out.println( name == otherName); // true , the same reference refer to same object
两个引用引用池中的相同位置。
String name = new String("my name"); // one object is created, no string pool checking
String otherName = new String("my name"); // other object is created, no string pool checking
System.out.println( name == otherName); // false, we have 2 different object
这里我们在内存中有两个不同的String对象,每个对象都有自己的值。
请参阅此文章了解更多信息: http://www.javaranch.com/journal/200409/Journal200409.jsp#a1
答案 4 :(得分:1)
String s2 = new String("abc")
它将在堆内存中只创建一个对象。我们需要显式地使用java.lang.String的intern()
方法在String池中创建条目。
String s = "def".
这里将创建两个对象。当您使用Java的字符串文字表示法创建时,它会自动调用intern()
方法将该对象放入字符串池中,前提是它已不存在于池中。
答案 5 :(得分:-1)
String s2 = new String("abc");
这里将创建1个文字和1个对象。
使用new运算符1 String对象将在堆中创建为“abc”,s2将引用它,而且“abc”也是在字符串构造函数中传递的字符串文字,因此它将进入字符串常量池。
将文字视为对象,因此将在此处创建2个对象。