zoukankan      html  css  js  c++  java
  • 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,有空整理下。

  • 相关阅读:
    mysql 的远程链接字符
    SqlSessionFactoryUtil
    mysql 的链接字符
    web 项目运用通用的xml配置
    配置文件转意符使用
    new和newInstance的区别
    子选择器与后代选择器的区别
    Vivado_HLS 学习笔记1-数据类型
    Vivado_HLS 学习笔记3-循环的pipeline与展开
    Vivado_HLS 学习笔记2-接口综合
  • 原文地址:https://www.cnblogs.com/thinkqin/p/11760279.html
Copyright © 2011-2022 走看看