为什么在Java中将公共字段添加到匿名类不起作用?

| 我有一个示例类,如下所示:
public class FooBar {

  void method1(Foo foo){ // Should be overwritten
    ...
  }

}
稍后,当我尝试这样做时:
FooBar fooBar = new FooBar(){
  public String name = null;
  @Override
  void method1(Foo foo){
    ...
  }
};

fooBar.name = \"Test\";
我收到一条错误消息,说名称字段不存在。为什么?     
已邀请:
        因为变量
\"fooBar\"
的类型是
FooBar
(该变量中对象的运行时类型是实现
FooBar
的匿名类的对象,运行时类型也是
FooBar
的子类型)... ...而类型
FooBar
没有该成员。因此,出现编译错误。 (请记住,变量
\"fooBar\"
可以包含任何符合
FooBar
的对象,即使没有ѭ9的对象也是如此,因此编译器会拒绝不是类型安全的代码。) 编辑:对于一种解决方案,请参见irreputable的答案,该答案使用本地类声明创建新的命名类型(以替换帖子中的匿名类型)。 Java不支持执行此操作的方法(主要是:Java不支持有用的类型推断),尽管以下内容确实起作用,即使不是很有用:
(new foobar(){
  public String name = null;
  @Override
  void method1(Foo foo){
    ...
  }
}).name = \"fred\";
快乐的编码。 Scala和C#都支持所需的类型推断,从而支持局部变量的匿名类型专门化。 (尽管C#不支持匿名扩展现有类型)。但是,Java没有。     
        当地的班级会做
{
    class MyFooBar extends FooBar{
        String name = null;
        ...
    };

    MyFooBar fooBar = new MyFooBar();

    fooBar.name = \"Test\";
}
    
        尝试这个。
@SafeVarargs
public static <T> void runWithObject(T object, Consumer<T>... progs) {
    for (Consumer<T> prog : progs)
        prog.accept(object);
}
runWithObject(
    new FooBar() {
        String name = null;
        @Override
        void method1(Foo foo) {
            System.out.println(\"name=\" + name);
        }
    },
    object -> object.name = \"Test\",
    object -> object.method1(new Foo())
);
结果:
name=Test
或者,您可以在Java 10或更高版本中像这样使用
var
var fooBar = new FooBar() {
    public String name = null;

    @Override
    void method1(Foo foo) {
        System.out.println(\"name=\" + name);
    }
};
fooBar.name = \"Test\";
fooBar.method1(new Foo());
    
        
fooBar
是对类型
foobar
的对象的引用,并且此类对象没有字段
name
。就那么简单。而且,由于它是匿名类型,所以引用该字段的唯一方法是通过其“ѭ20”引用。     
        您正在创建类型为“ 18”的对象。编译器仅知道为类/接口“ 18”定义的成员。 记住,java是一种静态语言,而不是动态语言。它不会在运行时检查对象是否存在,而是在编译时根据类型声明进行检查。     
        
fooBar
类型是
foobar
,它没有这样的变量,因此代码无法编译。您可以通过反射访问它。     
        就像大家都说的那样,这是由于静态键入而
FooBar
类不包含
name
。因此它将无法正常工作。 我想指出匿名类的建议用法。 匿名类(或接近Closures,可能是lambdas。类似但不相同)来自功能编程范例,在该范例中状态应该是不可变的。 话虽这么说,为什么还要使用此类课程呢?当您需要快速而简短的事情来完成时,不一定要参加完整的课程。例:
MyTask() //This is a method
{
    new Thread(new Runnable() { //Anonymous class
        public void run()
        {}
    }).start();
}
了解仅将实现包含在一个函数/类中的理解很重要。
scope of the variables defined in the Anonymous class (or closed-over function) should only be used inside the Anonymous class
,无法从其他程序代码访问。 因此,您不应(也不能)设置set29ѭ     
        你也可以这样
Boolean var= new anonymousClass(){
    private String myVar; //String for example
    @Overriden public Boolean method(int i){
          //use myVar and i
    }
    public String setVar(String var){myVar=var; return this;} //Returns self instane
}.setVar(\"Hello\").method(3);
    

要回复问题请先登录注册