简体   繁体   English

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

[英]It is possible to get local variable names programmatically in Java or Kotlin?

It is possible to get local variable names programmatically in Java or Kotlin? 可以在Java或Kotlin中以编程方式获取局部变量名称吗?

For example, this code 例如,这段代码

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

    printLocalVariables(one, two);
}

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

//result: "one, two"

I need to convert variable one to string "one" 我需要将变量one转换为字符串"one"

Theoretically, it is possible. 从理论上讲,这是可能的。

You can use a byte code parser like ASM to extract a method's local variable table from the class file of the declaring class. 您可以使用像ASM这样的字节代码解析器从声明类的类文件中提取方法的局部变量表。 This table contains the names of all local variables and an offset for their validity to identify the declaration order. 此表包含所有局部变量的名称以及用于标识声明顺序的有效性的偏移量。

Do however note that this attribute is optional. 但请注意,此属性是可选的。 A compiler can omitt adding this debug information. 编译器可以省略添加此调试信息。

No, it's not possible. 不,这是不可能的。 Only the variable values are passed, no data that could give you the name is available. 只传递变量值,没有可以提供名称的数据。

In the case like your example one and two will be inlined in the call site and leave no trail in the compiled code. 在类似于您的示例的情况下,将在调用站点中内联onetwo并且在编译的代码中不留下任何痕迹。 Ups. UPS。

If all you want is easy logging, and you are using InteliJ (you should!), then use code templates. 如果你想要的只是简单的日志记录,并且你正在使用InteliJ(你应该!),那么使用代码模板。 They allow one to use the local name, so you'll type one.log<tab> and get one.log("one") , for example 它们允许一个人使用本地名称,因此您将键入one.log<tab>并获取one.log("one") ,例如

This is an interesting question. 这是个有趣的问题。 But What is the purpose? 但目的是什么? Is it just an exercise? 这只是一个练习吗?

Yes, getting local variable names programmatically is possible under certain conditions. 是的,在某些条件下可以以编程方式获取本地变量名称。

  1. According to some definitions, in java, function parameters are a kind of local variable. 根据一些定义,在java中,函数参数是一种局部变量。 You can get those , if the code was compiled using debug information, with java reflection, method.getParameterTypes() 如果使用调试信息编译代码,可以使用java反射,method.getParameterTypes()获取这些代码

  2. If you have a .class file compiled with debug information, you can read it the local variables from it, for example using asm's ClassReader. 如果您使用调试信息编译了.class文件,则可以从中读取本地变量,例如使用asm的ClassReader。 The following code looks at the locals of class A's function f1 以下代码查看了类A函数f1的局部变量

Here is the 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. I'm not sure about this, but I think you could also do it using the LocalVariable class of the Java Debug Interface 我不确定这一点,但我认为你也可以使用Java Debug Interface的LocalVariable类来做到这一点

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM