在网上学习了马士兵老师的设计模式视屏,过程中也有认真的做相应的笔记。在次分享我的一些
成果,方便大家的进一步学习。
1、接口
public interface Moveable {
void move();
}
2、被代理的对象
public class Tank implements Moveable {
@Override
public void move() {
System.out.println("Tank Moving...");
try {
Thread.sleep(new Random().nextInt(10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3、测试主类
public class Test {
public static void main(String[] args) throws Exception{
String rt = "\r\n";
//代理类的字符串代码
String src =
"public class TankTimeProxy implements Moveable {"+rt+
" Moveable t;"+rt+
" public TankTimeProxy(Moveable t) {"+rt+
" this.t = t;"+rt+
" }"+rt+
" @Override"+rt+
" public void move() {"+rt+
" long start = System.currentTimeMillis();"+rt+
" System.out.println(\"start time is \"+start);"+rt+
" t.move();"+rt+
" long end = System.currentTimeMillis();"+rt+
" System.out.println(\"end time is \"+end);"+rt+
" System.out.println(\"time is \"+(end - start));"+rt+
" }"+rt+
"}";
//将字符串写入java文件********************************************************************************
String fileName = System.getProperty("user.dir")+"/src/TankTimeProxy.java";//放置在(根目录+文件名)下
File f = new File(fileName);
FileWriter fw = new FileWriter(f);
//写入内容
fw.write(src);
fw.flush();
fw.close();
//进行编译********************************************************************************************
//首先获得编译器
//compiler 为java编译器 即javac
//获得编译器对象
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
//参数含义 (编译诊断,locale,charset)
//管理动态生成的文件的StandardJavaFileManager对象
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null,null,null);//默认值
//根据参数获取多个java文件 返回java文件对象集
Iterable units = fileManager.getJavaFileObjects(fileName);
//“编译任务”对象
JavaCompiler.CompilationTask task = compiler.getTask(null,fileManager,null,null,null,units);
task.call();//调用
fileManager.close();
//************以上过程获得了java文件源码,编译java文件生成了相对应的class文件****************
//***************以下过程为将class文件加载至内存,生成新对象*****************************
//Class.load() 是加载path路径的class文件
//URLClassLoader是将硬盘中的class文件加载进入
//通过Url引入本地文件
URL[] urls = new URL[]{new URL("file:/"+System.getProperty("user.dir")+"/out/production/proxy")}; //访问本地class文件,这里我用的是IntellijIDEA,默认 生成的class文件的目录在 /out/production/ 下
//去指定路径寻找class文件
URLClassLoader urlClassLoader = new URLClassLoader(urls);
Class c = urlClassLoader.loadClass("TankTimeProxy");
System.out.println(c);
//执行
//c.newInstance(); 是调用空的构造方法
//获得构造方法
//根据java虚拟机,每一个构造方法也相当于一个对象
Constructor constructor = c.getConstructor(Moveable.class);
//产生新对象
Moveable m = (Moveable) constructor.newInstance(new Tank()); //new Tank()为构造方法的参数 即被代理对象
m.move();
}
}
4、执行结果