Почему методы Java с переменными varargs определены как временные? - PullRequest
21 голосов
/ 08 февраля 2011

Я играл с Java Reflection API и заметил, что методы со списком переменных аргументов становятся временными. Почему это так и что означает ключевое слово transient в этом контексте?

Из Java Glossary, transient :

Ключевое слово в языке программирования Java, которое указывает, что поле не является частью сериализованной формы объекта. Когда объект сериализуется, значения его переходных полей не включаются в последовательное представление, в то время как значения его не переходных полей включаются.

Однако это определение ничего не говорит о методах. Есть идеи?

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Dummy {
    public static void main(String[] args) {
        for(Method m : Dummy.class.getDeclaredMethods()){
            System.out.println(m.getName() + " --> "+Modifier.toString(m.getModifiers()));
        }
    }

    public static void foo(int... args){}
}

Выходы:

main --> public static
foo --> public static transient

Ответы [ 3 ]

22 голосов
/ 08 февраля 2011

Вид ответа можно найти в коде javassist AccessFlag

public static final int TRANSIENT = 0x0080;
public static final int VARARGS   = 0x0080;

Похоже, оба имеют одинаковые значения. А поскольку transient ничего не значит для методов, тогда как varargs ничего не значит для полей, они могут быть одинаковыми.

Но класс Modifier не может не принимать это во внимание. Я бы подал вопрос об этом. Нужна новая константа - VARARGS и новый метод - isVarargs(..). И метод toString() можно переписать так, чтобы он включал «transient / varargs».

6 голосов
/ 08 февраля 2011

Это похоже на ошибку в реализации.Я думаю, что основной причиной может быть то, что бит, установленный в файле .class для переходных полей, одинаков для методов varargs (см. http://java.sun.com/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf, страницы 122 и 119).

3 голосов
/ 08 февраля 2011

Флаг для переходного поля был перегружен в контексте метода, чтобы означать, что метод является методом vararg.

Аналогично, флаг для изменчивого поля был перегружен в контексте метода, чтобы означать, что метод является мостовым методом.

См .: http://java.sun.com/docs/books/vmspec/2nd-edition/ClassFileFormat-Java5.pdf

страниц 118-122 (или 26-30 в файле PDF)

Обновление

Чтение исходного кода для Modifier.java подтверждает первое предложение этого ответа («Флаг для переходного поля был перегружен»). Вот соответствующий исходный код:

// Bits not (yet) exposed in the public API either because they
// have different meanings for fields and methods and there is no
// way to distinguish between the two in this class, or because
// they are not Java programming language keywords
static final int BRIDGE    = 0x00000040;
static final int VARARGS   = 0x00000080;
static final int SYNTHETIC = 0x00001000;
static final int ANNOTATION  = 0x00002000;
static final int ENUM      = 0x00004000;
static final int MANDATED  = 0x00008000;
...