Why does adding a public field to an anonymous class in Java not work?
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.
A local class would do
{
class MyFooBar extends FooBar{
String name = null;
...
};
MyFooBar fooBar = new MyFooBar();
fooBar.name = "Test";
}
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());
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.