gpt4 book ai didi

Java性能: private static final String vs local String ?堆空间中创建的对象数量

转载 作者:行者123 更新时间:2023-12-01 16:44:50 24 4
gpt4 key购买 nike

在这段代码中,每次我调用 goodMethod() 时,它将使用在堆空间中通过静态字创建的唯一对象。

我的问题是:当我调用 badMethod() 时,每次调用此方法时是否都会在堆空间中创建一个新的 String 对象?因此,如果我调用我的方法 1_200_000 次,它是否会在堆空间中创建 1_200_000 个字符串对象?

毫无疑问第一种方法更好(对于代码的可读性和可维护性)。我在这里只是询问内存中创建的对象的数量

谢谢

我在谷歌上读到了很多关于这方面的内容,但没有找到带有论证或证据的回应。如果您知道我如何测试这个,也请感谢分享。

public class Main {

private static final String HELLO = "hello";
private static final String WORLD = "world";

public static void main(String[] args) {

for (int i = 0; i < 1_200_000; i++) {
goodMethod();
badMethod();
}

}

private static void goodMethod(){
System.out.println(HELLO);
System.out.println(WORLD);
}

private static void badMethod(){
System.out.println("hello");
System.out.println("world");
}

}


// an other example
Map<String, Object> map = new HashMap<>();
map.put("myKey", xxx.getYYY());
// somewhere else
map.put("myKey", zzz.getYYY());

// instead of :
private static final String MY_KEY = "myKey"
map.put(MY_KEY, xxx.getYYY());
map.put(MY_KEY, zzz.getYYY());

编辑:我不是在询问串联,我已从示例代码中删除了串联

最佳答案

查看代码示例

public class Main {
private static final String HELLO = "hello";
private static final String WORLD = "world";

private static void goodMethod(){
System.out.println(HELLO);
System.out.println(WORLD);
}

private static void badMethod(){
System.out.println("hello");
System.out.println("world");
}
}

goodMethod()badMethod() 之间没有任何区别。

关键点在于,不仅"hello""world"是编译时常量,HELLO也是编译时常量。 WORLD 也是如此。

The Java® Language Specification说:

A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.28). Whether a variable is a constant variable or not may have implications with respect to class initialization (§12.4.1), binary compatibility (§13.1), reachability (§14.21), and definite assignment (§16.1.1).

§13.1 :

A reference to a field that is a constant variable (§4.12.4) must be resolved at compile time to the value V denoted by the constant variable's initializer.

If such a field is static, then no reference to the field should be present in the code in a binary file, including the class or interface which declared the field.

换句话说,对 HELLOWORLD 的字段引用在编译时得到解析,并替换为它们的常量值,就像您将这些值写入第一名。

您可以通过查看字节码来验证这一点,例如使用javap -p -c 主要:

Compiled from "Main.java"
public class Main {
private static final java.lang.String HELLO;

private static final java.lang.String WORLD;

public Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return

private static void goodMethod();
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #4 // String hello
5: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: ldc #6 // String world
13: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
16: return

private static void badMethod();
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #4 // String hello
5: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: ldc #6 // String world
13: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
16: return
}

您不需要了解字节码的所有细节,就能看到 goodMethod()badMethod() 两种方法的编译代码是相同的。当然,相同的代码不能因其创建方式而产生性能差异。

这同样适用于您的第二个示例,使用字符串文字或常量变量没有区别。

关于编码风格,我同意Peter Lawrey’s answer 。当常量变量的名称没有提供附加含义时,使用常量变量不会改进代码。如果没有这样的含义,实际值就比变量名更能说明问题。另请参阅this answer .

关于Java性能: private static final String vs local String ?堆空间中创建的对象数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53835748/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com