2016-11-28 9 views
7

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

Если у меня есть класс вроде этого:

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". 

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

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

+2

Довольно уверен, что Java не имеет ничего точно эквивалент. Так что, как и до C# 6, вам скорее всего придется использовать строковые литералы. – juharr

+0

'nameof' - это синтаксический сахар, добавленный в последней версии C# (6).Я почти уверен, что Java (или большинство популярных языков вообще) не будет иметь эквивалент. – Abion47

+5

Какую проблему вы пытаетесь решить, имея такую ​​возможность? – OldProgrammer

ответ

9

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

См Get name of a field

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

6

Вы не можете.

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

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

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

+1

Этот вопрос не имеет ничего общего с свойствами C#. Вопрос заключается в том, спрашиваете, можете ли вы получить имя метода или поля без использования самого имени. Ваша мысль об отражении, требующая имя для получения метода или поля, является родной. –

+0

Вопрос упоминает свойства C# очень специфично. И я ответил на вопрос «нет». Так почему же downvote? Кроме того, что означает «родной»? – f1sh

+1

Хорошо, я упомянул свойства C#, но, очевидно, они не существуют в Java. Это был только пример. Пункт моего вопроса состоит в том, чтобы получить представление строковых элементов/переменных/полей/идентификаторов, и вы ответили с некоторыми полезными вещами. –

3

Вы не можете.

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

+0

Вопрос сначала запрашивает имена классов, методов и полей, которые включены в скомпилированный код и отображаются через отражение. –

+1

@ AndyThomas нет, это не так. Остановите downvoting правильные ответы. – f1sh

+0

good going @ f1sh –

3

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

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

Подход, описанный здесь: пример http://in.relation.to/2016/04/14/emulating-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)); 
    } 
}