这方面的具体指导方针是什么?单独使用哪种方式是否有优化原因或只是良好的实践?是否存在可以偏离正确操作方式的情况?
尽可能在第一次使用变量的地方声明变量。这并不是为了效率,而是使您的代码更可读。变量声明越接近其使用位置,阅读代码时需要滚动/搜索的内容就越少。将变量声明更接近它们首次使用的位置还会自然缩小它们的作用范围。
正确的方法是在第一次使用变量时声明它们,并将变量的作用域尽可能缩小,以使代码更易于理解。
在函数顶部声明变量是从C语言中继承下来的(在那里是必需的),并且没有任何优点(变量作用域仅存在于源代码中,在字节码中所有局部变量都按顺序存在于堆栈上)。永远不要这样做。
有些人可能会试图通过声称它更“整洁”来为这种做法辩护,但需要在方法内部“组织”代码通常表明该方法太长了。
6.3 声明的位置
只在块的开头进行声明。(块是由大括号“{”和“}”包围的任何代码。)不要等到变量首次使用再声明它们;这可能会让不谨慎的程序员感到困惑,并且阻碍代码在作用域内的可移植性。
void myMethod() { int int1 = 0; // beginning of method block if (condition) { int int2 = 0; // beginning of "if" block ... } }
唯一一个例外的规则是在Java中,for循环的索引可以在for语句中声明:
for (int i = 0; i < maxLoops; i++) { ... }
避免本地声明掩盖在更高级别上的声明。例如,不要在内部块中声明相同的变量名:
int count; ... myMethod() { if (condition) { int count = 0; // AVOID! ... } ... }
for
语句的主体中。for( Iterator i= someObject.iterator(); i.hasNext(); )
4.8.2.2 在需要时声明
局部变量不习惯在其所在的块或类似块的开头声明。相反,局部变量在第一次使用它们的地方附近(合理范围内)声明,以最小化它们的作用域。局部变量声明通常具有初始化程序,或者在声明后立即进行初始化。
好吧,我会遵循Google的做法。表面上看,将所有变量在方法/函数的顶部声明可能会更“整洁”,但显然根据需要声明变量会更有益。这是主观的,取决于您感觉哪种方式更直观。
/** Return true iff s is a blah or a blub. */
public boolean checkB(String s) {
// Return true if s is a blah
... code to return true if s is a blah ...
// Return true if s is a blub. */
int helpblub= s.length() + 1;
... rest of code to return true is s is a blah.
return false;
}
在这里,局部变量helpblub被放置在必要的位置,用于测试s是否为blub的代码中。它是实现“如果s是blub,则返回true”的代码的一部分。
把声明helpblub作为方法的第一条语句是毫无逻辑意义的。可怜的读者会想,为什么要有那个变量?它是干什么用的?
我发现将变量在需要时声明比一开始就声明能减少错误。我还发现,在尽可能小的范围内声明它们也可以防止错误。
几年前,我查看了声明位置生成的字节码,发现它们大体上是相同的。根据赋值时间不同,有时会有差异。甚至像这样的:
for(Object o : list) {
Object temp = ...; //was not "redeclared" every loop iteration
}
vs
Object temp;
for(Object o : list) {
temp = ...; //nearly identical bytecoode, if not exactly identical.
}
基本上是一样的
将变量定义在比需要更宽泛的范围内会显著影响代码的可理解性。限定变量的作用域可以表明该变量仅对该小代码块有意义,阅读代码时您不必考虑更多。由于大脑只有微小的短期工作记忆(平均只能追踪7件事情),因此这是一个相当重要的问题。少一件需要追踪的事情就有很大的意义。
同样地,您真的应该尽量避免变量在文字上的意义。尝试一次性分配所有内容,并将其声明为 final,以向读者说明这一点。不必再考虑某些东西是否发生改变,真正减轻了认知负担。