21

我正在使用 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
4

3 回答 3

21

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

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

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

Modifier但是班级不考虑这一点是不行的。我会提出一个关于它的问题。它需要一个新的常数——VARARGS和一个新的方法—— isVarargs(..)。并且toString()可以重写该方法以包括“瞬态/可变参数”。

于 2011-02-08T18:31:39.463 回答
6

这看起来像是实现中的一个错误。我认为根本原因可能是 .class 文件中为瞬态字段设置的位对于 varargs 方法是相同的(请参阅http://java.sun.com/docs/books/jvms/second_edition/ClassFileFormat-Java5。 pdf,第 122 和 119 页)。

于 2011-02-08T18:30:40.830 回答
4

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

同样,易失性字段的标志在方法的上下文中已被重载,以表示该方法是桥方法。

请参阅: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;
于 2011-02-08T18:47:31.707 回答