简体   繁体   English

Java转发引用在不同情况下的行为是否有所不同?

[英]Does java forward referencing act differently in different situations?

Please take a look at this snippet: 请查看以下代码段:

public class A {
    void method() {
        System.out.print(B.j);//This is legal!
        class C {
            void method () {
                System.out.print(j);//This is illegal!
            }
        }
        final int j = 10;
        class D {
            void method() {
                System.out.print(j);//This is legal!
            }
        }
    }
}
class B {
    static int j = 10;
}

We can access the 'Bj' in a place before it's definition whilst this is illegal in the case of accessing 'final int j' in class C. 我们可以在定义之前的某个地方访问“ Bj”,而在C类中访问“ final int j”的情况则是非法的。

Does java compiler looks at local classes as simple variables/objects? Java编译器是否将本地类视为简单变量/对象? Specially, what's the rationale behind this behavior? 特别是,这种行为背后的原理是什么? I mean forward checking is working for the Bj but it doesn't work for the 'j' inside the class C. 我的意思是向前检查对Bj有效,但对C类中的'j'不适用。

I believe this is simple scoping. 我相信这很简单。 If you replace your inner classes with simple System.out.println() calls, 如果您将内部类替换为简单的System.out.println()调用,

public class A {
  void method() {
    System.out.print(j);//This is illegal!
    final int j = 10;
    System.out.print(j);//This is legal!
  }
}

you'll find you get the same message. 您会发现收到相同的消息。 The scope of local variables starts where they are declared and continues through the end of the block they're declared in. 局部变量的范围从声明它们的位置开始,一直持续到声明它们的块的末尾。

To answer your question about the reference to B: Consider 要回答有关对B的引用的问题:

public class A {
  void method() {
    System.out.print(k);//This is legal!
  }
  int k=17;
}

Java is not a single-pass compilation. Java不是单遍编译。 Classes, and their exposed fields and methods, can be forward referenced. 类及其公开的字段和方法可以向前引用。 A deliberate decision was made that local variables can not be forward referenced. 做出了一个故意决定,即不能向前引用局部变量。 I'm guessing that this was to let programmers establish restricted scopes without having to use additional levels of {} block statements -- if I introduce a new variable, especially with an initialization, I don't want anyone tampering with it before that. 我猜想这是为了让程序员不必使用附加级别的{}块语句就可以建立受限的作用域-如果我引入一个新变量,尤其是在初始化时,我不希望有人在此之前对其进行篡改。

That's how Java local variables happen to work. 这就是Java局部变量发生作用的方式。 This may not be a satisfying answer, but it's the best one we've got. 这可能不是令人满意的答案,但这是我们得到的最好的答案。

Setting the possibility that your code does not compile aside... 设置代码无法编译的可能性...

When class A is loaded by the classloader into memory, so is class B, because they're in the same file. 当类加载器将类A加载到内存中时,类B也会加载到内存中,因为它们位于同一文件中。 So Bj is already allocated on the heap when method is called at runtime. 因此,在运行时调用method时,Bj已分配在堆上。

On the other hand, when you declare variables in a method, those variables are stored on the stack when the method is invoked, in the order that you write them, so here order matters. 另一方面,当您在方法中声明变量时,这些变量在调用该方法时会按照您编写它们的顺序存储在堆栈中,因此这里的顺序很重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM