Неожиданный модификатор конструктора "переходный"
Я нашел интересную вещь, работая с размышлением. Я попытался получить конструкторы простого класса и их модификаторы.
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) или типа параметров (примитивный или ссылочный). Как это могло быть, тогда как "переходный" не является допустимым модификатором для конструктора?
Ответы
Ответ 1
Модификаторы доступа кодируются как битовые маски внутри файла класса. Спецификация 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
.