Подтвердить что ты не робот

Неожиданный модификатор конструктора "переходный"

Я нашел интересную вещь, работая с размышлением. Я попытался получить конструкторы простого класса и их модификаторы.

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) или типа параметров (примитивный или ссылочный). Как это могло быть, тогда как "переходный" не является допустимым модификатором для конструктора?

4b9b3361

Ответ 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.