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

Jes*_*ris 13 java anonymous-class

我有一个如下定义的示例类:

public class FooBar {

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

}
Run Code Online (Sandbox Code Playgroud)

后来,当我尝试这个:

FooBar fooBar = new FooBar(){
  public String name = null;
  @Override
  void method1(Foo foo){
    ...
  }
};

fooBar.name = "Test";
Run Code Online (Sandbox Code Playgroud)

我收到一个错误,说明名称字段不存在.为什么?

小智 15

因为类型的变量"fooBar"FooBar(在运行时类型的的对象,在所述变量是匿名类的实现FooBar这也是一个亚型FooBar)...

......并且该类型FooBar没有所述成员.因此,编译错误.(请记住,变量"fooBar"可以包含任何符合的对象FooBar,甚至包含没有的对象name,因此编译器会拒绝非类型安全的代码.)

编辑:对于一个解决方案,请参阅不可响应的答案,该答案使用本地类声明来创建新的命名类型(以替换帖子中的匿名类型).

Java 支持这样做的方法(主要是:Java不支持有用的类型推断),尽管以下方法确实有效,即使不是很有用:

(new foobar(){
  public String name = null;
  @Override
  void method1(Foo foo){
    ...
  }
}).name = "fred";
Run Code Online (Sandbox Code Playgroud)

快乐的编码.


Scala和C#都支持所需的类型推断,因此支持局部变量的匿名类型特化.(尽管C#不支持匿名扩展现有类型).但是,Java没有.


irr*_*ble 7

一个本地类会做

{
    class MyFooBar extends FooBar{
        String name = null;
        ...
    };

    MyFooBar fooBar = new MyFooBar();

    fooBar.name = "Test";
}
Run Code Online (Sandbox Code Playgroud)