我想尝试一些在运行时需要参数名称的框架功能,所以我需要编译我的应用程序,-parameters它将在JVM字节代码中存储参数的名称.
除了jar/war的大小之外,这个参数用法存在哪些缺点?
Stu*_*rks 25
JEP 118涵盖了在类文件格式中添加参数名称,这是在Java 8中提供的.有一些讨论为什么在OpenJDK电子邮件线程中包含参数名称是可选的在这里和这里.简而言之,使参数名称可选的所述原因是关于类文件大小,兼容性表面和敏感信息的暴露的担忧.
兼容性问题的问题值得进一步讨论.上面链接的一个线程表示更改参数名称是二进制兼容的更改.这是事实,但仅限于JVM二进制兼容性概念的严格上下文.也就是说,更改方法的参数名称永远不会改变JVM是否可以链接该方法.但该声明并不代表一般的兼容性.
从历史上看,参数名称已被视为局部变量名称.(毕竟,它们是本地的.)您可以随意更改它们,并且方法之外的任何内容都不会受到影响.但是,如果启用对参数名称的反射访问,则突然您无法在不考虑程序的其他部分可能正在使用它的情况下更改名称.更糟糕的是,除非您对参数名称的所有使用都有严格的测试用例,否则没有任何东西可以告诉您,或者您有一个非常好的静态分析器可以找到这些情况(我不知道一个).
这些注释与使用Jackson(一个JSON处理库)的问题相关联,该问题具有将方法参数名称映射到JSON属性名称的功能.这可能非常方便,但这也意味着如果更改参数名称,JSON绑定可能会中断.更糟糕的是,如果程序基于Java方法参数名称生成JSON结构,则更改方法参数名称可能会静默更改数据格式或有线协议.显然,在这样的环境中,可靠地使用此功能意味着您必须进行非常好的测试,并在代码周围添加注释,指示不得更改哪些参数名称.
唯一的事情是 的大小.class会改变,因为字节码现在将包含更多信息:
public class DeleteMe3 {
public static void main(String[] args) {
}
private static void go(String s) {
}
}
Run Code Online (Sandbox Code Playgroud)
例如,这将包含有关参数名称的信息,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
如果没有 ,这MethodParameters根本不会出现-parameters。
可能有些框架对此不太满意。这是一个Spring Data JPA 问题。我知道这一点是因为我们前段时间遇到了它并且不得不升级(从那时起我就没有遇到过任何其他问题)。
| 归档时间: |
|
| 查看次数: |
2589 次 |
| 最近记录: |