¿Qué es el objeto Class (java.lang.Class)?

81

La documentación de Java para Classdice:

ClassLos objetos son construidos automáticamente por la Máquina Virtual Java a medida que se cargan las clases y mediante llamadas al defineClassmétodo en el cargador de clases.

¿Qué son estos Classobjetos? ¿Son los mismos que los objetos instanciados de una clase llamando new?

Además, por ejemplo, object.getClass().getName()¿cómo se puede convertir todo en superclase Class, incluso si no lo heredo java.lang.Class?

Carbonizador
fuente

Respuestas:

97

No se escribe nada Class. Cada Objecten Java pertenece a un cierto class. Es por eso que la Objectclase, que es heredada por todas las demás clases, define el getClass()método.

getClass(), o el literal de clase: Foo.classdevuelve un Classobjeto, que contiene algunos metadatos sobre la clase:

  • nombre
  • paquete
  • métodos
  • campos
  • constructores
  • anotaciones

y algunos métodos útiles como fundición y diversos controles ( isAbstract(), isPrimitive(), etc). el javadoc muestra exactamente qué información puede obtener sobre una clase.

Entonces, por ejemplo, si a un método suyo se le da un objeto y desea procesarlo en caso de que esté anotado con la @Processableanotación, entonces:

public void process(Object obj) {
    if (obj.getClass().isAnnotationPresent(Processable.class)) {
       // process somehow; 
    }
}

En este ejemplo, obtiene los metadatos sobre la clase del objeto dado (cualquiera que sea) y comprueba si tiene una anotación determinada. Muchos de los métodos en una Classinstancia se denominan "operaciones reflexivas" o simplemente "reflexión. Lea aquí sobre la reflexión, por qué y cuándo se usa".

Tenga en cuenta también que el Classobjeto representa enumeraciones e interfaces junto con clases en una aplicación Java en ejecución y tiene los metadatos respectivos.

Para resumir, cada objeto en java tiene (pertenece a) una clase y tiene un Classobjeto respectivo , que contiene metadatos sobre él, que es accesible en tiempo de ejecución.

Bozho
fuente
37
Y es divertido pensar más en esto. La Classclase hereda de Objectsí misma. Class.classdevuelve un Classobjeto que representa la Classclase. Puedes reflexionar sobre la reflexión. MI CABEZA ASPLODE.
cdhowie
1
@pst: lo tengo. Me dan ganas de herir a la gente. Cualquier lenguaje / marco con tantos métodos en su tipo raíz merece ser enterrado. Tiene el síndrome de estilo PHP tack-random-crap-into-the-API-sin-ninguna-previsión. Cue the flames ...
cdhowie
1
Class c1 = Car.class; ¿Qué es esta "clase"? ¿Es una variable pública que existe en todas las clases?
David Blaine
1
En cierto modo, sí. De hecho, es un "literal de clase", así es como se refiere al objeto Class por su nombre.
Bozho
1
@cdhowie Tu comentario me sació semánticamente la palabra 'clase'.
stillanoob
44

Un objeto Class es una especie de metaobjeto que describe la clase de un objeto. Se utiliza principalmente con las capacidades de reflexión de Java. Puede pensar en ello como un "modelo" de la clase real. Por ejemplo, tienes un coche de clase como este:

public class Car {
    public String brand;
}

Luego puede construir un objeto Class que describa su clase "Car".

Class myCarClass = Class.forName("Car");

Ahora puede hacer todo tipo de consultas en su clase Car en ese objeto Class:

myCarClass.getName() - returns "Car"
myCarClass.getDeclaredField("brand") - returns a Field object describing the "brand" field

y así. Cada objeto java tiene un método getClass () que devuelve el objeto Class que describe la clase del objeto Java. Entonces podrías hacer algo como:

Car myCar = new Car();
Class myCarClass  = myCar.getClass();

Esto también funciona para objetos que no conoce, por ejemplo, objetos que obtiene del exterior:

public void tellMeWhatThisObjectsClassIs(Object obj) {
    System.out.println(obj.getClass().getName());
}

Puede alimentar este método con cualquier objeto java e imprimirá la clase real del objeto que le ha dado.

Cuando trabaja con Java, la mayoría de las veces no necesita preocuparse por los objetos Class. Sin embargo, tienen algunos casos prácticos de uso. Por ejemplo, le permiten instanciar mediante programación objetos de una determinada clase, que se utiliza a menudo para la serialización y deserialización de objetos (por ejemplo, conversión de objetos Java hacia / desde XML o JSON).

Class myCarClass = Class.forName("Car");
Car myCar = myCarClass.newInstance();  // is roughly equivalent to = new Car();

