Retrieving a Class Name in Java – 在Java中检索一个类的名称

最后修改: 2018年 11月 28日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll learn about four ways to retrieve a class’s name from methods on the Class API: getSimpleName(), getName(), getTypeName() and getCanonicalName(). 

在本教程中,我们将了解从Class API的方法中检索类的名称的四种方法。getSimpleName(), getName(), getTypeName()getCanonicalName()

These methods can be confusing because of their similar names and their somewhat vague Javadocs. They also have some nuances when it comes to primitive types, object types, inner or anonymous classes, and arrays.

这些方法可能会令人困惑,因为它们的名字很相似,而且它们的Javadocs有些模糊。当涉及到原始类型、对象类型、内部或匿名类以及数组时,它们也有一些细微的差别。

2. Retrieving Simple Name

2.检索简单名称

Let’s begin with the getSimpleName() method.

让我们从getSimpleName()方法开始。

In Java, there are two kinds of names: simple and qualified. A simple name consists of a unique identifier while a qualified name is a sequence of simple names separated by dots.

在Java中,有两种名称。简单的合格的简单名称由一个唯一的标识符组成,而限定名称是由点分隔的简单名称的序列。

As its name suggests, getSimpleName() returns the simple name of the underlying class, that is the name it has been given in the source code.

顾名思义,getSimpleName()返回底层类的简单名称,也就是它在源代码中被赋予的名称

Let’s imagine the following class:

让我们想象一下下面这个班级。

package com.baeldung.className;
public class RetrieveClassName {}

Its simple name would be RetrieveClassName:

它的简单名称是RetrieveClassName

assertEquals("RetrieveClassName", RetrieveClassName.class.getSimpleName());

We can also get primitive types and arrays simple names. For primitive types that will simply be their names, like int, boolean or float.

我们还可以获得原始类型和数组的简单名称。对于原始类型来说,这将只是它们的名字,像int, boolean float

And for arrays, the method will return the simple name of the type of the array followed by a pair opening and closing brackets for each dimension of the array ([]):

而对于数组,该方法将返回数组类型的简单名称,后面是数组每个维度的一对开括号和闭括号([])

RetrieveClassName[] names = new RetrieveClassName[];
assertEquals("RetrieveClassName[]", names.getClass().getSimpleName());

Consequently, for a bidimensional String array, calling getSimpleName() on its class will return String[][].

因此,对于一个二维的String数组,在其类上调用getSimpleName()将返回String[][]

Finally, there is the specific case of anonymous classes. Calling getSimpleName() on an anonymous class will return an empty string.

最后,还有一个匿名类的特殊情况。在匿名类上调用getSimpleName()将返回一个空字符串。

3. Retrieving Other Names

3.检索其他名称

Now it’s time to have a look at how we would obtain a class’s name, type name, or canonical name. Unlike getSimpleName(), these names aim to give more information about the class.

现在是时候看看我们如何获得一个类的名称、类型名称或规范名称。与getSimpleName()不同,这些名字旨在提供关于类的更多信息。

The getCanonicalName() method always returns the canonical name as defined in the Java Language Specification.

getCanonicalName()方法总是返回Java语言规范中定义的规范名称。

As for the other methods, the output can differ a little bit according to the use cases. We’ll see what that means for different primitive and object types.

至于其他方法,根据使用情况,输出会有一些不同。我们将看到这对不同的基元和对象类型意味着什么。

3.1. Primitive Types

3.1.原始类型

Let’s start with primitive types, as they are simple. For primitive types, all three methods getName(), getTypeName() and getCanonicalName() will return the same result as getSimpleName():

让我们从原始类型开始,因为它们很简单。对于原始类型,所有三个方法getName()、getTypeName()getCanonicalName()将返回与getSimpleName()同样的结果。

assertEquals("int", int.class.getName());
assertEquals("int", int.class.getTypeName());
assertEquals("int", int.class.getCanonicalName());

3.2. Object Types

3.2.对象类型

We’ll now see how these methods work with object types. Their behavior is generally the same: they all return the canonical name of the class.

我们现在来看看这些方法如何与对象类型一起工作。它们的行为通常是相同的:它们都返回类的标准名称

In most cases, this is a qualified name which contains all the class packages simple names as well as the class simple name:

在大多数情况下,这是一个限定的名称,它包含了所有类包的简单名称,以及类的简单名称。

assertEquals("com.baeldung.className.RetrieveClassName", RetrieveClassName.class.getName());
assertEquals("com.baeldung.className.RetrieveClassName", RetrieveClassName.class.getTypeName());
assertEquals("com.baeldung.className.RetrieveClassName", RetrieveClassName.class.getCanonicalName());

3.3. Inner Classes

3.3.内层类

What we’ve seen in the previous section is the general behavior of these method calls, but there are a few exceptions.

我们在上一节看到的是这些方法调用的一般行为,但也有一些例外。

Inner classes are one of them. The getName() and getTypeName() methods behave differently than the getCanonicalName()  method for inner classes.

内层类是其中之一。对于内部类,getName()getTypeName()方法的行为与getCanonicalName()方法不同。

getCanonicalName() still returns the canonical name of the class, that is the enclosing class canonical name plus the inner class simple name separated by a dot.

getCanonicalName()仍然返回类的经典名称,也就是包围类的经典名称加上用点分隔的内层类的简单名称。

