Resumen de Java aprendizaje basado en - la reflexión

En primer lugar, ¿cuál es la reflexión?

mecanismo de reflexión JAVA está en el estado de funcionamiento, para cualquier clase, que se dan a conocer a todas las propiedades y métodos de esta clase; para cualquier objeto, son capaces de llamar a cualquiera de sus métodos y propiedades; esta dinámica y la información dinámica obtuvieron llamada a la función método del objeto se llama lenguaje java reflexión.

En segundo lugar, se puede utilizar la reflexión para hacer?

Sabemos que el mecanismo de reflexión interna que permite a los programas para obtener información sobre cualquier nombre de la clase conocida en tiempo de ejecución, que comprende incluir constructor (constructor), campos (atributos), métodos (método) y similares, y puede cambiar el contenido de los campos en el tiempo de ejecución o llamar a métodos. Entonces podemos ser más flexibles para escribir código, el código puede ser ensamblado en tiempo de ejecución, sin la necesidad de establecer vínculos de código fuente entre los componentes, lo que reduce el acoplamiento del código; no es la realización de un proxy dinámico etc; pero tenga en cuenta que el uso indebido de la reflexión que dará lugar a un alto consumo de recursos!

En tercer lugar, pre-conocimiento de

(A) la carga de la clase

¿Quieres saber cómo utilizar la reflexión, debemos primero entender el tipo de carga.

Cuando se desea utilizar una clase si ésta aún no ha sido cargado en la memoria, el sistema de carga, conexión, inicializar tres pasos para inicializar la clase.

  1. La carga
    que se refiere al archivo de clase se lee en la memoria, y quien para crear un objeto de clase.
    Cualquier clase que se utiliza cuando el sistema va a construir un objeto de clase.
  2. Conexión
    para verificar que la estructura interna correcta, y otros tipos de coordinación y
    listo para ser responsable de la clase miembro estático de memoria asignada, y establecer el valor de inicialización por defecto
    símbolo resolución binaria tipo de datos va a reemplazar las referencias en referencia directa
  3. La inicialización básica de la etapa de inicialización

(Ii) cargador de clases

  1. Cargador de clases: archivo .class responsable de cargar el intrínseco en para, y generar la clase de objeto correspondiente.
    A pesar de que no se preocupan por el mecanismo de carga de clases, pero entendemos que este mecanismo se puede ejecutar una mejor comprensión del programa.

  2. Composición de clase cargador
    Bootstrap ClassLoader clase raíz cargador de
    Extensión cargador de clases de clases de ampliación del cargador
    cargador de clases del sistema sysetm ClassLoader

  3. Actuando cargador de clases
    (1) cargador de clases raíz Bootstrap cargador de clases, también conocido como el cargador de clases de arranque. Responsable de cargar las clases principales de Java
    como sistema, cuerdas y así sucesivamente. En el archivo en el directorio lib rt.jar del JDK JRE

    (2) Ampliación ClassLoader cargador de clases de extensión. Responsable de cargar el directorio de extensiones JRE en un frasco.
    En el directorio lib JRE JDK bajo el ext directorio
    (3) sysetm ClassLoader clase del sistema cargador. Responsable de cargar archivos de clase en el comando java, y el medio ambiente ruta de clase variable especificada paquete frasco y ruta de clase cuando JVM inicio

En cuarto lugar, cómo utilizar la reflexión?

Existiendo una clase Persona

public class Person {
	
	private String name;
	int age;
	public String address;

	public Person() {
	}

	private Person(String name) {
		this.name = name;
	}

	Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public Person(String name, int age, String address) {
		this.name = name;
		this.age = age;
		this.address = address;
	}

	public void show() {
		System.out.println("show");
	}

	public void method(String s) {
		System.out.println("method " + s);
	}

	public String getString(String s, int i) {
		return s + "-->" + i;
	}

	private void function() {
		System.out.println("function");
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", address=" + address
				+ "]";
	}
}

Así que para esta clase, la forma de utilizar el reflejo de ella?

(A) Obtener objeto Class que corresponde a los archivos de código de bytes de clases en la memoria

/**
 *有三种方式可以获得Class对象
 */
//1、通过对象调用 getClass() 方法来获取,通常应用在:比如你传过来一个 Object
//  类型的对象,而我不知道你具体是什么类,用这种方法
  Person p1 = new Person();
  Class c1 = p1.getClass();
        
//2、直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高
//  这说明任何一个类都有一个隐含的静态成员变量 class
  Class c2 = Person.class;
        
//3、通过 Class 对象的 forName() 静态方法来获取,用的最多,
//   但可能抛出 ClassNotFoundException 异常
  Class c3 = Class.forName("com.ys.reflex.Person");

Nota: una clase en la JVM sólo habrá una instancia de clase, que obtenemos por encima de c1, c2, c3 fueron == comparación, el resultado es verdadero

(B) obtener el constructor proporcionado por los métodos de la clase Class

  1. La obtención de método de construcción
/**
 *反射之获取无参构造方法,并使用
 */
public class TestConstructor01 {
	public static void main(String[] args) throws Exception {
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
        //获取无参构造函数
		Constructor con = c.getDeclaredConstructor();	
	
		//创建实例
		Object obj = con.newInstance();
	}
}
/**
 *反射之获取带参构造方法,并使用
 */
