我发现基本类型问题
System.out.println("Integer.class.isAssignableFrom(int.class) = " + Integer.class.isAssignableFrom(int.class));
System.out.println("int.class.isAssignableFrom(Integer.class) = "+int.class.isAssignableFrom(Integer.class));
两个语句都返回false给调用者。看来拳击在这里并不适用。我的问题是,如果我的观察是正确的,或者有其他API谁可以正确地做这个测试?
-------------------------------- 跟进 ---------------------------------------------
正如我所说的,我主要想检查一个对象在使用反射时是否可分配给一个字段。我希望这个机制能够在运行时更加精确,所以我做了这样一个实现。
public static boolean isAssignableFrom(final Field field, final Object obj) {
if (field.getType().equals(Integer.class) || field.getType().equals(int.class)) {
return obj.getClass().equals(Integer.class) || field.getType().equals(int.class);
} else if (field.getType().equals(Float.class) || field.getType().equals(float.class)) {
return obj.getClass().equals(Float.class) || field.getType().equals(float.class);
} else if (field.getType().equals(Double.class) || field.getType().equals(double.class)) {
return obj.getClass().equals(Double.class) || field.getType().equals(double.class);
} else if (field.getType().equals(Character.class) || field.getType().equals(char.class)) {
return obj.getClass().equals(Character.class) || field.getType().equals(char.class);
} else if (field.getType().equals(Long.class) || field.getType().equals(long.class)) {
return obj.getClass().equals(Long.class) || field.getType().equals(long.class);
} else if (field.getType().equals(Short.class) || field.getType().equals(short.class)) {
return obj.getClass().equals(Short.class) || field.getType().equals(short.class);
} else if (field.getType().equals(Boolean.class) || field.getType().equals(boolean.class)) {
return obj.getClass().equals(Boolean.class) || field.getType().equals(boolean.class);
} else if (field.getType().equals(Byte.class) || field.getType().equals(byte.class)) {
return obj.getClass().equals(Byte.class) || field.getType().equals(byte.class);
}
return field.getType().isAssignableFrom(obj.getClass());
}
}
这似乎是我能做的最好的-_-!由于
我想,Apache commons-lang的ClassUtils.isAssignable(Class, Class, boolean)
可以帮上忙。
JavaDoc
int.class
和Integer.class
是两个独立的类对象。查看this
答案了解更多细节
From Java doc Class#isAssignableFrom
确定此class对象所表示的类或接口是否与指定的class参数所表示的类或接口相同,或者是否是该类或接口的超类或超接口。如果是,则返回true;否则返回false。如果这个Class对象表示一个基本类型,如果指定的Class参数正是这个Class对象,这个方法返回true;否则返回false。
来自isAssignableFrom
的文档:
此方法测试是否可以通过标识转换或通过扩展引用转换将指定的Class参数表示的类型转换为此Class对象表示的类型。详细信息请参见Java语言规范第5.1.1节和5.1.4节。
Integer
不能通过这种方式分配给int
(反之亦然),因此您的方法将返回false——装箱和拆箱是在编译时完成的,而不是在运行时完成的——有关它的更多信息,请参阅本文
提示一下,上面粘贴的代码有一个bug。如果您使用"field= int.class"调用方法,无论对象类型是什么,该方法将始终返回true。似乎是复制粘贴错误;)
if (field.getType().equals(Integer.class) || field.getType().equals(int.class)) {
return obj.getClass().equals(Integer.class) || field.getType().equals(int.class);
最好是:
if (field.getType().equals(Integer.class) || field.getType().equals(int.class)) {
return obj.getClass().equals(Integer.class) || obj.getType().equals(int.class);