If you're unsure about something, try writing a test first.
(如果您对某些事情不确定,请先尝试编写测试。)
I did this:
(我这样做了:)
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();
}
}
Prints:
(打印:)
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
There's an empty entry in the last block where getSimpleName
returns an empty string.
(最后一个块中有一个空条目,其中getSimpleName
返回一个空字符串。)
The upshot looking at this is:
(看到这个的结果是:)
- the name is the name that you'd use to dynamically load the class with, for example, a call to
Class.forName
with the default ClassLoader
. (名称是您用于动态加载类的名称,例如,使用默认的ClassLoader
调用Class.forName
。)
Within the scope of a certain ClassLoader
, all classes have unique names. (在某个ClassLoader
的范围内,所有类都具有唯一的名称。)
- the canonical name is the name that would be used in an import statement.
(规范名称是将在import语句中使用的名称。)
It might be useful during toString
or logging operations. (在toString
或logging操作期间它可能很有用。)
When the javac
compiler has complete view of a classpath, it enforces uniqueness of canonical names within it by clashing fully qualified class and package names at compile time. (当javac
编译器具有类路径的完整视图时,它通过在编译时碰撞完全限定的类和包名称来强制其中的规范名称的唯一性。)
However JVMs must accept such name clashes, and thus canonical names do not uniquely identifies classes within a ClassLoader
. (但是,JVM必须接受此类名称冲突,因此规范名称不能唯一标识ClassLoader
。)
(In hindsight, a better name for this getter would have been getJavaName
; but this method dates from a time when the JVM was used solely to run Java programs.) ((事后看来,这个getter的一个更好的名称就是getJavaName
;但是这个方法可以追溯到JVM仅用于运行Java程序的时候。))
- the simple name loosely identifies the class, again might be useful during
toString
or logging operations but is not guaranteed to be unique. (简单名称松散地标识类,在toString
或日志记录操作期间可能也很有用,但不保证是唯一的。)
- the type name returns "an informative string for the name of this type", "It's like toString(): it's purely informative and has no contract value" (as written by sir4ur0n)
(类型名称返回“此类型名称的信息字符串”,“它就像toString():它纯粹提供信息,没有合同价值”(由sir4ur0n编写))
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…