Anthony Dito
Anthony Dito

Reputation: 3670

Variadic Parameter of Class Types - Java

Take for instance, the method below.

<T extends MyInterface> void myFunction(Class<T>... types) {
    // Do some stuff that requires T to implement MyInterface
}

Now, given the method call below assuming MyClass1 and MyClass2 both implement MyInterface.

myFunction(MyClass1.class, MyClass2.class)

I get the following error.

Incompatible equality constraint: MyClass1 and MyClass2

How do I make this work? More specifically, how would one use a variadic parameter of class types implementing an interface in Java?

Upvotes: 3

Views: 179

Answers (3)

Johannes Kuhn
Johannes Kuhn

Reputation: 15173

With the first parameter, the type variable T is set to MyClass1.
MyClass1 should implement the interface, so the constraint extends MyInterface is fulfilled. Of course a Class<MyClass2> is not a Class<MyClass1>.

And that's why you get the error.

Upvotes: 1

rgettman
rgettman

Reputation: 178303

You've declared T to have an upper bound of MyInterface. By passing in MyClass1.class and MyClass2.class, the compiler must infer MyInterface for T.

However, the type of the parameter type is Class<T>..., restricting what is passed in to MyInterface.class and no subtypes.

Depending on the "stuff" you're doing, you can place a wildcard upper bound on the type of types to get it to compile.

<T extends MyInterface> void myFunction(Class<? extends T>... types) {

Upvotes: 3

John Kugelman
John Kugelman

Reputation: 361879

Having a T means that T has one fixed value, which means that all of the Class<T>... parameters must be the exact same type. The compiler cannot infer T==MyInferface because Class<MyClass1> is not a subclass of Class<MyInterface>.

You want to allow each parameter to have a different type. That requires a different signature:

void myFunction(Class<? extends MyInterface>... types)

There's no need for T at all.

Upvotes: 3

Related Questions