对于newProxyInstance方法我们先将一下整个实现的思路。
总体思路就是他通过字符串化产生一个新的java类,再动态编译返回对象。注意是动态编译。
简单来说就是他通过一些传递进来的参数,自己动态模拟写了一个java类,编译返回给用户,因为用户只要求得到一个对象。中间就比较自由。
-------------------------------------------------------------------------------------------------------
A.首先通过string构造 这个方法。
第一步利用传递进来的接口类,通过反射机制获得这个接口的所有方法。
Method[]
methods
=
inter
.getMethods();
这个inter 就是上篇中的Moveable.class
然后遍历这个方法。
for
(Method
m
:
methods
){
利用字符串把中间所有的方法都相加。
method
+=
"@Override "
+
rt
+
" public void "
+
m
.getName() +
"(){"
+
rt
+
" try{"
+
rt
+
" Method md ="
+
inter
.getName()+
".class.getMethod(\""
+
m
.getName()+
"\");"
+
rt
+
" h.invoke(this, md);"
+
rt
+
" }catch(Exception e){"
+
rt
+
" e.printStackTrace();"
+
rt
+
" }"
+
rt
+
" }"
+
rt
+
" "
;
}
这段字符串后期生成的代码是这样的:
@Override
public void move(){
try{
Method md = Moveable.class.getMethod(" move");
h.invoke(this, md);
}catch(Exception e){
e.printStackTrace();
}
}
public void move(){
try{
Method md = Moveable.class.getMethod(" move");
h.invoke(this, md);
}catch(Exception e){
e.printStackTrace();
}
}
红色是动态生成的部分,我们可以看到 对move方法的操作:
1.首先生成一个move这个方法的对象,这里注意我们传递给invoke的那些方法是对象而不是一个个方法名,而我们通过newProxyInstance 第一个参数获得的仅仅是方法名字。所以这里我们要通过反射机制 利用得到的move方法名 再去获得方法对象md。
这时,我们可以回想第二篇中重写的invoke方法:md就是Method m这个参数,也就是move方法。
2.调用h的invoke方法。有人会问 h 是什么,h就是newProxyInstnce 第二个参数,TimeHandler 这个h对象才能调用 TimeHandler里面的invoke方法呀。但是h是实体,但是我们现在书写的是在string里面的字符串。所以我们要继续写 一个构造方法。
String
src
=
"import java.lang.reflect.Method;"
+
rt
+
"public class TankTime implements "
+
inter
.getName() +
"{"
+
rt
+
" private InvocationHandler h;"
+
rt
+
" public TankTime(InvocationHandler h){"