百科问答小站 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语言规范里就没那么容易了…




  

相关话题

  怎么在.net 平台上用和 WP7 开发类似的技术或思想来实现 Android 开发? 
  多线程下载一个大文件的速度更快的真正原因是什么? 
  自学Java最起码要学到什么程度? 
  工厂模式(factory Method)的本质是什么?为什么引入工厂模式? 
  Java里面的封装是不是多此一举? 
  买了《阿里巴巴JAVA开发手册》的人,后悔了吗? 
  自学Java最起码要学到什么程度? 
  程序员如何快速上手一个自己不太熟悉的新项目?有什么技巧? 
  为什么java返回json时用code=0表示成功, 而我观察的php和nodejs都是用1表示成功? 
  为什么同样作为程序员,和BAT的差距就那么大呢? 

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





© 2024-05-20 - tinynew.org. All Rights Reserved.
© 2024-05-20 - tinynew.org. 保留所有权利