2016-05-11 107 views
1

在Java是未修改方法变量,在一个Java静态/实例方法优化

  1. 静态方法final, 预选赛重新初始化每次缺
  2. 实例方法

如果回答为1.或2.(或两者)final限定符 允许Java执行优化并存储方法 变量只有一次?

如果答案取决于变量的类型,哪种类型的 变量被优化/未优化?例如,String, int优化,而Map未优化?

为了比较,Java的只能存储静态类变量 如

private static final String foo = "Teenage Mutant Ninja Turtle"; 

一次。澄清:问题是是否

1:

static SomeReturnValueOrVoid SomeMethod() { 
    // 1.a Not modified, is this reinitialized each method call? 
    String foo = "Teenage Mutant Ninja Turtle"; 

    // 1.b Marked final, is this reinitialized each method call? 
    final String bar = "Teenage Mutant Hero Turtle"; 
} 

2:

SomeReturnValueOrVoid SomeMethod() { // not static 
    // 2.a Not modified, is this reinitialized each method call? 
    String foo = "Teenage Mutant Ninja Turtle"; 

    // 2.b Marked final, is this reinitialized each method call? 
    final String bar = "Teenage Mutant Hero Turtle"; 
} 

相当于

3:

class SomeClass { 
    static final String foo = "Teenage Mutant Ninja Turtle"; 

    SomeReturnValueOrVoid SomeMethod() { 
     // Uses foo 
    } 

    static SomeReturnValueOrVoid SomeMethod() { 
     // Uses foo 
    } 

    ... 
} 
+0

字符串常量在编译过程中被解析 – AdamSkywalker

+0

除'Map'之外的其他类型,如何在这种情况下处理? –

+0

如果您在方法内部创建新映射,无论它是否为最终映射,它都会每次创建。 – AdamSkywalker

回答

3

不管是static方法还是final变量或两者都没有区别。局部变量的范围意味着每次都会执行此分配(除了优化*之外)。

但是,当涉及到示例中的字符串时,字符串将来自string pool。所以每次都会发生作业,但他们都会参考相同的string实例。

*优化 - JIT compiler可以内联这些值,因此每个解决方案可以与另一个解决方案一样快地运行。所以你不应该尝试微观优化自己,除非你知道实际的性能问题。

+0

感谢提到字符串池,非常宝贵的知识。当然,不成熟的优化是万恶之源。只是有一个好奇心。 –

1

在Java中未修改方法变量,缺乏决赛中,资格赛每次

(该方法被调用)重新初始化 - 当然他们,否则会被初始化。

我认为你真正想问的是,这种初始化可以通过某种方式进行优化吗?如果变量被分配了一个常数值,那么是的; JIT编译器可能完全删除该变量,并用它的(已知常量)值替换对它的引用。

最终限定符是否允许Java执行优化并仅存储方法变量一次?

编号A final -qualified局部变量不能有它的价值变化,但在方法的每次调用都有自己的变量副本,不同的实例可能为同一final变量使用不同的值。考虑:

void someMethod() 
{ 
    final int number = new Random().nextInt(); 
} 

的值不能被程序执行期间只分配一次,因为它每个被调用的方法时是不同的。

对本地变量的final修饰符对优化几乎没有或没有直接影响。它只对变量做了什么限制 - 对任何变量都可能遵循的限制,不管限制如何 - 这又会允许某些优化。如果优化器是值得的,那么它将不会在乎变量是否被声明为final,而是会考虑它是否是有效的常量。

+0

当然!现在点击了。我应该完全意识到这一点,因为方法变量是线程安全的。 –

+0

@FilipAllberg对于其他变量,JIT不关心。除非你声明一个变量volatile,或者执行一些强制它们同步的东西,编译器可以自由地假定没有其他线程修改任何变量。它可以避免多余的加载和存储。这是合理的,因为没有同步,易失性和朋友,Java存储器模型中没有可视性保证(这与硬件的行为相对应;按照核心缓存来考虑)。 – maaartinus