繁体   English   中英

Java中字符串创建的时间

[英]Time of Strings Creation in Java

我正在为J2ME设备编写一个应用程序,并且非常关心不必要的字符串创建。 由于使用Strings是内置的,即没有必要明确地创建它们,我不确定我是否理解它。

例如,返回一个String(只是使用双引号)在返回时创建字符串,即如果我有几个返回语句返回不同的字符串,则只会创建一个字符串。 是对的吗?

此外,当使用字符串打印带有异常的消息时,如果不抛出异常,这些字符串永远不会被创建,对吧?

抱歉打扰你这样一个新手问题。

到目前为止,我对你收到的答案一点也不确定。 如果你只是返回一个字符串文字,例如

return "foo";

然后将这些值嵌入到类文件中。 JVM确保只创建该字符串的一个实例(来自文字) - 但我不认为在加载类本身时,它不会保证它不会为类中的所有常量创建字符串。

然后再次,因为字符串只会被创建一次 (每个字符串常量),这不太可能是一个问题。

现在,如果您的代码实际上更像是这样:

return "foo" + new Date();

就是动态创建一个字符串 - 但只有在实际命中了return语句时才会创建它。

答案比其他一些答案建议的要复杂一些。

  • 在加载类时,将创建一次与源代码中的字符串文字对应的String值。 此外, 这些字符串会自动“实现”,这意味着如果相同的字面值出现在任何类的多个位置,则只保留一个字符串副本。 (任何其他副本, 如果它们被创建将收集垃圾。)

  • 当应用程序调用new String(...) ,当它计算字符串连接表达式(即+运算符)时,或者当它调用在引擎盖下创建字符串的许多库方法之一时,将创建一个新的String。

那么回答你的问题:

1 - 以下内容实际上根本不会创建一个String。 而是它将返回在加载类时创建的String:

        return "some string";

2 - 以下将创建两个字符串。 首先它将调用someObject.toString(),然后它将与文字连接,以给出另一个String。

        return "The answer is :" + someObject;

3 - 以下内容不会创建字符串; 见1。

        throw new Exception("Some message");

4 - 以下将在执行时创建两个字符串; 见2。

        throw new Exception(someObject + "is wrong");

(实际上,3和4掩盖了这样一个事实,即创建异常会导致捕获当前线程的调用堆栈的详细信息,并且这些细节包括每个帧的方法名称,类名和文件名。字符串时未指定表示这些东西实际上是创建的,或者它们是否被实现。因此,创建Exception对象的行为可能会触发创建多个字符串。)

是。 如果通过调用构造函数创建实例的表达式或不执行(对于字符串)评估文字的表达式,则不会创建任何内容。

而且,编译器会进行一些优化。 基于字符串文字的字符串对象将只创建一次并在之后实现。 像这儿:

 
 
 
  
  public String getHello() { return "Hello"; } public void test() { String s = getHello(); // String object created String t = getHello(); // no new String object created }
 
  


JVMS有不同的“意见”:

在以下情况下可能会隐式创建新的类实例:

  • 加载包含String文字的类或接口可能会创建一个新的String对象(第2.4.8节)来表示该文字。 如果已经创建了一个String对象来表示该文字的上一个匹配项,或者如果已在表示与该文字相同的字符串的String对象上调用了String.intern方法,则可能不会发生这种情况。

所以上面的例子是不正确的(我每天都在学习新东西)。 VM在类加载期间检查是否必须创建"Hello" (如果尚未存在,则将创建String实例)。

所以现在我的理解是,VM为每个唯一的String文字创建一个String实例(在字节代码级别上!),无论它是否被使用。

在字节代码级别上,因为编译器可以优化字符串文字与一个文字的连接,如:表达式"one"+"two"将被编译为"onetwo"

只有在调用时才会创建字符串(和其他对象)。

那么回答你的问题:

  1. 是的,只会创建返回的String
  2. 是的,只有在抛出异常时,才会创建此String

这里的主要概念是,在您的逻辑流使解释器执行该行编译代码之前,任何String的堆分配(您所说的创建)或任何对象的更一般术语都不会发生。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM