Revisión básica de Java (4) --- Reflexión de Java

reflejo de java

1. Teoría

El mecanismo de reflexión de JAVA está en estado de ejecución, para cualquier clase, puede conocer todos los atributos y métodos de esta clase; para cualquier objeto, puede llamar a cualquiera de sus métodos y atributos; este tipo de información adquirida dinámicamente y llamadas dinámicas La función del método del objeto se llama mecanismo de reflexión del lenguaje java.

Si desea analizar una clase, primero debe obtener el objeto de archivo de código de bytes de la clase. La anatomía utiliza los métodos de la clase Class, por lo que primero debe obtener el objeto de tipo Class correspondiente a cada archivo de código de bytes.

2. Demostración de casos

/**
	 * 演示类
	 */
	public static class Person {
		static {
			System.out.println("静态代码块执行");
		}
		private Integer id;
		private String name;
		public Person(Integer id, String name) {
			super();
			this.id = id;
			this.name = name;
		}
		public Person() {
			super();
		}
		public Integer getId() {
			return id;
		}
		public void setId(Integer id) {
			this.id = id;
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		@Override
		public String toString() {
			return "Person [id=" + id + ", name=" + name + "]";
		}
		
	}

1. Tres formas de obtener objetos de clase

	/**
	 * 	类.class
	 *  对象.getClass
	 *  Class.forName
	 */
	@Test
	public void test1() throws Exception {
		String className = "d18_reflect.review.ReflectDemo.Person";
		Class<?> clazz = Class.forName(className); // 方式1
		clazz = Person.class; // 方式2
		clazz = new Person().getClass(); // 方式3
 	}

2. Los tres parámetros de class.forName () y la secuencia alternativa del cargador de clases de diseño propio

	 * 自设定类加载器数组的顺序一般是:自设,Thread,本类,system。
	 * forName第二个参数如果为false,那么静态代码块不执行。
	 */
	@Test
	public void test2() throws Exception {
		String className = "d18_reflect.review.ReflectDemo$Person";
		ClassLoader cl = new ClassLoader[]{Thread.currentThread().getContextClassLoader(), getClass().getClassLoader(), 
				 ClassLoader.getSystemClassLoader()}[1];
		Class<?> clazz = Class.forName(className, true, cl);
		//  为false,静态代码块不执行
	}

 3. Reflexión del método

 * getDeclaredMethods : 本类的所有方法
	 * getMethods:本类的公开方法含父类
	 */
	@Test
	public void test3() throws Exception {
		Class<?> clazz = Person.class;
		Person person = (Person)clazz.newInstance();
		Method[] methods = clazz.getDeclaredMethods(); // 所有本类声明的方法
		for (Method method : methods) {
			System.out.println(method);
		}
		System.out.println("_______________");
		Method[] methods2 = clazz.getMethods(); //本类所有公开的方法
		for (Method method : methods2) {
			System.out.println(method);
		}
		Method method = clazz.getMethod("setName",new Class[]{String.class});
		System.out.println(method);
		Object object = method.invoke(person, "哈哈"); //方法执行
	}
	

 4. Reflexión sobre el terreno

 * getDeclaredFields : 本类的声明字段
	 * getFields:全部公开字段
	 * setAccessible(true) 可访问公开字段
	 */
	@Test
	public void test4() throws Exception{
		Person demo = new Person();
		Class<?> clazz1 = Person.class;
		Field[] fields = clazz1.getFields();
		for (Field field : fields) {
			System.out.println("全部公开字段"+field.getName());
		}
		Field[] fields2 = clazz1.getDeclaredFields();
		for (Field field : fields2) {
			System.out.println("本类声明字段:"+field.getName());
		}
		//测试如何调用一个字段?
		Field declaredField = clazz1.getDeclaredField("name");                  
		declaredField.setAccessible(true); //暴力反射,私有字段采用
		declaredField.set(demo,"5");
		Object object = declaredField.get(demo);
		System.out.println(object.toString());
	}

5. Reflexión de matriz

    /**
	 * 5、数组的反射
	 * clazz.isArray() : 判断是数组
	 * Array.getLength : 数组长度
	 * Array.get(arr, 3):数组角标3的元素
	 */
	@Test
	public void test5() throws Exception{
		Object[] arr = new String[5];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = i +"";
		}
		Class<?> class2 = arr.getClass();
		if(class2.isArray()){
			System.out.println(Array.getLength(arr));
			System.out.println(Array.get(arr, 3));
		}
	}

6. Reflexión genérica

class Parent<T>{}

	class Student extends Parent<Object> {}
	
	class StudentExt extends Student{}
	
	/**
	 * 6、泛型反射
	 * getGenericSuperclass : 带泛型参数的父类
	 * ParameterizedType : type的子接口
	 * ParameterizedType.getActualTypeArguments : 真实类型参数的数组
	 */
	@Test
	public void test6() {
//		System.out.println(Object.class.getSuperclass()); //null
//		System.out.println(Student.class.getSuperclass());//class d18_reflect.review.ReflectDemo$Parent
//		System.out.println(Student.class.getGenericSuperclass());//d18_reflect.review.ReflectDemo$Parent<java.lang.Object>
		Class<?> clazz = findTtype(Person.class);
		System.out.println(clazz);
	}
	
	/**
	 * 父级泛型参数的类型查询-只支持2级查询
	 */
	public static Class<?> findTtype(Class<?> entity){
		Type type = entity.getGenericSuperclass(); // 带泛型参数的类型,class父接口
		if (!(type instanceof ParameterizedType)) { 
			type = entity.getSuperclass().getGenericSuperclass();
		}
		ParameterizedType parameterizedType = (ParameterizedType) type;
		Class entityClass = (Class) parameterizedType.getActualTypeArguments()[0];
		return entityClass;
	}
	
	/**
	 * 通过继承方式TypeReference类方式,获取子类传递的实际泛型参数
	 */
	abstract class TypeReference<T> {
		private final Type rawType;
		protected TypeReference() {
			rawType = getSuperclassTypeParameter(getClass());
		}
		Type getSuperclassTypeParameter(Class<?> clazz) {
			Type genericSuperclass = clazz.getGenericSuperclass();
			if (genericSuperclass instanceof Class) {
				if (TypeReference.class != genericSuperclass) {
					return getSuperclassTypeParameter(clazz.getSuperclass());
				}
			}
			Type rawType = ((ParameterizedType) genericSuperclass).getActualTypeArguments()[0];
			if (rawType instanceof ParameterizedType) {
				rawType = ((ParameterizedType) rawType).getRawType();
			}
			return rawType;
		}
		public final Type getRawType() {
			return rawType;
		}
	}

 

 

 

 

Supongo que te gusta

Origin blog.csdn.net/shuixiou1/article/details/112591588
Recomendado
Clasificación