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


195

我正在玩Java的反射API,并尝试处理一些字段。现在,我要确定字段的类型。字符串很简单,只要这样做myField.getType().equals(String.class)。其他非派生类也是如此。但是,如何检查派生类?例如LinkedList作为的子类List。我无法找到任何isSubclassOf(...)extends(...)方法。我是否需要遍历所有人getSuperClass()并自己找到超人?


11
LinkedList不是的子类List。这是一个实现List
TJ Crowder

2
子类型可能是一个更好的术语
jpaugh

Answers:


401

您需要此方法:

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

一般情况下,List(以上)应替换为superclassmyClass应替换为subclass

JavaDoc

确定此Class对象表示的类或接口是否与指定Class参数表示的类或接口相同或超类或超接口。true如果是,则返回;否则返回。否则返回false。如果此Class对象表示原始类型,true则如果指定的Class参数正是此Class对象,则此方法返回;否则,此方法返回。否则返回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);
}

20
注意方案:SUPERCLASS.isAssignableFrom(SUBCLASS)这首先让我感到困惑,尽管考虑到命名实际上是显而易见的。
codepleb

7
@TrudleR我同意。像SUPERCLASS.isExtendedBy(SUBCLASS)这样的东西会更容易理解
肖恩·帕特里克·弗洛伊德

@SeanPatrickFloyd实际上isExtendedBy是一个坏名字,因为它CLASS.isAssignableFrom(CLASS)是正确的(因此CLASS.isExtendedBy(CLASS)也是如此)。这不是我所期望的。
Qw3ry

@ Qw3ry是的,我想这也是Api作者的想法:-)
肖恩·帕特里克·弗洛伊德

24

另一种选择是instanceof:

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

好电话(+1)。然后还有两种机制的组合:Class.isInstance(object) download.oracle.com/javase/6/docs/api/java/lang/…–
肖恩·帕特里克·弗洛伊德

5
这暗示您要实例化Field。但是我只想“看”我的课及其领域,不想“尝试一下”。
craesh 2011年

在需要检查对象的继承树的情况下,我看到此方法比“ isAssignableFrom”方法更加清晰明了。
cbuchart 2014年

请记住,instanceof也适用于父(在这种情况下Number)本身不仅是儿童的
lukaszrys

9

instanceof适用于实例,即对象。有时您想直接使用类。在这种情况下,您可以使用Class类的asSubClass方法。一些例子:

1)

    Class o=Object.class;
    Class c=Class.forName("javax.swing.JFrame").asSubclass(o);

这将顺利进行,因为JFrame是Object的子类。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对象。

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


5

这对我有用:

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

1
效果很好,但是如果遇到不具有超类的java.lang.Object,可能需要在clazz = clazz.getSuperclass()之后添加一个空检查。
乔纳斯·皮德森

4

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

3

一种检查a Class<?>是否为另一个Class<?>... 的子类的递归方法。

@To Kra答案的改进版本:

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

3

//遗产

    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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.