Métodos de objetos de Java: getClass ()

    Introducción

    Este artículo es una continuación de una serie de artículos que describen los métodos a menudo olvidados de la clase Object base del lenguaje Java. A continuación se muestran los métodos del objeto Java base presente en todos los objetos Java debido a la herencia implícita de Object junto con enlaces a cada artículo de esta serie.

    • Encadenar
    • getClass (estás aquí)
    • es igual a
    • código hash
    • clon
    • finalizar
    • esperar y notificar

    El enfoque de este artículo es el getClass() método, que se utiliza para acceder a los metadatos sobre la clase del objeto con el que está trabajando.

    El método getClass ()

    El método Object algo confuso o incomprendido getClass() devuelve una instancia de la clase Class, que contiene información sobre la clase que getClass() fue llamado desde. Vaya, si ya no estás confundido por esa última declaración, bien por ti, ¡porque lo estoy y lo escribí!

    Permítanme intentar descomponer esa oración con una demostración de cómo podría usarse. A continuación encontrará el Person clase que utilicé en el artículo inicial sobre la clase Object toString() método.

    package com.adammcquistan.object;
    
    import java.time.LocalDate;
    
    public class Person {
        private String firstName;
        private String lastName;
        private LocalDate dob;
    
        public Person(String firstName, String lastName, LocalDate dob) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.dob = dob;
        }
    
        public String getFirstName() {
            return firstName;
        }
    
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
    
        public String getLastName() {
            return lastName;
        }
    
        public void setLastName(String lastName) {
            this.lastName = lastName;
        }
    
        public LocalDate getDob() {
            return dob;
        }
    
        public void setDob(LocalDate dob) {
            this.dob = dob;
        }
    
        @Override
        public String toString() {
            return "<Person: firstName=" + firstName + ", lastName=" + lastName + ", dob=" + dob + ">";
        }
    }
    

    Centrémonos en lo anulado toString() método, que enumera el nombre de la clase, Persona, junto con los valores de los campos de la instancia. En lugar de «codificar» el nombre de la clase, Persona, en la propia cadena, podría haber usado el getClass() método para devolver una instancia de la clase Class, que contendrá esa información y me permitirá usarla así:

    public class Person {
        // omitting everyting else remaining the same
    
        @Override
        public String toString() {
            Class c = getClass();
            return "<" + c.getName() + ": firstName=" + firstName + ", lastName=" + lastName + ", dob=" + dob + ">";
        }
    }
    

    Esto llevaría a reemplazar el texto original codificado «Person» con el nombre de clase completamente calificado de «com.adammcquistan.object.Person». La clase Class está repleta de diferentes métodos que le permiten identificar todo tipo de cosas sobre el objeto de clase que getClass() fue llamado.

    Por ejemplo, si quisiera obtener una versión más simplificada toString() representación de mi Person clase simplemente podría cambiar el c.getName() llamar con c.getSimpleName() como se muestra a continuación. Esto a su vez devolvería «Person» en lugar del nombre de clase completo «com.adammcquistan.object.Person».

    public class Person {
        // omitting everyting else remaining the same
    
        @Override
        public String toString() {
            Class c = getClass();
            return "<" + c.getSimpleName() + ": firstName=" + firstName + ", lastName=" + lastName + ", dob=" + dob + ">";
        }
    }
    

    Una gran diferencia en la semántica de cómo getClass() se utiliza en comparación con el otro Object métodos es que getClass() no se puede anular porque se declara como final método.

    ¿Para qué sirve el objeto Class?

    En este punto, es posible que se esté preguntando: «Ok, supongo que es muy bueno que pueda obtener información sobre una clase llamando a getClass () y recuperando su representación del objeto Class, pero ¿cómo me resulta útil como programador?» Créame, yo también me he hecho esta pregunta y mi conclusión general ha sido … no lo es. Al menos no es realmente desde la perspectiva de un programador cotidiano. Sin embargo, si es un desarrollador de bibliotecas o frameworks, es probable que se familiarice con la información y el comportamiento de Class objetos porque es esencial para el concepto conocido como reflexión.

    La reflexión permite dos cosas principales: (i) investigación en tiempo de ejecución de objetos y su contenido y (ii) acceso dinámico a campos y ejecución de métodos durante el tiempo de ejecución.

    El elemento número uno ya se demostró anteriormente usando getClass() para obtener una representación en tiempo de ejecución del Person class para acceder al nombre de clase completo o simple en una versión modificada del toString() método.

    El segundo elemento es un poco más complicado para preparar un ejemplo, pero es algo muy útil para poder acceder a los metadatos en una clase. Parte de la información que puede interrogar una instancia de Class porque son cosas como constructores, campos y métodos además de otras cosas como jerarquías de herencia de una clase, como sus superclases e interfaces.

    Un ejemplo de esto es la capacidad de usar depuradores en un IDE como Eclipse y Netbeans para ver al miembro y sus valores en una clase mientras el programa está en ejecución.

    Tomemos por ejemplo lo siguiente:

    public class Main {
        public static void main(String[] args) {
            Person me = new Person("Adam", "McQuistan", LocalDate.parse("1987-09-23"));
    
            Class c = me.getClass();
            for (Field f : c.getDeclaredFields()) {
                f.setAccessible(true);
                try {
                    System.out.println(f.getName() + " = " + f.get(me));
                } catch (Exception e) {
                    e.printStackTrace();
                }
    
            }
        }
    }
    

    Produciría lo siguiente:

    firstName = Adam
    lastName = McQuistan
    dob = 1987-09-23
    

    Una vez más, ningún no masoquista probablemente haría esto en la programación diaria normal, pero verá que este tipo de cosas se hacen a menudo en los marcos.

    Conclusión

    En este artículo describí el significado y uso del misterioso getClass() método de la clase Java Object. He mostrado cómo se puede usar para obtener metadatos en una instancia de clase, como el nombre de la clase de un objeto en tiempo de ejecución, y también proporcioné una explicación de por qué puede ser útil acceder a una instancia de clase.

    Como siempre, gracias por leer y no dude en comentar o criticar a continuación.

     

    Etiquetas:

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *