Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 470
Hugh Rawlinson Avatar asked Jul 02 '15 14:07

Hugh Rawlinson


2 Answers

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;}
        );
    }
}
like image 142
muued Avatar answered Sep 23 '22 05:09

muued


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.

like image 24
Eran Avatar answered Sep 25 '22 05:09

Eran