Java 8 javac-parameters标志的缺点

Java 8 javac-parameters标志的缺点,java-8,javac,Java 8,Javac,我想尝试一些在运行时需要参数名的框架功能,因此我需要使用-parameters编译我的应用程序,它将参数名存储在JVM字节码中 除了jar/war的大小之外,此参数使用还有哪些缺点?唯一的问题是.class的大小将发生变化,因为字节码现在将包含更多信息: public class DeleteMe3 { public static void main(String[] args) { } private static void go(String s) { }

我想尝试一些在运行时需要参数名的框架功能,因此我需要使用
-parameters
编译我的应用程序,它将参数名存储在JVM字节码中


除了jar/war的大小之外,此参数使用还有哪些缺点?

唯一的问题是
.class
的大小将发生变化,因为字节码现在将包含更多信息:

public class DeleteMe3 {
    public static void main(String[] args) {
    }

    private static void go(String s) {
    }
}
例如,这将包含有关参数名称的信息,如下所示:

private static void go(java.lang.String);
   descriptor: (Ljava/lang/String;)V
   flags: ACC_PRIVATE, ACC_STATIC
   Code:
     stack=0, locals=1, args_size=1
       0: return
     LineNumberTable:
       line 11: 0
   MethodParameters:
     Name                           Flags
     s
如果没有
-参数
,此
方法参数
将不存在


可能有一些框架不能很好地处理这个问题。这里有一个。我知道这一点,因为我们不久前遇到了它,并且必须升级(从那以后我再也没有遇到过任何其他问题)。

在类文件格式中添加参数名的内容包含在中,它是在Java 8中提供的。关于为什么在OpenJDK电子邮件线程和应用程序中选择包含参数名,有一些讨论。简单地说,使参数名可选的原因是担心类文件大小、兼容性表面和敏感信息的暴露

兼容性表面的问题值得进一步讨论。上面链接的一个线程说更改参数名是一种二进制兼容的更改。这是正确的,但仅在JVM的二进制兼容性概念的严格上下文中。也就是说,更改方法的参数名永远不会更改JVM是否可以链接该方法。但该声明并不适用于一般的兼容性

在历史上,参数名一直被视为局部变量名。(毕竟,它们在作用域中是局部的。)您可以随意更改它们,方法之外的任何内容都不会受到影响。但是,如果您启用对参数名称的反射访问,那么突然之间,您就无法在不考虑程序的其他部分可能正在使用它的情况下更改名称。更糟糕的是,除非您对所有参数名的使用都有严格的测试用例,或者您有一个非常好的静态分析器可以找到这些用例(我不知道)


这些评论链接到一个关于使用Jackson(一个JSON处理库)的问题,Jackson具有将方法参数名映射到JSON属性名的功能。这可能非常方便,但也意味着如果更改参数名,JSON绑定可能会中断。更糟糕的是,如果程序基于Java方法参数名生成JSON结构,那么更改方法参数名可能会悄悄地更改数据格式或有线协议。显然,在这样的环境中,可靠地使用此功能意味着您必须进行非常好的测试,并在代码周围添加注释,指示哪些参数名称不能更改。

这将是令人惊讶的。此处已询问,但没有回答: