public class Knowing {
static final long tooth = 343L;
static long doIT(long tooth) {
System.out.print(++tooth + " ");
return ++tooth;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.print(tooth + " ");
final long tooth = 340L;
new Knowing().doIT(tooth);
System.out.println(tooth);
}
}
好的,这是我的问题:
如果我们有一个全局变量声明static final long tooth = 343L;
我们如何在声明为final long tooth = 340L;
的main方法中有另一个变量我只是想知道为什么这是允许的,因为我运行它并且有没有错误?
也不应该使用 className.variableName 来访问全局静态变量,而不是通过创建新的 instance.variable 名称只有警告才允许这样做?
答案 0 :(得分:7)
我们如何在main方法中声明最终长齿= 340L;
因为语言规范说你可以。来自section 6.4.1 of the JLS,关于阴影:
在整个d范围内,名为n shadows的局部变量或异常参数的声明d,(a)在d发生的范围内在范围内的任何其他名为n的字段的声明,以及(b)名为n的任何其他变量的声明,这些变量在d出现的范围内,但未在声明d的最内层类中声明。
你做这个吗?很少。另一方面,我很少看到这是一个问题。
关于你的第二个问题:
也不应该通过使用className.variableName来访问全局静态变量,而不是通过创建一个新的instance.variable名称,只有警告才允许这样做?
这是Java,IMO的一个设计缺陷。即使警告也不是语言规范的一部分。你应该始终避免这样做,因为它会使代码执行除了它正在执行的操作之外的其他操作。我通常给出的例子是:
Thread backgroundThread = new Thread(someRunnable);
backgroundThread.start();
backgroundThread.sleep(1000);
这使执行线程休眠,而不是新线程。
答案 1 :(得分:2)
本地变量使全局变得黯然失色。但是你仍然可以使用classname.variable来访问全局。
答案 2 :(得分:1)
tooth
中的main
变量是局部变量,优先于全局变量。如果您想访问全局的,请按以下方式引用this.tooth
。
如果您想了解有关变量和范围的更多信息,建议您阅读Oracle Docs.
答案 3 :(得分:1)
参数/变量隐藏是语言设计中的常见功能。例如,第三方库中的方法的客户端无法控制库用于形式参数的名称。语言设计的另一个常见做法是一致性。这意味着你可以在任何地方声明一个变量,你可以从外部范围隐藏一个类似命名的变量。请注意,如果您尝试在相同范围内声明与变量同名的局部变量,则会从编译器中收到错误。
使用Builder模式时,静态变量的非静态访问是一个方便的功能。但是,它具有欺骗性(如图所示的另一个答案),因此编译器将其标记为警告。
答案 4 :(得分:1)
首先className.variableName is a legal way of accessing a static member, but its possible to create an instance of the class which has the static member
,访问该静态成员。将此视为一个错误或缺陷,在Math这样的类中变得不可能,其中构造函数是私有的,而且该类中没有实例变量,因此创建对象无用。
对于Scope的事情请看这个链接
http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.4.1