public class TestConstructor02 {
	public static void main(String[] args) throws Exception {
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
		//public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
		//获取构造方法
		Constructor con = c.getDeclaredConstructor(String.class, int.class, String.class);
		
		//创建实例
		Object obj = con.newInstance("张三", 27, "北京");
	}
}
/**
 *反射之获取private修饰的构造方法,并使用
 */
public class TestConstructor03 {
	public static void main(String[] args) throws Exception{
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
		//获取构造方法
		Constructor con = c.getDeclaredConstructor(String.class);
		
		//设置访问权限
		con.setAccessible(true);	//值为true则指示反射的对象在使用时应该取消Java语言访问检查。
		
		//创建实例
		Object obj = con.newInstance("林青霞");
	}
}

(C) el método proporcionado por las clases de variables miembro operativo Clase

  1. Para la asignación variable miembro
public class TestField01 {
	public static void main(String[] args) throws Exception{
		test();
	}

	public static void test() throws Exception {
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
		//获取Constructor
		Constructor con = c.getDeclaredConstructor();
		
		//创建实例
		Object obj = con.newInstance();
		System.out.println(obj);
		
		//获取Field
		Field addressField = c.getDeclaredField("address");
		//赋值Field
		addressField.setAccessible(true);
		addressField.set(obj, "北京");
		System.out.println(obj);
		
		Field nameField = c.getDeclaredField("name");
		nameField.setAccessible(true);  	
		nameField.set(obj, "张三");
		System.out.println(obj);
		
		Field ageField = c.getDeclaredField("age");
		ageField.setAccessible(true);
		ageField.set(obj, 27);
		System.out.println(obj);
	}
}

resultados de la prueba son los siguientes:

  1. La adquisición de las variables miembro
public class TestField02 {
	public static void main(String[] args) throws Exception{
		test();
	}

	public static void test() throws Exception {
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
		//获取Constructor
		Constructor con = c.getDeclaredConstructor();
		
		//创建实例
		Object obj = con.newInstance();
		System.out.println(obj);
        
		//获取Field
		Field addressField = c.getDeclaredField("address");
		//赋值Field
		addressField.setAccessible(true);
		addressField.set(obj, "北京");
		System.out.println(obj);
		System.out.println(addressField.get(obj));
	}
}	

resultados de la prueba son los siguientes:

(Iv) el método mediante el método llama a los miembros de la clase Class ofrece

/**
 * 反射之获取无参无返回值成员方法,并调用
 */
public class TestMethod01 {
	public static void main(String[] args) throws Exception {
		test0();
	}
	
	//获取单个方法对象
    /**
    * 1、public 方法 getMethod(String name, Class<?>... parameterTypes):获取所有方法,包括父类的
    * 参数 :	name:方法的名称  parameterTypes:该方法的参数列表 
    * 2、public 方法 getDeclaredMethod(String name, Class<?>... parameterTypes):获取所有子类定义的方法
    * 参数 :	name:方法的名称  parameterTypes:该方法的参数列表 
    */	
	public static void test() throws Exception {
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
		//获取构造方法
		Constructor con = c.getDeclaredConstructor();
		
		//创建实例
		Object obj = con.newInstance();
		
		//获取需要的方法对象
	
		Method m = c.getDeclaredMethod("show");
		
		//调用方法
		/**
		 * public Object invoke(Object obj, Object... args)
		 * obj - 被调用的对象  args - 用于方法调用的参数
		 */
		m.invoke(obj);
	}
}

resultados de la prueba son los siguientes:

/**
 * 反射之获取有参有返回值成员方法,并调用
 */
public class TestMethod02 {
	public static void main(String[] args) throws Exception {
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
		//获取构造方法
		Constructor con = c.getDeclaredConstructor();
		
		//创建实例
		Object obj = con.newInstance();
		
		//获取需要的方法对象
		//public void method(String s)
		Method m = c.getDeclaredMethod("method", String.class);
		m.invoke(obj, "java");
		
		//public String getString(String s, int i) 
		Method m1 = c.getDeclaredMethod("getString", String.class, int.class);
		Object rst = m1.invoke(obj, "hello", 200);
		System.out.println(rst);
	}
}

resultados de la prueba son los siguientes:

/**
 * 反射之获取privste成员方法,并调用
 */
public class TestMethod02 {
	public static void main(String[] args) throws Exception {
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
		//获取构造方法
		Constructor con = c.getDeclaredConstructor();
		
		//创建实例
		Object obj = con.newInstance();
		
		//获取需要的方法对象
		//private void function()
		Method m2 = c.getDeclaredMethod("function");
		m2.setAccessible(true);
		m2.invoke(obj);
	}
}

resultados de la prueba son los siguientes:

V. Resumen

El uso flexible de la reflexión nos permite código más flexible, pero todo tiene un rendimiento dos lados, lo que refleja el consumo del sistema aumentará la complejidad, etc., que es realmente el uso justo!

Supongo que te gusta

Origin www.cnblogs.com/Java-biao/p/12589636.html
Recomendado
Clasificación