[英]Java Generic Type Number
我已经阅读了几页关于泛型方法的页面,并且对它们有所了解,但我仍然不理解它们。 所以说我有一种方法可以将两个数字相乘并返回乘积:
public double multiply(SomeNumberVariableType x, SomeNumberVariableType y){
return x * y;
}
如何使用有界 generics 只允许数字类型作为参数?
也许这是您的意图:
public static <N extends Number> double multiply(N x, N y){
return x.doubleValue() * y.doubleValue();
}
尽管我也必须说,用Number代替诸如Java原始double
这样的具体不可变值类型的一般用法可能不太健康,因为在上面的示例中,参数甚至可以是不同的类型,例如Integer和Double。
注意:
我确认,自变量可以是上面给出的签名的不同类型。 因此,波希米亚的答案是错误的。 我刚刚测试了它(但之前已经知道了)。 编译器仅保证两个参数的类型均为Number,其他都没有。
为了声明相同的参数类型,编译器需要自引用泛型。 Number-class无法满足此功能(不幸的是,<N扩展Number <N >>是不可能的)。 这就是为什么我认为整个数字方法并不真正健康。 这是每个人都可以执行的测试代码:
Integer x = Integer.valueOf(10);
Double y = new Double(2.5);
System.out.println(multiply(x, y));
// Output: 25.0
通常,Java泛型不适用于数学。
在Java中:
看起来您可以对对象执行数学运算,因为您可以执行以下操作:
Integer a = 1;
Integer b = 2;
Integer c = a + b;
但这仅是由于自动装箱。 实际发生的是编译器用以下代码替换该代码:
Integer a = new Integer(1);
Integer b = new Integer(3);
Integer c = Integer.valueOf(a.intValue() + b.intValue());
使用泛型,您可以指定一个界限,以便您的类型必须是Number或它的子类型:
static <N extends Number> N multiply(N n1, N n2) {
return n1 * n2; // but you cannot do this because the type is not known
// so the compiler cannot do autoboxing
}
如果已知超类型,则可以在其上调用方法,以便按照已指出的方法进行操作:
static <N extends Number> double multiply(N n1, N n2) {
return n1.doubleValue() * n2.doubleValue();
}
但这与以下内容没有什么不同:
static double multiply(double n1, double n2) {
return n1 * n2;
}
例如,除了通用版本可以将BigDecimal用作参数之外,它当然不会提供可靠的结果(请参阅BigDecimal#doubleValue )。 (对此也不会渴望。)
如果确实有决心,则可以编写自己的数字类并使用多态。 否则,请使用重载或(最好)使用一种类型。
您可以通过编码<T extends Number>
指定类型的绑定 :
public static double <T extends Number> multiply(T x, T y){
return x.doubleValue() * y.doubleValue();
}
这将Number类型限制为相同类型,例如Integer和Integer,但不是Integer和Long。
但您根本不需要泛型:
public static double multiply(Number x, Number y){
return x.doubleValue() * y.doubleValue();
}
它允许任何两个数字,例如Integer和Long。
这是什么
import java.util.function.BinaryOperator;
public class GenericArithmetic {
public static <T extends Number> BinaryOperator<T> get_multiplier(T t1){
BinaryOperator<Integer> intMultiper = (i1, i2) -> i1 * i2;
BinaryOperator<Float> floatMultiper = (i1, i2) -> i1 * i2;
// should cache
switch (t1.getClass().getName()) {
case "java.lang.Integer":
return (BinaryOperator<T>) intMultiper;
case "java.lang.Float":
return (BinaryOperator<T>) floatMultiper;
default:
return null;
}
}
public static <T extends Number> Number multiply(T x, T y) throws Exception{
var multiplier = get_multiplier(x);
var res = multiplier.apply(x, y);
return res;
}
public static void main(String[] args) throws Exception{
var a1 = 3;
var a2 = 5;
var res = multiply(a1, a2);
System.out.println(res);
var b1 = 2.0f;
var b2 = 3.0f;
var res2 = multiply(b1,b2);
System.out.println(res2);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.