Получение имени класса в Java

Получение имени класса в Java

1. обзор

В этом руководстве мы узнаем о четырех способах получения имени класса из методов APIClass:getSimpleName(), getName(), getTypeName() иgetCanonicalName().

Эти методы могут сбивать с толку из-за их похожих имен и их несколько расплывчатых Javadocs. Они также имеют некоторые нюансы, когда речь идет о примитивных типах, типах объектов, внутренних или анонимных классах и массивах.

2. Получение простого имени

Начнем с методаgetSimpleName().

В Java есть два типа имен:simple иqualified. A simple name consists of a unique identifier while a qualified name is a sequence of simple names separated by dots.

Как следует из названия,getSimpleName() возвращает простое имя базового класса, то естьthe name it has been given in the source code.

Представим себе следующий класс:

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

Его простое имя будетRetrieveClassName:

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

Мы также можем получить примитивные типы и массивы простых имен. Для примитивных типов это будут просто их имена, напримерint, boolean илиfloat.

А для массивов метод вернет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());

Следовательно, для двумерного массиваString вызовgetSimpleName() для его класса вернетString[][].

Наконец, есть особый случай анонимных классов. Calling getSimpleName() on an anonymous class will return an empty string.с

3. Получение других имен

Теперь пора посмотреть, как мы получим имя класса, имя типа или каноническое имя. В отличие отgetSimpleName(), эти имена призваны дать больше информации о классе.

МетодgetCanonicalName() всегда возвращает каноническое имяas defined in the Java Language Specification.

Что касается других методов, вывод может немного отличаться в зависимости от вариантов использования. Мы увидим, что это означает для различных типов примитивов и объектов.

3.1. Примитивные типы

Начнем с примитивных типов, они простые. For primitive types, all three methods getName(), getTypeName() and getCanonicalName() will return the same result as getSimpleName():

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

3.2. Типы объектов

Теперь посмотрим, как эти методы работают с типами объектов. Их поведение в целом одинаково:they all return the canonical name of the class.

В большинстве случаев это квалифицированное имя, которое содержит простые имена всех пакетов классов, а также простое имя класса:

assertEquals("com.example.className.RetrieveClassName", RetrieveClassName.class.getName());
assertEquals("com.example.className.RetrieveClassName", RetrieveClassName.class.getTypeName());
assertEquals("com.example.className.RetrieveClassName", RetrieveClassName.class.getSimpleName());

3.3. Внутренние классы

В предыдущем разделе мы видели общее поведение этих вызовов методов, но есть несколько исключений.

Внутренние классы являются одним из них. МетодыgetName() andgetTypeName() ведут себя иначе, чем методgetCanonicalName() для внутренних классов.

getCanonicalName() still returns the canonical name of the class, то есть каноническое имя включающего класса плюс простое имя внутреннего класса, разделенное точкой.

С другой стороны, методыgetName() andgetTypeName() возвращают почти то же самое, ноuse a dollar as the separator between the enclosing class canonical name and the inner class simple name.

Представим себе внутренний классInnerClass нашегоRetrieveClassName:

public class RetrieveClassName {
    public class InnerClass {}
}

Тогда каждый вызов обозначает внутренний класс немного по-другому:

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

3.4. Анонимные классы

Анонимные классы являются еще одним исключением.

Как мы уже видели, у них нет простого имени, а естьthey also don’t have a canonical name. Следовательно,getCanonicalName() ничего не возвращает. In opposition to getSimpleName()getCanonicalName() will return null, а не пустая строка при вызове анонимного класса.

Что касаетсяgetName() иgetTypeName(), они вернут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() для второго, объявив их вcom.example.Main:

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

Следует отметить, что второй вызов возвращает имя с увеличенным числом в конце, как это применяется ко второму анонимному классу.

3.5. Массивы

Наконец, давайте посмотрим, как массивы обрабатываются тремя вышеуказанными методами.

Чтобы указать, что мы имеем дело с массивами, каждый метод обновит свой стандартный результат. The getTypeName() and getCanonicalName() methods will append pairs of brackets to their result.с

Давайте посмотрим на следующий пример, в котором мы вызываемgetTypeName() andgetCanonicalName() для двумерного массиваInnerClass:

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

Обратите внимание, что в первом вызове вместо точки используется знак доллара, а не внутренняя часть класса.

Теперь посмотрим, как работает методgetName(). При вызове для массива примитивных типов он вернетan opening bracket and a letter representing the primitive type. . Давайте проверим это в следующем примере, вызвав этот метод для двумерного массива примитивных целых чисел:

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

С другой стороны, при вызове массива объектов он будетadd an opening bracket and the L letter to its standard result and finish with a semi-colon. Давайте попробуем это на массивеRetrieveClassName:

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

4. Заключение

В этой статье мы рассмотрели четыре метода доступа к имени класса в Java. Это следующие методы:getSimpleName(), getName(), getTypeName() иgetCanonicalName().

Мы узнали, что первый просто возвращает имя исходного кода класса, в то время как другие предоставляют больше информации, такой как имя пакета и указание, является ли класс внутренним или анонимным классом.

Код этой статьи можно найтиover on GitHub.