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

2022-09-03 12:17:24

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

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";

我收到一个错误,指出名称字段不存在。为什么?


答案 1

因为变量的类型是(所述变量中对象运行时类型是匿名类实现的类型,它也是)..."fooBar"FooBarFooBarFooBar

...并且该类型没有所述成员。因此,会出现编译错误。(请记住,该变量可以包含任何符合 的对象,即使没有 的对象也是如此,因此编译器会拒绝非类型安全的代码。FooBar"fooBar"FooBarname

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

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

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

快乐编码。


Scala 和 C# 都支持局部变量所需的类型推断,从而支持匿名类型特化。(尽管 C# 不支持匿名扩展现有类型)。然而,Java却没有。


答案 2

本地类可以

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

    MyFooBar fooBar = new MyFooBar();

    fooBar.name = "Test";
}

推荐