Подтвердить что ты не робот

Имя эквивалента в Java

В С# 6.0 введен оператор nameof(), который возвращает строку, представляющую имя любого идентификатора класса/функции/метода/локальной переменной/свойства, помещенного в него.

Если у меня есть такой класс:

class MyClass
{
    public SomeOtherClass MyProperty { get; set; }

    public void MyMethod()
    {
        var aLocalVariable = 12;
    }
}

Я могу использовать оператор так:

// with class name:
var s = nameof(MyClass); // s == "MyClass"

// with properties:
var s = nameof(MyClass.OneProperty); // s == "OneProperty"

// with methods:
var s = nameof(MyClass.MyMethod); // s == "MyMethod"

// with local variables:
var s = nameof(aLocalVariable); // s == "aLocalVariable".

Это полезно, поскольку правильная строка проверяется во время компиляции. Если я неправильно пишу имя какого-либо свойства/метода/переменной, компилятор возвращает ошибку. Кроме того, если я сделаю рефакторинг, все строки будут автоматически обновлены. Смотрите, например, эту документацию для реальных случаев использования.

Есть ли эквивалент этого оператора в Java? В противном случае, как я могу достичь того же результата (или аналогичного)?

4b9b3361

Ответ 1

К сожалению, нет ничего подобного. Я искал эту функциональность некоторое время назад, и ответ, казалось, состоял в том, что, вообще говоря, этого не существует.

См. Получить имя поля

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

Ответ 2

Вы не можете.

Вы можете получить метод или поле с использованием отражения, но вам придется жестко указать имя метода как String, что устраняет целую цель.

Понятие свойств не встроено в java, как в С#. Геттеры и сеттеры - это обычные методы. Вы даже не можете ссылаться на метод так же легко, как и на свой вопрос. Вы можете попробовать с отражением, чтобы получить дескриптор метода геттера, а затем отрезать get, чтобы получить имя "свойства", которое оно напоминает, но это уродливое и не то же самое.

Что касается локальных переменных, это вообще невозможно.

Ответ 3

Это можно сделать с помощью инструментария времени выполнения, например, с помощью библиотеки Byte Buddy.

Смотрите эту библиотеку: https://github.com/strangeway-org/nameof

Подход описан здесь: http://in.relation.to/2016/04/14/emulation-property-literals-with-java-8-method-references/

Пример использования:

public class NameOfTest {
    @Test
    public void direct() {
        assertEquals("name", $$(Person.class, Person::getName));
    }

    @Test
    public void properties() {
        assertEquals("summary", Person.$(Person::getSummary));
    }
}

Ответ 4

Вы не можете.

Если вы компилируете с помощью отладочных символов, тогда файл .class будет содержать таблицу имен переменных (как отладчики сопоставляют переменные с исходным кодом), но нет никакой гарантии, что это будет там, и она не будет отображаться во время выполнения.