466. Java 反射 - 类的规范名

466. Java 反射 - 类的规范名

1. 什么是 Canonical Name?

  • 规范名(Canonical Name):在 Java 语言规范中定义,等价于 包名 + 类的简单名
    • 例如:java.lang.String
  • 它和 简单名(Simple Name) 的区别:
    • 简单名:String
    • 规范名:java.lang.String

⚠️ 并不是所有类都有规范名。以下几类没有规范名:

  • 本地类(Local Class) —— 定义在方法中的类
  • 匿名类(Anonymous Class) —— new Object(){}
  • 隐藏类(Hidden Class) —— Java 15 引入的新特性

如果类没有规范名,getCanonicalName() 会返回 null


2. 示例代码

import java.util.function.Supplier;

public class CanonicalNameDemo {
    public static void main(String[] args) {
        // 普通类
        Class<?> c1 = String.class;
        System.out.println("Canonical name: " + c1.getCanonicalName());

        // 匿名类
        Object key = new Object() {};
        Class<?> c2 = key.getClass();
        System.out.println("Canonical name: " + c2.getCanonicalName());

        // Lambda 表达式
        Supplier<String> supplier = () -> "Hello";
        Class<?> c3 = supplier.getClass();
        System.out.println("Canonical name: " + c3.getCanonicalName());
    }
}

运行结果

Canonical name: java.lang.String
Canonical name: null
Canonical name: chapter466.Demo$$Lambda$1/2003749087

说明

  • String 是正常类 → 有规范名 java.lang.String
  • 匿名类 → 没有规范名 → 返回 null
  • Lambda → 由编译器生成匿名类 → 也没有规范名 → 返回 null

3. 与其他名称方法对比

方法 输出示例(匿名类) 输出示例(Lambda) 输出示例(普通类)
getName() pkg.Outer$1 pkg.Main$$Lambda$23/0x0000... java.lang.String
getSimpleName() ""(空字符串) Main$$Lambda$23/0x... String
getCanonicalName() null null java.lang.String

📌 口诀

  • getName() → JVM 内部名(最全)
  • getSimpleName() → 源码里的类名(匿名类为空)
  • getCanonicalName() → 规范名(可能为 null

4. 总结

  • getCanonicalName() 用来获取类的 全限定名(包名 + 类名)
  • 匿名类、局部类、隐藏类没有规范名 → 返回 null
  • 在日志、框架内部通常优先使用 getCanonicalName(),因为它最接近源码中的“真实名字”。
  • 如果你需要保证不为 null,用 getName() 更保险。
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容