我在使用反射时发现了一件有趣的事情。我试图检索简单类的构造函数及其修饰符。
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
) 就是这样一个位。
ACC_VARARGS 0x0080 Declared with variable number of arguments.
ACC_TRANSIENT 0x0080 Declared transient; not written or read by a persistent
object manager.
由于您正在查看一种方法,因此该修饰符的正确解释是 ACC_VARARGS
而不是 ACC_TRANSIENT
。
然而,Modifier
class 似乎只能处理 JVM 规范中定义的修饰符子集。因为它只需要一个 int
,所以它无法区分 ACC_VARARGS
和 ACC_TRANSIENT
。
关于java - 意外的 "transient"构造函数修饰符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14170684/