查询java中的变量范围

ano*_*428 0 java

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

好的,这是我的问题:

  • 如果我们声明了一个全局变量static final long tooth = 343L;我们怎么能在声明的main方法中有另一个变量final long tooth = 340L;我只想知道为什么这是允许的,因为我运行它并且没有错误?

  • 并且也不应该通过使用className.variableName来访问全局静态变量齿,而不是通过创建一个新的instance.variable名称,只有一个警告才允许这样做?

Jon*_*eet 7

我们如何在main方法中声明最终长齿= 340L的另一个变量;

因为语言规范说你可以.从JLS的第6.4.1节开始,关于阴影:

在整个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);
Run Code Online (Sandbox Code Playgroud)

这使得执行线程休眠,而不是新线程.