También puede usarlo para averiguar todos los campos o métodos declarados de su clase, etc., lo cual es muy útil en ciertos casos. Entonces, por ejemplo, si su método recibe un objeto desconocido y necesita saber más sobre él, como si implementa alguna interfaz, etc., la clase Class es su amiga aquí.

En pocas palabras, las clases Class, Field, Method, etc.que están en el paquete java.lang.reflect le permiten analizar sus clases, métodos, campos definidos, crear nuevas instancias de ellos, llamar a métodos todo tipo de otras cosas y te permiten hacer esto dinámicamente en tiempo de ejecución.

Jan Thomä
fuente
1
Class c1 = Car.class; ¿Qué es esta "clase"? ¿Es una variable pública que existe en todas las clases?
David Blaine
5
Es básicamente azúcar sintáctico. Es algo que el compilador evalúa como algo que carga el objeto de clase con el nombre dado. Aproximadamente equivalente a Class.forName ("nombre de clase totalmente calificado") pero se comprueba que la clase exista en tiempo de compilación mientras Class.forName () se ejecuta en tiempo de ejecución.
Jan Thomä
8

getClass()es un método que devuelve un objeto que es una instancia de java.lang.Class... no hay conversión involucrada. El casting se vería así:

Class<?> type = (Class<?>) object;
ColinD
fuente
6

También me gustaría agregar a la respuesta de ColinD que getClass devolverá el mismo objeto para instancias del mismo tipo. Esto imprimirá verdadero :

    MyOtherClass foo = new MyOtherClass();
    MyOtherClass bar = new MyOtherClass();
    System.out.println(foo.getClass()==bar.getClass());

Tenga en cuenta que no lo es equals, lo estoy usando ==.

Koray Tugay
fuente
3

Un objeto Class es una instancia de Class (java.lang.Class). A continuación, la cita tomada de javadoc de la clase debería responder a su pregunta

La clase no tiene ningún constructor público. En su lugar, los objetos de clase son construidos automáticamente por la máquina virtual Java a medida que se cargan las clases y mediante llamadas al método defineClass en el cargador de clases.

Pakka Techie
fuente
2

Para comprender completamente el objeto de clase, regresemos y comprendamos que obtenemos el objeto de clase en primer lugar. Verá, cada .javaarchivo que crea, cuando compila ese .javaarchivo, el jvm creará un .classarchivo, este archivo contiene toda la información sobre la clase, a saber:

  1. Nombre completo de la clase
  2. Padre de clase
  3. Información del método
  4. Campos variables
  5. Constructor
  6. Información del modificador
  7. Piscina constante

La lista que ve arriba es la que normalmente ve en una clase típica. Ahora, hasta este punto, su .javaarchivo y .classarchivo existe en su disco duro, cuando realmente necesita usar la clase, es decir, ejecutar el código en el main()método, el jvm usará ese .classarchivo en su disco duro y lo cargará en una de las 5 memorias areas en jvm, que es el área de método, inmediatamente después de cargar el .classarchivo en el área de método, jvm usará esa información y un objeto Class que representa esa clase que existe en el área de memoria del montón.

Aquí está la vista de nivel superior,

.java--compilar -> .class-> cuando ejecuta su script -> .classcarga en el área de método --jvm crea un objeto de clase desde el área de método -> nace un objeto de clase

Con un objeto de clase, obtienes información como el nombre de la clase y los nombres de los métodos, todo sobre la clase.

Además, debe tener en cuenta que solo habrá un objeto de clase para cada clase que use en el script.

Espero que esto tenga sentido

Brendon Cheung
fuente
buenos puntos adicionales. un comentario sobre la redacción, no sé un tema que sea bueno para editarme "el jvm usará esa información y un objeto Class que representa esa clase que existe en el área de memoria del montón". parece incorrecto, la línea más tarde con -> parece más lógico. ¿Estoy aquí? por favor, hazlo consistente, ¡gracias!
Alexei Martianov
1

La clase Object es la clase principal de todas las clases en Java de forma predeterminada. En otras palabras, es la clase más alta de java.

La clase Object es beneficiosa si desea hacer referencia a cualquier objeto cuyo tipo no conoce. Observe que la variable de referencia de la clase principal puede hacer referencia al objeto de la clase secundaria, conocido como upcasting.

Tomemos un ejemplo, hay un método getObject () que devuelve un objeto, pero puede ser de cualquier tipo, como Empleado, Estudiante, etc., podemos usar la referencia de clase Objeto para referir ese objeto. Por ejemplo:

Object obj=getObject(); // no sabemos qué objeto será devuelto por este método

Ishanka Abeysinghe
fuente