Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以在Java或Kotlin中以编程方式获取局部变量名?_Java_Kotlin - Fatal编程技术网

是否可以在Java或Kotlin中以编程方式获取局部变量名?

是否可以在Java或Kotlin中以编程方式获取局部变量名?,java,kotlin,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

是否可以在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”
不,这是不可能的。只传递变量值,没有可以提供名称的数据。

理论上,这是可能的

您可以使用类似ASM的字节码解析器从声明类的类文件中提取方法的局部变量表。此表包含所有局部变量的名称及其有效性的偏移量,以标识声明顺序


但是请注意,此属性是可选的。编译器可以忽略添加此调试信息

在您的示例中,
one
two
将内联在调用站点中,并且在编译的代码中不会留下任何痕迹。Ups


如果您想要的只是简单的日志记录,并且您正在使用InteliJ(您应该!),那么就使用代码模板。它们允许用户使用本地名称,因此您将键入
one.log
并获取
one.log(“one”)
,例如,这是一个有趣的问题。但目的是什么?这只是一个练习吗

是的,在某些条件下,以编程方式获取局部变量名是可能的

  • 根据一些定义,在java中,函数参数是一种局部变量。如果代码是使用调试信息编译的,那么可以使用java反射method.getParameterTypes()获得这些信息

  • 如果您有一个使用调试信息编译的.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);
                    }
            }
        }
    }
    
    导入java.io.File;
    导入java.io.FileInputStream;
    导入java.io.FileNotFoundException;
    导入java.io.IOException;
    导入java.util.List;
    导入org.objectweb.asm.ClassReader;
    导入org.objectweb.asm.ClassVisitor;
    导入org.objectweb.asm.tree.ClassNode;
    导入org.objectweb.asm.tree.LocalVariableNode;
    导入org.objectweb.asm.tree.MethodNode;
    公开课范例{
    公共静态void main(字符串[]args)抛出FileNotFoundException、IOException{
    ClassReader=newclassreader(newfileinputstream(新文件(“A.class”));
    final ClassNode ClassNode=new ClassNode();
    accept((ClassVisitor)classNode,0);
    for(final MethodNode mn:(列表)classNode.methods){
    如果(mn.name.equals(“f1”))
    for(localvariablenoden:(列表)mn.localVariables){
    System.out.println(n.name);
    }
    }
    }
    }
    
  • 我不确定这一点,但我认为您也可以使用Java调试接口的LocalVariable类来完成

  • 没有。变量名只是为了方便程序员而存在;编译器抛出它们。考虑你认为它应该打印的代码> PrrtLoopalAsvices(1,一+ 1);<代码>。但是,您可以获得内存位置表示。所以,“一”可以变成@2123d517,你可以来回追踪那个“指针”。如果它是相同的值,那么它就是相同的变量,在该上下文中。@AndyTurner“value\u int1,value\u int2”例如,谢谢你的回答。@Bonatti谢谢,我想做另一个魔术,我需要将变量1转换成字符串“one”