Why does adding a public field to an anonymous class in Java not work?

后端 未结 8 1591
渐次进展
渐次进展 2020-12-17 15:48

I have an example class defined like below:

public class FooBar {

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

}

Later,

相关标签:
8条回答
  • 2020-12-17 16:23

    A local class would do

    {
        class MyFooBar extends FooBar{
            String name = null;
            ...
        };
    
        MyFooBar fooBar = new MyFooBar();
    
        fooBar.name = "Test";
    }
    
    0 讨论(0)
  • 2020-12-17 16:27

    fooBar type is foobar which has not such variable and therefore the code can not be compiled. You can access it by reflection.

    0 讨论(0)
  • 2020-12-17 16:33

    You're creating an object of type foobar. The compiler only knows about the members defined for the class/interface foobar.

    Remember, java is a static language, not dynamic. It doesn't check the object at runtime for what exists, it checks at compile time based on the type declaration.

    0 讨论(0)
  • 2020-12-17 16:36

    Try this.

    @SafeVarargs
    public static <T> void runWithObject(T object, Consumer<T>... progs) {
        for (Consumer<T> prog : progs)
            prog.accept(object);
    }
    

    and

    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())
    );
    

    result:

    name=Test
    

    Or you can use var like this in Java 10 or later.

    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());
    
    0 讨论(0)
  • 2020-12-17 16:43

    You can also do it like this

    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);
    
    0 讨论(0)
  • 2020-12-17 16:44

    Because the type of the variable "fooBar" is FooBar (the run-time type of the object in said variable is that of the anonymous class implementing FooBar which is also a subtype of FooBar)...

    ...and the type FooBar does not have said member. Hence, a compile error. (Remember, the variable "fooBar" can contain any object conforming to FooBar, even those without name, and thus the compiler rejects the code which is not type-safe.)

    Edit: For one solution, see irreputable's answer which uses a Local Class Declaration to create a new named type (to replace the anonymous type in the post).

    Java does not support a way to do this (mainly: Java does not support useful type inference), although the following does work, even if not very useful:

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

    Happy coding.


    Both Scala and C# support the required type inference, and thus anonymous type specializations, of local variables. (Although C# does not support extending existing types anonymously). Java, however, does not.

    0 讨论(0)
提交回复
热议问题