JAVA Advanced - Reflection

Table of contents

1. What is reflection?

 2. Three ways to get the Class object

3. Reflection acquisition method (Constructor)

Fourth, reflective access to member variables (Field)

Five, reflective acquisition member method (Method)

6. Comprehensive exercises

1. Saving information

2. Combining configuration files to create objects


1. What is reflection?

  • Reflection allows programmatic access to information on member variables, member methods, and constructors.
  • Reflection is to map various components in the java class into Java objects one by one

  • For example: A class has information such as member variables, methods, construction methods, etc., and reflection technology can be used to dissect a class and map each component into each object.

idea automatic prompt

Question: Why can't I use the IO stream to read line by line from top to bottom?

  • But when we read the constructor and ordinary member methods, we cannot distinguish.
  • Member variables and local variables are also difficult to distinguish.

So we use  reflection to get member variables to get all the member information :

 The role of reflection:

  • Get all the information in a class, and then execute other business logic after getting it.
  • Combined with configuration files, dynamically create objects and call methods.

 2. Three ways to get the Class object

Preconditions for using reflection: You must first obtain the Class of the bytecode represented, and the Class class is used to represent the .class file (bytecode)

  1.  Class.forName ( " full class name " );              (most commonly used)
  2. Class name. class        (generally more passed as parameters)
  3. object.getClass ( ) ;  (can only be used when there is already a class object)

public class MyReFlectDemo {
	public static void main(String[] args) throws ClassNotFoundException {
		// 1.第一种方式
		// 全类名 : 包名 + 类名
		Class clazz1 = Class.forName("ReFlect.Student");
		System.out.println(clazz1); // class ReFlect.Student

		// 2.第二种方式
		Class clazz2 = Student.class;
		System.out.println(clazz2); // class ReFlect.Student
		System.out.println(clazz1 == clazz2); // true

		// 3.第三种方式
		Student s = new Student();
		Class clazz3 = s.getClass();
		System.out.println(clazz1 == clazz2); // true
		System.out.println(clazz2 == clazz3); // true
	}
}

3. Reflection acquisition method (Constructor)

The method of obtaining the constructor method in the Class class:

Constructor <?> [ ] getConstructors() Returns an array of all public constructor objects
Constructor <?> [ ] getDeclaredConstructors() Returns an array of all constructor objects
Constructor <T> getConstructor ( Class <> .. parameterTypes ) Returns a single public constructor object
Constructor <T> getDeclaredConstructor(Class <>.. parameterTypes) returns a single constructor object

Methods used in the Constructor class to create objects:

T newInstance ( Oject... initargs ) Create an object according to the specified constructor
setAccessible ( boolean flag ) Set to true to cancel the access check
public class MyReFlectDemo {
	public static void main(String[] args) throws 
          ClassNotFoundException, NoSuchMethodException, SecurityException {

		// 1.获取Class字节码文件的对象
		Class clazz = Class.forName("ReFlect.Student");

		// 2.获取构造方法
		// 获取所有
		Constructor[] cons1 = clazz.getConstructors();
		for (Constructor con : cons1) {
			System.out.println(con);
		}

		Constructor[] cons2 = clazz.getDeclaredConstructors();
		for (Constructor con : cons2) {
			System.out.println(con);
		}
			// 获取单个
			Constructor con1 = clazz.getDeclaredConstructor();
			System.out.println(con1);  //public ReFlect.Student()

			Constructor con2 = clazz.getDeclaredConstructor(String.class);
			System.out.println(con2);  //public ReFlect.Student(java.lang.String)
			
			Constructor con3 = clazz.getDeclaredConstructor(int.class);
			System.out.println(con3);  //public ReFlect.Student(int)
			
			//获取两个参数
			Constructor con4 = 
               clazz.getDeclaredConstructor(String.class,int.class);
			System.out.println(con4);  //public 
               ReFlect.Student(java.lang.String,int)
			//接下来我们就可以反射获取所有信息:
			//比如1:权限修饰符
			int modifiers = con4.getModifiers();
			System.out.println(modifiers); //1
			//比如2:获取构造方法所有参数
			Parameter[] parameters = con4.getParameters();
			for(Parameter parameter:parameters) {
				System.out.println(parameter); 
				//java.lang.String arg0
				//int arg1
			}
			//比如3:利用构造方法创建对象
			con4.setAccessible(true); //暴力反射:表示临时取消权限校验
			Object stu = (Student)con4.newInstance("张三",23);
			System.out.println(stu); //Student [name=张三, age=23]
	}
}


//Student.java
public class Student {
	private String name;
	private int age;

	public Student() {
	}

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

	public Student(String name) {
		this.name = name;
	}

	public Student(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

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

Fourth, reflective access to member variables (Field)

The method of obtaining member variables in the Class class:

Field [ ]  getFields() Returns an array of all public member variable objects
Field [ ]  getDeclaredFields ( ) Returns an array of all member variable objects
Field getField ( String name ) returns a single public member variable object
Field getDeclaredField ( String name ) returns a single member variable object

Methods used to create objects in the Field class:

void set ( Object obj , Object value ) assignment
Object get ( Object obj ) get value
public class MyReFlectDemo {
	public static void main(String[] args) throws 
               ClassNotFoundException, NoSuchFieldException{

		// 1.获取Class字节码文件的对象
		Class clazz = Class.forName("ReFlect.Student");

		// 获取成员变量
		//获取所有的成员变量
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			System.out.println(field);
			//private java.lang.String ReFlect.Student.name
			//private int ReFlect.Student.age
			//public java.lang.String ReFlect.Student.gender
		}
		
		//获取单个成员变量
		Field gender = clazz.getField("gender");
		System.out.println(gender);
		//public java.lang.String ReFlect.Student.gender
		
		//Field name = clazz.getField("name");  
		//无法获取 name是private私有的
		Field name = clazz.getDeclaredField("name"); 
		System.out.println(name);
		//private java.lang.String ReFlect.Student.name
		
		//获取到成员变量后我们可以继续:
		//1.获取权限修饰符
		int modifier = name.getModifiers();
		System.out.println(modifier);  //2
		//2.获取成员变量名
		String n = name.getName();
		System.out.println(n); //name
		//3.获取数据类型
		Class<?> type = name.getType();
		System.out.println(type); //class java.lang.String
		//4.获取成员变量记录的值
		Student s = new Student("张三",23,"男");
		name.setAccessible(true);
		Object value = (String)name.get(s);  //张三
		System.out.println(value);
		//5.修改成员变量记录的值
		name.set(s, "李四");
		System.out.println(s);  //Student [name=李四, age=23, gender=男]	
	}
}



public class Student {
	private String name;
	private int age;
	public String gender;

