Check if a Class Object is subclass of another Class Object in Java

前端 未结 8 1031
鱼传尺愫
鱼传尺愫 2020-11-28 20:33

I\'m playing around with Java\'s reflection API and trying to handle some fields. Now I\'m stuck with identifying the type of my fields. Strings are easy, just do myFi

相关标签:
8条回答
  • 2020-11-28 21:00

    //Inheritance

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

    //Methods

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

    // Test the code

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

    //Result

        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
    
    0 讨论(0)
  • 2020-11-28 21:00

    In addition to @To-kra's answer. If someone doesn't like recurrence:

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

    NOTE: no null checking for clarity.

    0 讨论(0)
  • 2020-11-28 21:06

    instanceof works on instances, i.e. on Objects. Sometimes you want to work directly with classes. In this case you can use the asSubClass method of the Class class. Some examples:

    1)

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

    this will go through smoothly because JFrame is subclass of Object. c will contain a Class object representing the JFrame class.

    2)

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

    this will launch a java.lang.ClassCastException because JFrame is NOT subclass of JButton. c will not be initialized.

    3)

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

    this will go through smoothly because JFrame implements the java.io.Serializable interface. c will contain a Class object representing the JFrame class.

    Of course the needed imports have to be included.

    0 讨论(0)
  • 2020-11-28 21:11

    Another option is instanceof:

    Object o =...
    if (o instanceof Number) {
      double d = ((Number)o).doubleValue(); //this cast is safe
    }
    
    0 讨论(0)
  • 2020-11-28 21:12

    You want this method:

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

    where in general, List (above) should be replaced with superclass and myClass should be replaced with subclass

    From the JavaDoc:

    Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter. It returns true if so; otherwise it returns false. If this Class object represents a primitive type, this method returns true if the specified Class parameter is exactly this Class object; otherwise it returns false.

    Reference:

    • Class.isAssignableFrom(Class)

    Related:

    a) Check if an Object is an instance of a Class or Interface (including subclasses) you know at compile time:

    boolean isInstance = someObject instanceof SomeTypeOrInterface;
    

    Example:

    assertTrue(Arrays.asList("a", "b", "c") instanceof List<?>);
    

    b) Check if an Object is an instance of a Class or Interface (including subclasses) you only know at runtime:

    Class<?> typeOrInterface = // acquire class somehow
    boolean isInstance = typeOrInterface.isInstance(someObject);
    

    Example:

    public boolean checkForType(Object candidate, Class<?> type){
        return type.isInstance(candidate);
    }
    
    0 讨论(0)
  • 2020-11-28 21:12

    A recursive method to check if a Class<?> is a sub class of another Class<?>...

    Improved version of @To Kra's answer:

    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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题