在Java中,这些有什么区别:
Object o1 = .... o1.getClass().getSimpleName(); o1.getClass().getName(); o1.getClass().getCanonicalName();
我已经多次检查了 Javadoc,但这从来没有很好地解释它。我还进行了一个测试,这并没有反映出调用这些方法的方式背后的任何真正含义。
如果您不确定某事,请先尝试编写测试。
我这样做了:
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 (primitive): getName(): int getCanonicalName(): int getSimpleName(): int getTypeName(): int String.class (ordinary class): getName(): java.lang.String getCanonicalName(): java.lang.String getSimpleName(): String getTypeName(): java.lang.String java.util.HashMap.SimpleEntry.class (nested class): getName(): java.util.AbstractMap$SimpleEntry getCanonicalName(): java.util.AbstractMap.SimpleEntry getSimpleName(): SimpleEntry getTypeName(): java.util.AbstractMap$SimpleEntry new java.io.Serializable(){}.getClass() (anonymous inner class): getName(): ClassNameTest$1 getCanonicalName(): null getSimpleName(): getTypeName(): ClassNameTest$1
最后一个块中有一个空条目,其中getSimpleName返回一个空字符串。
getSimpleName
看这个的结果是:
name 是您用于动态加载类的名称,例如,使用Class.forNamedefault调用ClassLoader。在一定的范围内ClassLoader,所有的类都有唯一的名字。 规范名称 是在导入语句中使用的名称。toString在或记录操作期间它可能很有用。当javac编译器拥有类路径的完整视图时,它通过在编译时冲突完全限定的类和包名称来强制其中规范名称的唯一性。但是 JVM 必须接受这种名称冲突,因此规范名称不能唯一标识ClassLoader. (事后看来,这个 getter 的一个更好的名字应该是getJavaName;但是这个方法可以追溯到 JVM 仅用于运行 Java 程序的时候。) 简单的 名称 松散地标识类,在或记录操作期间可能很有用,toString但不能保证是唯一的。 类型名称 返回“此类型名称的信息字符串”,“就像toString:它纯粹是信息性的,没有合同价值”。(由 sir4ur0n 撰写)
Class.forName
ClassLoader
toString
javac
getJavaName
您还可以通常参考 Java 语言规范文档以了解这些类型的技术 Java API 详细信息:
这是有关此主题 的Java 11 规范: https ://docs.oracle.com/javase/specs/jls/se11/html/jls-6.html#jls-6.7 Example 6.7-2.并分别Example 6.7-2.过去Fully Qualified Names和Fully Qualified Names v. Canonical Name
Java 11
Example 6.7-2.并分别Example 6.7-2.过去Fully Qualified Names和Fully Qualified Names v. Canonical Name
Example 6.7-2.
Fully Qualified Names
Fully Qualified Names v. Canonical Name