如何解决在 Java 中,当我们将字符串文字打印到终端时,该字符串文字是否也存储在字符串池中?
我知道当我们将一个字符串文字初始化为一个变量时,这个文字将被 JVM 存储在字符串池中。考虑下面的一段代码。
System.out.println("This is a string literal");
即使我没有将其初始化为变量,引号内的字符串文字是否也存储在字符串池中?
解决方法
我将在这个答案的开头说,在深入了解 Java 字符串池方面几乎没有实际用途。从实践的角度来看,您只需要记住两件事:
-
不要使用
==
来比较字符串。使用equals
、compareTo
或等效方法。 -
不要在代码中使用显式的
String.intern
调用。如果您想避免重复字符串的潜在问题,请启用现代 Java GC 中提供的字符串重复数据删除功能。
我知道当我们使用 'new' 关键字或不使用 'new' 关键字初始化字符串文字时,该文字将被 JVM 存储在字符串池中。
这是乱码。
首先,您不“初始化”字符串文字。你初始化一个变量。
String hi = "hello"; // This initializes the variable `hi`.
其次,您通常不/不应该将字符串文字与 new
一起使用。
String hi = new String("hello"); // This is bad. You should write this as above.
使用 new
创建字符串的正常用例是这样的:
String hi = new String(arrayOfCharacters,offset,count);
实际上,对应于字符串文字的 String
对象的创建和驻留发生在该文字第一次在表达式中使用时或更早的时间。确切的细节(即何时发生)未指定并且(我理解)取决于版本。
第一次使用可能是在变量初始化中,也可能是在其他地方;例如方法调用。
所以你的问题:
考虑下面的一段代码:
System.out.println("This is a string literal");
即使我不初始化,引号内的字符串文字是否也存储在字符串池中?
是的,确实如此。如果这是第一次使用文字,上面的代码可能会触发这种情况。但它可能以前发生过;例如如果上面的代码之前运行过。
作为后续,您问:
为什么字符串池会收集未存储在变量中而仅显示在控制台中的字符串文字?
因为 JLS 3.10.5 要求对应于字符串文字的 String
对象是实习的:
“此外,字符串字面量总是指类 String 的同一个实例。这是因为字符串字面量 - 或者更一般地说,作为常量表达式(第 15.28 节)的值的字符串 - 是“内嵌的”以便使用方法 String.intern
(第 12.5 节)共享唯一实例。”
你问:
字符串池的存在有助于优化程序。通过这样存储文字(这实际上不是必需的,因为它只是为了在控制台中显示),是不是违背了它的全部目的(即优化)?
实习和字符串池的最初想法是为了节省内存。在 25 年前设计和最初指定 Java 语言时,这是有道理的。如今,即使是低端的 Android 手机也有 1GB 的内存,而为了节省几千字节而对字符串文字进行实习是毫无意义的。除了 JLS 说这必须发生。
但答案是否定的,它不违背(原始)目的。本声明:
System.out.println("This is a string literal");
可以执行多次。您不希望/不需要每次执行时为文字创建一个新的 String
对象。问题是 JVM 不知道会发生什么。
无论如何,实习必须发生,因为规范是这样说的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。