On the other hand, the getName() and getTypeName() methods return pretty much the same but use a dollar as the separator between the enclosing class canonical name and the inner class simple name.

另一方面,getName()getTypeName()方法的返回值基本相同,但在包围类的规范名称和内部类的简单名称之间使用美元作为分隔符

Let’s imagine an inner class InnerClass of our RetrieveClassName:

让我们想象一下我们的InnerClass的内类RetrieveClassName

public class RetrieveClassName {
    public class InnerClass {}
}

Then each call denotes the inner class in a slightly different way:

然后,每次调用都以稍微不同的方式表示内层类。

assertEquals("com.baeldung.RetrieveClassName.InnerClass", 
  RetrieveClassName.InnerClass.class.getCanonicalName());
assertEquals("com.baeldung.RetrieveClassName$InnerClass", 
  RetrieveClassName.InnerClass.class.getName());
assertEquals("com.baeldung.RetrieveClassName$InnerClass", 
  RetrieveClassName.InnerClass.class.getTypeName());

3.4. Anonymous Classes

3.4.匿名类

Anonymous classes are another exception.

匿名班是另一个例外。

As we’ve already seen they have no simple name, but they also don’t have a canonical name. Therefore, getCanonicalName() doesn’t return anything. In opposition to getSimpleName()getCanonicalName() will return null and not an empty string when called on an anonymous class.

正如我们已经看到的,它们没有简单的名字,但是它们也没有一个规范的名字。因此,getCanonicalName()不会返回任何东西。getSimpleName()相反,getCanonicalName()在调用匿名类时将返回null而不是空字符串。

As for getName() and getTypeName() they will return the calling class canonical name followed by a dollar and a number representing the position of the anonymous class among all anonymous classes created in the calling class.

至于getName()getTypeName(),它们将返回调用类的标准名称,后面是一个美元和一个数字,代表该匿名类在调用类创建的所有匿名类中的位置

Let’s illustrate this with an example. We’ll create here two anonymous classes and call getName() on the first and getTypeName() on the second, declaring them in com.baeldung.Main:

让我们用一个例子来说明这一点。我们将在这里创建两个匿名类,并在第一个类上调用getName(),在第二个类上调用getTypeName(),将它们声明在com.baeldung.Main中。

assertEquals("com.baeldung.Main$1", new RetrieveClassName() {}.getClass().getName());
assertEquals("com.baeldung.Main$2", new RetrieveClassName() {}.getClass().getTypeName());

We should note that the second call returns a name with an increased number at its end, as it’s applied on the second anonymous class.

我们应该注意到,第二次调用返回的是一个末尾有增加数字的名字,因为它是应用于第二个匿名类的。

3.5. Arrays

3.5.数组

Finally, let’s see how arrays are handled by the above three methods.

最后,让我们看看上述三种方法是如何处理数组的。

To indicate we’re dealing with arrays, each method will update its standard result. The getTypeName() and getCanonicalName() methods will append pairs of brackets to their result.

为了表明我们正在处理数组,每个方法都将更新其标准结果。getTypeName()getCanonicalName()方法将在其结果中附加一对括号。

Let’s see the following example where we call getTypeName() and getCanonicalName() on a bidimensional InnerClass array:

让我们看看下面的例子,我们在一个二维InnerClass数组上调用getTypeName() getCanonicalName()

assertEquals("com.baeldung.RetrieveClassName$InnerClass[][]", 
  RetrieveClassName.InnerClass[][].class.getTypeName());
assertEquals("com.baeldung.RetrieveClassName.InnerClass[][]", 
  RetrieveClassName.InnerClass[][].class.getCanonicalName());

Note how the first call uses a dollar instead of a dot to separate the inner class part from the rest of the name.

注意第一个调用是如何使用美元而不是点来分隔内部类的部分和名字的其余部分的。

Let’s now see how the getName() method works. When called on a primitive type array, it will return an opening bracket and a letter representing the primitive type. Let’s check that with the following example, calling that method on a bidimensional primitive integers array:

现在让我们看看getName()方法是如何工作的。当对原始类型数组进行调用时,它将返回一个大括号和一个代表原始类型的字母让我们通过下面的例子来检查,在一个二维原始整数数组上调用该方法。

assertEquals("[[I", int[][].class.getName());

On the other hand, when called on an object array it will add an opening bracket and the L letter to its standard result and finish with a semi-colon. Let’s try it on an array of RetrieveClassName:

另一方面,当对一个对象数组进行调用时,它将在其标准结果中添加一个开头括号和L字母,并以分号结束。让我们在一个RetrieveClassName的数组上试试吧。

assertEquals("[Lcom.baeldung.className.RetrieveClassName;", RetrieveClassName[].class.getName());

4. Conclusion

4.总结

In this article, we looked at four methods to access a class name in Java. These methods are: getSimpleName(), getName(), getTypeName() and getCanonicalName().

在这篇文章中,我们看了在Java中访问类名的四个方法。这些方法是。getSimpleName(), getName(), getTypeName()getCanonicalName()

We learned that the first just returns the source code name of a class while the others provide more information such as package name and an indication of whether the class is inner or an anonymous class.

我们了解到,第一个只是返回一个类的源代码名称,而其他的则提供更多的信息,如包的名称和指示该类是内部类还是匿名类。

The code of this article can be found over on GitHub.

这篇文章的代码可以在GitHub上找到over