一直以来都有个疑问:明明在方法里写匿名内部类时都是new 一个外部类的,那为何叫匿名内部类呢?
public class Test{public void testSomeThing() {// 如此处,假设LoginUser类与Test类不在同一包下 LoginUser loginUser1 = new LoginUser() {@Overridepublic void setId(String id) {super.setId(id);}};}
}
查阅了相关资料,发现此时是创建了一个基于此类的子类
public class Test{// 一个子类继承了LoginUserclass LoginUserTest extends LoginUser{}public void testSomeThing() {// 如此处,假设LoginUser类与Test类不在同一包下 LoginUser loginUser1 = new LoginUser() {@Overridepublic void setId(String id) {super.setId(id);}};// 实际上loginUser1 等价于loginUserTest ,此时会自动创建一个类似LoginUserTest 的匿名类LoginUserTest loginUserTest = new LoginUserTest();}
}
这个类由于是匿名的,所以通常在idea下是看不到的,但是如果使用javac编译可以看到,
假如编译了Test文件,会发现一个叫
$Test
的java文件,这个文件就是匿名内部类,一个等价于LoginUserTest 的类(不是LoginUserTest ,这个会直接编译成LoginUserTest的)

(此图中的CourseResultServiceImpl看成是Test类,CourseResultB看成是LoginUserTest ,匿名内部类idea中不会显示所以此处没有显示,但实际上会有一个$CourseResultServiceImpl的匿名内部类)
部署项目的时候,如果是单个java文件(Test.java)而不是那种.jar(my-test.jar)的形式的话,对应的java类里尽量不要写匿名内部类(包括双大括号写法{{}},lambda表达式)的写法,否则可能会报找不到$XXX类的错误。这个就是因为没有吧对应内部类的java文件也给部署上去的缘故
如果是接口形式的话,内部类会变成接口的实现类
public class Test{// 一个子类继承了LoginUserclass LoginUserTest extends LoginUser{}// 一个接口的实现类,UserService是一个接口class MyServiceImpl implements UserService{@Overridepublic void test(){}}public void testSomeThing() {// 如此处,假设LoginUser类与Test类不在同一包下 LoginUser loginUser1 = new LoginUser() {@Overridepublic void setId(String id) {super.setId(id);}};// 实际上loginUser1 等价于LoginUserTest ,但不是LoginUserTest ,此时会自动创建一个类似LoginUserTest 的匿名类LoginUserTest loginUserTest = new LoginUserTest();// 此时等价于MyServiceImpl,但不是MyServiceImpl,此时会自动创建一个类似MyServiceImpl的匿名类UserService service = new UserService(){@Overridepublic void test(){}}}
}