Java:反射
Java:设计模式
Java:反射动态代理
各位读者请注意:以上连续三篇(包括本篇),属于引导型博客,并不是对知识点的详细解释,而是对“反射、设计模式和反射动态代理”这三个知识模块的个人理解型的白话文。对于初学java,尤其是别的语言转java语言的同学来说应该可以有不小帮助,对于“想要钻研深入的技术的同学”,可以忽略本文。
文章目录
一、反射与工厂模式
1.工厂模式的缺点
class WorkFactory {
public WorkFactory() {
}
public static Worker getInstance(String className) {
if ("student".equals(className)) {
return new Student();
} else if ("teacher".equals(className)) {
return new Teacher();
} else {
return null;
}
}
}
可以看到
工厂模式中,如果需要新增子类,那么就要修改WorkFactory的接口
,如下:
class WorkFactory {
public WorkFactory() {
}
public static Worker getInstance(String className) {
if ("student".equals(className)) {
return new Student();
} else if ("teacher".equals(className)) {
return new Teacher();
} else if ("cooker".equals(className)) {
return new Cooker();//增加一个Cooker子类就得修改一次
} else {
return null;
}
}
}
2.引入反射后就能解决这个缺点
因为
Class类可以使用newInstance() 实例化对象,同时Class.forName()能够接收类名称
,如下
class WorkFactory {
public WorkFactory() {
}
public static Worker getInstance(String className) {
//不再是添加一个子类就new一个对应的对象,而是统一使用反射后的Class类使用newInstance()实例化对象
Worker worker = null;
try {
worker = (Worker) Class.forName(className).newInstance() ;
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
return worker ;
}
}
public class test {
public static void main(String[] args) {
Worker worker = WorkFactory.getInstance("Student");
worker.doWork();
worker = WorkFactory.getInstance("Teacher");
worker.doWork();
}
}
二、反射与代理模式(动态)
1.什么是动态代理
上篇Java:设计模式中简单讲了静态代理模式,其特点就是:一个被代理类对应一个代理类,当有多个被代理类时,静态代理模式就需要设计多个代理类,很不方便,那么动态代理模式就是解决这个问题的设计模式,
它可以使用一个代理类来代理多个不同的被代理类。
2.动态代理模式的核心部分
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
class ProxySubject implements InvocationHandler {
// 绑定任意接口的对象,使用Object描述
private Object proxy_obj;
//这是一个自定义方法,作用有两个:
//1.给“被代理类”的对象实例化
//2.返回一个“代理类”的对象
public Object bind(Object obj) {
this.proxy_obj = obj;
//绑定“被代理类”实现的所有接口,取得“代理类”
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
//当“代理类”的对象调用“被代理类”的“重写方法”时,就会转为调用该方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//执行proxy_obj对象中参数为args的方法,返回值类型为Object
Object ret = method.invoke(this.proxy_obj, args);
return ret;
}
}
3.动态代理模式代码示例
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class test {
public static void main(String[] args) {
Worker worker = (Worker) new ProxySubject().bind(new Teacher());
worker.doWork();//打印"教师改作业"
worker = (Worker) new ProxySubject().bind(new Student());
worker.doWork();//打印"学生写作业"
}
}
interface Worker {
void doWork();
}
class Teacher implements Worker {
@Override
public void doWork() {
System.out.println("教师改作业");
}
}
class Student implements Worker {
@Override
public void doWork() {
System.out.println("学生写作业");
}
}
class ProxySubject implements InvocationHandler {
private Object proxy_obj;
public Object bind(Object obj) {
this.proxy_obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object ret = method.invoke(this.proxy_obj, args);
return ret;
}
}
4.运行结果
三、最后可以总结一下动态代理的作用
我的总结不够精简,Java 动态代理作用是什么?这个知乎贴里有各路大神的精辟总结!!!