java - 需要了解的字符串、字符串常量池和字符串实习生方法
问题描述
假设字符串常量池中没有字符串,如果我说,
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 书中所读到的,当您使用 new 创建一个 String 时,会创建 2 个对象,一个在堆上,一个在池中。
解决方案
我将假设在下面的每个示例中,您每次都在一个新的 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 的书中读到,当您使用 创建 String 时
new
,会创建 2 个对象,一个在堆上,一个在池中。
我怀疑这本书是否准确地说。(你在解释,我认为你的解释有些不准确。)
但是,您的解释大致正确,尽管(这很重要!)表示文字的字符串对象是在加载代码片段时创建并添加到池中的1,而不是在执行时。
为了解决另一个混淆点:
“我的真正意思是,从你给出的答案来看,似乎总是会在字符串常量池中添加一个字符串。”
这是不正确的。这是一个错误的概括。
虽然上述所有 4 种情况都适用,但其他情况则不适用。这取决于原始字符串的来源。在典型的应用程序中,大多数文本数据都是从文件、套接字或用户界面中读取的。发生这种情况时,字符串是从字符数组直接或通过库调用创建的。
这是一个简单(但不切实际)的示例,显示了从其组成字符创建字符串。
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中创建第二个字符串。
1 - 显然,在某些 JVM 中,字符串文字的创建和实习是延迟完成的,因此无法 100% 确定何时实际发生。但是,它只会发生一次(每个引用文字的类),无论 JVM 执行多少次代码片段。
2 - 没有办法将new
一个字符串放入字符串池中。这实际上违反了 JLS。JLS将new
操作指定为始终创建新对象。
推荐阅读
- angular - 如何从角度控制器调用 MVC 控制器?
- vector - 在 Keras 中导出每个时期的嵌入
- d3.js - d3 - 条形图重叠我的文本,我怎样才能减少域,所以它不会?
- javascript - 不知道如何修复一些 404 可以找到文件错误
- javascript - 循环检测到@computed 属性的错误
- c# - 在 word 365 中,我在哪里可以找到将它们放置在页面上的模板变量?
- javascript - 如何使表格中的空白单元格可点击并使用javascript使其在另一个表格上显示某些内容?
- r - 匹配2列数据框中的值并提取特定值
- symfony - Symfony2 security.interactive_login 无法正确获取 passwordUpdatedAt 的值 显示 flash msg 密码即将过期
- python - 关于 .apply() 和通过函数传递整个列的问题