2012-09-30 52 views
6

Mi pregunta principal: sé que puede generar genéricamente campos de clase con reflexión, incluso si no conoce los nombres de las variables, los tipos o incluso cuántos hay. Sin embargo, ¿hay alguna manera de enumerar todas las variables dentro de la función actual o del alcance actual, suponiendo que no sé cuáles son los nombres de las variables?¿Cómo enumero todas las variables locales dentro de un método/función de Java?

En otras palabras:

int x = 5; 
int y = 42; 
// some more code 
//Now I want to println x and y, but assuming I cannot use "x" or "y". 

También sería feliz con una respuesta a esta pregunta: ¿ Digamos que se me permite almacenar los nombres de todas las variables, ayuda eso? e.g .:

Set<String> varNames = new HashSet<String>(); 
int x = 5; 
varNames.add("x"); 
int y = 42; 
varNames.add("y"); 
// some more code 
//Now with varNames, can I output x and y without using "x" or "y"? 

¿Por qué estoy preguntando esto? Estoy traduciendo el (los) idioma (s) XYZ a java usando ANTLR, y me gustaría proporcionar un método simple para mostrar todo el estado del programa en cualquier momento.

Tercera solución posible Me alegraría: si esto no es posible en Java, ¿hay alguna manera de escribir código de bytes para una función que visita la función de llamada y examina la pila? Esto también resolvería el problema.

Lo que sería increíble si Java tuviera el equivalente de Python's eval() o php's get_defined_vars().

Si hace una diferencia, estoy usando Java 6, pero cualquier cosa para Java 5, 6 o 7 debería ser buena.

Gracias!

+0

quizás esta pregunta está relacionada (http://stackoverflow.com/questions/2946279/how-do-i-print-the-method-body-reflectively) – user1406062

Respuesta

4

No puede, por lo que yo sé. Al menos, no con el código Java normal. Si puede ejecutar el bytecode a través de algún tipo de post-procesador antes de ejecutarlo, y suponiendo que todavía está construyendo con los símbolos de depuración incluidos, entonces podría autogenerar el código para hacerlo, pero no creo que haya cualquier forma de acceder a las variables locales en el marco de la pila actual a través de la reflexión.

+0

Interesante. ¿Cómo algo como el depurador de eclipse inspecciona la pila? ¿Necesita conectarse a través de un conducto de red local a la JVM, o está en un hilo que tiene acceso a la memoria del programa? – Arcymag

+0

@Arcymag - No creo que el depurador necesite inspeccionar la pila; se basa en archivos de símbolos (o algo similar) creados en tiempo de compilación. –

1

Si no desea utilizar esto como parte de la ruta de ejecución normal de su programa, pero solo para la depuración, utilice el Java platform debugger architecture (JPDA). Esencialmente, escribiría su propio depurador, establecería un punto de interrupción y usaría el JDI API para consultar el estado del programa. Las variables locales se pueden enumerar con StackFrame#visibleVariables().

Si lo anterior no es una opción, será muy difícil de lograr. Para obtener los nombres de las variables, puede analizar el archivo de clase y leer el atributo de la tabla de variables locales del método. Sin embargo, la única forma de obtener el valor de una variable local es a través de aload/iload/etc. instrucciones bytecode. Estos tienen que estar presentes en el método que desea analizar, por lo que no puede poner esta funcionalidad en un método de ayuda diferente.

+0

¿podría decirme dónde encontrar ejemplos de JPDA y comunidad en línea activa para JPDA? – WSS

Cuestiones relacionadas