意外的"瞬态"构造函数修饰符

Gra*_*ade 11 java reflection jvm

我在使用反射时发现了一些有趣的东西.我试图检索简单类及其修饰符的构造函数.

public class Test {
    public Test(Object... args) {}
}
Run Code Online (Sandbox Code Playgroud)

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

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)));
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是:

    public transient  
Run Code Online (Sandbox Code Playgroud)

如果我传递给构造函数不是变量参数,而只是数组,那没关系.

public class Test {
    public Test(Object[] args) {}
}
Run Code Online (Sandbox Code Playgroud)

结果是:

    public  
Run Code Online (Sandbox Code Playgroud)

无论构造函数修饰符(public,protected,private)或参数类型(基元或引用)如何,都会发生相同的情况.怎么可能,而"transient"对构造函数来说不是有效的修饰符?

NPE*_*NPE 17

访问修饰符在类文件中编码为位掩码.JVM规范为某些位赋予不同的含义,具体取决于它们是出现在方法修饰符还是字段修饰符中.位7(0x0080)就是这样一个位.

对于方法:

ACC_VARARGS    0x0080  Declared with variable number of arguments.
Run Code Online (Sandbox Code Playgroud)

对于字段:

ACC_TRANSIENT  0x0080  Declared transient; not written or read by a persistent
                       object manager.
Run Code Online (Sandbox Code Playgroud)

既然你正在寻找一种方法,这种改性剂的正确解释是ACC_VARARGS,不ACC_TRANSIENT.

但是,Modifier该类似乎只能处理JVM规范中定义的修饰符子集.因为所需要的只是一个int,它无法区分ACC_VARARGSACC_TRANSIENT分开.