我在使用反射时发现了一些有趣的东西。我试图检索简单类及其修饰符的构造函数。
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),都会发生同样的情况。怎么可能,而“transient”对于构造函数来说不是有效的修饰符?
答案 0 :(得分:17)
访问修饰符在类文件中编码为位掩码。 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
。