	public Student() {
	}

	public Student(String name, int age, String gender) {
		this.name = name;
		this.age = age;
		this.gender = gender;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

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

Five, reflective acquisition member method (Method)

The method of obtaining member methods in the Class class:

Method [ ]  getMethods ( ) Returns an array of all public member method objects, including inherited
Method [ ]  getDeclaredMethods ( ) returns an array of all member method objects, excluding inherited
Method getMethod ( String name ,  Cass <?> .. parameterTypes ) returns a single public member method object
Method getDeclaredMethod ( String name ,  Class<?>... parameterTypes ) returns a single member method object

Methods used to create objects in the Method class:

Object invoke ( Object obj ,  Object... args ) run method
Parameter 1: call the method with the obj object
Parameter 2: the passed parameters of the calling method (if not written)
return value: the return value of the method (if not written)
public class MyReFlectDemo {
	public static void main(String[] args) throws 
           ClassNotFoundException, NoSuchFieldException {

		// 1.获取Class字节码文件的对象
		Class clazz = Class.forName("ReFlect.Student");

		// 2.获取里面所有的方法对象
		//(包含所有父类中的所有的公共方法)
		Method[] methods1 = clazz.getMethods();
		for(Method method : methods1) {
			System.out.println(method);
		}
		//获取里面所有的方法对象(只能获取本类中私有方法)
		Method[] methods2 = clazz.getDeclaredMethods();
		for(Method method : methods2) {
			System.out.println(method);
		}
		
		//3.获取指定单一方法对象
		Method m = clazz.getDeclaredMethod("eat", String.class);
		System.out.println(m); //private void ReFlect.Student.eat(java.lang.String)
		  //1.获取权限修饰符
		int modifers = m.getModifiers();
		System.out.println(modifers); //2
		//2.获取方法名
		String name = m.getName();
		System.out.println(name);  //eat
		//3.获取方法形参
		Parameter[] parameters = m.getParameters();
		for (Parameter parameter : parameters) {
		System.out.println(parameter);	 //java.lang.String arg0
		}
		//4.获取方法返回值
		//5.获取方法抛出异常
		Class<?>[] exceptionTypes = m.getExceptionTypes();
		for(Class exceptiontype : exceptionTypes) {
			System.out.println(exceptiontype);
			//class Java.io.TOException
			//class java. lang. NullPointerException
			//class java. lang.ClassCastException

		}
		
		//方法运行
		Student s = new Student();
		m.setAccessible(true);
		m.invoke(s, "汉堡包");
	}
}


public class Student {
	private String name;
	private int age;

	public Student() {
	}

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

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

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

	public void sleep() throws 
            IOException, NullPointerException, ClassCastException {
		System.out.println("睡觉");
	}

	private void eat(String something) {
		System.out.println("在吃" + something);
	}
}

6. Comprehensive exercises

1. Saving information

For any object, all field names and values ​​of the object can be saved to a file.

public class MyReFlectDemo {
	public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, IOException {

		Student s = new Student("张三", 23, '男', 175, "睡觉");
		Teacher t = new Teacher("李四", 10000);

		saveObject(s);

	}

	// 把对象里面所有的成员变量名和值保存到本地文件中
	public static void saveObject(Object obj) throws IllegalArgumentException, IllegalAccessException, IOException {
		// 1.获取字节码文件的对象
		Class clazz = obj.getClass();

		// 创建IO流
		BufferedWriter bw = new BufferedWriter(new FileWriter("java02//a.txt"));

		// 2.获取所有的成员变量
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
			// 获取成员变量的名字
			String name = field.getName();
			// 获取成员变量的值
			Object value = field.get(obj);
			// 写出数据
			bw.write(name + "=" + value);
			bw.newLine();
			// System.out.println(name + "=" +value);
		}
		bw.close();
	}
}

2. Combining configuration files to create objects

Combined with configuration files, dynamically create objects and call methods

public class MyReFlectDemo {
	public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

		//1.读取配置文件中的信息
		Properties prop = new Properties();
		FileInputStream fis = new FileInputStream("java02//prop.properties");
		prop.load(fis);
		fis.close();
		System.out.println(prop);
		
		//2.获取全类名和方法名
		String classname = (String)prop.get("classname");
		String methodname = (String)prop.get("method");
		
		System.out.println(classname);
		System.out.println(methodname);
		
		//3.利用反射创建对象并运行方法
		Class clazz = Class.forName(classname);
		
		//获取构造方法
		Constructor con = clazz.getDeclaredConstructor();
		Object o = con.newInstance();
		System.out.println(o);
		
		//获取成员方法并运行
		Method method = clazz.getDeclaredMethod(methodname);
		method.setAccessible(true);
		method.invoke(o);
	}
}

Guess you like

Origin blog.csdn.net/hdakj22/article/details/129663016