为Number子类生成布尔检查

时间:2018-08-09 09:36:11

标签: java

我想创建一个方法,该方法可以将名为value的对象作为输入来实现:

value instanceof Double && (Double.isInfinite((Double) value) || Double.isNaN((Double) value))
value instanceof Float && (Float.isInfinite((Float) value) || Float.isNaN((Float) value))

所以我的想法是除了传递值外,还要传递在每种情况下要使用的类的参数。该方法的签名可能类似于:

isInfiniteOrNaN(Object value, ??? type)

所以我可以调用它来获得所需的行为,

isInfiniteOrNaN(value, Double)
isInfiniteOrNaN(value, Float)

FloatDouble都从Number扩展而来,但是Number没有方法isInfiniteisNan,所以我不能使用超级课。

用Java可以做到吗? (我目前使用的是Java 10)

与最有效或最快速的代码相比,我更喜欢易于阅读和理解的代码,但是如果它既简单又快速,那将是最重要的!

2 个答案:

答案 0 :(得分:2)

使用原语double作为value的类型可以解决该问题:

static boolean isInfiniteOrNaN(double value) {
    return Double.isInfinite(value) || Double.isNaN(value);
}

public static void main(String args[]) throws IOException {
    System.out.println(isInfiniteOrNaN(Double.NaN)); //true
    System.out.println(isInfiniteOrNaN(Float.NaN)); //true
}

对于可为null的双精度浮点数,可以将其包装为带有Number的null安全版本,但可以调用doubleValue()来获取原语:

static boolean isInfiniteOrNaN(Number value) {
    return value == null || Double.isInfinite(value.doubleValue());
}

同时使用Double.valueOf(Double.NaN)Float.valueOf(Float.NaN)进行测试时,此最新版本有效

答案 1 :(得分:0)

一种方法是使用反射(一种):

private static boolean isInfiniteOrNaN(Object x) {
    MethodType methodType = MethodType.methodType(boolean.class);
    Lookup l = MethodHandles.lookup();
    try {
        MethodHandle isInfinite = l.findVirtual(x.getClass(), "isInfinite", methodType);
        MethodHandle isNaN = l.findVirtual(x.getClass(), "isNaN", methodType);
        return (boolean) isInfinite.invoke(x) || (boolean) isNaN.invoke(x);
    } catch (Throwable e) {
        throw new RuntimeException(e);
    }
}