Java动态代码(包含代理模式)
比较C++和java ,前者是编译成机器码,只要编译过就是可执行的了,后者是编译成java class文件,执行时动态生产java类,所以就有泛型时不能通过设置值就确定了具体的class类型,也有了动态生产可执行的方法和类,这里持续记录
看这个例子,标红的部分,其实a已经可以确定就是A的字类MainTest6了,但是编译过不去的,(可以强转类型成MainTest6,执行不会报错),Java的泛型基本就是相当于Object类了。
public class MainTest6 {
public void doTest(){}
static abstract class Human {
protected abstract void sayBye();
}
static class Man extends Human {
protected void sayBye(){
System.out.println("man bye");
}
}
static class Woman extends Human {
protected void sayBye(){
System.out.println("women bye");
}
}
public void sayHello(Human guy) {
System.out.println("hello,guy!");
}
public void sayHello(Man guy) {
System.out.println("hello,gentleman!");
}
public void sayHello(Woman guy) {
System.out.println("hello,lady!");
}
public static void sayHello(Object arg) {
System.out.println("hello Object");
}
/*public static void sayHello(int arg) {
System.out.println("hello int");
}*/
/*public static void sayHello(long arg) {
System.out.println("hello long");
}*/
/*public static void sayHello(Character arg) {
System.out.println("hello Character");
}*/
/*public static void sayHello(char arg) {
System.out.println("hello char");
}*/
public static void sayHello(char ...arg) {
System.out.println("hello char……");
}
public static void sayHello(MainTest6 arg) {
System.out.println("hello Serializable");
}
static class A<T>{
public T a;
public A (T aa){
a = aa;
}
public void printA(){
System.out.println(" a: "+ a.getClass());
}
}
public static void main(String[] args) {
MainTest6 mainTest6 = new MainTest6();
A a = new A<MainTest6>(mainTest6);//使用泛型类才能编译过去
//a.a.doTest(); 泛型直接使用方法编译不过去,C++可以编译过去。
mainTest6.doTest();
a.printA();
Human man = new Man();
Human woman = new Woman();
MainTest6 sr = new MainTest6();
sr.sayHello( man);
sr.sayHello(woman);
sayHello('a');
man.sayBye();
woman.sayBye();
man = new Woman();
man.sayBye();
}
}
---------------------------------
一 JDK动态代理
为了方便理解动态代理 ,我先一句话说明白静态代理:
就是代理类和被代理类都继承一个接口,代理类里有个被代理类的field,暴露给外界的时代理类,代理类的每个方法都执行一下代理的逻辑,再调用被代理类。
开始说jdk的动态代理,还是需要一个接口类,就是把原来代码里直接的 被代理类.方法()的调用方式, 换成了反射方式调用,代码的编写上少了许多,不需要每个方法都写一遍了。
二 cglib动态生成类来实现代理模式:
public class MainTest5 {
public static void main(String[] args)
{
if (true) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OOMObject.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("before doPrint");
Object o = proxy.invokeSuper(obj, args);
System.out.println("after doPrint");
return o;
}
});
Object o = enhancer.create();
((OOMObject)(o)).doPrint();
((OOMObject)(o)).doPrint2();
}
}
static class OOMObject { //没有static关键字 main方法里会报错
public void doPrint(){
System.out.println("doPrint");
}
public void doPrint2(){
System.out.println("doPrint2");
}
}
}
执行结果:
三 byteCode(javaassist 等) 动态生成类
dubbo源码里有javaassist,有空整理下。