nameof equivalent in Java

2019-02-11 22:05发布

C# 6.0 introduced the nameof() operator, that returns a string representing the name of any class / function / method / local-variable / property identifiers put inside it.

If I have a class like this:

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

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

I can use the operator like this:

//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 is useful since the correct string is checked at compile time. If I misspell the name of some property/method/variable the compiler returns an error. Also, if I refactor, all the strings are automatically updated. See for example this documentation for real use cases.

Is there any equivalent of that operator in Java? Otherwise, how can I achieve the same result (or similar)?

标签: java nameof
4条回答
疯言疯语
2楼-- · 2019-02-11 22:27

Sadly, there is nothing like this. I had been looking for this functionality a while back and the answer seemed to be that generally speaking, this stuff does not exist.

See Get name of a field

You could, of course, annotate your field with a "Named" annotation to essentially accomplish this goal for your own classes. There's a large variety of frameworks that depend upon similar concepts, actually. Even so, this isn't automatic.

查看更多
虎瘦雄心在
3楼-- · 2019-02-11 22:28

It can be done using runtime byte code instrumentation, for instance using Byte Buddy library.

See this library: https://github.com/strangeway-org/nameof

The approach is described here: http://in.relation.to/2016/04/14/emulating-property-literals-with-java-8-method-references/

Usage example:

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

    @Test
    public void properties() {
        assertEquals("summary", Person.$(Person::getSummary));
    }
}
查看更多
放荡不羁爱自由
4楼-- · 2019-02-11 22:32

You can't.

You can get a Method or Field using reflection, but you'd have to hardcode the method name as a String, which eliminates the whole purpose.

The concept of properties is not built into java like it is in C#. Getters and setters are just regular methods. You cannot even reference a method as easily as you do in your question. You could try around with reflection to get a handle to a getter method and then cut off the get to get the name of the "property" it resembles, but that's ugly and not the same.

As for local variables, it's not possible at all.

查看更多
Summer. ? 凉城
5楼-- · 2019-02-11 22:38

You can't.

If you compile with debug symbols then the .class file will contain a table of variable names (which is how debuggers map variables back to your source code), but there's no guarantee this will be there and it's not exposed in the runtime.

查看更多
登录 后发表回答