This is mostly just an example of Foo<Subclass>
not being a subtype of Foo<Superclass>
. See: Is List<Dog> a subclass of List<Animal>?
The problem is in the signature of FizzBuzzNetwork.class
:
The type of C.class, where C is the name of a class, interface, or array type (§4.3), is Class.
So FizzBuzzNetwork.class
is Class<FizzBuzzNetwork>
, which is not a superclass of Class<FizzBuzzNetwork<PRM,?>>
in the same way that List<Animal>
is not a superclass of List<Dog>
.
You could get around this by casting the operand to a raw Class
reference, and then downcasting it back:
(Class<? extends FizzBuzzNetwork<PRM, ?>>) (Class) FizzBuzzNetwork.class
This will give you an unchecked cast warning, which you can suppress via SuppressWarnings("unchecked")
. But keep in mind that the warning is there for a reason. Specifically, the class' parameters aren't there at runtime due to erasure. So Class<? extends FizzBuzzNetwork<PRM, ?>>
is exactly the same as Class<FizzBuzzNetwork>
, which could lead to confusing bugs.
For instance, if you use its instanceof
method to check, it can't check if something is an instance of FizzBuzzNetwork<PRM, ?>
as opposed to, say, FizzBuzzNetwork<NotAPrm, ?>
-- that information is erased from the runtime. The check will succeed (they're both FizzBuzzNetwork objects, which is all the check can look for), but trying to use it to work with PRMs will likely lead to a ClassCastException.
If you wanted to be safe, you should require just a Class<FizzBuzzNetwork>
, as Java provides. Then, whenever you use it (for instanceof checks, casting, etc), you can only get at its FizzBuzzNetwork-ness at compile time. That's a good thing, because that's all the runtime will be able to give you, too. You'll have to find some other mechanism of determining whether the object you're working with is a FizzBuzzNetwork<PRN,?>
.