In Java, it is possible to get a String representation of a class by calling the Class.getName()
method.
Since Java 1.5 (AKA Java 5), it has been possible to get the canonical name using Class.getCanonicalName()
.
javadoc: java.lang.Class
For many classes, these two methods will return identical values. Things get more interesting when it comes to some of the more esoteric types such as arrays and inner classes. The code is provided for completeness, but feel free to skip to the output table.
public class ClassFoo {
|
Using the example class above, the following code introspects the types:
Class<?>[] someTypes = {
|
The following table lists the output.
Class Instance | Class.getName() | Class.getCanonicalName() | Notes |
---|---|---|---|
String.class | java.lang.String | java.lang.String | |
String[].class | [Ljava.lang.String; | java.lang.String[] | string array |
String[][].class | [[Ljava.lang.String; | java.lang.String[][] | two-dimensional string array |
Integer.class | java.lang.Integer | java.lang.Integer | Integer object |
Integer.TYPE | int | int | primitive int |
int[].class | [I | int[] | int array |
int[][].class | [[I | int[][] | two-dimensional int array |
ClassFoo.class | ClassFoo | ClassFoo | (default package) |
ClassFoo.FooEnum.VAL1.getClass() | ClassFoo$FooEnum | ClassFoo.FooEnum | inner enumeration |
ClassFoo.InnerClassFoo2.class | ClassFoo$InnerClassFoo2 | ClassFoo.InnerClassFoo2 | inner class |
ClassFoo.InterfaceBar.class | ClassFoo$InterfaceBar | ClassFoo.InterfaceBar | inner interface |
ClassFoo.getAnonymousInnerClass() | ClassFoo$1 | null | anonymous inner class |
ClassFoo.getLocalInnerClass() | ClassFoo$1X | null | local inner class |
Void.TYPE | void | void | void type |
Note that in the case of arrays, class names are prefixed by the number of '['
characters equivalent to the number of array dimensions followed by a letter constant.
For example, [I
is the class name for an int[]
object and [L
denotes any object array. The remaining primitive types are listed in the
javadoc.
Which value to use depends on the application. getCanonicalName()
is useful for displaying
the type to developers or generating code. getName()
provides more useful information on
inner types and corresponds more closely to the class names as defined in class repositories (like JAR files).
For example, the following is the valid method for loading the type InnerClassFoo2
.
ClassLoader.getSystemClassLoader().loadClass("ClassFoo$InnerClassFoo2")
|
This might just be the perfect blog post. Really concise and helpful. I wouldn't have thought of that last point about use with class loading, which is actually really important for me. Thanks for saving me a lot of time.
ReplyDeleteYes, excellent post!
ReplyDeleteThere's also a Class.getSimpleName() method that might be worth including in this comparison.
To this end I changed the System.out.print lines in McDowell's code to:
System.out.print(String.format("%-25s", c.getName()));
System.out.print(String.format("%-25s", c.getCanonicalName()));
System.out.println(c.getSimpleName());
/Mikko Östlund (Stockholm, Sweden)