我有一个Object实例obj
和一个Method对象method
。如何查看obj
是method
的有效回报?
假设method
没有参数,并且它不是void
的返回类型(确认为getter)。
例如,如果obj
为null
,则method
的返回类型不能是原语。好吧,弄清楚了。但是,Class.isAssignableFrom
没有考虑从基元中取消装箱和装箱。例如,int.class.isAssignableFrom(Integer.class)
返回false,但这将是该方法的有效返回。
我可以使用的选项是使用Class.cast
但是使用编程流程的异常是相当讨厌的,并且生成异常也是昂贵的。但这是我所知道的。
我有点难以理解如何优雅地解决这个问题。非常感谢帮助。
答案 0 :(得分:1)
你需要处理的案件数量并不大。正如您已经提到的,如果返回类型是原始的,则不能返回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
,假设包装类型并进行比较。任何失败都表示实际类型不是包装类型。
当然,这种反光检查很简洁,但不是最好的编码风格,也不保证良好的性能。它只适用于一些临时检查。如果您想更频繁地和/或在生产代码中使用该检查,最佳解决方案仍然是手动填充的地图:
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);
}
答案 1 :(得分:-1)
这不适合你吗? - https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#isInstance(java.lang.Object)
这不会引发异常并完全符合您的预期。
答案 2 :(得分:-1)
您可以使用运算符instanceof
来检查返回对象是否是您的预期结果类型的实例(或继承自)。
if (obj instanceof ExpectedResultClass) {
//do your stuff
}