我在使用反射时发现了有趣的事情。我试图检索简单类的构造函数和它们的修饰符。
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)或形参类型(primitive或reference)如何,都是一样的。它怎么可能,而"瞬态"不是构造函数的有效修饰符? 访问修饰符在类文件中被编码为位掩码。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
类似乎只能够处理JVM规范中定义的修饰符子集。因为它只需要一个int
,所以它无法区分ACC_VARARGS
和ACC_TRANSIENT
。