Java匿名类命名疑问:为何提供名称仍被称为匿名类?
关于Java匿名类的两个常见疑惑解答
Great questions—these are exactly the kind of nuanced details that trip up even seasoned Java developers, so let’s unpack them one by one.
问题一:为何匿名类在我们提供名称的情况下仍被称为“匿名类”?
其实这里有个关键误解:你根本没法给匿名类提供一个自定义的、可在代码中直接引用的名称。所谓的“匿名”,是站在开发者编写源代码的角度来说的——我们从来没有在代码中给这个类赋予一个正式的类名,也没法用一个自定义名字去实例化它或者引用它。
举个例子对比普通内部类和匿名类:
普通内部类(有明确自定义名称)
public class OuterClass { // 我们给这个类起了明确的名字:MyCustomRunnable private class MyCustomRunnable implements Runnable { @Override public void run() { System.out.println("Running from named class"); } } public void startTask() { // 可以直接用我们定义的类名创建实例 Runnable task = new MyCustomRunnable(); new Thread(task).start(); } }
匿名类(无自定义名称)
public class OuterClass { public void startTask() { Runnable task = new Runnable() { // 这里没有任何语法位置允许我们写自定义类名! @Override public void run() { System.out.println("Running from anonymous class"); } }; new Thread(task).start(); } }
你可能会发现编译器会生成类似OuterClass$1.class这样的字节码文件,这是编译器自动生成的内部标识名,但这个名字对开发者完全不可用——你没法在代码里写new OuterClass$1(),编译器会直接报错。所以从开发者的视角,这个类确实是“匿名”的。
问题二:它们被称作“无名称的类”是否因为编译器不会包含我们提供的名称?
答案是:我们根本没有机会给匿名类提供自定义名称。Java语法严格规定了匿名类的写法:必须直接继承一个类或实现一个接口,紧接着写类的实现代码块,没有任何语法位置允许我们输入自定义类名。
编译器生成的字节码文件名(比如Outer$1、Outer$2)是它自身的命名规则,用来区分同一个外部类中的不同匿名类,这些名称和我们开发者没有任何关系。所以“无名称的类”指的是在源代码层面没有开发者指定的类名,而非编译器生成的文件没有名称。
简单总结
- 匿名类的“匿名”是针对开发者编写的源代码而言,和编译器生成的字节码内部名称无关。
- 我们无法给匿名类赋予自定义的可引用名称,这是Java语法层面的硬性限制。
内容的提问来源于stack exchange,提问作者masterofdisaster
相关产品推荐
相关产品推荐

