代码之家  ›  专栏  ›  技术社区  ›  Arcones

为数字子类生成布尔检查

  •  1
  • Arcones  · 技术社区  · 6 年前

    我想创建一个方法,它以一个名为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)
    

    两者 Float Double 延伸自 Number ,但是 数字 没有方法 isInfinite isNan 所以我不能用超级班。

    用Java有什么办法吗?(我目前使用Java10)

    我更喜欢易于阅读和理解的代码,而不是最有效或最快的代码,但如果它可以既容易又快,将是顶级的!

    2 回复  |  直到 6 年前
        1
  •  2
  •   ernest_k Petronella    6 年前

    使用原语 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
    }
    

    对于可为空的double和float,它可以包装成一个空安全的版本 Number ,但是打电话 doubleValue() 要得到原语:

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

    最后一个版本在测试两个版本时都有效 Double.valueOf(Double.NaN) Float.valueOf(Float.NaN)

        2
  •  0
  •   Eugene    6 年前

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

    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);
        }
    }