鉴于这些代码示例:
示例1
public class SomeClass {
private static final int onlyUsedByMethodFoo = 1;
// many lines of code
public static void foo() {
final String value = items[onlyUsedByMethodFoo];
}
}
示例2
public class SomeClass {
// many lines of code
public static void foo() {
final int onlyUsedByMethodFoo = 1;
final String value = items[onlyUsedByMethodFoo];
}
}
我更喜欢第二个代码示例,因为该值接近于使用它的位置。它只用于Foo()。我没有看到将它声明为全局值的优势,即使频繁调用Foo()也是如此。我能看到的全局静态值的唯一优势可能在于性能,但目前尚不清楚它将具有多大的性能优势。也许Java认识到这一点并优化字节码。
关于绩效,是否值得在全球宣布一个恒定的价值?性能增益是否合理地将恒定值从程序员使用和读取的位置移动得更远?
答案 0 :(得分:5)
Java编译器用它的值替换所有出现的这个静态final字段;局部变量是运行时堆栈帧的一部分。有关更全面的说明,请参阅The Java® Virtual Machine Specification。
我认为在你的情况下,性能没有任何差异。
答案 1 :(得分:2)
首先,这种微优化并不是您应该关注的细节。如果有的话,在更复杂的代码片段中,性能会有更多的胜利。
这种微优化并不会给你带来太大的影响,你可能会牺牲可读性来获得可忽略的性能提升。
您的代码没有存在巨大性能瓶颈的地方,因此如果您进行任何微优化,我不会指望任何重大的性能优势。
对于你的主要问题,静态最终变量背后的想法将是双重的:
我认为,如果其他类没有使用它,那么它不需要是public
。我仍然建议它是一个类变量,因此它具有样本1的样式,但声明为private static final int onlyUsedByMethodFoo = 1;
。
答案 2 :(得分:0)
对于这种情况,性能(至少对于原始类型)不是问题。更重要的是,“代码质量”,即代码的一致性,可读性和清洁性。 所以,如果你想要一个特定于上下文的变量,定义它真正属于的地方,并且不要弄乱全局上下文
答案 3 :(得分:0)
进行预成熟优化不是一个好习惯。专注于设计,良好的设计易于扩展和维护。如果你有一个好的设计和代码,识别性能问题(如果有的话)不会很麻烦并且可以处理。再次 - 永远不要进行预成熟优化。此外,如今,编译器已经过调整以生成优化的字节码。
答案 4 :(得分:0)
特定Java实现/版本的JIT编译器可以选择基于它可以推断出的关于代码的各种事物进行特别优化。但是,通常,它可以比static final
方法变量更轻松地优化final
类成员。
有问题的变量是原始的(int
)可能会改变事物;如果它是一个参考类型,它的优化就会困难得多。因为它不是一个对象,所以你可以使用引用相等或其他类似的技巧;请考虑此示例,并将其与final int
:
void foo() {
final Object o = new SomeObject();
}
我认为,在这种情况下,final
对性能没有任何帮助,因为语法的期望是如果您要比较o
在单个方法调用之间,它应该是一个不同的对象,即它不会==
来自先前方法调用的o
。但是如果你把它变成一个静态的最终类成员,你真的有一个单例对象。
我不清楚JIT是否必须优化或不优化方法中的final
原语,因为可以想象它只是优化它只存储在一个地方,但很明显,对于引用类型,类成员在内存/ CPU方面将会(略微)降低开销。