我正在摆弄Java的反射API,并试图处理一些字段。现在我不得不识别字段的类型。字符串很简单,只需执行myField.getType().equals(String.class)。这同样适用于其他非派生类。但是如何检查派生类呢?例如,LinkedList作为List的子类。我找不到任何isSubclassOf(…)或extends(…)方法。我需要遍历所有getSuperClass()并通过自己的超类找到我的超类吗?
当前回答
你需要这样的方法:
boolean isList = List.class.isAssignableFrom(myClass);
在一般情况下,List(上面)应该替换为超类和myClass应该替换为子类
从JavaDoc:
确定此class对象表示的类或接口是否与指定class参数表示的类或接口相同,或者是否是类或接口的超类或超接口。如果是,则返回true;否则返回false。如果这个Class对象表示一个基本类型,如果指定的Class参数恰好是这个Class对象,则此方法返回true;否则返回false。
参考:
Class.isAssignableFrom(类)
相关:
a)检查一个对象是否是你在编译时知道的类或接口(包括子类)的实例:
boolean isInstance = someObject instanceof SomeTypeOrInterface;
例子:
assertTrue(Arrays.asList("a", "b", "c") instanceof List<?>);
b)检查对象是否是你只在运行时才知道的类或接口(包括子类)的实例:
Class<?> typeOrInterface = // acquire class somehow
boolean isInstance = typeOrInterface.isInstance(someObject);
例子:
public boolean checkForType(Object candidate, Class<?> type){
return type.isInstance(candidate);
}
其他回答
你需要这样的方法:
boolean isList = List.class.isAssignableFrom(myClass);
在一般情况下,List(上面)应该替换为超类和myClass应该替换为子类
从JavaDoc:
确定此class对象表示的类或接口是否与指定class参数表示的类或接口相同,或者是否是类或接口的超类或超接口。如果是,则返回true;否则返回false。如果这个Class对象表示一个基本类型,如果指定的Class参数恰好是这个Class对象,则此方法返回true;否则返回false。
参考:
Class.isAssignableFrom(类)
相关:
a)检查一个对象是否是你在编译时知道的类或接口(包括子类)的实例:
boolean isInstance = someObject instanceof SomeTypeOrInterface;
例子:
assertTrue(Arrays.asList("a", "b", "c") instanceof List<?>);
b)检查对象是否是你只在运行时才知道的类或接口(包括子类)的实例:
Class<?> typeOrInterface = // acquire class somehow
boolean isInstance = typeOrInterface.isInstance(someObject);
例子:
public boolean checkForType(Object candidate, Class<?> type){
return type.isInstance(candidate);
}
除了@To-kra的回答。如果有人不喜欢递归:
public static boolean isSubClassOf(Class<?> clazz, Class<?> superClass) {
if(Object.class.equals(superClass)) {
return true;
}
for(; !Object.class.equals(clazz); clazz = clazz.getSuperclass()) {
if(clazz.getSuperclass().equals(superClass)) {
return true;
}
}
return false;
}
注意:没有空检查的清晰度。
另一个选项是instanceof:
Object o =...
if (o instanceof Number) {
double d = ((Number)o).doubleValue(); //this cast is safe
}
instanceof工作在实例上,即对象上。有时您希望直接使用类。在这种情况下,您可以使用Class类的asSubClass方法。 一些例子:
1)
Class o=Object.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
这将顺利通过,因为JFrame是对象的子类。c将包含一个表示JFrame类的Class对象。
2)
Class o=JButton.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
这将启动java.lang.ClassCastException,因为JFrame不是JButton的子类。C将不会被初始化。
3)
Class o=Serializable.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
这将顺利进行,因为JFrame实现了java.io.Serializable接口。c将包含一个表示JFrame类的Class对象。
当然,必须包括所需的进口。
这是@schuttek的答案的改进版本。改进的原因是它正确地为原语返回false(例如isSubclassOf(int.class, Object.class) => false),也正确地处理接口(例如isSubclassOf(HashMap.class, Map.class) => true)。
static public boolean isSubclassOf(final Class<?> clazz, final Class<?> possibleSuperClass)
{
if (clazz == null || possibleSuperClass == null)
{
return false;
}
else if (clazz.equals(possibleSuperClass))
{
return true;
}
else
{
final boolean isSubclass = isSubclassOf(clazz.getSuperclass(), possibleSuperClass);
if (!isSubclass && clazz.getInterfaces() != null)
{
for (final Class<?> inter : clazz.getInterfaces())
{
if (isSubclassOf(inter, possibleSuperClass))
{
return true;
}
}
}
return isSubclass;
}
}
推荐文章
- 如何添加JTable在JPanel与空布局?
- Statement和PreparedStatement的区别
- 为什么不能在Java中扩展注释?
- 在Java中使用UUID的最重要位的碰撞可能性
- 转换列表的最佳方法:map还是foreach?
- 如何分割逗号分隔的字符串?
- Java字符串—查看字符串是否只包含数字而不包含字母
- Mockito.any()传递带有泛型的接口
- 在IntelliJ 10.5中运行测试时,出现“NoSuchMethodError: org.hamcrest. matcher . descripbemismatch”
- 使用String.split()和多个分隔符
- Java数组有最大大小吗?
- 在Android中将字符串转换为Uri
- 从JSON生成Java类?
- 为什么java.util.Set没有get(int index)?
- Swing和AWT的区别是什么?