FULL PRODUCT VERSION :
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.15063]
EXTRA RELEVANT SYSTEM CONFIGURATION :
Building using Maven
A DESCRIPTION OF THE PROBLEM :
The occurring bug is believed to be from disregard of priority in Token definition when the definition itself is passed to the implementing class.
The Java source code to reproduce this issue can be found under "Steps to Reproduced" section.
When Baz is being defined via Baz<B extends Foo<B>> the initial B, defining the name of the generic token is not what is used when specifying the first generic type of Foo (i.e. Foo<B>). Instead, however, because class B exists within the same scope as Baz, it opts to use the class B instead of the generic type B, which is being defined at that point in time.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
interface Foo<B extends Foo<B>> {}
interface FooBar extends Foo<FooBar> {}
class Main {
interface Baz<B extends Foo<B>> {}
public static class B implements Baz<FooBar> {}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Baz to extend Foo with the generic type being the very generic type definition in Baz, i.e. B the generic type.
ACTUAL -
Baz extends Foo with the generic type being the static class B, and not the generic token, B.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
$ javac Main.java
Main.java:10: error: type argument Main.B is not within bounds of type-variable B
interface Baz<B extends Foo<B>> {}
^
where B is a type-variable:
B extends Foo<B> declared in interface Foo
Main.java:12: error: type argument FooBar is not within bounds of type-variable B
public static class B implements Baz<FooBar> {}
^
where B is a type-variable:
B extends Foo<Main.B> declared in interface Baz
2 errors
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
interface Foo<B extends Foo<B>> {}
interface FooBar extends Foo<FooBar> {}
class Main {
interface Baz<B extends Foo<B>> {}
public static class B implements Baz<FooBar> {}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Remove Baz from the same scope as static class B. The scope itself does not matter, as long as they are not the same.