I am writing a method with a generic List<T> as an argument. I want to limit T to Integer, Float and Double with this:
private Method(List<T> list) {
this.list = list;
}
public static <T extends Integer> Method<T> create(List<T> list) {
return new Method<>(list);
}
public static <T extends Float> Method<T> create(List<T> list) {
return new Method<>(list);
}
public static <T extends Double> Method<T> create(List<T> list) {
return new Method<>(list);
}
But I get this error:
error: name clash: <T#1>create(List<T#1>) and <T#2>create(List<T#2>) have the same erasure
public static <T extends Float> Method<T> create(List<T> list) {
^
where T#1,T#2 are type-variables:
T#1 extends Float declared in method <T#1>create(List<T#1>)
T#2 extends Integer declared in method <T#2>create(List<T#2>)
I get the same error for T#1 extends Double as well.
The code is based on this answer, which works well. So I think the problem is related to the fact that I used a list of generics as an input instead of a single generic.
How can I fix this? Is there some way to give Java the ability to discern between the different instances?
CodePudding user response:
You could use the Number superclass of Integer, Float, and Double as your bound.
public class Method<T extends Number> {
private final List<T> list;
public Method(List<T> list) {
this.list = list;
}
public static void main(String[] args) {
var mFloats = new Method(Arrays.asList(1.0f, 2.0f, 3.0f));
var mDoubles = new Method(Arrays.asList(1.0,2.0,3.0));
var mInts = new Method(Arrays.asList(1,2,3));
}
}
CodePudding user response:
Type Erasure affects Generic Collections like List, so each generic method is type erased into having a parameter signature with parameter type Obejct. See Oracle Docs To avoid this you can use arrays instead.
import java.util.Arrays;
import java.util.List;
public class Method<T> {
private final List<T> list;
private Method(List<T> list) {
this.list = list;
}
public static <T extends Integer> Method<T> create(T[] arr) {
return new Method<>(Arrays.asList(arr));
}
public static <T extends Float> Method<T> create(T[] arr) {
return new Method<>(Arrays.asList(arr));
}
public static <T extends Double> Method<T> create(T[] arr) {
return new Method<>(Arrays.asList(arr));
}
public static void main(String[] args) {
var floatMethod = Method.create(new Float[] {1.0f, 2.0f});
var doubleMethod = Method.create(new Double[] {1.0, 2.0});
var intMethod = Method.create(new Integer[] {1, 2});
}
}