[Java core technology] Java reflection technology detailed

reflection

Coupling degree: the relationship between modules (high cohesion, low coupling)

Reflection occurs during runtime

definition

Reflection: The process of parsing the information of the class, obtaining the bytecode object, and then generating the instance object

Transparent operation of the class name of the bytecode file (one and only one copy) loaded into the memory (you can get any data in the class)

Relatively low efficiency

Classes used by reflection:Class

  • In the running state, for any class, properties and methods can be obtained;

  • For any object, you can call properties and methods;

  • We call the process of dynamically obtaining and invoking properties and methods called reflection

Reflection is basically not used when writing programs in normal times, and the framework is usually completed

  • Features: Make the project more flexible, and the efficiency is relatively hard-coded

Disadvantage

  • Reflection breaks the principle of encapsulation

  • Reflection skips type checking

Representative classClass

No matter which method is used to obtain the Class object of the object, it is equal, and there is only one copy in the memory

Known class name

Class<E> xxx = 类名.class

//只知道类名的情况下
//字符串的字节码对象
Class<String> clz = String.class;
//class java.lang.String

//接口的字节码对象
Class<List> clz1 = List.class;
//interface java.util.List

//数组的字节码对象
Class<int[]> clz2 = int[].class;//class [I

//基本类型的字节码对象
Class<Integer> clz3 = int.class;//int

Known objects

Use the getClass() method of the object to obtain the Class object

  • Class<E> xxx = 对象名.getClass();
//已知对象,使用对象的getClass()方法,获取Class对象
Student stu = new Student();
Class clazz2 = stu.getClass();

String str = "abc";
Class<String> clz = (Class<String>) str.getClass();

The most frequently used method in the framework to obtain the Class object

Class<E> xxx = Class.forName("包名.类名");

forName()Obtain the Class object: first check whether there is a bytecode file in the memory

  • If it exists, return the Class object
  • If it is not loaded into memory, first load the bytecode file of this class into memory and return the Class object of this class
Class clazz3 = Class.forName("cn.sxh.Student");
System.out.println(clazz3);//class cn.sxh.Student

Class representing the constructorConstructor

Obtain the construction method through reflection, use the construction method to create an object

newInstance(): Call the no-argument construction of the specified class

Class[] cs: getParameterTypes(): Get all parameter types

isPrimitive(): Determine whether it is a basic type

Avoid some classes without parameterless construction

public static Object clone1(Object o) throws 
 IllegalAccessException, InstantiationException, 
InvocationTargetException {
     
     
 //1.获取原对象的字节码对象
 Class<Object> clz = (Class<Object>) o.getClass();

 //把所有构造方法放到数组中,只拿数组中第一个元素,保证一定会拿到一个构造方法
 Constructor<Object> c = (Constructor<Object>) clz.getDeclaredConstructors()[0];
 Class[] cs = c.getParameterTypes();

 //新建数组,用于存储参数值
 Object[] os = new Object[cs.length];
 //定义遍历,表示os数组下标
 int index = 0;
 //遍历cs数组
 for (Class i : cs) {
     
     //每个i代表构造方法的每个参数类型
     //判断是否是基本数据类型
     if (i.isPrimitive()) {
     
     
         //判断是否是字符类型
         if (i  char.class) {
     
     //判断类型是否一致
             os[index++] = '\u0000';
         }
         if (i  boolean.class) {
     
     
             os[index++] = false;
         }
         if (i  float.class) {
     
     
             os[index++] = 0.0f;
         }
         if (i  double.class) {
     
     
             os[index++] = 0.0;
         }
         //整形
         os[index++]=0;
     }else {
     
     
         os[index++] = null;
     }
 }

 //2.获取实例对象---克隆对象
 Object obj = c.newInstance(os);
 //3.获取原对象身上的所有属性
 Field[] fields = clz.getDeclaredFields();
 //4.把原对象所有属性赋值给实例对象(克隆)身上
 for (Field field : fields) {
     
     
     field.setAccessible(true);
     field.set(obj, field.get(o));
 }
 return obj;
}

Get all non-private constructors

类名.class.getConstructors():Constructors[ ]

//获取所有的非私有的构造方法
Constructor[] cons = Student.class.getConstructors();
for(Constructor con : cons) {
    
    
    System.out.println(con);
}

Get the specified construction method

  • Get the construction method without parameters:

类名.class.getConstructor(null);: Constructor<class name>

Constructor<Student> con1 = Student.class.getConstructor(null);
//通过无参的构造方法创建对象
Student stu1 = con1.newInstance();
stu1.sleep();
stu1.name = "admin";
stu1.eat("苹果");

Get the parameterized construction method:

getConstructor(String.class,int.class);: The parameter corresponds to the Class type of the type of the parameter list of the constructor

  • String:String.class

  • int:int.class

//有参的构造方法
Class<Student> clz = Student.class;
Constructor<Student> con2 = clz.getConstructor(String.class,int.class);
Student stu2 = con2.newInstance("张三",20);
stu2.eat("包子");

