首先new SQL(){{}}代码会在mybatis(新版本)注解的动态sql中会用到
其中两层花括号含义:第一层是创建一个匿名内部类,第二层是调用匿名内部类的构造方法(由评论区铃儿响兮琳琅提及,现做改正),内层的花括号是一个构造代码块,在实例化一个对象时会先于构造方式执行,编译时会将构造代码块移入构造方法中
- 首先新建一个测试类
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============
这里和普通的类继承实例化过程没有什么区别,先静态代码,后普通代码;先父类构造方法,后子类构造方法;父类的内容执行完了之后才是子类的内容 -
然后离开ide工具,单独用命令javac编译一下当前类的内容
然后会得到如下的类
其中Test$1.class和Test$2.class是Test类中main方法中的两个匿名内部类 -
然后用jd-gui.exe打开Test$1.class或Test$2.class文件(ps:jd-gui.exe百度下载,也可用其他的反编译软件,也可以用命令javap -c -verbose)
-
打开之后文件内容是这样的(我打开的是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(){{}}代码中第二层花括号中的内容是一样的;
-
代码new SQL(){{}}中,外层花括号是创建一个匿名内部内,
内层花括号是执行匿名内部类中的构造方法(由评论区铃儿响兮琳琅提及,现做改正),内层的花括号是一个构造代码块,在实例化一个对象时会先于构造方式执行,编译时会将构造代码块移入构造方法中 -
加一点题外话
new 接口(){}的方式赋值给一个接口,对接口进行实列化时是创建一个匿名内部类对接口的实现,所以需要在花括号里是实现接口中的抽象方法。
欢迎加群:517413713 讨论