464. Java 反射 - 读取类名
在反射中,所有元素(类、字段、方法、构造器、参数)都有名字。本节我们聚焦于 类名的获取。
1. 获取类名的常用方法
在 Class 对象上,有多种方法可以获取类名,最常用的有:
-
getCanonicalName():返回完整类名(包名 + 类名) -
getSimpleName():返回类的简单名(不含包名)
示例:显式类名
Class<?> arrayList = Class.forName("java.util.ArrayList");
System.out.println("Canonical name: " + arrayList.getCanonicalName());
System.out.println("Simple name: " + arrayList.getSimpleName());
输出:
Canonical name: java.util.ArrayList
Simple name: ArrayList
✅ 说明:
-
getCanonicalName()→ 适合日志、调试、框架内部标识 -
getSimpleName()→ 适合展示给用户或做 UI 显示
2. 运行时类名(动态场景)
有时你写的代码是针对接口或工厂方法的,运行时拿到的对象实际类型可能不是你写在代码里的。
示例
import java.util.*;
List<String> strings1 = new ArrayList<>();
List<String> strings2 = Arrays.asList("one", "two", "three");
List<String> strings3 = List.of("one", "two", "three");
System.out.println("Canonical name 1: " + strings1.getClass().getCanonicalName());
System.out.println("Canonical name 2: " + strings2.getClass().getCanonicalName());
System.out.println("Canonical name 3: " + strings3.getClass().getCanonicalName());
输出:
Canonical name 1: java.util.ArrayList
Canonical name 2: java.util.Arrays$ArrayList
Canonical name 3: java.util.ImmutableCollections$ListN
✅ 说明:
-
strings1→ 明确是java.util.ArrayList -
strings2→ 实际上是Arrays的内部类Arrays$ArrayList -
strings3→ JDK 9 引入的不可变集合实现,运行时类是ImmutableCollections$ListN
📌 小结:运行时类名 ≠ 编译期声明类型,尤其是在使用工厂方法或工具类时。
3. 其他常见方法(扩展)
除了 getCanonicalName() 和 getSimpleName(),还有:
-
getName()- 返回内部 JVM 使用的类名(可能包含
$) - 例如:
java.util.Arrays$ArrayList
- 返回内部 JVM 使用的类名(可能包含
-
getTypeName()- 与
getCanonicalName()类似,但对匿名类、数组类更友好
- 与
-
toString()- 默认带上
class或interface前缀
- 默认带上
4. 总结
-
常用场景:
-
getCanonicalName()→ 日志、框架标识 -
getSimpleName()→ 界面展示
-
-
注意事项:
- 工厂方法、不可变集合等返回的实际运行时类可能与你声明的接口不同
- 匿名类、内部类、lambda 表达式的名字通常包含
$,是编译器生成的