1. Introducción
La reflexión de Java es un mecanismo que nos permite obtener información interna de métodos de clase, propiedades, clases de padres, interfaces, etc. en tiempo de ejecución. En otras palabras, la reflexión es esencialmente un proceso "inversa". Cuando creamos una instancia de una clase a través de new , en realidad está construida por la máquina virtual Java basada en Class de esta clase en tiempo de ejecución, y la reflexión es obtener su información de definición a través Class de una clase, para que podamos acceder a sus propiedades y métodos, conocer la clase principal de esta clase, qué interfaces se implementan y otra información.
2. Clase
Sabemos que usar Javac puede compilar archivos .Java en archivos .class, que contienen nuestra información de definición original para la clase (clase principal, interfaz, constructor, propiedades, métodos, etc.). El archivo .class se cargará en la máquina virtual Java (JVM) ClassLoader en tiempo de ejecución. Cuando se carga un archivo .class, el JVM generará un objeto de clase para él. Los objetos que instanciamos a través de nuevo en el programa en realidad se construyen en función del objeto de clase correspondiente en tiempo de ejecución. Para ser precisos, este objeto de clase es en realidad una instancia de java.lang.Class<T> . Por ejemplo, Class<MyClass> es una instancia Class<T> que encapsula la información de definición de MyClass . Dado que java.lang.Class<T> no tiene un constructor público, no podemos instanciar esta clase directamente. Podemos obtener un objeto de clase a través del siguiente método.
En la siguiente explicación, tomaremos la clase de personas y la clase de estudiantes como ejemplos:
gente de clase pública {nombre de cadena privada; edad privada int; Public People (Nombre de cadena, int Age) {this.name = name; this.age = edad; } public int getAge () {return Age; } public String getName () {nombre de retorno; } public void setAge (int Age) {this.age = edad; } public void setName (nombre de cadena) {this.name = name; } public void speak () {System.out.println (getName () + "" + getage ()); }} El estudiante de clase pública extiende a las personas {Private int Grade; Estudiante público (nombre de cadena, int Age) {super (nombre, edad); } Estudiante público (nombre de cadena, int Age, Int Grade) {super (nombre, edad); this.grade = grado; } public int getGrade () {RETURN GRADE; } public void setgrade (int grado) {this.grade = grado; } Private void Learn (Curso de cadena) {System.out.println (nombre + "Learn" + curso); }} Obtener objeto de clase por nombre de clase
Si conocemos el nombre de una clase durante el período de compilación, podemos obtener su objeto de clase como este:
Clase <People> PeopleClass = People.class;
También hay un método para obtener objetos de clase basados en el nombre de ruta completo de la clase de la siguiente manera:
// Suponga que la clase People está en la clase de paquete com.test <People> PeopleClass = class.forname ("com.test.people"); Tenga en cuenta que el parámetro del método Class.forName() debe ser el nombre de ruta completo de una clase. De hecho, mientras "importemos com.test.people", podemos obtener directamente su objeto de clase a través de " People.class " sin tener que escribir la ruta completa. (Si la clase correspondiente no se encuentra en classpath al llamar Class.forName() , se lanzará ClassNotFoundException .
Obtenga su objeto de clase a través del objeto en sí
People People = New People ("Bill", 18); Clase <People> PeopleClass = People.getClass (); Obtenga el constructor de la clase por reflexión
Una vez que hayamos obtenido el objeto de clase de People , podemos obtener la información de definición original de la clase People a través de este objeto de clase. Primero, obtengamos el objeto constructor de People . Con este objeto constructor, podemos construir un objeto People . Por ejemplo, podemos agregar el siguiente código en Student.java:
public static void main (string [] args) {clase <people> pclass = personas.class; Pruebe {Constructor <People> Constructor = PClass.getConstructor (string.class, int.class); Personas personas = constructor.newinstance ("Bill", 18); obj.speak (); } capt (excepción e) {}} En lo anterior, llamamos getConstructor para obtener un objeto de constructor de People . Dado que el constructor queremos obtener los parámetros formales de la String tipo e int , pasamos en String.class e int.class . Con el objeto Constructor, podemos llamar al método newInstance para crear un objeto people .
Tenga en cuenta que cuando el Constructor , Method y los objetos Field de la clase se obtienen a través de la reflexión, antes de llamar a los métodos de estos objetos, el indicador accessible de este objeto se establece en true para cancelar la verificación de acceso al idioma Java, lo que puede mejorar la velocidad de reflexión. Como se muestra en el siguiente código:
Constructor <People> Constructor = PeopleClass.getConstructor (string.class, int.class); // Establezca la propiedad accesible del constructor para ture para cancelar el cheque de acceso Java Constructor.SetAccessible (true);
Obtener métodos declarados en clase a través de la reflexión
Obtenga el método declarado en la clase actual (excluyendo heredado de la clase principal)
Para que se declaren todos los métodos en la clase actual, puede usar la función getDeclaredMethods en clase. Obtendrá todos los métodos declarados en la clase actual (incluidos los métodos private , public , static y de otro tipo). Devolverá una matriz de objetos Method , y cada objeto Method representa el método declarado en una clase. Para obtener el método especificado, puede llamar getDeclaredMethod(String name, Class...<T> parameterTypes) .
Como se muestra en el siguiente código:
privado void static showDeclaredMethods () {estudiante estudiante = nuevo estudiante ("factura", 18); // Obtenga todos los métodos declarados por el método de clase de estudiante [] métodos = student.getclass (). GetDeclaredMethods (); Pruebe {// Obtenga el objeto LearnMethod (encapsulado el método de aprendizaje) Método LearnMethod = Student.getClass (). GetDeclaredMethod ("Learn", String.Class); // Obtenga la lista de parámetros del método de aprendizaje e imprima la clase <?> [] ParamClasses = LearnMethod.getParametertypes (); for (clase <?> class: paramClasses) {System.out.println ("Aprender parámetros del método:" + class.getName ()); } // juzga si el método de aprendizaje es privado sistema.out.println (LearnMethod.getName () + "es privado" + modificador.isprivate (aprendizaje de LearnMethod.getModifiers ())); // Llame al método de aprendizaje LearnMethod.Invoke (estudiante, "Reflexión de Java"); } capt (excepción e) {}} Obtenga métodos públicos declarados en la clase actual y la clase principal
Para obtener la clase actual y todos los métodos public declarados en la clase principal, puede llamar a la función getMethods y obtener un método public especificado, puede llamar al método getMethod . Consulte el siguiente código:
showmethods vacío estático privado () {estudiante estudiante = nuevo estudiante ("mr.simple"); // Obtenga todos los métodos públicos (incluido el mismo estudiante y heredado de la clase principal) método [] métodos = student.getclass (). GetMethods (); Pruebe {// Tenga en cuenta que solo se pueden obtener métodos públicos a través de GetMethod. Si intenta obtener un método privado, se lanzará una excepción. Método LearnMethod = student.getClass (). GetMethod ("Learn", String.Class); } capt (excepción e) {}} Obtenga los atributos definidos en la clase por reflexión
Obtener atributos es similar a obtener métodos, excepto que la llamada a los métodos getMethods() / getDeclaredMethods() se reemplaza con una llamada a los métodos getFields() / getDeclaredFields() .
Obtenga los atributos definidos en la clase actual (excluyendo los atributos heredados de la clase principal)
Para obtener todos los atributos definidos en la clase actual (incluidos varios atributos como private , public , static , etc.), puede llamar a la función getDeclaredFields del objeto de clase; Para obtener los atributos especificados, puede llamar getDeclaredField .
Como se muestra en el siguiente código:
privado void static showDeclaredfields () {estudiante estudiante = nuevo estudiante ("factura", 18); // Obtenga todos los atributos definidos en el campo de clase actual [] campos = student.getclass (). GetDeclaredFields (); Pruebe {// Obtenga el atributo especificado Campo stateField = student.getClass (). getDeclaredField ("grado"); // Obtener el value de atributo System.out.println ("La calificación es:" + grado de campo.getInt (estudiante)); // Establecer el valor de atributo Gradefield.set (estudiante, 10); } capt (excepción e) {}} Obtenga los atributos públicos definidos en la clase actual y la clase principal
Para obtener todas las propiedades public definidas en la clase actual y la clase principal, puede llamar a la función getFields del objeto Class . Para obtener una propiedad public específica, puede llamar getField , como se muestra en el siguiente código:
privado void staty showfields () {estudiante estudiante = nuevo estudiante ("factura", 18); // Obtenga todas las propiedades públicas del campo actual de clase y clase principal [] publicfields = student.getclass (). GetFields (); } Reflexión para obtener la clase principal de la clase y la interfaz implementada por la clase
Obtenga la clase madre
Simplemente llame al método getSuperClass del objeto Class , como se muestra en el siguiente código:
Estudiante estudiante = nuevo estudiante ("bill", 18); clase <?> Superclass = student.getclass (). GetsuperClass (); Obtenga la interfaz implementada
Para saber qué interfaces implementa una clase, simplemente llame al método getInterfaces del objeto Class , como se muestra en el siguiente código:
Private static void showInterfaces () {Student Student = New Student ("Bill", 19); Clase <?> [] Interfaces = student.getclass (). GetInterfaces ();}Resumir
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el estudio y el trabajo de todos.