java反射原理

动态代理:

image-20241114213414206

image-20241114213902826

image-20241114221141977

如何为java对象创建一个代理对象?

java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法

1
2
3
4
 public static Object newProxyInstance(ClasLoader loader, Class<?>[] interfaces, InvocationHandler h)
参数一:用于指定用哪个类加载器,去加载生成的代理类
参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
参数三:用来指定生成的代理对象要干什么事情

image-20241124153154267

反射就是能够获取到一个类的全部信息

image-20241124153315026

获取class对象:

1
2
3
Class.forName("全类名");  //---------全类名: 包名+类名
类名.class
对象.getclass();

三个阶段:
第一个阶段:

image-20241124153624672

使用的是Class.forName(“全类名”);获取字节码文件,这是未写入内存

image-20241124153814310

用的是类名.class

image-20241124153836265

用的是对象.getclass();

获取class对象后才能获取构造的方法

image-20241124162012345

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/*
Class类中用于获取构造方法的方法
Constructor<?>[] getConstructors() ------公共函数的数组
Constructor<?>[] getDeclaredConstructors() ------所有函数的数组
Constructor<T> getConstructor(Class<?>... parameterTypes) -----返回单个公共构造方法对象
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) -----返回翻个构造方法的对象


Constructor类中用于创建对象的方法
T newInstance(odject... initargs)
setAccessible(boolean flag)

*/

//1.获取class字节码文件对象
Class clazz= Class.forName("MyReflect2.Student");
//2.获取构造方法
/*Constructor[] cons =clazz.getConstructors();
for (Constructor c:cons){
System.out.println(c);
}
Constructor[] con1=clazz.getDeclaredConstructors();
for (Constructor c:con1){
System.out.println(c);
}*/
//获取名字
// Constructor con2=clazz.getConstructor(String.class);
// System.out.println(con2);
// Constructor con3=clazz.getDeclaredConstructor(int.class);
// System.out.println(con3);
// Constructor con4=clazz.getDeclaredConstructor(String.class,int.class);
// System.out.println(con4);

Constructor con46=clazz.getDeclaredConstructor(String.class,int.class);
//获取修饰符
int modifiers = con46.getModifiers();
System.out.println(modifiers);
//获取形参列表
Parameter[] parameters= con46.getParameters();
for (Parameter p:parameters)
{
System.out.println(p);
}

//暴力反射:临时取消权限的校验
// con4.setAccessible(true);
// //创建对象
// Student stu = (Student) con46.newInstance("zhangsan",23);
// System.out.println(stu);

利用反射获取成员变量

image-20241124223524736

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package MyReflect3;

import java.lang.reflect.Field;

public class MyReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
/*
*Class类中用于获取成员变量的方法
* Field[] getFields(): 返回所有公共成员变量对象的数组
* Field[] getDeclaredFields(): 返回所有成员变量对象的数组
* Field getField(String name): 返回单个公共成员变量对象
* Field getDeclaredField(String name): 返回单个成员变量对象
*
* Field类中用于创建对象的方法
* void set(Object obj ,Object value): 赋值
* Object get(Object obj) 获取值
*
*/
//1.获取class字节码文件的对象
Class clazz=Class.forName("MyReflect3.Student");
//2.获取所有的成员变量
Field[] fields=clazz.getDeclaredFields();

for (Field f:fields){
System.out.println(f);
}

//获取单个的成员变量
Field gender = clazz.getDeclaredField("name");
System.out.println(gender);

//获取权限修饰符
int zhuangtai =gender.getModifiers();
System.out.println(zhuangtai);

//获取成员变量的名字
String n = gender.getName();
System.out.println(n);
//获取数据类型
Class type = gender.getType();
System.out.println(type);

//获取成员变量记录的值;
Student s = new Student("zhangsan",23,"nan");
gender.setAccessible(true);
Object value = gender.get(s);
System.out.println(value);

//修改对象里面记录的值
gender.set(s,"lisi");
System.out.println(s);
}
}

利用反射获取成员方法:

image-20241125210102701

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package MyReflect4;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MyReflectDemo {
public static void main(String [] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
/*
* Class类中用于获取成员方法的方法
* Method[]getMethods():返回所有公共成员方法对象的数组,包括继承的
* Method0 getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
* Method getMethod(String name,Class<?>.parameterTypes):返回单个公共成员方法对象
* Method getDeclaredMethod(String name,Class<?>parameterTypes):返回单个成员方法对象
* Method类中用于创建对象的方法
* Object invoke(Object obj,,Object..args):运行方法
* 参数一:用obj对象调用该方法
* 参数二:调用方法的传递的参数(如果没有就不写)
* 返回值:方法的返回值(如果没有就不写)
*
*获取方法的修饰符
*获取方法的名字
*获取方法的形参
* 获取方法的返回值
* 获取方法的抛出的异常
*
*/

//1.获取class字节码文件对象
Class clazz = Class.forName("MyReflect4.Student");
//2.获取里面的所有方法对象(包含符类中所有的父类方法)
/*Method[] methods=clazz.getMethods();
for (Method m:methods){
System.out.println(m);
}*/
//2,获取里面的所有的方法(不能获取符父类的,可以获取本类中的所有方法)
Method[] methods1=clazz.getDeclaredMethods();
for (Method m:methods1){
System.out.println(m);
}

Method m=clazz.getDeclaredMethod("eat", String.class);
m.setAccessible(true);
System.out.println(m);

//获取方法的修饰符
int modifiers= m.getModifiers();
System.out.println(modifiers);

//获取方法的名字
String name= m.getName();
System.out.println(name);

//获取方法的形参
Class[] parameterTypes= m.getParameterTypes();
for (Class c:parameterTypes){
System.out.println(c);
}
//获取方法的返回值
Class returnType= m.getReturnType();
System.out.println(returnType);
//获取方法的抛出的异常
Class[] exceptionTypes= m.getExceptionTypes();
for (Class e:exceptionTypes){
System.out.println(e);
}
//创建对象
Student s=new Student();
Object o=m.invoke(s,"apple");//参数一obj是对象,参数二:调用方法的参数
System.out.println(o);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package MyReflect4;

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

public Student() {
}

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

/**
* 获取
* @return name
*/
public String getName() {
return name;
}

/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}

/**
* 获取
* @return age
*/
public int getAge() {
return age;
}

/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
public void sleep(){
System.out.println("睡觉");
}
private void eat(String something){
System.out.println("再吃"+something);
}
private void eat(String something,int age){
System.out.println("再吃"+something);
}

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