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

JavaClassReflection

Java Problem Overview


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 myField.getType().equals(String.class). The same applies for other non-derived classes. But how do I check derived classes? E.g. LinkedList as subclass of List. I can't find any isSubclassOf(...) or extends(...) method. Do I need to walk through all getSuperClass() and find my supeclass by my own?

Java Solutions


Solution 1 - Java

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][1]:

> 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)][1]

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

[1]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Class.html#isAssignableFrom(java.lang.Class) "Class.isAssignableFrom(Class)"

Solution 2 - Java

Another option is instanceof:

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

Solution 3 - Java

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:

    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.

    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.

    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.

Solution 4 - Java

This works for me:

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

Solution 5 - Java

This is an improved version of @schuttek's answer. It is improved because it correctly return false for primitives (e.g. isSubclassOf(int.class, Object.class) => false) and also correctly handles interfaces (e.g. 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;
    }
}

Solution 6 - Java

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

Solution 7 - Java

//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

Solution 8 - Java

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncraeshView Question on Stackoverflow
Solution 1 - JavaSean Patrick FloydView Answer on Stackoverflow
Solution 2 - JavaLandeiView Answer on Stackoverflow
Solution 3 - JavaMarcoView Answer on Stackoverflow
Solution 4 - JavaTo KraView Answer on Stackoverflow
Solution 5 - Javauser2415587View Answer on Stackoverflow
Solution 6 - JavaschuttekView Answer on Stackoverflow
Solution 7 - JavajoseluisbzView Answer on Stackoverflow
Solution 8 - JavajwpolView Answer on Stackoverflow