Получение имени класса в Java
Эти методы могут сбивать с толку из-за похожих названий и несколько расплывчатой Javadocs. У них также есть некоторые нюансы, когда речь идет о примитивных типах, объектных типах, внутренних или анонимных классах и массивах.
2. Получение простого имени
Начнем с метода getSimpleName() .
В Java есть два типа имен: простые и квалифицированные . Простое имя состоит из уникального идентификатора, а полное имя представляет собой последовательность простых имен, разделенных точками.
Как следует из названия, getSimpleName() возвращает простое имя базового класса, то есть имя, данное ему в исходном коде .
Представим себе следующий класс:
package com.foreach.className; public class RetrieveClassName >
Его простое имя будет RetrieveClassName :
assertEquals("RetrieveClassName", RetrieveClassName.class.getSimpleName());
Мы также можем получить простые имена примитивных типов и массивов. Для примитивных типов это будут просто их имена, такие как int, boolean или float .
А для массивов метод вернет простое имя типа массива, за которым следует пара открывающих и закрывающих скобок для каждого измерения массива ([]) :
RetrieveClassName[] names = new RetrieveClassName[]; assertEquals("RetrieveClassName[]", names.getClass().getSimpleName());
Следовательно, для двумерного массива String вызов getSimpleName() для его класса вернет String[][] .
Наконец, есть конкретный случай анонимных классов. Вызов getSimpleName() для анонимного класса вернет пустую строку.
3. Получение других имен
Теперь пришло время посмотреть, как мы можем получить имя класса, имя типа или каноническое имя. В отличие от getSimpleName() , эти имена предназначены для предоставления дополнительной информации о классе.
Метод getCanonicalName() всегда возвращает каноническое имя , определенное в Спецификации языка Java .
Что касается других методов, выходные данные могут немного отличаться в зависимости от вариантов использования. Мы увидим, что это означает для различных типов примитивов и объектов.
3.1. Примитивные типы
Начнем с примитивных типов, так как они простые. Для примитивных типов все три метода getName(), getTypeName() и getCanonicalName() вернут тот же результат, что и getSimpleName() :
assertEquals("int", int.class.getName()); assertEquals("int", int.class.getTypeName()); assertEquals("int", int.class.getCanonicalName());
3.2. Типы объектов
Теперь мы увидим, как эти методы работают с объектными типами. Их поведение в целом одинаково: все они возвращают каноническое имя класса .
В большинстве случаев это полное имя, которое содержит все простые имена пакетов классов, а также простое имя класса:
assertEquals("com.foreach.className.RetrieveClassName", RetrieveClassName.class.getName()); assertEquals("com.foreach.className.RetrieveClassName", RetrieveClassName.class.getTypeName()); assertEquals("com.foreach.className.RetrieveClassName", RetrieveClassName.class.getCanonicalName());
3.3. Внутренние классы
То, что мы видели в предыдущем разделе, — это общее поведение вызовов этих методов, но есть несколько исключений.
Внутренние классы являются одним из них. Методы getName() и getTypeName() ведут себя иначе, чем метод getCanonicalName() для внутренних классов.
getCanonicalName() по-прежнему возвращает каноническое имя класса , то есть каноническое имя окружающего класса плюс простое имя внутреннего класса, разделенное точкой.
С другой стороны, методы getName() и getTypeName() возвращают примерно одно и то же, но используют доллар в качестве разделителя между каноническим именем окружающего класса и простым именем внутреннего класса .
Давайте представим внутренний класс InnerClass нашего RetrieveClassName :
public class RetrieveClassName public class InnerClass > >
Тогда каждый вызов обозначает внутренний класс немного по-другому:
assertEquals("com.foreach.RetrieveClassName.InnerClass", RetrieveClassName.InnerClass.class.getCanonicalName()); assertEquals("com.foreach.RetrieveClassName$InnerClass", RetrieveClassName.InnerClass.class.getName()); assertEquals("com.foreach.RetrieveClassName$InnerClass", RetrieveClassName.InnerClass.class.getTypeName());
3.4. Анонимные классы
Еще одним исключением являются анонимные классы.
Как мы уже видели, у них нет простого имени, но у них также нет и канонического имени . Поэтому getCanonicalName() ничего не возвращает. В отличие от getSimpleName() , getCanonicalName() вернет null , а не пустую строку при вызове анонимного класса.
Что касается getName() и getTypeName() , они вернут каноническое имя вызывающего класса, за которым следует доллар и число, представляющее позицию анонимного класса среди всех анонимных классов, созданных в вызывающем классе .
Проиллюстрируем это примером. Мы создадим здесь два анонимных класса и вызовем getName() для первого и getTypeName() для второго, объявив их в com.foreach.Main :
assertEquals("com.foreach.Main$1", new RetrieveClassName() >.getClass().getName()); assertEquals("com.foreach.Main$2", new RetrieveClassName() >.getClass().getTypeName());
Следует отметить, что второй вызов возвращает имя с увеличенным числом в конце, так как он применяется ко второму анонимному классу.
3.5. Массивы
Наконец, давайте посмотрим, как массивы обрабатываются тремя вышеуказанными методами.
Чтобы указать, что мы имеем дело с массивами, каждый метод будет обновлять свой стандартный результат. Методы getTypeName() и getCanonicalName() добавляют к своему результату пары квадратных скобок.
Давайте посмотрим на следующий пример, где мы вызываем getTypeName() и getCanonicalName() для двумерного массива InnerClass :
assertEquals("com.foreach.RetrieveClassName$InnerClass[][]", RetrieveClassName.InnerClass[][].class.getTypeName()); assertEquals("com.foreach.RetrieveClassName.InnerClass[][]", RetrieveClassName.InnerClass[][].class.getCanonicalName());
Обратите внимание, как в первом вызове используется доллар вместо точки, чтобы отделить внутреннюю часть класса от остальной части имени.
Давайте теперь посмотрим, как работает метод getName() . При вызове массива примитивных типов он вернет открывающую скобку и букву, представляющую примитивный тип . ** ** Давайте проверим это на следующем примере, вызвав этот метод для двумерного примитивного массива целых чисел:
assertEquals("[[I", int[][].class.getName());
С другой стороны, при вызове массива объектов он добавит открывающую скобку и букву L к своему стандартному результату и завершит запись точкой с запятой . Давайте попробуем это на массиве RetrieveClassName :
assertEquals("[Lcom.foreach.className.RetrieveClassName;", RetrieveClassName[].class.getName());
4. Вывод
В этой статье мы рассмотрели четыре метода доступа к имени класса в Java. Этими методами являются: getSimpleName(), getName(), getTypeName() и getCanonicalName() .
Мы узнали, что первый просто возвращает имя исходного кода класса, в то время как другие предоставляют дополнительную информацию, такую как имя пакета и указание на то, является ли класс внутренним или анонимным классом.
Код этой статьи можно найти на GitHub .
- 1. Обзор
- 2. Получение простого имени
- 3. Получение других имен
- 3.1. Примитивные типы
- 3.2. Типы объектов
- 3.3. Внутренние классы
- 3.4. Анонимные классы
- 3.5. Массивы
Как получить имя объекта в java?
Ну спасибо. Будем что w1 без дополнительного поля, похоже никак не получить. Я скромно вам отвечу +1.
14 сен 2015 в 16:47
Даже если найти способ получить имя переменной из объекта, то это будет не корректно. Представьте, если, допустим, сделать так: Wheel w1 = new Wheel(«Колесо1», 5); Wheel w11 = w1; w1.c(); w11.c(); Неужели по Вашему мнению вывод в консоль должен быть разным? Объект то один и тот же, мы не создаем второе колесо. Мы всего лишь создаем вторую переменную, которая указывает на то же самое колесо.
14 сен 2015 в 17:01
а я где-то слышал, что у ∀ объекта должно быть уникальное имя. И даже если я склонирую объект, метод w1.equals.(w11) даст на выходе false.
14 сен 2015 в 17:28
Во-первых, уникальное имя и имя переменной — разные вещи. Во-вторых, присвоить значение переменной и склонировать объект — это тоже разные вещи.
Как получить имя текущего метода/класса?
Бывают ситуации, когда кроме какого-либо сообщения хочется залогировать имя класса, имя метода или даже номер строки, на которой в данной момент происходит выполнение кода. Если с именем класса все более-менее понятно – достаточно в функцию логирования передать ссылку на класс – то с именем метода такой фокус не пройдет. Но и эта проблема решается достаточно просто.
Для этого необходимо создать инстанс класса Throwable и получить из него текущий стэк вызовов. Найти нужный нам элемент стэка и получить оттуда всю необходимую информацию: объект класса, имя класса, имя метода и, даже, номер строки.
Ниже представлен кусок кода, где показато как это может быть реализовано.
public class Test < public static void main(String[] args) < new Test().execute(); >public void execute() < log("Some message"); >public static void log(String message) < Throwable t = new Throwable(); StackTraceElement trace[] = t.getStackTrace(); // Глубина стэка должна быть больше 1-го, поскольку интересующий // нас элемент стэка находится под индексом 1 массива элементов // Элемент с индексом 0 - это текущий метод, т.е. log if (trace.length >1) < StackTraceElement element = trace[1]; System.out.format("[%s] [%s, %d] %s", element.getClassName(), element.getMethodName(), element.getLineNumber(), message); >else System.out.format("[no info] %s", message); > >Получение имени класса в Java
Изучите различные способы получения имени класса в Java.
- Автор записи Автор: François Dupire
- Дата записи 08.05.2021
1. Обзор
В этом уроке мы узнаем о четырех способах извлечения имени класса из методов Class API: getSimpleName () , getName () , getTypeName() и getCanonicalName() .
Эти методы могут сбивать с толку из-за их схожих названий и их несколько расплывчатых Javadoc. Они также имеют некоторые нюансы, когда речь заходит о примитивных типах, типах объектов, внутренних или анонимных классах и массивах.
2. Получение Простого Имени
Давайте начнем с метода getSimpleName () .
В Java существует два типа имен: простые и квалифицированные . Простое имя состоит из уникального идентификатора, в то время как полное имя представляет собой последовательность простых имен, разделенных точками.
Как следует из его названия, getSimpleName() возвращает простое имя базового класса, то есть имя, которое было дано в исходном коде .
Давайте представим себе следующий класс:
package com.baeldung.className; public class RetrieveClassName <>
Его простое имя будет RetrieveClassName :
assertEquals("RetrieveClassName", RetrieveClassName.class.getSimpleName());Мы также можем получить примитивные типы и массивы простых имен. Для примитивных типов, которые будут просто их именами, например int, boolean или float .
А для массивов метод вернет простое имя типа массива, за которым следует пара открывающих и закрывающих скобок для каждого измерения массива ([]) :
RetrieveClassName[] names = new RetrieveClassName[]; assertEquals("RetrieveClassName[]", names.getClass().getSimpleName());Следовательно, для двумерного String массива вызов getSimpleName() в его классе вернет String[][] .
Наконец, есть конкретный случай анонимных классов. Вызов getSimpleName() в анонимном классе вернет пустую строку.
3. Получение Других Имен
Теперь пришло время взглянуть на то, как мы могли бы получить имя класса, имя типа или каноническое имя. В отличие от getSimpleName() , эти имена предназначены для предоставления дополнительной информации о классе.
Метод getCanonicalName() всегда возвращает каноническое имя , определенное в спецификации языка Java .
Что касается других методов, выходные данные могут немного отличаться в зависимости от вариантов использования. Мы увидим, что это означает для различных типов примитивов и объектов.
3.1. Примитивные типы
Давайте начнем с примитивных типов, поскольку они просты. Для примитивных типов все три метода getName (), getTypeName() и getCanonicalName() вернут тот же результат, что и getSimpleName() :
assertEquals("int", int.class.getName()); assertEquals("int", int.class.getTypeName()); assertEquals("int", int.class.getCanonicalName());3.2. Типы объектов
Теперь мы посмотрим, как эти методы работают с типами объектов. Их поведение, как правило, одинаковое: все они возвращают каноническое имя класса .
В большинстве случаев это полное имя, которое содержит все простые имена пакетов классов, а также простое имя класса:
assertEquals("com.baeldung.className.RetrieveClassName", RetrieveClassName.class.getName()); assertEquals("com.baeldung.className.RetrieveClassName", RetrieveClassName.class.getTypeName()); assertEquals("com.baeldung.className.RetrieveClassName", RetrieveClassName.class.getSimpleName());3.3. Внутренние классы
То, что мы видели в предыдущем разделе, – это общее поведение этих вызовов методов, но есть несколько исключений.
Внутренние классы-один из них. Методы getName() и getTypeName() ведут себя иначе, чем метод getCanonicalName() для внутренних классов.
getCanonicalName() по-прежнему возвращает каноническое имя класса , то есть каноническое имя заключающего класса плюс простое имя внутреннего класса, разделенное точкой.
С другой стороны, методы getName() и getTypeName() возвращают почти то же самое, но используют доллар в качестве разделителя между каноническим именем заключающего класса и простым именем внутреннего класса .
Давайте представим себе внутренний класс InnerClass нашего RetrieveClassName :
public class RetrieveClassName < public class InnerClass <>>
Затем каждый вызов обозначает внутренний класс немного по-другому:
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. Анонимные классы
Анонимные классы-еще одно исключение.
Как мы уже видели, у них нет простого имени, но у них также нет канонического имени . Поэтому getCanonicalName() ничего не возвращает. В отличие от getSimpleName() , getCanonicalName() вернет null | и не пустую строку при вызове анонимного класса.
Что касается getName() и getTypeName () , они вернут каноническое имя вызывающего класса, за которым последуют доллар и число, представляющее положение анонимного класса среди всех анонимных классов, созданных в вызывающем классе .
Давайте проиллюстрируем это на примере. Мы создадим здесь два анонимных класса и вызовем getName() на первом и getTypeName() на втором, объявив их в com.baeldung.Главная :
assertEquals("com.baeldung.Main$1", new RetrieveClassName() <>.getClass().getName()); assertEquals("com.baeldung.Main$2", new RetrieveClassName() <>.getClass().getTypeName());Следует отметить, что второй вызов возвращает имя с увеличенным числом в конце, поскольку оно применяется ко второму анонимному классу.
3.5. Массивы
Наконец, давайте посмотрим, как массивы обрабатываются вышеперечисленными тремя методами.
Чтобы указать, что мы имеем дело с массивами, каждый метод обновит свой стандартный результат. Методы getTypeName() и getCanonicalName() добавят пары скобок к своему результату.
Давайте рассмотрим следующий пример, в котором мы вызываем getTypeName() и getCanonicalName() для двумерного внутреннего класса массива:
assertEquals("com.baeldung.RetrieveClassName$InnerClass[][]", RetrieveClassName.InnerClass[][].class.getTypeName()); assertEquals("com.baeldung.RetrieveClassName.InnerClass[][]", RetrieveClassName.InnerClass[][].class.getCanonicalName());Обратите внимание, как первый вызов использует доллар вместо точки, чтобы отделить внутреннюю часть класса от остальной части имени.
Теперь давайте посмотрим, как работает метод getName () . При вызове массива примитивного типа он возвращает открывающую скобку и букву, представляющую примитивный тип . Давайте проверим это на следующем примере, вызвав этот метод для двумерного массива примитивных целых чисел:
assertEquals("[[I", int[][].class.getName());С другой стороны, при вызове массива объектов он добавит открывающую скобку и букву L к своему стандартному результату и завершится точкой с запятой . Давайте попробуем это на массиве RetrieveClassName :
assertEquals("[Lcom.baeldung.className.RetrieveClassName;", RetrieveClassName[].class.getName());4. Заключение
В этой статье мы рассмотрели четыре метода доступа к имени класса в Java. Эти методы: getSimpleName(), getName(), getTypeName() и getCanonicalName() .
Мы узнали, что первый просто возвращает имя исходного кода класса, в то время как другие предоставляют дополнительную информацию, такую как имя пакета и указание на то, является ли класс внутренним или анонимным классом.
Код этой статьи можно найти на GitHub .
- Метки class, getcanonicalname