为什么带有可变参数的 Java 方法被标识为瞬态?
我正在使用 Java Reflection API 并观察到带有可变参数列表的方法变得瞬态。为什么会这样? transient
关键字在这种情况下意味着什么?
来自 Java 术语表,瞬态:
Java 编程语言中的关键字,指示字段不是对象序列化形式的一部分。当对象被序列化时,其瞬态字段的值不包含在序列表示中,而包含其非瞬态字段的值。
然而这个定义并没有提及任何关于方法的内容。有什么想法吗?
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Dummy {
public static void main(String[] args) {
for(Method m : Dummy.class.getDeclaredMethods()){
System.out.println(m.getName() + " --> "+Modifier.toString(m.getModifiers()));
}
}
public static void foo(int... args){}
}
输出:
main --> public static
foo --> public static transient
I was playing with Java Reflection API and observed that methods with variadic argument list become transient. Why is that and what does transient
keyword mean in this context?
From Java Glossary, transient:
A keyword in the Java programming language that indicates that a field is not part of the serialized form of an object. When an object is serialized, the values of its transient fields are not included in the serial representation, while the values of its non-transient fields are included.
However this definition does not say anything about methods. Any ideas?
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Dummy {
public static void main(String[] args) {
for(Method m : Dummy.class.getDeclaredMethods()){
System.out.println(m.getName() + " --> "+Modifier.toString(m.getModifiers()));
}
}
public static void foo(int... args){}
}
Outputs:
main --> public static
foo --> public static transient
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
可以在 的代码中找到某种答案javassist
AccessFlag
看起来两者具有相同的值。由于
transient
对于方法来说没有任何意义,而 varargs 对于字段来说没有任何意义,所以它们可以相同。但
Modifier
类不考虑这一点是不行的。我会就此提出一个问题。它需要一个新常量 -VARARGS
和一个新方法 -isVarargs(..)
。并且可以重写 toString() 方法以包含“transient/varargs”。Sort of an answer can be found in the code of javassist
AccessFlag
It appears both have the same values. And since
transient
means nothing for methods, while varargs means nothing for fields, it is ok for them to be the same.But it is not OK for the
Modifier
class not to take this into account. I'd file an issue about it. It needs a new constant -VARARGS
and a new method -isVarargs(..)
. And thetoString()
method can be rewritten to include "transient/varargs".这看起来像是实现中的一个错误。我认为根本原因可能是 .class 文件中为瞬态字段设置的位与 varargs 方法相同(请参阅 http://java.sun.com/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf,第 122 和 119 页)。
This looks like a bug in the implementation. I think that the root cause might be that the bit set in the .class file for transient fields is the same for varargs methods (see http://java.sun.com/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf, pages 122 and 119).
瞬态字段的标志已在方法的上下文中重载,这意味着该方法是可变参数方法。
同样,易失性字段的标志已在方法的上下文中重载,这意味着该方法是桥接方法。
请参阅: http://java.sun.com/ docs/books/vmspec/2nd-edition/ClassFileFormat-Java5.pdf
第 118-122 页(或 PDF 文件中的 26-30 页)
更新
阅读 Modifier.java 的源代码确认该答案的第一句话(“瞬态字段的标志已超载”)。这是相关的源代码:
The flag for a transient field has been overloaded in the context of a method to mean that the method is a vararg method.
Likewise, the flag for a volatile field has been overloaded in the context of a method to mean that the method is a bridge method.
See: http://java.sun.com/docs/books/vmspec/2nd-edition/ClassFileFormat-Java5.pdf
pages 118-122 (or 26-30 in the PDF file)
Update
Reading the source code for Modifier.java confirms the first sentence of this answer ("The flag for a transient field has been overloaded"). Here's the relevant source code: