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?
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;}
);
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With