重载方法的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也是正确的,编译不会看到重载版本,因为它不是接口的一部分。谢谢。我可能会选择这个解决方案!