Given the code
abstract class Base<Thistype extends Base>
{
public void addOnSomethingListener(Consumer<? super Thistype> action)
{}
public void foo()
{
System.out.println("foo");
}
}
class Simple<Thistype extends Simple> extends Base<Thistype>
{
}
class Test1 extends Simple<Test1>
{
}
class Test2 extends Simple
{
}
class Test
{
public static void main(String[] args)
{
Test1 test1 = new Test1();
Test2 test2 = new Test2();
test1.addOnSomethingListener(test ->
{
test.foo(); // VALID as "test" is of type "Thistype" which is "Test1".
});
test2.addOnSomethingListener(test ->
{
test.foo(); // INVALID as "test" is of type "Thistype" which is "java.lang.Object" instead of "Base" which is the upper bound.
});
}
}
Why is the generic type of class Test2
not defaulted to class Base
but instead defaulted to class java.lang.Object
?
I provided the upper bound, but it seems that that is irrelevant if wildcards are used or when no generic is given at all.
The code in the main function should be able to be compiled if you ask me.