0

This error below, I simply need a direction in which I can read some resources, a search tag that encapsulates the required prerequisites to learn the solution that may prevent errors like this.

Error:(188, 65) java: incompatible types: java.lang.Class<org.base.vm.net.fizzbuzz.FizzBuzzNetwork> cannot be converted to java.lang.Class<? extends org.base.vm.net.fizzbuzz.FizzBuzzNetwork<PRM,?>>

Corresponding line of the error.

public class FizzBuzzNetworkProvider<PRM extends Serializable>
    extends NetworkProvider<PRM> {
          public FizzBuzzNetworkProvider(
          final IVMParameters<PRM> parameters,
          final boolean foo, final int boo
     {
        this(
            ((Class<? extends FizzBuzzNetwork<PRM, ?>>) (FizzBuzzNetwork.class)),
            parameters, foo, boo);
     }
}
raptor
  • 1
  • 4

1 Answers1

2

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,?>.

Community
  • 1
  • 1
yshavit
  • 42,327
  • 7
  • 87
  • 124