说String常量池中是否没有字符串,如果我说,
String s = "Java";
那么将创建多少个对象?
现在游泳池里什么也没有了,我说,
String s = new String("Java");
现在,将创建多少个对象?
现在游泳池里什么也没有了,我说,
String s = new String("Java");
s.intern();
实习生方法会做什么?
现在游泳池里什么也没有了,我说,
String s = new String("Java");
String s1 = s.intern();
现在会发生什么?
请回答,因为我对此感到非常困惑。
正如我在SCJP5凯西·塞拉(Kathy Sierra)的书中读到的那样,当您用新的字符串创建一个字符串时,会创建2个对象,一个在堆上,一个在池中。
答案 0 :(得分:4)
我将假设在下面的每个示例中,每次都在新的JVM中仅加载和执行一次代码。 (我还将假设您在代码的其他地方都没有使用文字"Java"
...,因为那样会使事情复杂化。)
1)说字符串常量池中是否没有字符串,并且是否 说,
String s = "Java";
那么将创建多少个对象?
在加载方法时,将创建一个字符串并将其添加到池中。
2)现在池中什么也没有了,我说,
String s = new String("Java");
现在将创建多少个对象。
在加载方法时,将创建一个字符串并将其添加到池中。
运行代码时,new
将创建第二个字符串,并且不会将其添加到池中。
3)现在游泳池里什么也没有了,我说,
String s = new String("Java"); s.intern();
实习生方法会做什么?
在加载方法时,将创建一个字符串并将其添加到池中。
new
创建了第二个字符串,并且未将其添加到池中。
intern
调用返回第一个字符串。 (您没有保留引用...)
4)现在游泳池里什么也没有了,我说,
String s = new String("Java"); String s1 = s.intern();
现在会发生什么?
与示例3相同。因此,s1
将保留对表示String
字符串文字的"Java"
对象的引用。
我读过SCJP5 Kathy Sierra的书,当您使用
new
创建一个String时,会创建2个对象,一个在堆上,一个在池中。
我怀疑这本书到底是怎么说的。 (您在解释,我认为您的解释有些不准确。)
但是,您的措辞大致正确,(这很重要!)表示文字的字符串对象是在加载代码片段时创建的,并添加到池中,而不是在加载时 1 被执行。
并要解决另一个困惑点:
“我的实际意思是,从您给出的答案来看,似乎将始终在String常量池中添加一个String。”
那是不正确的。这是一个错误的概括。
虽然上述所有4种情况都适用,但其他情况则并非如此。这取决于原始字符串的来源。在典型的应用程序中,大多数文本数据是从文件,套接字或用户界面中读取的。发生这种情况时,可以直接或通过库调用从字符数组创建字符串。
这是一个简单(但不切实际)的示例,显示了根据其组成字符创建String的情况。
String s = new String(new char[]{'J', 'a', 'v', 'a'});
在上面的代码段中,仅创建了一个字符串,并且不在字符串池中。如果您希望结果字符串在字符串池中,则需要明确调用intern
,如下所示:
String s = new String(new char[]{'J', 'a', 'v', 'a'});
s = s.intern();
...,这将(如有必要)在字符串池 2 中创建一个 second 字符串。
1-显然,在某些JVM中,懒惰的创建和内部字符串文字的创建是很懒惰的,因此当它实际发生时不可能百分百确定。但是,无论代码片段被JVM执行多少次,它只会发生一次(每个引用文字的类)。
2-无法将new
的字符串插入字符串池。实际上,这将违反JLS。 JLS将new
操作指定为始终创建新对象。
答案 1 :(得分:3)
- 那么将创建多少个对象?
池中有一个String
。
- 现在将创建多少个对象?
将创建一个String
,池中仍然有一个String
。
- 实习生方法会做什么?
它将尝试将"Java"
放入池中,在其中找到另一个"Java"
,并从步骤1返回对该"Java"
的引用。
- 现在会发生什么?
第1步中的"Java"
将返回,s1
现在将其引用。
答案 2 :(得分:0)
说String常量池中是否没有字符串,如果我说,
String s =“ Java”;
那么将创建多少个对象?
在内部池中创建一个String对象。
s
由该引用分配。
现在游泳池里什么也没有了,我说,
String s = new String(“ Java”); 现在将创建多少个对象。 创建两个String对象。
一个被"Java"
拘禁,另一个是"Java"
内容相同的新字符串
现在游泳池里什么也没有了,我说,
String s = new String(“ Java”); s.intern(); 实习生方法会做什么?
intern()
方法将:
调用intern方法时,如果池已经包含等于equals(Object)方法确定的与此String对象相等的字符串,则返回池中的字符串。否则,将此String对象添加到池中,并返回对该String对象的引用。
因此,在这种情况下,此字符串将添加到池中,并返回对此的引用
最后一个问题:
现在游泳池里什么也没有了,我说,
String s = new String(“ Java”); 字符串s1 = s.intern(); 现在会发生什么?
这里发生的是:
char[]
数组“ Java”支持s.intern()
在池中查找参考,s1
由实习参考分配答案 3 :(得分:0)
String strObject = new String("Java");
和
String strLiteral = "Java";
两个表达式都为您提供String对象,但是它们之间有细微的差别。
使用new()运算符创建String对象时,它总是在heap memory
中创建一个新对象。
另一方面,如果您使用String文字语法创建对象,例如“ Java”,它可能会从String pool
返回一个现有对象(Perm gen空间中String对象的高速缓存,现在已在最近的Java版本中将其移至堆空间)(如果已存在)。否则,它将创建一个新的字符串对象,并将其放入字符串池中以备将来重用。
- 字符串s =“ Java”;
将在Pool
中创建一个对象。
String s = new String(“ Java”);
将在Heap
中创建一个对象
String s = new String(“ Java”);
s.intern();
实习生方法会做什么?
intern()方法会将Sting对象复制到池中,但是由于没有被引用,因此将无用,因此Heap
String s = new String(“ Java”);
字符串s1 = s.intern();
现在会发生什么?
将创建Heap
中的一个对象和Pool
中的一个对象。