Java 字符串s=新字符串(“Rohit”);该语句是仅在堆中创建对象,还是在字符串池中创建条目?

Java 字符串s=新字符串(“Rohit”);该语句是仅在堆中创建对象,还是在字符串池中创建条目?,java,string,Java,String,我参加了面试,有人问我这个问题 String s=new String("Rohit"); 该语句是仅在堆中创建对象,还是在字符串池中创建条目 我回答说它不能进入游泳池。我认为使用.intern()可以在字符串池中创建条目。面试官的想法正好相反 如果我错了或面试官错了,你能指导我吗 提前谢谢 编辑: String s1=new String("Rohit"); String s2="Rohit"; String s3=new String("Rohit")

我参加了面试,有人问我这个问题

String s=new String("Rohit"); 
该语句是仅在堆中创建对象,还是在字符串池中创建条目

我回答说它不能进入游泳池。我认为使用
.intern()
可以在字符串池中创建条目。面试官的想法正好相反

如果我错了或面试官错了,你能指导我吗

提前谢谢

编辑:

String s1=new String("Rohit");

        String s2="Rohit";

        String s3=new String("Rohit").intern();

        System.out.println(" "+(s2==s3)+" "+(s1==s2)+" "+(s1==s3)+" "+(s2==s3));
结果为:
true-false-true


这让我想到,如果不将intern()与new一起使用,那么池中就不会有该对象的条目

您所说的有几点错误:

首先,执行
newstring
操作总是会返回一个新字符串,而不会返回一个临时字符串

其次,虽然字符串文字“Rohit”的存在确实可能会导致该值的字符串被“interned”(错误地称为放置在“字符串池”或“字符串常量池”中),但这将在类加载时完成(如果已完成),而不是在语句执行时完成

第三,由于在interned String表中只能有一个具有给定模式的字符串副本,因此即使加载该类也不能保证添加一个新条目,因为可能已经存在一个条目了


当然,通常情况下,你们中的一方或双方可能有一些误解,或者问题(或答案)的措辞可能很糟糕/不清楚。

他说的话有几处不对劲:

首先,执行
newstring
操作总是会返回一个新字符串,而不会返回一个临时字符串

其次,虽然字符串文字“Rohit”的存在确实可能会导致该值的字符串被“interned”(错误地称为放置在“字符串池”或“字符串常量池”中),但这将在类加载时完成(如果已完成),而不是在语句执行时完成

第三,由于在interned String表中只能有一个具有给定模式的字符串副本,因此即使加载该类也不能保证添加一个新条目,因为可能已经存在一个条目了


当然,通常情况下,你们中的一方或双方可能有一些误解,或者问题(或答案)的措辞可能很糟糕/不清楚。

我同意@hotlicks,但Java 7 AFAICS中加载字符串文字时的行为发生了变化

在Java 6中加载类时会加载字符串文本,但在Java 7中,他们将其更改为在执行使用字符串的第一行时加载。您可以通过查看
String.intern()返回的字符串来检测这一点
第一次为字符串调用它时,它将返回同一个对象,但是当再次使用equals()字符串调用它时,它将返回上一个对象

StringBuilder sb = new StringBuilder("Hell");
sb.append("o");
String s = sb.toString();
String si = s.intern(); /* same string if not loaded. */
String s2 = "Hello";
System.out.println( System.getProperty("java.version")+" " + (s == si) + " "+(s2 == s)); 
印刷品

1.6.0_45 false false
正如您所期望的,但是在Java7中+

1.7.0_45 true true 

如果先加载
s2
,intern()字符串
si
将与之相同,因此与
s
不同。但是,如果之后加载
s2
,则所有字符串都使用相同的对象。

我同意@Hot-Licks,但在Java 7 AFAICS中加载字符串文字时的行为发生了变化

在Java 6中加载类时会加载字符串文本,但在Java 7中,他们将其更改为在执行使用字符串的第一行时加载。您可以通过查看
String.intern()返回的字符串来检测这一点
第一次为字符串调用它时,它将返回同一个对象,但是当再次使用equals()字符串调用它时,它将返回上一个对象

StringBuilder sb = new StringBuilder("Hell");
sb.append("o");
String s = sb.toString();
String si = s.intern(); /* same string if not loaded. */
String s2 = "Hello";
System.out.println( System.getProperty("java.version")+" " + (s == si) + " "+(s2 == s)); 
印刷品

1.6.0_45 false false
正如您所期望的,但是在Java7中+

1.7.0_45 true true 

如果先加载
s2
,则intern()字符串
si
将与其相同,因此与
s
不同。但是,如果在加载之后加载
s2
,则所有字符串使用相同的对象。

用于快速回答任何字符串文字,如“Rohit”在这种情况下,字符串将进入字符串常量池,字符串
s
将进入堆,堆将指向存储在字符串常量池中的字符串。加载类时,将创建“字符串池中的条目”(不正确的内部描述),并在类的常量池中解析字符串文字“Rohit”。执行
new String
操作不会创建新的插入字符串(或导致共享现有字符串)。@Braj-但该语句不会“创建”插入字符串。相反,加载类可以做到这一点(假设“Rohit”还没有被其他类占用)。而且
s
不会指向被占用的字符串——它将是它自己的对象。当谈到对象时,请记住字符串是两个对象,其中一个是
char[]
。要快速回答任何字符串文字,如“Rohit”在这种情况下,字符串将进入字符串常量池,字符串
s
将进入堆,堆将指向存储在字符串常量池中的字符串。加载类时,将创建“字符串池中的条目”(不正确的内部描述),并在类的常量池中解析字符串文字“Rohit”。执行
new String
操作不会创建新的插入字符串(或导致共享现有字符串)。@Braj-但该语句不会“创建”插入字符串。相反,加载类可以做到这一点(假设“Rohit”还没有被其他类占用)。而且
s
不会指向被占用的字符串——它将是它自己的对象。当谈到对象时,请记住字符串是两个对象,其中一个是
char[]
+1
new
始终意味着新对象。如果没有
new
就没有新的对象。在Java 7+中,当执行语句时(对于