Reflexión Java: ¿Cómo obtener el nombre de una variable?
Usando Java Reflection, ¿es posible obtener el nombre de una variable local? Por ejemplo, si tengo esto:
Foo b = new Foo();
Foo a = new Foo();
Foo r = new Foo();
¿Es posible implementar un método que pueda encontrar los nombres de esas variables, así:
public void baz(Foo... foos)
{
for (Foo foo: foos) {
// Print the name of each foo - b, a, and r
System.out.println(***);
}
}
EDITAR: Esta pregunta es diferente de ¿Existe alguna forma en Java de encontrar el nombre de la variable que se pasó a una función? en el sentido de que plantea de manera más pura la pregunta sobre si se puede usar la reflexión para determinar el nombre de una variable local, mientras que la otra pregunta (incluida la respuesta aceptada) se centra más en probar los valores de las variables.
A partir de Java 8, cierta información del nombre de la variable local está disponible mediante reflexión. Consulte la sección "Actualización" a continuación.
La información completa suele almacenarse en archivos de clase. Una optimización en tiempo de compilación es eliminarlo, ahorrando espacio (y proporcionando cierta confusión). Sin embargo, cuando está presente, cada método tiene un atributo de tabla de variables locales que enumera el tipo y nombre de las variables locales, y el rango de instrucciones en las que se encuentran dentro del alcance.
Quizás una biblioteca de ingeniería de código de bytes como ASM le permitiría inspeccionar esta información en tiempo de ejecución. El único lugar razonable que se me ocurre para necesitar esta información es en una herramienta de desarrollo, por lo que la ingeniería de código de bytes probablemente también sea útil para otros fines.
Actualización: se agregó soporte limitado para esto a Java 8. Los nombres de los parámetros (una clase especial de variable local) ahora están disponibles mediante reflexión. Entre otros propósitos, esto puede ayudar a reemplazar @ParameterName
las anotaciones utilizadas por los contenedores de inyección de dependencia.
No es posible en absoluto. Los nombres de las variables no se comunican dentro de Java (y también pueden eliminarse debido a optimizaciones del compilador).
EDITAR (relacionado con comentarios):
Si se aleja de la idea de tener que usarlo como parámetro de función, aquí tiene una alternativa (que yo no usaría; consulte a continuación):
public void printFieldNames(Object obj, Foo... foos) {
List<Foo> fooList = Arrays.asList(foos);
for(Field field : obj.getClass().getFields()) {
if(fooList.contains(field.get()) {
System.out.println(field.getName());
}
}
}
Habrá problemas si a == b, a == r, or b == r
hay otros campos que tengan las mismas referencias.
EDITAR ahora es innecesario ya que se aclaró la pregunta