Java 中的等效名称
nameof equivalent in Java
C# 6.0 引入了 nameof()
运算符,即 returns 一个字符串,代表任何 class / 函数 / 方法 / 局部变量 / 属性 标识符的名称里面。
如果我有这样的class:
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".
这很有用,因为在编译时会检查正确的字符串。如果我拼错了一些property/method/variable的名字,编译器returns就会出错。此外,如果我重构,所有字符串都会自动更新。有关实际用例,请参见示例 this documentation。
Java 中是否有任何与该运算符等效的运算符?否则,我怎样才能达到相同(或类似)的结果?
你不能。
您可以使用反射获取方法或字段,但您必须将方法名称硬编码为字符串,这会消除整个目的。
java 没有像 C# 那样内置属性的概念。 getter 和 setter 只是常规方法。您甚至不能像在问题中那样轻松地引用方法。您可以尝试使用反射来获取 getter 方法的句柄,然后切断 get
以获得它相似的 "property" 的名称,但这很丑陋而且不一样。
至于局部变量,根本不可能。
可悲的是,没有这样的事情。前一段时间我一直在寻找这个功能,答案似乎是一般来说,这个东西不存在。
见Get name of a field
当然,您可以使用 "Named" 注释来注释您的字段,从而从根本上实现您自己 类 的目标。实际上,有很多框架都依赖于类似的概念。即便如此,这也不是自动的。
你不能。
如果您使用调试符号进行编译,那么 .class 文件将包含 table 个变量名称(这是调试器将变量映射回您的源代码的方式),但不能保证这一点将在那里并且不会在运行时公开。
可以使用运行时字节码检测来完成,例如使用 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));
}
}
Lombok 有一个实验性功能 @FieldNameConstants
添加注释后,您将获得带有字段名称的内部类型 Fields
。
@FieldNameConstants
class MyClass {
String myProperty;
}
...
String s = MyClass.Fields.myProperty; // s == "myProperty"
我也很懊恼Java没有可比性,于是自己实现了:https://github.com/mobiuscode-de/nameof
您可以像这样简单地使用它:
Name.of(MyClass.class, MyClass::getProperty)
这只是 return 字符串
"property"
<dependency>
<groupId>de.mobiuscode.nameof</groupId>
<artifactId>nameof</artifactId>
<version>1.0</version>
</dependency>
或 Gradle:
implementation 'de.mobiuscode.nameof:nameof:1.0'
我意识到它与 library from strangeway 非常相似,但我认为最好不要引入奇怪的 $
/$$
符号和增强的字节码工程。我的库只使用代理 class,在其上调用 getter 以确定传递的方法的名称。这允许简单地提取 属性 名称。
C# 6.0 引入了 nameof()
运算符,即 returns 一个字符串,代表任何 class / 函数 / 方法 / 局部变量 / 属性 标识符的名称里面。
如果我有这样的class:
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".
这很有用,因为在编译时会检查正确的字符串。如果我拼错了一些property/method/variable的名字,编译器returns就会出错。此外,如果我重构,所有字符串都会自动更新。有关实际用例,请参见示例 this documentation。
Java 中是否有任何与该运算符等效的运算符?否则,我怎样才能达到相同(或类似)的结果?
你不能。
您可以使用反射获取方法或字段,但您必须将方法名称硬编码为字符串,这会消除整个目的。
java 没有像 C# 那样内置属性的概念。 getter 和 setter 只是常规方法。您甚至不能像在问题中那样轻松地引用方法。您可以尝试使用反射来获取 getter 方法的句柄,然后切断 get
以获得它相似的 "property" 的名称,但这很丑陋而且不一样。
至于局部变量,根本不可能。
可悲的是,没有这样的事情。前一段时间我一直在寻找这个功能,答案似乎是一般来说,这个东西不存在。
见Get name of a field
当然,您可以使用 "Named" 注释来注释您的字段,从而从根本上实现您自己 类 的目标。实际上,有很多框架都依赖于类似的概念。即便如此,这也不是自动的。
你不能。
如果您使用调试符号进行编译,那么 .class 文件将包含 table 个变量名称(这是调试器将变量映射回您的源代码的方式),但不能保证这一点将在那里并且不会在运行时公开。
可以使用运行时字节码检测来完成,例如使用 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));
}
}
Lombok 有一个实验性功能 @FieldNameConstants
添加注释后,您将获得带有字段名称的内部类型 Fields
。
@FieldNameConstants
class MyClass {
String myProperty;
}
...
String s = MyClass.Fields.myProperty; // s == "myProperty"
我也很懊恼Java没有可比性,于是自己实现了:https://github.com/mobiuscode-de/nameof
您可以像这样简单地使用它:
Name.of(MyClass.class, MyClass::getProperty)
这只是 return 字符串
"property"
<dependency>
<groupId>de.mobiuscode.nameof</groupId>
<artifactId>nameof</artifactId>
<version>1.0</version>
</dependency>
或 Gradle:
implementation 'de.mobiuscode.nameof:nameof:1.0'
我意识到它与 library from strangeway 非常相似,但我认为最好不要引入奇怪的 $
/$$
符号和增强的字节码工程。我的库只使用代理 class,在其上调用 getter 以确定传递的方法的名称。这允许简单地提取 属性 名称。