Obtain a private construction method

getDeclaredConstructor(): Get the specified non-public construction method

setAccessible(true): Brute force cracking, allowing to break through modifier permissions to pass in values

Class<String> clz = String.class;
//获取有参构造
Constructor<String> con;
con = clz.getDeclaredConstructor(char[].class,boolean.class);
con.setAccessible(true);//暴力破解

String s = con.newInstance(new char[]{
    
    'a','b'},true);
System.out.println(s);

Class representing the attributeField

Get all non-private attributes of the class

getFields():Field[] returns all non-private member variables, stored in the array

getModifiers():int returns the access modifier of the member variable, public-1

getName():String returns the name of the member variable

getType():String returns the type of member variable (int, String, double...)

Class clazz = Student.class;
Student stu = (Student) clazz.newInstance();

//获取类的所有非私有属性
Field[] fields = clazz.getFields();
for(Field field : fields) {
    
    
    System.out.println(field.getModifiers());
    System.out.println(field.getName());
    System.out.println(field.getType());
}

Get the specified attribute

类名.class.getField(String name);:name is the name of the member variable of the class to be obtained, return type: Field

//获取指定的属性
Field field1 = Student.class.getField("name");

Set the value of the property, get the value

set(obj,String);Assign a value to a variable

  • obj: object name, manipulate attributes in the variable of the object
  • String: content, the content of the attribute to be set

get(obj)Get the value of a variable

  • obj: the object to get the variable
//给属性设置值,获取值
field1.set(stu, "张三");
System.out.println(field1.get(stu));

Get private properties, set values, get values

类名.class.getDeclaredField(String name);Get variable age

setAccessible(true);Set private attribute access permissions

//获取私有属性,设置值,获取值
Field field2 = Student.class.getDeclaredField("age");
field2.setAccessible(true);//设置私有属性访问权限
field2.set(stu, 22);
System.out.println(field2.get(stu));

Class representing methodMethod

Get all non-private member methods

类名.class.getMethods();: Method[ ]

  • Return all non-private methods in the class to an array of Method type

getModifiers(): Int access modifier for access method

getReturnType():The return type of the String get method

getName(): String get the name of the method

Class clazz = Student.class;
//获取所有的非私有成员方法
Method[] methods = clazz.getMethods();
for(Method method:methods) {
    
    
    System.out.print(method.getModifiers()+"\t");
    System.out.print(method.getReturnType()+"\t");
    System.out.println(method.getName());
}

Get the specified member method

类名.class.getMethod(String name,Class parameterType);

  • name: The name of the method to get
  • parameterType: Get the Class type of the parameters of the method, if the method does not have a parameter list, write null
    • String:String.class
    • int:int.class
    • and many more

Calling method:

  • invoke(Object obj,Object args);
  • obj: the object name of the object to call the method
  • args: the parameter list of the method, when the method has no parameters, write null
//获取指定的成员方法
Method m1 = clazz.getMethod("eat", String.class);
//创建对象,clazz = Student.class,没有获取构造方法,所有要强制类型转换
Student stu = (Student) clazz.newInstance();
m1.invoke(stu, "苹果");

Get private member method

类名.class.getDeclaredMethod(String name,Class parameterType);

  • name: The name of the method to get
  • parameterType: Get the Class type of the parameters of the method, if the method does not have a parameter list, write null
    • String:String.class
    • int:int.class
    • and many more

Because it is a private method, it can be used only after setting access permissions

setAccessible(true)Set access permissions for private member methods

//获取私有的成员方法
Method m2 = clazz.getDeclaredMethod("study",null);
m2.setAccessible(true);
m2.invoke(stu,null);

Class representing annotationAnnotation

Configuration file use reflection

Configuration file

The configuration file stores data in a way similar to key-value pairs

The path is represented by the hexadecimal Unicode code

className: indicates the class name

  • \u6848: Case
  • \ u4f8b: Example
  • DDC: Class name
  • \u6848\u4f8b.DDC: Case.DDC

methodName: indicates the method name

  • qi: method name in DDC
className=\u6848\u4f8b.DDC
methodName=qi

Load the configuration file in the class

Load the configuration file to read the content of the configuration file through the IO stream

Properties: Read the class of the configuration file

load(InputStream input): Load configuration file

Properties p = new Properties();
InputStream input = new FileInputStream("pro.properties");
p.load(input);

Extract the class path and method name

getProperty(String Key);: Get the key value in the configuration file

  • key: the key value in the configuration file
String className = p.getProperty("className");
String methodName = p.getProperty("methodName");

Create objects through reflection, call methods

Class clazz = Class.forName(className);
Method m = clazz.getMethod(methodName, null);

m.invoke(clazz.newInstance(), null);

DDC class

public class DDC {
    
    
	
	public void qi() {
    
    
		System.out.println("骑电动车出去兜风");
	}	
}

Guess you like

Origin blog.csdn.net/weixin_54707168/article/details/114125792