在已编译的 Java 类中保留参数/参数名称

2022-09-02 13:07:37

当我编译这样的东西时:

public class MyClass
{
    void myMethod(String name, String options, String query, String comment)
    {
        ...
    }
}

并将其编译为类文件,似乎参数名称丢失了。也就是说,当其他一些Java代码引用并希望调用或覆盖时,我的IDE(当前为Eclipse)似乎从类文件中获取此方法签名:MyClassmyMethod

void myMethod(String arg0, String arg1, String arg2, String arg3);

我知道Eclipse(可能还有其他IDE)允许我提供指向源代码或Javadoc的链接(正如Bishiboosh所指出的那样),并且可以利用这一点。但是我很好奇是否有某种方法可以告诉将名称包含在类文件中,以便该类的用户可以看到参数名称,即使他们只有类文件。MyClassjavac

类解决方案

当我编译一个带有 的类时,参数的名称包含在类文件中。 似乎等同于Eclipse ->项目属性 ->Java编译器 ->将变量属性添加到生成的类文件中java -g:vars-g:vars

这个解决方案是由几位作者提出的,但尼克的答案最终让我相信了。

在我的机器上,Eclipse有时会使用这些信息,有时它没有,这可能是我的错或Eclipse中的错误,但不是类文件或编译的问题。无论如何,现在我知道这些信息肯定存在。

但没有接口解决方案

虽然这对类(有点)很好,但它不适用于接口。

对我来说,合乎逻辑的原因似乎是,这只提供了局部变量的名称,这是javac的文档也声明的。在方法的主体中,它的参数与局部变量非常相似,因此它们被 覆盖。接口方法没有主体,因此它们不能有局部变量。-g:vars-g:vars

我最初的问题只要求上课,因为我不知道可能有什么区别。

类文件格式

正如gid所指出的,类文件格式不支持参数名称的存储。我在类文件规范中发现了一个部分,它描述了一个数据结构,它应该对方法的参数名称进行霍尔化,但是在编译接口时绝对不会使用。

在编译类时,我无法判断是否使用了提到的数据结构,或者Eclipse是否从方法体中参数的用法推断出参数名称。专家可以澄清这一点,但我认为这并不相关。


答案 1

要在类文件中保留名称以进行调试,请尝试使用项目属性、Java 编译器,然后尝试“将变量属性添加到生成的类文件中”(请参阅 Eclipse 帮助)。

编译以下源代码:

public class StackOverflowTest {
    public void test(String foo, String bar) {
        // blah
    }
}

被反编译为:

// Compiled from StackOverflowTest.java (version 1.5 : 49.0, super bit)
public class StackOverflowTest {

    // Method descriptor #6 ()V
    // Stack: 1, Locals: 1
    public StackOverflowTest();
        0  aload_0 [this]
        1  invokespecial java.lang.Object() [8]
        4  return
        Line numbers:
            [pc: 0, line: 1]
        Local variable table:
            [pc: 0, pc: 5] local: this index: 0 type: StackOverflowTest

    // Method descriptor #15 (Ljava/lang/String;Ljava/lang/String;)V
    // Stack: 0, Locals: 3
    public void test(java.lang.String foo, java.lang.String bar);
        0  return
        Line numbers:
            [pc: 0, line: 4]
        Local variable table:
            [pc: 0, pc: 1] local: this index: 0 type: StackOverflowTest
            [pc: 0, pc: 1] local: foo index: 1 type: java.lang.String
            [pc: 0, pc: 1] local: bar index: 2 type: java.lang.String
}

请参阅参数名称保留在类文件中。

我建议你研究一下你的源代码是如何编译的,它是为哪个版本编译的,等等。

编辑:

啊,我看到这对接口来说是不同的 - 它们似乎没有可用于调试器的此信息,我想这是有道理的。我不认为会有办法解决这个问题,如果你只是想在编辑源代码时看到参数名称,你需要按照Nagrom_17的建议去javadoc路由(附加源代码)。


答案 2

您不需要特别需要源代码来使 arg 名称出现在 Eclipse 中...如果指定 Javadoc,Eclipse 将显示参数。


推荐