Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从nester内部类访问外部内部类_Java_Inner Classes_Anonymous Class_Anonymous Inner Class - Fatal编程技术网

Java 从nester内部类访问外部内部类

Java 从nester内部类访问外部内部类,java,inner-classes,anonymous-class,anonymous-inner-class,Java,Inner Classes,Anonymous Class,Anonymous Inner Class,我有以下代码: public class Bar {} public class FooBar {} public class Foo { public void method() { new Bar() { void otherMethod() { } void barMethod() { new FooBar() { void fooBa

我有以下代码:

public class Bar {}
public class FooBar {}

public class Foo {

    public void method() {
        new Bar() {

            void otherMethod() { }

            void barMethod() {

                new FooBar() {

                    void fooBarMethod() {
                        Bar.this.otherMethod(); // not compiles
                    }   
                };
            }
        };
    }

}

所以我有一个匿名内部类,其中有另一个匿名内部类。问题:是否有任何方法可以从内部类
FooBar
访问外部内部类
Bar
的方法?

您可以使用简单的名称直接调用该方法:

void fooBarMethod() {
    otherMethod(); // compiles
}
当您在
new FooBar()
匿名类中定义另一个名为
otherMethod()
的方法时,这将失败

Bar。这个
不会真正起作用,因为那里是一个匿名类,其名称在编译时给出。它将得到一个类似于
Foo$1
的名称。所以,不,你不能有类似于
条的东西。这是


好的,我已经编写了这个源文件:

class Bar { }

class FooBar { }

public class Demo {

    public static void main() {
        new Demo().method();
    }

    public void method() {
        new Bar() {

            void otherMethod() { System.out.println("Hello"); }

            void barMethod() {

                new FooBar() {

                    void fooBarMethod() {
                        otherMethod(); // not compiles
                    }   
                }.fooBarMethod();
            }
        }.barMethod();
    }
}
生成的类文件将是:

Bar.class
FooBar.class
Demo.class

Demo$1.class    // For `new Bar()` anonymous class
Demo$1$1.class  // For `new FooBar()` anonymous class
现在,让我们直接进入
newfoobar()匿名类的字节码。该类将命名为-
Demo$1$1
。因此,运行
javap
命令,我得到以下输出:

class Demo$1$1 extends FooBar {
  final Demo$1 this$1;

  Demo$1$1(Demo$1);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #1                  // Field this$1:LDemo$1;
       5: aload_0
       6: invokespecial #2                  // Method FooBar."<init>":()V
       9: return

  void fooBarMethod();
    Code:
       0: aload_0
       1: getfield      #1                  // Field this$1:LDemo$1;
       4: invokevirtual #3                  // Method Demo$1.otherMethod:()V
       7: return
}
class Demo$1$1扩展了FooBar{
最终演示1美元这1美元;
演示$1$1(演示$1);
代码:
0:aload_0
1:aload_1
2:putfield#1//fieldthis$1:LDemo$1;
5:aload_0
6:invokespecial#2//方法FooBar.“:()V
9:返回
void fooBarMethod();
代码:
0:aload_0
1:getfield#1//此字段为$1:LDemo$1;
4:invokevirtual#3//方法演示$1。其他方法:()V
7:返回
}
final
字段中有一个对
newbar()
实例的引用副本。因此,
otherMethod()
这个$1
引用上被调用,它是对
newbar()
匿名内部类实例的引用。好吧,您只是想这样做,但是因为这是一个匿名的内部类,所以您不能直接访问
这个
引用。但是,这是隐含的


有关更详细的分析:


如果命名它们,那么它们就不是匿名内部类,它们只是内部类。如果您不给它们命名,那么您就不能显式地调用它们,尽管如果没有名称冲突,您可以调用它们

但是,您的代码完全无效,您正在创建一个新的Bar,但从未定义一个名为Bar的类


忘记你说的“不编译”这句话,第一个“new Bar()”不编译…

这是一个纯粹的理论问题还是你打算这么做?这是一个理论问题。:)阅读。@Miseraverable,@Tim B我扩展了这个例子。抱歉,我认为很明显,
Bar
FooBar
是现有的类型,可以在匿名类中进行扩展。我想在这种情况下,
Bar
是接口、抽象类还是类并不重要。调用的
otherMethod
方法是什么引用?基本上,它为什么工作?简单的解决方案。那么从
FooBar
访问
Bar
对象本身会怎么样呢?“
Bar.this
”)@SotiriosDelimanolis仍在解码它。坦率地说,这是一个非常复杂的代码。@WonderCsabo不,你不能那样做。这是一个匿名的内部类。它在编译时获得名称。我认为很明显,这只是一个简化的示例,可以假设
Bar
FooBar
是现有的非最终类。