關於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 討論

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