Java 中 getCanonicalName、getSimpleName、getName、getTypeName 的区别

1. 核心区别总结

方法作用数组类型示例非数组类型示例
getName()返回 JVM 内部格式的类全名,适用于反射操作(如 Class.forName()int[][IStringjava.lang.String
getTypeName()返回更友好的类型名称,对数组递归处理组件类型,显示为 Type[] 形式int[]int[]Stringjava.lang.String
getCanonicalName()返回符合 Java 语言规范的名称,对内部类使用点分隔,匿名类返回 nullint[]int[]Outer.Innercom.xxx.Outer.Inner
getSimpleName()返回无包名的类名(含数组维度符号)int[]int[]StringString

2. 详细说明

(1) getName()

  • JVM 视角:返回类在 JVM 中的全限定名,对数组使用内部表示法。
  • 数组规则
    • 一维原始类型数组:[ + 类型缩写(如 int[][I)。
    • 多维原始类型数组:多个 [(如 int[][][[I)。
    • 对象数组:[L + 类全名 + ;(如 Object[][Ljava.lang.Object;)。
  • 用途:适用于 Class.forName() 等需要 JVM 格式类名的场景。

(2) getTypeName()(Java 8+)

  • 开发者视角:返回更易读的类型名,对数组递归处理组件类型。
  • 规则
    • 非数组类型:与 getName() 相同。
    • 数组类型:组件类型 TypeName + [](如 int[][]int[][])。
  • 用途:日志输出、调试或需要直观类型名的场景。

(3) getCanonicalName()

  • 规范名称:符合 Java 语言规范的类全名,对内部类使用 . 分隔。
  • 特殊场景
    • 内部类:Outer.InnergetName() 返回 Outer$Inner)。
    • 匿名类:返回 null(如 new Runnable(){}null)。
    • 数组类型:与 getTypeName() 结果一致(如 int[]int[])。
  • 用途:生成与代码中书写形式一致的类名。

(4) getSimpleName()

  • 简洁名称:仅保留类名(不含包名),对数组保留 []
  • 示例
    • StringString
    • Object[]Object[]
    • 匿名类:空字符串或未命名符号(如 ""Class$1 中的 1)。
  • 用途:显示简洁类名(如日志或 UI 界面)。

3. 示例对比

// 示例 1:原始类型数组
Class<?> intArrayClazz = int[].class;
System.out.println(intArrayClazz.getName());          // [I
System.out.println(intArrayClazz.getTypeName());       // int[]
System.out.println(intArrayClazz.getCanonicalName());  // int[]
System.out.println(intArrayClazz.getSimpleName());     // int[]

// 示例 2:对象数组
Class<?> objArrayClazz = Object[].class;
System.out.println(objArrayClazz.getName());          // [Ljava.lang.Object;
System.out.println(objArrayClazz.getTypeName());       // java.lang.Object[]
System.out.println(objArrayClazz.getCanonicalName());  // java.lang.Object[]
System.out.println(objArrayClazz.getSimpleName());     // Object[]

// 示例 3:内部类
class Outer { class Inner {} }
Class<?> innerClazz = Outer.Inner.class;
System.out.println(innerClazz.getName());             // Outer$Inner
System.out.println(innerClazz.getTypeName());          // Outer$Inner
System.out.println(innerClazz.getCanonicalName());     // Outer.Inner
System.out.println(innerClazz.getSimpleName());        // Inner

// 示例 4:匿名类
Runnable anonymous = new Runnable() {
    @Override
    public void run() {}
};
Class<?> anonymousClazz = anonymous.getClass();
System.out.println(anonymousClazz.getName());         // com.xiaolingting.Main$1
System.out.println(anonymousClazz.getTypeName());      // com.xiaolingting.Main$1
System.out.println(anonymousClazz.getCanonicalName()); // null
System.out.println(anonymousClazz.getSimpleName());    // "" (空字符串)

4. 使用场景推荐

场景推荐方法
反射加载类(如 Class.forName()getName()
日志输出类型信息getTypeName()
生成代码或文档中的类名getCanonicalName()
显示简洁类名(如 UI 界面)getSimpleName()

总结

  • getName() 关注 JVM 内部表示,getTypeName() 提供开发者友好的类型名(尤其对数组)。
  • getCanonicalName() 严格遵循 Java 语言规范,适合生成代码或文档。
  • getSimpleName() 用于简洁显示类名,忽略包和内部符号。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值