(我一直在重新阅读那个问题标题并思考它必须看起来有多荒谬,但我向你保证这是问题的最佳描述,而且我有一个实际应用,这是最好的结构。我发誓我“我不疯狂。”
请考虑以下事项。每个块都是一个单独的文件:
package myPackage;
public class A {
public int i;
public A(int i) {
this.i = i;
}
public class B {
}
}
package myPackage;
import myPackage.A.B;
public class Main {
public static void main(String[] args) {
class C extends B {
public C(A enclosingInstance) {
enclosingInstance.super();
}
public void show() {
System.out.println(A.this.i);
}
}
A myA = new A(2);
C myC = new C(myA);
myC.show();
}
}
请注意,enclosingInstance
业务是解决涉及中间构造函数调用的问题。请参阅"Why can't outer classes extend inner classes?"。
我希望输出为“2”。但相反,我在System.out.println(A.this.i);
上有编译错误:
在范围
中无法访问类型A的封闭实例
我认为我试图解决的程序化概念是合理的:在main
内创建一种新类型的B,以便给A使用A类中可以访问的东西。
那么我做错了什么,或者为什么这在Java中不可能?
编辑/更新:请注意,当main
中的代码移动到非静态方法时,会出现相同的错误。也就是说,我尝试将static void main
内的所有内容移动到名为class Main
的{{1}}新的非静态方法。然后我将go()
更改为单行static void main
。错误在同一位置。因此,在静态上下文中定义new Main().go();
似乎不是问题。
答案 0 :(得分:3)
这是一个荒谬的代码,你永远不应该为生产而写。
部分地在Explicit Constructor Invocations
的文档中进行了解释合格的超类构造函数调用以
.75
开头 表达式或Primary
。它们允许子类构造函数 显式指定新创建的对象立即封闭 关于直接超类的实例(第8.1.3节)。 这可能是 当超类是内部类时必需。
所有这些都说ExpressionName
是一个本地类(which is an inner
class, which is kind of nonsense because if you declare it in a static
method there is no enclosing instance),它是C
的子类,但不是B
的嵌套类。因此,没有封闭的实例。 A
的实例没有封闭实例。 (虽然如果你在实例方法中声明它,但那将是C
的实例。)
新创建的对象立即封闭实例(来自JLS)是通过构造函数参数间接指定的。
您必须自己存储
Main
由于private A enclosingInstance;
public C(A enclosingInstance) throws CloneNotSupportedException {
enclosingInstance.super();
this.enclosingInstance = enclosingInstance;
}
为A#i
,您可以正常访问
public
答案 1 :(得分:3)
您希望A.this
引用B
实例的封闭实例。但为什么要呢?这不是语法的意思。 A.this
表示A
实例的封闭C
实例,这没有意义,因为C
不是A
的内部类。
为了更清楚,以下是C
A
的内部类的示例。
public class A {
public int i;
public A(int i) {
this.i = i;
}
public class B {
void foo() {
System.out.println(A.this.i);
}
}
public class C extends B {
C(A a) {
a.super();
}
void bar() {
System.out.println(A.this.i);
}
}
public static void main(String[] args) {
A a1 = new A(1);
A a2 = new A(2);
C c = a1.new C(a2);
c.foo();
c.bar();
}
}
此处C
扩展B
,C
和B
都是A
的内部类。因此,任何C
都有一个封闭的A
实例,当它被视为A
时它还有一个封闭的B
实例,并且这些封闭的实例是不同的(正如foo
和bar
打印不同的数字所证明的那样)。
所以,A.this
不可能意味着你想要的意思,因为它已经意味着别的东西。我想语言设计者没有提出其他语法来表示超类的封闭实例的原因是因为这样的语法会非常复杂,几乎没有回报(简单的解决方法已经存在)。
答案 2 :(得分:1)
根据提供的信息,我会这样做:
public class B {
protected A getOuterInstance() {
return A.this;
}
}
并让C
继承并使用此方法。我知道你不喜欢这种方法,但这是我能看到的最简单的答案。有了更多的信息,我可能会提出一个不会涉及任何内部类的设计,因为这不是内部类的正常用例。