objeto - Verifica si una clase es una subclase de otra clase en Java
llamar variable de otra clase java (6)
Estoy jugando con la API de reflexión de Java y tratando de manejar algunos campos. Ahora estoy atascado con la identificación del tipo de mis campos. Las cadenas son fáciles, simplemente haz myField.getType().equals(String.class)
. Lo mismo aplica para otras clases no derivadas. ¿Pero cómo verifico las clases derivadas? Por ejemplo, LinkedList
como subclase de List
. No puedo encontrar ningún isSubclassOf(...)
o extends(...)
. ¿Tengo que recorrer todos los getSuperClass()
y encontrar mi supeclass por mi cuenta?
Esta es una versión mejorada de la respuesta de @ schuttek. Se mejora porque devuelve correctamente falso para las primitivas (por ejemplo, isSubclassOf (int.class, Object.class) => false) y también maneja correctamente las interfaces (por ejemplo, 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;
}
}
Esto funciona para mí:
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;
}
Otra opción es instanceof:
Object o =...
if (o instanceof Number) {
double d = ((Number)o).doubleValue(); //this cast is safe
}
Quieres este método:
boolean isList = List.class.isAssignableFrom(myClass);
donde, en general, List
(arriba) debe reemplazarse con superclass
y myClass
debe reemplazarse con subclass
Desde JavaDoc :
Determina si la clase o la interfaz representada por este objeto de
Class
es la misma o es una superclase o superinterfaz de la clase o interfaz representada por el parámetro deClass
especificado. Devuelvetrue
si es así; de lo contrario, devuelvefalse
. Si este objeto deClass
representa un tipo primitivo, este método devuelvetrue
si el parámetro deClass
especificado es exactamente este objeto deClass
; de lo contrario, devuelvefalse
.
Referencia:
Relacionado:
a) Compruebe si un objeto es una instancia de una clase o interfaz (incluidas las subclases) que conoce en tiempo de compilación:
boolean isInstance = someObject instanceof SomeTypeOrInterface;
Ejemplo:
assertTrue(Arrays.asList("a", "b", "c") instanceof List<?>);
b) Compruebe si un objeto es una instancia de una clase o interfaz (incluidas las subclases) que solo conoce en tiempo de ejecución:
Class<?> typeOrInterface = // acquire class somehow
boolean isInstance = typeOrInterface.isInstance(someObject);
Ejemplo:
public boolean checkForType(Object candidate, Class<?> type){
return type.isInstance(candidate);
}
Un método recursivo para comprobar si un clazz es un "niño" de una superclase ...
Versión mejorada de la respuesta de @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);
}
}
instanceof funciona en instancias, es decir, en Objetos. A veces quieres trabajar directamente con las clases. En este caso, puede usar el método asSubClass de la clase Class. Algunos ejemplos:
1)
Class o=Object.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
esto funcionará sin problemas porque JFrame es la subclase de Object. c contendrá un objeto Class que representa la clase JFrame.
2)
Class o=JButton.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
esto lanzará una java.lang.ClassCastException porque JFrame NO es una subclase de JButton. c no se inicializará.
3)
Class o=Serializable.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
esto funcionará sin problemas porque JFrame implementa la interfaz java.io.Serializable. c contendrá un objeto Class que representa la clase JFrame.
Por supuesto, las importaciones necesarias deben incluirse.