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

问题描述 投票:0回答:6

当我编译这样的东西时:

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

并将其编译为类文件,似乎参数名称丢失了。也就是说,当其他一些 Java 代码引用

MyClass
并想要调用或覆盖
myMethod
时,我的 IDE(当前为 Eclipse)似乎从类文件中获取此方法签名:

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

我知道 Eclipse(也可能还有其他 IDE)允许我提供指向源代码或 Javadoc (如 Bishiboosh 指出)

MyClass
的链接,并且可以利用它。但我很好奇是否有某种方法可以告诉
javac
将名称包含到类文件中,以便该类的用户即使只有类文件也可以看到参数名称。

课程解决方案

当我用

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

这个解决方案被几个作者提出,但尼克的回答终于让我相信了。

在我的机器上,Eclipse 有时使用此信息,有时不使用,这可能是我的错或 Eclipse 中的错误,但不是类文件或编译器的问题。不管怎样,现在我知道信息肯定存在了。

但是接口没有解决方案

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

对我来说,合乎逻辑的原因似乎是,

-g:vars
只提供局部变量的名称,这也是 javac 的文档中规定的。在方法体中,它的参数非常类似于局部变量,因此它们被
-g:vars
覆盖。接口方法没有主体,所以它们不能有局部变量。

我最初的问题只问了课程,因为我不知道这可能有什么不同。

课程文件格式

正如gid所指出的,类文件格式不支持存储参数名称。我在类文件 spec 中找到了一个section,它描述了一个数据结构,它应该包含方法的参数名称,但是在编译接口时绝对不会使用它。

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

java eclipse compilation javac
6个回答
10
投票

要在类文件中保留名称以进行调试,请尝试项目属性、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 路线。


7
投票

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


5
投票

使用调试支持进行编译可能会有所帮助,它将所有名称存储在 .class 文件中。

尽管我不知道 Eclipse 是否考虑到了这一点。


2
投票

如果您在类文件中包含调试信息,Eclipse 将获取参数的名称:

javac -g:vars
应该足够了。


2
投票

无论您使用什么 javac 选项,类文件数据结构都不支持将参数名称存储到任何方法。

为了在 IDE 中查看原始名称,您必须为它们提供 javadoc 或源代码。

如果您有特殊需要在运行时获取它们,可以向参数添加注释,但您必须创建自己的注释,因为没有标准集可供使用。

对不起不能更有帮助

编辑: 我完全纠正了......类文件格式显然有命名参数的空间(JLS 4.7

我看不到的是你怎么能用

java.lang.reflect.*

得到他们

0
投票

您不需要单独的 Javadoc 文件,您可以在 Eclipse 中创建“内联”javadoc,在多行注释的第一个斜杠后使用带有两个星号 (*) 的特殊注释。

示例代码:

   public class MyClass
{
 /**
  * documentation of your method
  * 
  * @param name    a String describing the name
  * @param options used to describe current option
  * @param query
  * @param comment
  * @return void
  */
    void myMethod(String name, String options, String query, String comment)
    {
        ...
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.