为什么带有可变参数的 Java 方法被标识为瞬态?

发布于 2024-10-17 01:02:35 字数 759 浏览 2 评论 0原文

我正在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

鲜肉鲜肉永远不皱 2024-10-24 01:02:35

可以在 的代码中找到某种答案javassist AccessFlag

public static final int TRANSIENT = 0x0080;
public static final int VARARGS   = 0x0080;

看起来两者具有相同的值。由于 transient 对于方法来说没有任何意义,而 varargs 对于字段来说没有任何意义,所以它们可以相同。

Modifier 类不考虑这一点是不行的。我会就此提出一个问题。它需要一个新常量 - VARARGS 和一个新方法 - isVarargs(..)。并且可以重写 toString() 方法以包含“transient/varargs”。

Sort of an answer can be found in the code of javassist AccessFlag

public static final int TRANSIENT = 0x0080;
public static final int VARARGS   = 0x0080;

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 the toString() method can be rewritten to include "transient/varargs".

╭ゆ眷念 2024-10-24 01:02:35

这看起来像是实现中的一个错误。我认为根本原因可能是 .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).

疯狂的代价 2024-10-24 01:02:35

瞬态字段的标志已在方法的上下文中重载,这意味着该方法是可变参数方法。

同样,易失性字段的标志已在方法的上下文中重载,这意味着该方法是桥接方法。

请参阅: http://java.sun.com/ docs/books/vmspec/2nd-edition/ClassFileFormat-Java5.pdf

第 118-122 页(或 PDF 文件中的 26-30 页)

更新

阅读 Modifier.java 的源代码确认该答案的第一句话(“瞬态字段的标志已超载”)。这是相关的源代码:

// Bits not (yet) exposed in the public API either because they
// have different meanings for fields and methods and there is no
// way to distinguish between the two in this class, or because
// they are not Java programming language keywords
static final int BRIDGE    = 0x00000040;
static final int VARARGS   = 0x00000080;
static final int SYNTHETIC = 0x00001000;
static final int ANNOTATION  = 0x00002000;
static final int ENUM      = 0x00004000;
static final int MANDATED  = 0x00008000;

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:

// Bits not (yet) exposed in the public API either because they
// have different meanings for fields and methods and there is no
// way to distinguish between the two in this class, or because
// they are not Java programming language keywords
static final int BRIDGE    = 0x00000040;
static final int VARARGS   = 0x00000080;
static final int SYNTHETIC = 0x00001000;
static final int ANNOTATION  = 0x00002000;
static final int ENUM      = 0x00004000;
static final int MANDATED  = 0x00008000;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文