Я играю с API Java reflection и пытаюсь обрабатывать некоторые поля. Теперь я застрял в определении типа моих полей. Строки просты, просто myField.getType().equals(String.class)
. То же самое относится к другим не производным классам. Но как проверить производные классы? Например. LinkedList
в качестве подкласса List
. Я не могу найти метод isSubclassOf(...)
или extends(...)
. Нужно ли мне проходить через все getSuperClass()
и найти мой суперкласс самостоятельно?
Проверьте, является ли объект класса подклассом другого объекта класса в Java
Ответ 1
Вам нужен этот метод:
boolean isList = List.class.isAssignableFrom(myClass);
где, вообще говоря, List
(выше) следует заменить на superclass
, а myClass
следует заменить на 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);
}
Ответ 2
Другой вариант - instanceof:
Object o =...
if (o instanceof Number) {
double d = ((Number)o).doubleValue(); //this cast is safe
}
Ответ 3
instanceof работает с экземплярами, то есть с объектами. Иногда вы хотите работать непосредственно с классами. В этом случае вы можете использовать метод asSubClass класса Class. Некоторые примеры:
1)
Class o=Object.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
это будет проходить гладко, потому что JFrame является подклассом Object. c будет содержать объект класса, представляющий класс JFrame.
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.
Разумеется, необходимый импорт должен быть включен.
Ответ 4
Это работает для меня:
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;
}
Ответ 5
Это улучшенная версия ответа @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;
}
}
Ответ 6
Рекурсивный метод для проверки, является ли 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);
}
}
Ответ 7
//Наследование
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