Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
567 views
in Technique[技术] by (71.8m points)

java - Java Class中的规范名称,简单名称和类名称有什么区别?(What is the difference between canonical name, simple name and class name in Java Class?)

In Java, what is the difference between these:

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

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

I have checked the Javadoc multiple times and yet this never explains it well.

(我多次检查过Javadoc,但这从未解释过。)

I also ran a test and that didn't reflect any real meaning behind the way these methods are called.

(我也进行了测试,并没有反映这些方法被调用的方式背后的任何真正含义。)

  ask by Mohamed Taher Alrefaie translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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编写))


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...