Java 范围规则和内部类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4848036/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java scoping rules and inner classes
提问by David K.
All the crazy Java scoping rules are making my head spin and the public static voidnonsense isn't helping matters. So far all the programming languages I have used either lexical scoping or some approximation of it without any access modifiers, i.e. inner stuff captures outer stuff and has access to the outer stuff as long as the inner stuff exists.
所有疯狂的 Java 范围规则都让我头晕目眩,而公共静态无效的废话也无济于事。到目前为止,我使用的所有编程语言要么是词法范围,要么是它的一些近似,没有任何访问修饰符,即内部内容捕获外部内容并且只要内部内容存在就可以访问外部内容。
So how do I make sense of the scoping rules for inner classes in Java? Do they get access to variables declared in the outer class or is there some weird edge cases I have to worry about because of all the public static privatestuff floating around?
那么如何理解 Java 内部类的范围规则呢?他们是否可以访问在外部类中声明的变量,或者是否有一些奇怪的边缘情况我不得不担心,因为所有公共静态私有东西都在浮动?
回答by Ted Hopp
Static nested classes1are exactly like external classes except that they have access to all members of the outer class, regardless of access qualifier. They exist apart from any instance of the outer class, so need a reference to an instance in order to access any instance variables or non-static methods of the outer class.
静态嵌套类1与外部类完全一样,除了它们可以访问外部类的所有成员,而不管访问限定符如何。它们存在于外部类的任何实例之外,因此需要对实例的引用才能访问外部类的任何实例变量或非静态方法。
Non-static nested classes (called inner classes) come into existence only in the context of an instance of the outer class. When constructed, they have a second this
field automatically generated, which you can access from within the inner class using the syntax Outer.this
. Each instance of the inner class is enclosed by a single instance of the outer class. Again, all the access privileges of static nested classes apply to inner classes. But since they already have an instance of the outer class available, they can automatically access instance variables and methods of the outer class.
非静态嵌套类(称为内部类)仅在外部类实例的上下文中存在。构造时,它们会this
自动生成第二个字段,您可以使用语法从内部类中访问该字段Outer.this
。内部类的每个实例都被外部类的单个实例包围。同样,静态嵌套类的所有访问权限都适用于内部类。但是由于它们已经有可用的外部类的实例,因此它们可以自动访问外部类的实例变量和方法。
For a nice (and very detailed) discussion of inner classes and access specifiers, you can read through the Inner Class Specification. It describes, among other things, how a nested class gets access to private
members of its outer class(es). A gentler read is the Nested Classes tutorial.
有关内部类和访问说明符的精彩(且非常详细)的讨论,您可以通读内部类规范。它描述了嵌套类如何访问private
其外部类的成员等。更温和的阅读是嵌套类教程。
An off-topic aside: Suppose you have this class structure:
题外话:假设你有这个类结构:
public class O {
public O() { ... }
public class I { // an inner class
public I() { ... }
...
}
...
}
and you've created an instance of O
:
并且您已经创建了一个实例O
:
O outer = new O();
Now suppose you want to create an instance of O.I
. you can't just use new O.I()
because the new instance of I
needs to be enclosed by a specific instance of O
. For this, Java provides the following syntax:
现在假设您要创建O.I
. 您不能仅仅使用,new O.I()
因为 的新实例I
需要被特定的O
. 为此,Java 提供了以下语法:
O.I inner = outer.new O.I();
Then inner
will then have its second this
field set to refer to outer
.
然后inner
将其第二个this
字段设置为引用outer
.
Note that this "qualified new
operator" syntax is only used for inner classes; it would be unnecessary (in fact, an error) if I
were a static
nested class.
请注意,这种“限定new
运算符”语法仅用于内部类;如果I
是static
嵌套类,则没有必要(实际上是错误)。
1 You'll often come across the phrase "static inner class" (including, embarrassingly, in an earlier version of this answer). This is incorrect terminology. In Java, "inner classes" are specifically non-static
nested classes.
1 您经常会遇到“静态内部类”这个词(令人尴尬的是,在此答案的早期版本中)。这是不正确的术语。在 Java 中,“内部类”特别是非static
嵌套类。
回答by Daniel
You have to differenciate:
你必须区分:
- Static inner classes have access to all static members outside their declaration.
- Instance inner classes have access to all class members outside their declaration, AND to finalfields in the function they are declared in.
- 静态内部类可以访问其声明之外的所有静态成员。
- 实例内部类可以访问其声明之外的所有类成员,并且可以访问声明它们的函数中的最终字段。
Have in mind that a non-static inner class also has a hidden variable with the instance of the outer class, to access the members there. And that all referenced final fields (therefore they must be final) are copied into the inner class in other hidden member variables when the inner class is instantiated.
请记住,非静态内部类也有一个带有外部类实例的隐藏变量,用于访问那里的成员。并且当内部类被实例化时,所有引用的最终字段(因此它们必须是最终的)被复制到其他隐藏成员变量中的内部类中。
Example:
例子:
public void doStuff(final int a, int b) {
final int c; // Can be referenced
int d; // Cannot be referenced, not final
executer.execute( new Runnable() {
public void run() {
System.out.println("a: "+a+" c: "+c);
}
}
b++; // Not final, not referencable
System.out.println(b);
}
回答by Andre85
I don't know if it helps, but from the java tutorials:
我不知道它是否有帮助,但来自java 教程:
Static Nested Classes
As with class methods and variables, a static nested class is associated with its outer class. And like static class methods, a static nested class cannot refer directly to instance variables or methods defined in its enclosing class— it can use them only through an object reference. Note: A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.
Inner Classes[Non-Static Nested class?]
As with instance methods and variables, an inner class is associated with an instance of its enclosing class and has direct access to that object's methods and fields. Also, because an inner class is associated with an instance, it cannot define any static members itself.
静态嵌套类
与类方法和变量一样,静态嵌套类与其外部类相关联。和静态类方法一样,静态嵌套类不能直接引用在其封闭类中定义的实例变量或方法——它只能通过对象引用来使用它们。注意:静态嵌套类与其外部类(和其他类)的实例成员交互,就像任何其他顶级类一样。实际上,静态嵌套类在行为上是一个顶层类,为了方便打包,它嵌套在另一个顶层类中。
内部类[非静态嵌套类?]
与实例方法和变量一样,内部类与其封闭类的实例相关联,并且可以直接访问该对象的方法和字段。此外,由于内部类与实例相关联,因此它本身不能定义任何静态成员。
You should check the java tutorial on nested classes.
您应该查看有关嵌套类的 Java 教程。
回答by alexvipul
Rules of the Inner classes in Java
Java内部类的规则
- In Java it is possible to define a class inside another class such classes are called nested classes or inner class.
- There are 3 types of the Inner classes Instance Inner class, static inner class and anonymous inner class
- If the Inner class is declared as instance inner class then it can access all of the members of the outer enclosing class including private members
- If the Inner class is declared as static then it can only access the static members of the outer class (including the private static members). But it can NOT access the instance members
- Consider that there is a variable x is defined in both the outer class and the instance inner classes then general form for accessing the variable from the inner class is
this.x
for the inner x andOuterClassname.this.x
for the outer x. - You can also define an inner class inside any method or any other block
- The general form for instantiating the inner class from outside the outer class is
Outer.Inner ob = new Outer.new Inner();
- The general form for instantiating the inner class from outside the outer class is (if the inner class is declared as static)
Outer.Inner ob = new Outer.Inner();
- The Inner classes can be declared with any of the access modifier keywords
- If the Inner class is declared as private then it can NOT be instantiated from outside the outer class. Also in this case you can NOT access the members of the Inner class from outside the outer class even you have an object reference and even if the members of the private inner class are declared as public.
- If the Inner class is declared as instance inner class then it can also access the superclass members of the outer class through the general statement
Outer.super.variable;
Outer.super.method(params);
- 在 Java 中,可以在另一个类中定义一个类,这样的类称为嵌套类或内部类。
- 内部类有 3 种类型:实例内部类、静态内部类和匿名内部类
- 如果内部类被声明为实例内部类,那么它可以访问外部封闭类的所有成员,包括私有成员
- 如果内部类声明为静态,则它只能访问外部类的静态成员(包括私有静态成员)。但它不能访问实例成员
- 考虑到在外部类和实例内部类中都定义了一个变量 x,那么从内部类访问变量的一般形式是
this.x
内部 x 和OuterClassname.this.x
外部 x。 - 您还可以在任何方法或任何其他块中定义内部类
- 从外部类外部实例化内部类的一般形式是
Outer.Inner ob = new Outer.new Inner();
- 从外部类外部实例化内部类的一般形式是(如果内部类声明为静态)
Outer.Inner ob = new Outer.Inner();
- 可以使用任何访问修饰符关键字声明内部类
- 如果内部类被声明为私有,那么它就不能从外部类的外部实例化。同样在这种情况下,即使您有对象引用,即使私有内部类的成员被声明为公共,您也无法从外部类外部访问内部类的成员。
- 如果将内部类声明为实例内部类,那么它还可以通过通用语句访问外部类的超类成员
Outer.super.variable;
Outer.super.method(params);
回答by user2701769
Rules for inner class
内部类规则
- Outer class accessed by inner class
- Inner class can't be accessed by outer class
- The inner class members only used the methods and members within the class only access the fulled information
- 内部类访问外部类
- 内部类不能被外部类访问
- 内部类成员只使用方法,类内成员只访问完整信息
回答by Shikhar
Method Scoped inner classes:- Can only access the final members of the outer class.
方法作用域内部类:- 只能访问外部类的最终成员。