在已编译的 Java 类中保留参数/参数名称 [英] Preserving parameter/argument names in compiled java classes

查看:19
本文介绍了在已编译的 Java 类中保留参数/参数名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我编译这样的东西时:

When I compile something like this:

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

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

and compile this to a class file, it seems that argument names are lost. That is, when some other Java code references MyClass and wants to call or overwrite myMethod, my IDE (currently Eclipse) seems to get this method signature from the class-file:

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

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

I know that Eclipse (and possibly other IDEs too) allows me to provide a link to the source or the javadoc (as Bishiboosh pointed out) of MyClass and can take advantage of this. But I'm curious if there is some way to tell javac to include the names into the class-file, so that users of that class can see the argument names even if they only have the class file.

当我用 java -g:vars 编译一个类时,参数的名称包含在类文件中.-g:vars 好像相当于 Eclipse -> 项目属性 -> Java 编译器 -> 为生成的类文件添加变量属性.

When I compile a class with java -g:vars, the names of parameters are included in the class file. -g:vars seems to be equivalent to Eclipse -> project properties -> Java compiler -> Add variable attributes to generated class files.

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

This solution was suggested by several authors, but the answer from Nick finally made me believe.

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

On my machine, Eclipse sometimes used this info, sometimes it didn't, which was probably my fault or a bug in Eclipse, but not a problem with the class files or the compile. Anyway, now I know that the information is definitely present.

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

While this works (kind of) fine for classes, it's not working for interfaces.

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

For me, the logical reason seems to be, that -g:vars only provides the names of local variables, which is what the documentation for javac also states. In the body of a method, it's parameters are very similar to local variables, thus they are covered by -g:vars. interface methods don't have bodies, so they can't have local varibles.

我最初的问题只要求上课,因为我不知道可能会有什么不同.

My initial question only asked for classes, because I was not aware that there might be any difference.

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

As gid pointed out, the class file format does not support storrage of parameter names. I found a section in the class file spec that descibes a data struture which should holf the parameter names of methods, but this is definitely not used when compiling interfaces.

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

When compiling a class, I can't tell if the mentioned data structure is used, or if Eclipse infers the parameter names from the usage of parameters inside the method body. An expert could clarify this, but it's not that relevant I think.

推荐答案

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

To preserve names in the class file for debugging purposes try project properties, Java compiler, then "Add variable attributes to generated class files" (See Eclipse Help).

编译以下源码:

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
}

看到参数名称保存在类文件中.

See the parameter names are preserved in the class files.

我建议你查看你的源代码是如何编译的,它是为哪个版本编译的等等.

I would suggest you look into how your source is being compiled, which version it is compiled for etc.

啊,我发现这对于接口来说是不同的——他们似乎没有为调试器提供这些信息,我认为这是有道理的.我认为没有办法解决这个问题,如果您只想在编辑源代码时查看参数名称,则需要按照 Nagrom_17 的建议使用 javadoc 路由(附上源代码).

Ah, I see this is different for interfaces - they don't seem to have this information available for the debugger which I guess makes sense. I don't think there'll be a way round this, if you just want to see the parameter names when you're editing source you'll need to go the javadoc route as Nagrom_17 suggests (attach the source).

这篇关于在已编译的 Java 类中保留参数/参数名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