私有静态方法中的final String 在调用时是否会实例化一个新对象?

发布于 2024-09-27 20:52:12 字数 238 浏览 4 评论 0原文

私有静态方法中的 static Final String 在调用时是否会实例化一个新对象?

private static String Test() {
    final String foo = "string literal";
    return foo;
}

或者编译器是否知道方法内部只有一个字符串文字?或者我应该将其设为私有静态最终类字段?这会通过将代码分布在类中来降低可读性。

Does a static final String inside a private static method instantiate a new object when invoked?

private static String Test() {
    final String foo = "string literal";
    return foo;
}

Or does the compiler know there is only a single, string literal, inside the method? Or should I make it a private static final class field? This has the effect of reducing readability by spreading the code around the class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦幻之岛 2024-10-04 20:52:12

不,将从字符串文字池中重用特定字符串。例如,如果是:

final String foo = new String("string literal");

那么每次调用该方法时都会创建一个新的。

这是一个证据:

public static void main(String[] args) throws Exception {
    String s1 = test1();
    String s2 = test1();
    System.out.println(s1 == s2); // true

    String s3 = test2();
    String s4 = test2();
    System.out.println(s3 == s4); // false
}

private static String test1() {
    final String foo = "string literal";
    return foo;
}

private static String test2() {
    final String foo = new String("string literal");
    return foo;
}

请注意,final 修饰符在这种特殊情况下没有任何影响。它仅禁止变量被重新分配。

No, the particular string will be reused from the string literal pool. If it was for example:

final String foo = new String("string literal");

Then indeed a new one will be created everytime the method is invoked.

Here's an evidence:

public static void main(String[] args) throws Exception {
    String s1 = test1();
    String s2 = test1();
    System.out.println(s1 == s2); // true

    String s3 = test2();
    String s4 = test2();
    System.out.println(s3 == s4); // false
}

private static String test1() {
    final String foo = "string literal";
    return foo;
}

private static String test2() {
    final String foo = new String("string literal");
    return foo;
}

Note that the final modifier doesn't have any influence in this particular case. It only prohibits the variable from being reassigned.

同展鸳鸯锦 2024-10-04 20:52:12

您不必太担心字符串文字。 JVM 对字符串文字进行了特殊处理,以提高性能并减少内存开销。代码中任何位置(本地或其他)使用的字符串文字都会被 JVM 池化并重用。这样做是为了减少 JVM 中创建的 String 对象的数量。每次代码创建字符串文字时,JVM 首先检查池中的字符串文字。如果该字符串已存在于池中,则返回对池实例的引用。如果池中不存在该字符串,则实例化一个新的 String 对象,然后将其放入池中。 Java 可以进行这种优化,因为字符串是不可变的并且可以共享而不必担心数据损坏。但是,这种行为仅适​​用于字符串文字,不适用于使用“new”关键字创建的对象。

总之,将字符串文字设置为类变量(私有静态最终类字段)或将其保留为局部变量具有相同的效果。

You do not have to worry too much about String literals. String literals are given special treatment by the JVM to increase performance and decrease memory overhead. A string literal used anywhere in your code (local or otherwise) is pooled and reused by the JVM. This is done to cut down on the number of String objects created in the JVM. Each time your code creates a string literal, the JVM checks the string literal in the pool first. If the string already exists in the pool, a reference to the pooled instance is returned. If the string does not exist in the pool, a new String object is instantiated, then is placed in the pool. Java can make this optimization since strings are immutable and can be shared without fear of data corruption. However, this behaviour is true for String literals only and not objects created with the "new" keyword.

In summary, making a string literal a class variable (private static final class field) or keeping it as a local variable has the same effect.

帅气尐潴 2024-10-04 20:52:12

仅为字符串文字创建一个 String 实例。它们存储在String类的“实习生池”中。因此,考虑到这些 String 初始化:

String copy = new String("x");
String alias = copy.intern();

语句 copy != "x"alias == "x" 都是 true。

在这种情况下,如果你只有一个字段,它会更具可读性。

Only one instance of a String is created for a string literal. These are stored in the "intern pool" of the String class. So, given these String initializations:

String copy = new String("x");
String alias = copy.intern();

The statements copy != "x" and alias == "x" are both true.

In this case, it would be much more readable if you just had a field.

桃扇骨 2024-10-04 20:52:12

每次调用函数时 foo 都会被实例化,因为它是方法内的局部变量。这个特定方法是静态的这一事实是无关紧要的。 foo 是 Final 对其实例化也没有影响,它只是意味着 foo 在初始赋值后不能更改。

使其成为私有静态类变量,以确保它仅实例化一次。

foo will be instantiated each time your function is called because it is a local variable inside a method. The fact that this particular method is static is irrelevant. foo being final also has no effect on when it is instantiated, it just means that foo cannot change after the initial assignment.

Make it a private static class variable to ensure it is only instantiated once.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文