Java反射机制
java的反射机制是一种逆向的思维。通常来所,知道一个类,然后new一个对象。而反射便是从一个对象开始,然后反推出它所在的类。前者是抽象到具体的过程。后者是从具体到抽象的过程。
1、类对象Class
- 通过类的实例获得该类的类对象。使用instance#getClass()方法。即通过具体获得类的框架。通过pClass可以获得Person类中的接口和函数等方法。当获得class类之后和实例的关系就分开了。
1
2Peson p = new Person("xiaoming");
Class pClass = p.getClass(); - 使用Class#getDeclaredField(“name”)->Field来获得类响应的属性。可以是公有的,也可以是私有的。但是获得的只是一个类的模板,想要获得一个实例的具体属性,就要用模板来加载实例,然后返回实例的值。也可以通过该Field来设置相应的值。
(1)Field#get(instance) 获得instance中对应Field字段的值
(2)Field#set(instance,value) 设置instance中对应Field字段的值输出结果:1
2
3
4
5
6
7
8
9
10
11// 获得Field对象,是一个模板,该模板是属性name的模板
Field f = pClass.getDeclaredField("name");
// 设置可访问私有属性
f.setAccessible(true);
// 调用Field的get方法来加载p,即获得p中的name属性值
// 等价于p.get("name");
Object value = f.get(p);
System.out.println(value);
// f.set(p,"张三") 对实例p的name属性进行赋值
f.set(p,"张三");
System.out.println(p.getName());2、反射调用函数1
2xiaoming
张三 - 每个Class类中都含有getMethod的方法。根据该方法返回一个Method的对象。该Mehtod对象便是方法的一个模板,使用Method#invoke(Object obj,Object.. args)来对obj对象执行Method方法。并且传入想要的参数。或者参数类输出结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17String s = "Hello World";
try{
// Method 的方法是String类中substring(beginIndex)中的方法
Method m = String.class.getMethod("substring",int.class);
// invoke 调用,等价于s.substring(6)
String sub = (String) m.invoke(s, 6);
System.out.println(sub);
String sub2 = s.substring(6);
System.out.println(sub2);
Method parseInt = Integer.class.getMethod("parseInt", String.class);
// invoke
Integer n = (Integer) parseInt.invoke(null, "12346");
System.out.println("n=" + n);
}catch(Exception e){
e.printStackTrace();
}1
2
3World
World
n=12346动态代理模式
- 核心函数
Proxy.newProxyInstance(ClassLoader,Interface,handler)
第一个参数:ClassLoader。除了jdk自带的一些类:ClassLoader不用使用之外,随意使用classLoader便可以了。
第二个参数:Interface。需要代理的类的接口,这个决定了所代理的类,以下的参数均通过测试
1、Student.class.getInterfaces()
2、new Class[]{Person.class}
3、student.getClass.getInterfaces()
第三个参数:handler,实现了Invocation的接口,并且实现public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
函数。method.invoke(object,args)必须object必须匹配接口 - 简单实现
接口类:Bird实现类:Swallow1
2
3
4
5
6public interface Bird {
/**
* 鸟
*/
void fly();
}接口类:Person1
2
3
4
5public class Swallow implements Bird {
public void fly(){
System.out.println("I'am fly...........");
}
}实现类:Student1
2
3
4public interface Person {
void run();
void say(String str);
}MyHandler实现InvocationHandler的接口1
2
3
4
5
6
7
8
9public class Student implements Person{
public void run() {
System.out.println("I'am Student running");
}
public void say(String str) {
System.out.println("I'am say "+str);
}
}主类,测试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
38public class MyHandler implements InvocationHandler{
/**
* 维护的的对象
*/
private Object target;
public MyHandler(){}
/**
* 构造函数,输入要代理的对象
* @param target
*/
public MyHandler(Object target){
this.target = target;
}
/**
* 设置代理对象
* @param target 代理的对象
*/
public void setTarget(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
//代理对象前的操作
System.out.println("before invoke .....");
System.out.println("Method:"+method);
// 调用原有的函数
method.invoke(target, args);
// 调用原有的函数之后
System.out.println("after invoke .....");
return null;
}
}输出结果: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
37public class Client{
public static void main(String[] args){
Bird realSubject = new Swallow();
try{
// 声明的代理类的处理者
InvocationHandler handler = new MyHandler(realSubject);
// 获得代理类
Bird birdProxy = (Bird)Proxy.newProxyInstance(
handler.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
handler);
System.out.println(birdProxy.getClass().getName());
// 调用鸟飞函数
birdProxy.fly();
Person student = new Student();
((MyHandler) handler).setTarget(student);
// 获得student的代理对象
HelloWorld helloWorld = new HelloWorld();
Person studentProxy =(Person) Proxy.newProxyInstance(
HelloWorld.class.getClassLoader(),
student.getClass().getInterfaces(),
handler);
// 代理类调用函数
studentProxy.run();
studentProxy.say("proxy");
}catch(Exception e){
e.printStackTrace();
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13com.sun.proxy.$Proxy0
before invoke .....
Method:public abstract void com.longquanxiao.proxy.Bird.fly()
I'am fly...........
after invoke .....
before invoke .....
Method:public abstract void com.longquanxiao.proxy.Person.run()
I'am Student running
after invoke .....
before invoke .....
Method:public abstract void com.longquanxiao.proxy.Person.say(java.lang.String)
I'am say proxy
after invoke .....