Hugh Rawlinson
Hugh Rawlinson

Reputation: 989

Java Generic Types Mismatch Error

I have a class with a constructor signature as follows:

public class MyClass <U>{
    public <T> MyClass(Set<T> data, Function<T,U> func)...
}

That's fine. But I want to overload the constructor, for the case that if you don't provide Function func, it will just use (item)->{return item;}. I've written another constructor that looks like this:

public <T> MyClass(Set<T> data){
    this(
      data,
      (item)->{return item;}
    );
}

This is causing a type mismatch error, because the function I'm providing as an argument to my constructor takes a value of type T, and returns that same value, which should be a U. I don't understand why the algebraic type system doesn't see that in this case U and T are the same and that's ok?

Upvotes: 5

Views: 353

Answers (3)

Alexei Kaigorodov
Alexei Kaigorodov

Reputation: 13535

Since you declared two distinct types T and U, compiler reasonably thinks they are different. If they are the same, do not declare T and use only U:

public MyClass(Set<U> data){
    this(
      data,
      (item)->{return item;}
    );
}

Upvotes: 0

Eran
Eran

Reputation: 394026

Let's try to create an instance of your class using the second constructor :

Set<Integer> ints = new HashSet<>();
MyClass<String> myobj = new <Integer> MyClass (ints);

your first constructor would expect a Set<Integer> and a Function<Integer,String> parameters, but your second constructor would try to pass to it a Function<Integer,Integer>. That's the reason your code doesn't pass compilation.

When you define generic classes and methods, they must be valid for any combination of types that can substitute their type parameters.

Upvotes: 3

muued
muued

Reputation: 1676

The system has to assume that T and U are two different types, since you gave them two different names. But you can just remove the additional generic type from your second ctor like that:

public class MyClass <U>{
    public <T> MyClass(Set<T> data, Function<T,U> func) {...}
    public MyClass(Set<U> data){
        this(
          data,
          (item)->{return item;}
        );
    }
}

Upvotes: 7

Related Questions