为字符串使用静态变量

以下内容取自最佳实践:编写高效代码,但我不明白为什么

private static String x = "example"; 

比…快

 private static final String x ="example"; 

任何人都可以解释一下。

为字符串使用静态变量

当您定义String类型的静态字段(也称为类字段)时,可以通过使用静态变量(而不是final)而不是常量(final)来提高应用程序速度。 对于原始数据类型(例如int)则相反。

例如,您可以创建一个String对象,如下所示:

 private static final String x = "example"; 

对于此静态常量(由final关键字表示),每次使用常量时,都会创建一个临时String实例。 编译器删除“x”并将其替换为字节码中的字符串“example”,以便每次引用“x”时,BlackBerry®Java®VirtualMachine都会执行哈希表查找。

相反,对于静态变量(没有final关键字),String创建一次。 BlackBerry JVM仅在初始化“x”时执行哈希表查找,因此访问速度更快。

 private static String x = "example"; 

您可以使用公共常量(即最终字段),但必须将变量标记为私有。

我没有意识到这一点,但它对我有意义:

JVM具有内部String Literal Cache。 每次使用文字创建String时,JVM都必须在缓存中查找它,如果不存在,则存储它。

现在,编译器可以使用String文字内联最终变量,因为它在编译时是已知的,并且它似乎是性能的好主意。

所以你的代码:

 static final String CONST = "myconst"; ... if (CONST.equals(aVar)) ... case CONST ... 

由编译器重写为:

 static final String CONST = "myconst"; ... if ("myconst".equals(aVar)) ... case "myconst" ... 

如果JVM实现不够聪明,则需要在此示例中查找“myconst”三次。

如果不将CONST标记为“final”,则编译器无法“优化”它,因为变量可能在运行时更改。 您的代码将以1:1编译,JVM只需要在变量中查找Object。

顺便说一句:错误的JVM实现不应该定义您的编码风格。 “final”提供了很多安全性,所以只要它没有真正达到你的性能:不关心它是否会增加或降低你的速度 – 无论如何它对于下一个JVM是不同的

文本解释它,只是阅读它。

但重写它:它更快,因为它。 黑莓jvm的使用方式更好地使用非最终版本。 就像那样,因为它以那种方式设计

这是Blackberry VM的细节。 其他VM可能会采用不同的方式。

旁注:在实际遇到性能问题(这称为“过早优化”)之前,不要过多关注优化,因为如果你这样做很可能会在你永远不会发生的地方泄露性能它来。

有一个运行时String Literal Pool。 当您将Strings创建为Final时,JVM每次使用时都会创建String的副本。 当String是非final时,它会在您第一次创建时插入到String Literal Pool中,之后只是从池中查找它,这样可以避免使用Strings的副本。