java - 意外的 "transient"构造函数修饰符

标签 java reflection jvm

我在使用反射时发现了一件有趣的事情。我试图检索简单类的构造函数及其修饰符。

public class Test {
    public Test(Object... args) {}
}

这是检索构造函数修饰符的代码:

Class<?> clazz = Test.class;
Constructor<?>[] ctors = clazz.getDeclaredConstructors();
for (Constructor<?> ctor : ctors) {        
    int mod = ctor.getModifiers();
    /*if not package-private modifier*/
    if(mod!=0) {
        System.out.println( Modifier.toString(mod)));
    }
}

结果是:

    public transient  

如果我传递给构造函数的不是变量参数,而是数组,没问题。

public class Test {
    public Test(Object[] args) {}
}

结果是:

    public  

无论构造函数修饰符(public、protected、private)或参数类型(原始或引用)如何,都会发生同样的情况。怎么可能,而“transient”不是构造函数的有效修饰符?

最佳答案

访问修饰符在类文件中编码为位掩码。 JVM 规范根据它们是出现在方法修饰符还是字段修饰符中,为某些位分配不同的含义。位 7 (0x0080) 就是这样一个位。

For methods :

ACC_VARARGS    0x0080  Declared with variable number of arguments.

For fields :

ACC_TRANSIENT  0x0080  Declared transient; not written or read by a persistent
                       object manager.

由于您正在查看一种方法,因此该修饰符的正确解释是 ACC_VARARGS 而不是 ACC_TRANSIENT

然而,Modifier class 似乎只能处理 JVM 规范中定义的修饰符子集。因为它只需要一个 int,所以它无法区分 ACC_VARARGSACC_TRANSIENT

关于java - 意外的 "transient"构造函数修饰符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14170684/

相关文章:

java - org.springframework.web.servlet.PageNotFound noHandlerFound

c# - .NET 通用类实例 - 传递可变数据类型

java - 使用 Xmx 操作 JVM 的内存限制

java - 前后增量,无循环

java.lang.InstantiationException : can't instantiate class; no empty constructor 异常

java - quartz 调度程序 2.2.1 中的 getJobNames()

Java:运行时方法解析

scala - 如何从TypeTag或同时获取ClassTag的ClassTag?

java - JVM 的任何编译器都使用 "wide"goto 吗?

java - 为什么使用方法引用会在字节码中生成内部类?