2016-07-29 90 views
2

可以通過Java或Kotlin以編程方式獲取局部變量名稱?可以通過Java或Kotlin編程獲取本地變量名稱嗎?

例如,該代碼

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

    printLocalVariables(one, two); 
} 

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

//result: "one, two" 

我需要可變one轉換爲字符串"one"

+0

號變量名的它僅僅是那裏的程序員的方便;編譯器將它們拋出。 –

+0

考慮一下你認爲應該爲printLocalVariables(1,one + 1)打印的內容。 –

+0

但是,您可以獲取內存位置表示。所以,「one」可以變成@ 2123d517,你可以來回追蹤這個「指針」。如果它在這種情況下具有相同的值,那麼它是相同的變量。例如, – Bonatti

回答

2

理論上有可能。

您可以使用一個字節碼解析器像ASM從聲明類的類文件中提取方法的局部變量表。該表包含所有局部變量的名稱以及用於識別聲明順序的有效偏移量。

但請注意,此屬性是可選的。編譯器可以省略添加此調試信息。

1

不,這是不可能的。只有變量值被傳遞,沒有可以給你名字的數據可用。

1

在你的例子中onetwo將在呼叫站點內聯,並且在編譯的代碼中沒有留下蹤跡。 UPS。

如果你想要的是簡單的日誌記錄,並且使用的是InteliJ(你應該!),然後使用代碼模板。他們允許使用本地名稱,因此您將輸入one.log<tab>並獲得one.log("one"),例如

1

這是一個有趣的問題。但是目的是什麼?這只是一個練習嗎?

是,編程變得局部變量名在一定條件下是可能的。

  1. 根據一些定義,在java中,函數參數是一種局部變量。如果使用調試信息編譯代碼,使用java反射,您可以獲得這些代碼。method.getParameterTypes()

  2. 如果您有一個用調試信息編譯的.class文件,您可以從中讀取它的局部變量,例如使用asm的ClassReader。 下面的代碼看起來在A類的函數f1

這裏的當地人是代碼:

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); 
       } 
     } 
    } 
} 
  • 我不知道這一點,但我想,你也可以做一個使用LocalVariable類的Java調試接口
  • 相關問題