繁体   English   中英

如何检查对象实例是否是方法的有效返回

[英]How to check if an Object instance is a valid return for a Method

我有一个 Object 实例obj和一个 Method 对象method 如何检查obj是否是该method的有效返回值?

假设method没有参数并且它不是void的返回类型(确认为 getter)。

例如,如果objnullmethod的返回类型不能是原始类型。 好的,明白了。 但是, Class.isAssignableFrom不考虑来自原语的拆箱和装箱。 例如int.class.isAssignableFrom(Integer.class)返回 false,但这将是该方法的有效返回。

我可以采取的一个选项是使用Class.cast但在编程流程中使用异常相当Class.cast ,并且生成异常的成本也Class.cast 但这是我所知道的。

我有点困惑到底如何优雅地解决这一切。 帮助将不胜感激。

您必须处理的案件数量并不多。 正如您已经提到的,如果返回类型是原始类型,则不得返回null 然后,您可以考虑拆箱,但不必处理装箱,因为您已经有一个要返回的对象(在反射操作中总是如此)。

因此,您必须检查的唯一额外情况是返回类型是否为原始类型,并且对象是否为适当的包装器类型。 如果您想保持代码简洁,您可以确定每个包装器类型都有一个名为TYPE的字段,其中包含相应原始类型的Class对象:

static boolean canReturn(Method m, Object value) {
    Class<?> rt=m.getReturnType();
    if(value==null) return !rt.isPrimitive();
    Class<?> act=value.getClass();
    if(rt==act) return true;
    if(rt.isPrimitive()) try {
        return act.getDeclaredField("TYPE").get(null)==rt;
    } catch(ReflectiveOperationException | NullPointerException ex) {
        return false;
    }
    return rt.isAssignableFrom(act);
}

上面的代码需要一些捷径。 如果值为null我们可以立即检查返回类型不能是原始类型的唯一约束。 否则,我们可以安全地假设我们有一个非null对象,并且如果它的类型恰好与返回类型完全匹配,我们就缩短其余部分。 如果返回类型不是原始类型,则使用简单的isAssignableFrom 但是如果返回类型是原始类型,我们乐观地尝试读取字段TYPE ,假设包装类型并进行比较。 任何失败都表明实际类型不是包装器类型。


当然,这种 Reflective 检查很简洁,但不是最好的编码风格,也不能保证良好的性能。 它只适用于一些临时检查。 如果您想更频繁地和/或在生产代码中使用该检查,最好的解决方案仍然是手动填充地图:

static final Map<Class<?>,Class<?>> PRIMITIVE2WRAPPER;
static {
    Map<Class<?>,Class<?>> p2w=new HashMap<>();
    p2w.put(boolean.class, Boolean.class);
    p2w.put(byte.class, Byte.class);
    p2w.put(short.class, Short.class);
    p2w.put(char.class, Character.class);
    p2w.put(int.class, Integer.class);
    p2w.put(long.class, Long.class);
    p2w.put(float.class, Float.class);
    p2w.put(double.class, Double.class);
    PRIMITIVE2WRAPPER=Collections.unmodifiableMap(p2w);
}
static boolean canReturn(Method m, Object value) {
    Class<?> rt=m.getReturnType();
    if(value==null) return !rt.isPrimitive();
    Class<?> act=value.getClass();
    if(rt==act) return true;
    return rt.isPrimitive()? PRIMITIVE2WRAPPER.get(rt)==act: rt.isAssignableFrom(act);
}

这不适合你吗? - https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#isInstance(java.lang.Object)

这不会引发异常并且完全符合您的期望。

您可以使用运算符instanceof来检查返回对象是否是您预期的结果类型的实例(或继承自)。

if (obj instanceof ExpectedResultClass) {
    //do your stuff
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM