2012-09-30 12 views
6

Moje główne pytanie: Wiem, że możesz generalnie generować pola klas z refleksją, nawet jeśli nie znasz nazw zmiennych, typów, a nawet ile ich jest. Czy istnieje jednak sposób na wylistowanie wszystkich zmiennych w ramach bieżącej funkcji lub bieżącego zakresu, zakładając, że nie wiem, jakie są nazwy zmiennych?Jak wyświetlić listę wszystkich zmiennych lokalnych w ramach metody/funkcji Java?

Innymi słowy:

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". 

byłbym też zadowolony z odpowiedzi na to pytanie: powiedzmy mi wolno przechowywać nazwy wszystkich zmiennych, czy to pomaga? np .:

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"? 

Dlaczego o to pytam? Tłumaczę język (y) XYZ na java przy użyciu ANTLR i chciałbym przedstawić prostą metodę wyprowadzania całego stanu programu w dowolnym momencie.

Trzecie możliwe rozwiązanie Byłbym szczęśliwy z: Jeśli nie jest to możliwe w Javie, czy jest jakiś sposób, aby napisać kod bajtowy dla funkcji, która odwiedza funkcję wywołującą i analizuje stos? To również rozwiązałoby problem.

Co byłoby niesamowite, gdyby Java miała odpowiednik Pythona eval() lub php w postaci get_defined_vars().

Jeśli to robi różnicę, używam Java 6, ale wszystko dla Javy 5, 6 lub 7 powinno być dobre.

Dzięki!

+0

Może to pytanie jest powiązane (http://stackoverflow.com/questions/2946279/how-do-i-print-the-method-body-reflectively) – user1406062

Odpowiedz

4

Nie możesz, o ile mi wiadomo. Przynajmniej nie z normalnym kodem Java. Jeśli jesteś w stanie uruchomić kod bajtowy za pomocą jakiegoś post-procesora przed uruchomieniem go i zakładając, że nadal budujesz z dołączonymi symbolami debugowania, możesz automatycznie wygenerować kod, aby to zrobić - ale nie wierzę, że istnieje dowolny sposób dostępu do zmiennych lokalnych w bieżącej ramce stosu poprzez odbicie.

+0

Interesujące. W jaki sposób coś takiego jak debugger Eclipse sprawdza stos? Czy musi się łączyć przez lokalną sieć z JVM, czy też znajduje się w wątku mającym dostęp do pamięci programu? – Arcymag

+0

@Arcymag - Nie sądzę, że debugger musi sprawdzić stos; opiera się na plikach symboli (lub podobnych) utworzonych podczas kompilacji. –

1

Jeśli nie chcesz używać tego jako części normalnej ścieżki wykonywania programu, ale tylko do debugowania, użyj Java platform debugger architecture (JPDA). Zasadniczo można napisać własny debugger, ustawić punkt przerwania i użyć JDI API, aby sprawdzić stan programu. Zmienne lokalne można wyświetlić pod numerem StackFrame#visibleVariables().

Jeśli powyższe nie jest możliwe, będzie to bardzo trudne. Aby uzyskać nazwy zmiennych, można przeanalizować plik klasy i odczytać atrybut tabeli zmiennej lokalnej metody. Jednak jedynym sposobem na uzyskanie wartości zmiennej lokalnej jest przejście przez aload/iload/etc. instrukcje kodu bajtowego. Muszą być obecne w metodzie, którą chcesz analizować, więc nie możesz umieścić tej funkcji w innej metodzie pomocnika.

+0

czy możesz mi powiedzieć, gdzie znaleźć przykłady JPDA i aktywnej społeczności online dla JPDA? – WSS