在Java中检查一个类对象是否是另一个类对象的子类

我正在摆弄Java的反射API,并试图处理一些字段。现在我不得不识别字段的类型。字符串很简单,只需执行myField.getType().equals(String.class)即可。这同样适用于其他非派生类。但是如何检查派生类呢?例如,LinkedList作为List的子类。我找不到任何isSubclassOf(...)extends(...)方法。我需要遍历所有getSuperClass()并自己找到我的超类吗?

197976 次浏览

你需要这样的方法:

boolean isList = List.class.isAssignableFrom(myClass);

一般来说,上面的List应该用superclass代替,而myClass应该用subclass代替

JavaDoc:

确定此Class对象所表示的类或接口是否与指定的Class参数所表示的类或接口相同,或者是否是其超类或超接口。如果是,则返回true;否则返回false。如果这个Class对象表示一个基元类型,如果指定的Class参数恰好是这个Class对象,则此方法返回true;否则返回false

参考:


相关:

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

另一个选项是instanceof:

Object o =...
if (o instanceof Number) {
double d = ((Number)o).doubleValue(); //this cast is safe
}

运算符适用于实例,即对象。有时您希望直接使用类。在这种情况下,你可以使用Class类的asSubClass方法。 一些例子:< / p >

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对象。

当然,必须包括所需的进口。

这对我来说很管用:

protected boolean isTypeOf(String myClass, Class<?> superClass) {
boolean isSubclassOf = false;
try {
Class<?> clazz = Class.forName(myClass);
if (!clazz.equals(superClass)) {
clazz = clazz.getSuperclass();
isSubclassOf = isTypeOf(clazz.getName(), superClass);
} else {
isSubclassOf = true;
}


} catch(ClassNotFoundException e) {
/* Ignore */
}
return isSubclassOf;
}

检查Class<?>是否是另一个Class<?>的子类的递归方法…

@To热泪盈眶回答的改进版本:

protected boolean isSubclassOf(Class<?> clazz, Class<?> superClass) {
if (superClass.equals(Object.class)) {
// Every class is an Object.
return true;
}
if (clazz.equals(superClass)) {
return true;
} else {
clazz = clazz.getSuperclass();
// every class is Object, but superClass is below Object
if (clazz.equals(Object.class)) {
// we've reached the top of the hierarchy, but superClass couldn't be found.
return false;
}
// try the next level up the hierarchy.
return isSubclassOf(clazz, superClass);
}
}

这是@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;
}
}

/ /继承

    class A {
int i = 10;
public String getVal() {
return "I'm 'A'";
}
}


class B extends A {
int j = 20;
public String getVal() {
return "I'm 'B'";
}
}


class C extends B {
int k = 30;
public String getVal() {
return "I'm 'C'";
}
}

/ /方法

    public static boolean isInheritedClass(Object parent, Object child) {
if (parent == null || child == null) {
return false;
} else {
return isInheritedClass(parent.getClass(), child.getClass());
}
}


public static boolean isInheritedClass(Class<?> parent, Class<?> child) {
if (parent == null || child == null) {
return false;
} else {
if (parent.isAssignableFrom(child)) {
// is child or same class
return parent.isAssignableFrom(child.getSuperclass());
} else {
return false;
}
}
}

//测试代码

    System.out.println("isInheritedClass(new A(), new B()):" + isInheritedClass(new A(), new B()));
System.out.println("isInheritedClass(new A(), new C()):" + isInheritedClass(new A(), new C()));
System.out.println("isInheritedClass(new A(), new A()):" + isInheritedClass(new A(), new A()));
System.out.println("isInheritedClass(new B(), new A()):" + isInheritedClass(new B(), new A()));




System.out.println("isInheritedClass(A.class, B.class):" + isInheritedClass(A.class, B.class));
System.out.println("isInheritedClass(A.class, C.class):" + isInheritedClass(A.class, C.class));
System.out.println("isInheritedClass(A.class, A.class):" + isInheritedClass(A.class, A.class));
System.out.println("isInheritedClass(B.class, A.class):" + isInheritedClass(B.class, A.class));

/ /结果

    isInheritedClass(new A(), new B()):true
isInheritedClass(new A(), new C()):true
isInheritedClass(new A(), new A()):false
isInheritedClass(new B(), new A()):false
isInheritedClass(A.class, B.class):true
isInheritedClass(A.class, C.class):true
isInheritedClass(A.class, A.class):false
isInheritedClass(B.class, A.class):false

除了@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;
}

注意:没有空检查的清晰度。