2016-07-29 4 views
2

Es ist möglich, lokale Variablennamen programmgesteuert in Java oder Kotlin zu erhalten?Es ist möglich, lokale Variablennamen programmgesteuert in Java oder Kotlin zu erhalten?

Zum Beispiel dieser Code

public void printOneTwo() { 
    int one = 1; 
    int two = 2; 

    printLocalVariables(one, two); 
} 

private void printLocalVariables(Objects... variables) { 
    //code 
} 

//result: "one, two" 

I Variable one auf String konvertieren müssen "one"

+0

Nein. Variablennamen sind nur für den Programmierer Bequemlichkeit; Der Compiler wirft sie weg. –

+0

Überlegen Sie, was Sie denken, dass es für 'printLocalVariables (1, eins + 1) drucken soll;'. –

+0

Sie können jedoch eine Speicherortsrepräsentation abrufen. So könnte "Eins" @ 2123d517 werden und Sie könnten diesen "Zeiger" vor und zurück verfolgen. Wenn es der gleiche Wert ist, dann ist es die gleiche Variable in diesem Kontext. – Bonatti

Antwort

2

Theoretisch ist es möglich.

Sie können einen Bytecode-Parser wie ASM verwenden, um die lokale Variablentabelle einer Methode aus der Klassendatei der deklarierenden Klasse zu extrahieren. Diese Tabelle enthält die Namen aller lokalen Variablen und einen Offset für ihre Gültigkeit, um die Deklarationsreihenfolge zu identifizieren.

Beachten Sie jedoch, dass dieses Attribut optional ist. Ein Compiler kann diese Debug-Informationen hinzufügen.

1

Nein, es ist nicht möglich. Nur die Variablenwerte werden übergeben, keine Daten, die Ihnen den Namen geben könnten, sind verfügbar.

1

In dem Fall wie Ihr Beispiel one und two werden in der Aufrufseite inline sein und keine Spur in dem kompilierten Code hinterlassen. UPS.

Wenn alles, was Sie wollen, ist einfach Logging, und Sie verwenden InteliJ (Sie sollten!), Dann verwenden Sie Code-Vorlagen. Sie erlauben einem, den lokalen Namen zu verwenden, also geben Sie one.log<tab> ein und erhalten one.log("one"), zum Beispiel

1

Dies ist eine interessante Frage. Aber was ist der Zweck? Ist es nur eine Übung?

Ja, das Abrufen lokaler Variablennamen ist unter bestimmten Bedingungen möglich.

  1. Laut einigen Definitionen sind Funktionsparameter in Java eine Art lokale Variable. Sie können diese erhalten, wenn der Code mit Debug-Informationen kompiliert wurde, mit Java-Reflektion, method.getParameterTypes()

  2. Wenn Sie eine .class-Datei mit Debug-Informationen kompiliert haben, können Sie die lokalen Variablen daraus lesen, zum Beispiel mit asm's ClassReader. Der folgende Code sieht bei den Einheimischen der Klasse A die Funktion f1

Hier ist der Code:

import java.io.File; 

import java.io.FileInputStream; 

import java.io.FileNotFoundException; 

import java.io.IOException; 

import java.util.List; 


import org.objectweb.asm.ClassReader; 

import org.objectweb.asm.ClassVisitor; 

import org.objectweb.asm.tree.ClassNode; 

import org.objectweb.asm.tree.LocalVariableNode; 

import org.objectweb.asm.tree.MethodNode; 

public class Example { 
    public static void main(String[] args) throws FileNotFoundException, IOException { 
     ClassReader reader = new ClassReader(new FileInputStream(new File("A.class"))); 

     final ClassNode classNode = new ClassNode(); 
     reader.accept((ClassVisitor) classNode, 0); 

     for (final MethodNode mn : (List<MethodNode>)classNode.methods) { 
      if (mn.name.equals("f1")) 
       for (LocalVariableNode n : (List<LocalVariableNode>)mn.localVariables) { 
        System.out.println(n.name); 
       } 
     } 
    } 
} 
  1. Ich bin darüber nicht sicher, aber Ich denke, Sie könnten es auch mit der LocalVariable-Klasse der Java-Debug-Schnittstelle
Verwandte Themen