Java中等价物的名称

Java中等价物的名称,java,nameof,Java,Nameof,C#6.0引入了nameof()操作符,它返回一个字符串,表示放入其中的任何类/函数/方法/局部变量/属性标识符的名称 如果我有这样一门课: class MyClass { public SomeOtherClass MyProperty { get; set; } public void MyMethod() { var aLocalVariable = 12; } } // with class name: var s = nameof(M

C#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".
我可以这样使用操作符:

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中是否有与该运算符等价的运算符?否则,我如何才能获得相同(或类似)的结果?

你不能

可以使用反射获取方法或字段,但必须将方法名称硬编码为字符串,这样就消除了整个目的

属性的概念不像在C#中那样内置在java中。getter和setter只是常规方法。你甚至不能像在问题中那样轻易地引用方法。您可以尝试使用反射来获取getter方法的句柄,然后切断
get
,以获取它类似的“属性”的名称,但这很难看,也不一样


至于局部变量,这是完全不可能的。

不幸的是,没有这样的。我之前一直在寻找这个功能,答案似乎是一般来说,这个东西并不存在

当然,您可以使用“命名”注释对字段进行注释,以基本上实现您自己的类的这一目标。实际上,有很多不同的框架依赖于类似的概念。即使如此,这也不是自动的。

你不能


如果使用调试符号编译,.class文件将包含一个变量名表(调试器将变量映射回源代码的方式),但不能保证它会在那里,并且不会在运行时公开。

可以使用运行时字节码插装来完成,例如使用byte Buddy library

请参阅此库:

此处描述了该方法:

用法示例:

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

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

非常确定Java没有完全相同的东西。所以像C#6之前的版本一样,你可能只需要使用字符串文字就可以了。你想用这个功能解决什么问题呢?我不是C#爱好者,但是如果不是为了日志记录等,使用
nameof()
听起来不像是干净的设计。@f1sh我自己也经常用它来处理对象更新事件。我将
nameof(AffectedProperty)
传递给事件args对象的相关属性,以通知侦听器更新了哪个属性。这是获得属性名编译时安全性的好方法。问题不在于C#,而在于Java,因此标记不相关。它确实包含并提到了C#,但这并不保证添加标记。另请参见此问题与C#属性无关。问题是,您是否可以在不使用名称本身的情况下获取方法或字段的名称。您关于反射需要名称来获取方法或字段的观点是密切相关的。问题非常具体地提到了C#properties。我的回答是“不”。那为什么要投否决票呢?还有,“germane”是什么意思?好吧,我提到了C#属性,但显然它们在Java中并不存在。这只是一个例子。我的问题的重点是获取类成员/变量/字段/标识符字符串表示形式,您回答了一些有用的问题。@f1sh-您说得对-示例中提到了一个属性。“密切”是指相关的。我编辑了你的答案,将最相关的部分放在首位,并删除了否决票。我认为答案可以进一步改进,注意你可以得到一个类的名称。@StephenP这是真的。但是如果你想得到一个特定的名称,你必须用equals或contains来检查方法/字段的名称,为此你必须再次以字符串形式键入名称。这个问题首先询问类、方法和字段的名称,这些名称包含在编译的代码中,并通过反射公开。@Andythonas否,没有。停止对正确答案进行向下投票。@f1sh-“返回一个字符串,表示放入其中的成员/类/字段的名称”。您不需要调试符号来获取类、方法和字段的名称(请参阅我对f1sh答案的评论)。您确实需要它们来获取在局部作用域中声明的任意变量的名称,但这不是OP所要求的。