【问题标题】:Referencing fields of an Inner Class [duplicate]引用内部类的字段[重复]
【发布时间】:2018-09-21 20:20:01
【问题描述】:

我是 java 新手,想了解匿名内部类的工作原理。

Object a = new Object(){
    Object b = new Object(){
        String c = "Hi!";
    };
};

System.out.println( a.b.c );

当我尝试运行上面的代码时,我收到“找不到符号”错误。有人可以解释一下为什么会出现这个错误,我该如何引用字符串 c。

我尝试“可能很奇怪”的原因是我想以分层方式组织小部件句柄,例如“ui.menu.file.open”。

【问题讨论】:

  • a 的类型是Object,而b 不是其接口的一部分。为此,您需要一个非匿名类。
  • 如果您想要分层常量,请尝试嵌套类,例如,class Ui { class Menu { class File { static final String OPEN = "foo"; }}}

标签: java anonymous-class


【解决方案1】:

虽然变量a动态 类型是具有字段c 的匿名类型,但它的静态 类型是Object,它没有字段c.

一旦 Java 引入了隐式派生类型的 var 声明,您将能够解决这个问题。不幸的是,this wouldn't be available until Java 10

// ** WARNING ** This would not compile until Java 10
var a = new Object() {
    String c = "Hi!";
};
System.out.println( a.c );

在此之前,您必须为匿名对象声明一个通用类型,并让它公开您需要的属性:

interface HasMyProperty {
    String getC();
}
interface HasMyObject {
    HasMyProperty getB();
}
...
HasMyObject a = new HasMyObject() {
    HasMyProperty b = new HasMyProperty() {
        private final String c = "Hi!";
        @Override
        public string getC() { return c; }
    };
    @Override
    public HasMyProperty getB() { return b; }
};
System.out.println( a.getB().getC() );

【讨论】:

  • @cppbeginner 对,我没有看到那里的第二层。我现在删除了它,并为当前的 Java 版本添加了一个更实际的示例。
【解决方案2】:

这里bc 是匿名类的字段,但您不能在匿名类之外引用它们,因为类的类型是Object,而Object 类没有这些字段。
虽然在匿名类本身中引用这些字段是合法的,例如:

Object a = new Object(){

    Object b = new Object(){

        String c = "Hi!";
        @Override
        public String toString(){
            return c;
        }
    };
};

为了解决您的要求(访问自定义字段),您不应使用匿名类,而应使用您自己的呈现预期结构的类,例如:

public class A{
   public B b = new B();
}
public class B{
   public String c = "Hi";
}

所以你可以写(虽然完全不推荐公共实例字段):

String c = new A().b.c;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-31
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 2021-08-03
    • 2015-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多