Article Directory
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 typeAvoid 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 getparameterType
: 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 getparameterType
: 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.DDCmethodName: 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("骑电动车出去兜风");
}
}