一尘不染

Java类中的规范名称,简单名称和类名称有什么区别?

java

在Java中,这些之间有什么区别:

Object o1 = ....
o1.getClass().getSimpleName();
o1.getClass().getName();
o1.getClass().getCanonicalName();

我已经多次检查过Javadoc,但这从来不能很好地解释它。我也进行了测试,但没有反映出调用这些方法背后的任何实际含义。


阅读 466

收藏
2020-09-09

共1个答案

一尘不染

如果不确定某件事,请尝试先编写测试。

我这样做:

class ClassNameTest {
    public static void main(final String... arguments) {
        printNamesForClass(
            int.class,
            "int.class (primitive)");
        printNamesForClass(
            String.class,
            "String.class (ordinary class)");
        printNamesForClass(
            java.util.HashMap.SimpleEntry.class,
            "java.util.HashMap.SimpleEntry.class (nested class)");
        printNamesForClass(
            new java.io.Serializable(){}.getClass(),
            "new java.io.Serializable(){}.getClass() (anonymous inner class)");
    }

    private static void printNamesForClass(final Class<?> clazz, final String label) {
        System.out.println(label + ":");
        System.out.println("    getName():          " + clazz.getName());
        System.out.println("    getCanonicalName(): " + clazz.getCanonicalName());
        System.out.println("    getSimpleName():    " + clazz.getSimpleName());
        System.out.println("    getTypeName():      " + clazz.getTypeName()); // added in Java 8
        System.out.println();
    }
}

印刷品:

int.class(原始):
    getName():int
    getCanonicalName():int
    getSimpleName():int
    getTypeName():int

String.class(普通类):
    getName():java.lang.String
    getCanonicalName():java.lang.String
    getSimpleName():字符串
    getTypeName():java.lang.String

java.util.HashMap.SimpleEntry.class(嵌套类):
    getName():java.util.AbstractMap $ SimpleEntry
    getCanonicalName():java.util.AbstractMap.SimpleEntry
    getSimpleName():SimpleEntry
    getTypeName():java.util.AbstractMap $ SimpleEntry

新的java.io.Serializable(){}。getClass()(匿名内部类):
    getName():ClassNameTest $ 1
    getCanonicalName():空
    getSimpleName():    
    getTypeName():ClassNameTest $ 1

最后一个块中有一个空条目,其中getSimpleName返回一个空字符串。

结果是:

  • 名称 是您愿意使用动态加载与类,例如,调用的名称Class.forName与默认ClassLoader。在一定范围内ClassLoader,所有类都有唯一的名称。
  • 规范名称 是将在import语句中使用的名称。在执行toString或记录操作时,它可能很有用。当javac编译器具有类路径的完整视图时,它通过在编译时冲突完全限定的类和包名称来在其中强制规范名称的唯一性。但是,JVM必须接受此类名称冲突,因此规范名称不能唯一地标识内的类ClassLoader。(事后看来,该getter的更好的名字应该是getJavaName;但是此方法可以追溯到JVM仅用于运行Java程序的时间。)
  • 简单的名字 松散标识类,又可能是有用的过程toString或记录的操作,但不能保证是唯一的。
  • 类型名称 返回“ 此 类型名称 的信息字符串”,“类似于toString():它纯粹是信息信息,没有合约值”(如sir4ur0n所写)
2020-09-09