百科问答小站 logo
百科问答小站 font logo



java能否获取到引用的名称? 第1页

  

user avatar   rednaxelafx 网友的相关建议: 
      

题主实际想做的是怎样的事情呢?

首先,

  • Java里的对象并没有“名字”的通用概念,
  • 引用也没有“名字”的概念,
  • 变量则可以名字的概念。

以题主的例子:

       Object abc = new Object();     

这个变量声明,

  • 赋值符号右手边的表达式所创建出来的对象并没有名字(不是“abc”);
  • 右手边这个表达式产生的引用也没有名字;
  • 而这个引用通过赋值传给了左手边一个有名字“abc”的变量。

所以题主真正想问的问题就是:能否获取变量的名字。

如果变量是静态变量或者成员变量(字段),那么它们的名字作为符号信息是一直存在Class文件并带到运行时的。所以在运行时还可以把名字找出来。

但如果题主想做的事情是类似:

       nameof(foo.bar);  //=> "bar" nameof(this.baz); //=> "baz"     

抱歉,Java没有这么方便的功能。

如果变量是参数或局部变量,则其符号信息在正常执行中是不需要的,因而也不会被保留到Class文件里。只有当从Java源码编译到Class文件时指定保留了局部变量的符号信息,才有可能在运行时知道参数或局部变量的名字。

Class文件里有一种属性表叫做

LocalVariableTable

,是用来记录参数与局部变量名字的符号信息表。javac编译Java源码时默认不生成这个属性表,只有指定了-g或-g:vars才会生成它。

这个属性表主要用于支持Java的调试器,以便调试器可以把某个slot里的局部变量映射到某个名字上。

一般来说,程序不应该猜测局部变量到底映射到了局部变量区的第几个slot上;但是因为局部变量区的头n个slot是用来存储方法的参数的,参数的位置与名字的映射关系倒是可以很方便的通过LocalVariableTable找出来。

因而这个表也有被调试器之外的程序“滥用”。一个经典的例子就是Spring的

LocalVariableTableParameterNameDiscoverer

,传给它一个java.lang.reflect.Method|Constructor,它可以返回一个数组的参数名回来。它就是通过人肉parse出Class文件里的LocalVariableTable来把信息找出来的。

顺带放个传送门:

valleytalk.org/wp-conte

这个场景对LocalVariableTable来说是种“滥用”,所以到Java 8的时候,Class文件格式新增了一个

MethodParameters

属性表专门用来存储参数名。这个属性表javac默认不生成,要指定-parameters参数来生成。Java的核心反射API添加了新的java.lang.reflect.Parameter来让代码访问这个属性表的信息。

请参考Obtaining Names of Method Parameters:

docs.oracle.com/javase/

JEP 118: Access to Parameter Names at Runtime

言归正传,如果有一个局部变量foo,Java里有没有简单的办法可以做到:

       nameof(foo); //=> "foo"     

呢?

答案是没有。

要nameof()运算符,请用C# 6:

C# - The New and Improved C# 6.0

想在Java语言层面添加个nameof()运算符其实不困难,稍微鼓捣下javac就好了。

真有人有需求而且愿意用定制的javac的话我可以写个patch。

但是要说服社区把nameof()运算符加到Java语言规范里就没那么容易了…




  

相关话题

  Java 8接口有default method后是不是可以放弃抽象类了? 
  Java学到什么程度才能叫精通? 
  为什么没有人去花时间搞个程序,让程序写编程呢? 
  如何看待 Android 绿色应用公约? 
  如何看待越来越多公司弃用 PHP 使用 Java? 
  如何获得高并发的经验? 
  为什么 Java 总被黑? 
  如何理解互斥锁、条件锁、读写锁以及自旋锁? 
  Spring是否代表着目前Java技术的顶峰,未来的Java将如何发展? 
  这篇博文c#比JAVA慢这么多 为什么? 

前一个讨论
NoSql是一种语言,还是一种概念?
下一个讨论
重载 Throwable.fillInStackTrace() 方法以提高Java性能这样的做法对吗?





© 2024-09-19 - tinynew.org. All Rights Reserved.
© 2024-09-19 - tinynew.org. 保留所有权利