Je m'amuse avec l'API de réflexion de Java et essaie de gérer certains champs. Maintenant, je suis coincé avec l'identification du type de mes champs. Les chaînes sont faciles, il suffit de faire myField.getType().equals(String.class)
. Il en va de même pour les autres classes non dérivées. Mais comment vérifier les classes dérivées? Par exemple. LinkedList
en tant que sous-classe de List
. Je ne trouve aucune méthode isSubclassOf(...)
ni extends(...)
. Dois-je parcourir toutes les getSuperClass()
et trouver ma classe par moi-même?
Vous voulez cette méthode:
boolean isList = List.class.isAssignableFrom(myClass);
où en général, List
(ci-dessus) doit être remplacé par superclass
et myClass
par subclass
De la JavaDoc :
Détermine si la classe ou l'interface représentée par cet objet
Class
est identique à ou est une superclasse ou une superinterface de la classe ou de l'interface représentée par le paramètreClass
spécifié. Il retournetrue
si c'est le cas; sinon, il retournefalse
. Si cet objetClass
représente un type primitif, cette méthode retournetrue
si le paramètreClass
spécifié est exactement cet objetClass
; sinon, il retournefalse
.
Référence:
Connexes:
a) Vérifiez si un objet est une instance d'une classe ou d'une interface (y compris des sous-classes) que vous connaissez au moment de la compilation:
boolean isInstance = someObject instanceof SomeTypeOrInterface;
Exemple:
assertTrue(Arrays.asList("a", "b", "c") instanceof List<?>);
b) Vérifiez si un objet est une instance d'une classe ou d'une interface (y compris des sous-classes) que vous ne connaissez qu'au moment de l'exécution:
Class<?> typeOrInterface = // acquire class somehow
boolean isInstance = typeOrInterface.isInstance(someObject);
Exemple:
public boolean checkForType(Object candidate, Class<?> type){
return type.isInstance(candidate);
}
Une autre option est instanceof:
Object o =...
if (o instanceof Number) {
double d = ((Number)o).doubleValue(); //this cast is safe
}
instanceof fonctionne sur des instances, c'est-à-dire sur des objets. Parfois, vous voulez travailler directement avec les classes. Dans ce cas, vous pouvez utiliser la méthode asSubClass de la classe Class. Quelques exemples:
1)
Class o=Object.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
cela se passera sans problème car JFrame est une sous-classe de Object. c contiendra un objet Class représentant la classe JFrame.
2)
Class o=JButton.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
cela lancera un Java.lang.ClassCastException car JFrame n'est PAS une sous-classe de JButton. c ne sera pas initialisé.
3)
Class o=Serializable.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
cela se fera en douceur car JFrame implémente l'interface Java.io.Serializable. c contiendra un objet Class représentant la classe JFrame.
Bien entendu, les importations nécessaires doivent être incluses.
Cela fonctionne pour moi:
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;
}
Ceci est une version améliorée de la réponse de @ schuttek. Il est amélioré car il renvoie correctement false pour les primitives (par exemple, isSubclassOf (int.class, Object.class) => false) et gère correctement les interfaces (par exemple, 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;
}
}
Une méthode récursive pour vérifier si un Class<?>
est une sous-classe d'un autre Class<?>
...
Version améliorée de @ 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);
}
}
//Héritage
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'";
}
}
// Méthodes
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;
}
}
}
// Teste le 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));
//Résultat
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