Home > database >  Inference variable T has incompatible bounds with specific Class<T> and instance <T> in
Inference variable T has incompatible bounds with specific Class<T> and instance <T> in

Time:12-21

I'm using library which contains method I want to use. Simplified signature would look like this:

final class ThirdPartyClass
{
    public static <T> void thirdPartyMethod(Class<T> clazz, T instance)
    {
        // does something
    }
}

Inside thirdPartyMethod() it expects class of T as first argument and an instance of that specific class T as second argument.

Now I have this simple abstract class, which is calling that method:

abstract class Parent<T extends Number>
{
    public Parent(T instance)
    {
        ThirdPartyClass.thirdPartyMethod(instance.getClass(), instance);
    }
}

I'm getting an error:

method thirdPartyMethod in class ThirdPartyClass cannot be applied to given types;
required: java.lang.Class, T
found: java.lang.Class<capture#1 of ? extends java.lang.Number>, T
reason: inference variable T has incompatible bounds
equality constraints: capture#2 of ? extends java.lang.Number
lower bounds: T

How can I modify the Parent class so it conforms to expected arguments of thirdPartyMethod()? If possible with explanation.

CodePudding user response:

According to the return type of Object.getClass()

The actual result type is Class<? extends |X|> where |X| is the erasure of the static type of the expression on which getClass is called.

Since T extends Number, the resulting type would be Class<? extends Number>, i.e. means an unknown type extending Number. Which doesn't match T extends Number (i.e. a particular type extending Number which would be provided at runtime).

How can I modify the Parent class so it conforms to expected arguments of thirdPartyMethod()?

1. Introduce a second parameter of type Class<T> in your constructor.

abstract class Parent<T extends Number> {
    public Parent(T instance, Class<T> tClass) {
        ThirdPartyClass.thirdPartyMethod(tClass, instance);
    }
}

2. Perform casting (as have been mentioned in the comments):

ThirdPartyClass.thirdPartyMethod((Class<T>) instance.getClass(), instance);

By the way, instead of calling methods from a constructor (especially ones that are not developed and tested by you/your colleagues) you might consider introducing a factory method that would produce your domain object based on the result of a method call.

  • Related