重载方法的Java泛型问题
我有以下类型化接口层次结构和一个实现:重载方法的Java泛型问题,java,generics,overloading,Java,Generics,Overloading,我有以下类型化接口层次结构和一个实现: public interface Operation<T> { T add(T object1, T object2); } public interface OperationNumeric<T extends Number> extends Operation<T> { T add(T number1, T number2); } 现在,我尝试使用两种不同类型的Float和Intege
public interface Operation<T> {
T add(T object1, T object2);
}
public interface OperationNumeric<T extends Number> extends Operation<T> {
T add(T number1, T number2);
}
现在,我尝试使用两种不同类型的Float和Integer调用calculate(),如下所示:
try {
calculate(2.2f,2, new OperationFloat());
} catch (Exception e) {
System.out.println(e.getMessage());
}
/**
* @param <O> first parameter-type of operation
* @param <P> second parameter-type of operation
* @param <R> result-type of operation
*/
public interface OperationNumeric<O extends Number
, P extends Number
, R extends Number> {
R add(O number1, P number2);
}
OperationNumeric<Float, Float, Float> floatAddition
= (Float f1, Float f2) -> f1 + f2);
OperationNumeric<Float, Integer, Float> floatIntAddition
= (Float f, Integer i) -> f + i;
OperationNumeric<Number, Number, Number> numberAddition
= (Number n1, Number n2) -> n1.doubleValue() + n2.doubleValue();
...
if ((n1 instanceof Integer) && (n2 instanceof Integer)) {
return (((Integer) n1) + ((Integer) n2));
}
一旦我调用它,Java就一直引用add(Float,Float)方法,而看不到重载的add(Float,Integer)方法
IDEA建议“将(T,T)添加为原始类型的成员的未选中调用…”
如何修改我的接口/类,以便能够使用重载方法?如果您使用的是由接口
操作数值操作数
声明的变量对象,则只能使用该接口中声明的方法。实例化对象的方法的其余部分不可见。尝试正确定义对象,如:
if (operand instanceof OperationFloat && operand2 instanceof Integer) {
((OperationFloat) operand).add(operand1, (Integer)operand2);
}
解决方案中的基本缺陷是
操作
接口中的两个操作数必须是同一类型。因此,方法Float add(Float,Integer)
在接口OperationNumeric
中不可见(因为Integer
和Float
没有直接的继承关系)
如果要对这两个参数使用不同的类型,实际上需要三个泛型参数(每个参数一个,返回类型一个)。这将产生如下界面:
try {
calculate(2.2f,2, new OperationFloat());
} catch (Exception e) {
System.out.println(e.getMessage());
}
/**
* @param <O> first parameter-type of operation
* @param <P> second parameter-type of operation
* @param <R> result-type of operation
*/
public interface OperationNumeric<O extends Number
, P extends Number
, R extends Number> {
R add(O number1, P number2);
}
OperationNumeric<Float, Float, Float> floatAddition
= (Float f1, Float f2) -> f1 + f2);
OperationNumeric<Float, Integer, Float> floatIntAddition
= (Float f, Integer i) -> f + i;
OperationNumeric<Number, Number, Number> numberAddition
= (Number n1, Number n2) -> n1.doubleValue() + n2.doubleValue();
...
if ((n1 instanceof Integer) && (n2 instanceof Integer)) {
return (((Integer) n1) + ((Integer) n2));
}
这很有趣。我以为Java会将
2
看作int,并使用整数
签名。将2
包装在Integer(2)
中时会发生什么?add(Float,Integer)
不是接口的一部分。如果您在OperationNumeric
接口上操作,为什么Java要调用此方法?该问题和回答的可能重复部分与此有关,因为您应该知道方法调用是如何被“选中”的。但是Turing85也是正确的,编译不会看到重载版本,因为它不是接口的一部分。谢谢。我可能会选择这个解决方案!