关于new SQL(){{}}的问题,匿名内部内的构造方法

首先new SQL(){{}}代码会在mybatis(新版本)注解的动态sql中会用到

其中两层花括号含义:第一层是创建一个匿名内部类,第二层是调用匿名内部类的构造方法

  1. 首先新建一个测试类
    public class Test {
        public static void main(String[] args) {
            new Children() {
                {
                    System.out.println("===========Children============");
                    subClass();//SubClass类subClass方法调用
                    children();//Children类children方法调用
                    System.out.println(this.getClass().getName());//当前类的类名,用getSimpleName()方法没有任何输入  Test$1
                    System.out.println(this.getClass().getSuperclass().getName());//第一级父类的类名  Children
                    System.out.println(this.getClass().getSuperclass().getSuperclass().getName());//第二级父类的类名  SubClass
                    System.out.println(this.getClass().getSuperclass().getSuperclass().getSuperclass().getName());//第三级父类的类名  Object
                    System.out.println("===========Children============");
                }
            };
            new SubClass() {
                {
                    System.out.println("===========SubClass============");
                    subClass();
                    System.out.println(this.getClass().getName());
                    System.out.println("===========SubClass============");
                }
            };
        }
    }
    class Children extends SubClass {
        public Children(){
            System.out.println("Children");
        }
        public void children(){
            System.out.println("children");
        }
    }
    class SubClass{
        public SubClass(){
            System.out.println("SubClass");
        }
        public void subClass(){
            System.out.println("subClass");
        }
    }

    输出内容:
    SubClass
    Children
    ===========Children============
    subClass
    children
    com.emreditor.Test$1
    com.emreditor.Children
    com.emreditor.SubClass
    java.lang.Object
    ===========Children============
    SubClass
    ===========SubClass============
    subClass
    com.emreditor.Test$2
    ===========SubClass============
    这里和普通的类继承实例化过程没有什么区别,先静态代码,后普通代码;先父类构造方法,后子类构造方法;父类的内容执行完了之后才是子类的内容

  2. 然后离开ide工具,单独用命令javac编译一下当前类的内容
    然后会得到如下的类
    其中Test$1.class和Test$2.class是Test类中main方法中的两个匿名内部类

  3. 然后用jd-gui.exe打开Test$1.class或Test$2.class文件(ps:jd-gui.exe百度下载,也可用其他的反编译软件,也可以用命令javap -c -verbose)

  4. 打开之后文件内容是这样的(我打开的是Test$1.class文件)
     

    import java.io.PrintStream;
    
    final class Test$1
      extends Children
    {
      Test$1()
      {
        System.out.println("===========Children============");
        subClass();
        children();
        System.out.println(getClass().getName());
        System.out.println(getClass().getSuperclass().getName());
        System.out.println(getClass().getSuperclass().getSuperclass().getName());
        System.out.println(getClass().getSuperclass().getSuperclass().getSuperclass().getName());
        System.out.println("===========Children============");
      }
    }

    这个构造方法中的内容和Test类中的main方法里new Children(){{}}代码中第二层花括号中的内容是一样的;

  5. 代码new SQL(){{}}中,外层花括号是创建一个匿名内部内,内层花括号是执行匿名内部类中的构造方法

  6. 加一点题外话
    new 接口(){}的方式赋值给一个接口,对接口进行实列化时是创建一个匿名内部类对接口的实现,所以需要在花括号里是实现接口中的抽象方法。

    ps:欢迎加群:517413713 讨论

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章