Синтетические аргументы перечисления Java для конструкторов

Пожалуйста, посмотрите на Синтетические Аргументы. Конструкторы Enum имеют два дополнительных синтетических аргумента.

Пожалуйста, посмотрите на раздел:

Другой пример: перечислимые классы Java

Как видите, он сохраняет довольно много кода, но также добавляет синтетические поля, методы и параметры конструктора. Если вы определили свой собственный конструктор с его собственным набором параметров.

Может ли возникнуть ситуация, когда конструктор enum не имеет никаких синтетических аргументов.

Извиняюсь за то, что не предоставил достаточно деталей.

3 ответа

Решение

Прочитав статью, я бы сказал, что ответ - нет. В статье объясняется, что типичные перечисления, такие как:

enum Colours {
    RED, BLUE;
}

становится:

final class Colours extends java.lang.Enum {
    public final static Colours RED = new Colours("RED", 0);
    public final static Colours BLUE = new Colours("BLUE", 1);

    private final static values = new Colours[]{ RED, BLUE };

    private Colours(String name, int sequence){
        super(name, sequence);
    }

    public static Colours[] values(){
        return values;
    }

    public static Colours valueOf(String name){
        return (Colours)java.lang.Enum.valueOf(Colours.class, name);
    }
}

где аргументы к Colours конструктор считается синтетическим (то есть он был создан компилятором, чтобы убедиться, что "все работает"). Таким образом, кажется, что синтетические аргументы неизбежны, поскольку они являются необходимой частью перевода перечисления в реальный класс.

Единственная возможность, если перечисление не имеет значений - все еще ли Java создает синтетические поля? Интуитивно, ответ да. Это подтверждается статьей в ОК, но зачем мне это беспокоиться? раздел. Здесь автор показывает, что пустое перечисление все еще имеет счетчик параметров два, если смотреть с отражением.

Проверьте исходный код класса Concurrent TimeUnit. Это перечисление со своими собственными методами. Вы можете работать с перечислениями, как если бы они были классом сами.

http://fuseyism.com/classpath/doc/java/util/concurrent/TimeUnit-source.html

Вот мой пример:

public enum ExampleEnum {
    ENUM_1 ( "ENUM_1", 1, Color.GREEN ) {
        @Override
        public void doMethingWeird( String stringToEnum ) {
            //Implementation goes here;
        }
    }, 
    ENUM_2 ( "ENUM_2", 2, Color.BLACK ) {
        @Override
        public void doMethingWeird( String stringToEnum ) {
            //Implementation goes here;
        }
    }, 
    ENUM_3 ( "ENUM_3", 3, Color.WHITE ){
        @Override
        public void doMethingWeird( String stringToEnum ) {
            //Implementation goes here;
        }
    };    //Don't forget the semicolon ';' after the enums, to separate them from the methods;

    //You can have static constants;
    private static final Object object = new Object();

    private final String enumName;
    private final int enumNumber;
    private final Color enumColor;  //why not?

    //CONSTRUCTOR IT MUST BE PRIVATE
    private Effect( String enumName, int enumNumber, Color enumColor ){
            this.enumName = enumName;
            this.enumNumber = enumNumber;
            this.enumColor = enumColor;
    }

    //you can have abstract methods and implement them on the enums.
    public abstract void public void doMethingWeird( String stringToEnum );

    public String getEnumName() {
            return enuName;
    }

    public int getEnumNumber() {
            return enumNumber;
    }

    public Color getEnumColor() {
            return enumColor;
    }
}

Я надеюсь, что помог.

Я столкнулся с той же проблемой, имея перечисление с конструкторами и параметрами дерева. Делая отражение и получая параметры конструкторов, вы получаете String и int extra в качестве первых 2 параметров. Мне было интересно, откуда они пришли. После отладки я обнаружил, что класс Enum имеет защищенный конструктор, который использует первые 2 параметра.

Я сделал тест, добавив конструктор без параметров, а также добавили 2 дополнительных параметра.

Код из Enum.java с конструктором:

/**
 * Sole constructor.  Programmers cannot invoke this constructor.
 * It is for use by code emitted by the compiler in response to
 * enum type declarations.
 *
 * @param name - The name of this enum constant, which is the identifier
 *               used to declare it.
 * @param ordinal - The ordinal of this enumeration constant (its position
 *         in the enum declaration, where the initial constant is assigned
 *         an ordinal of zero).
 */
protected Enum(String name, int ordinal) {
    this.name = name;
    this.ordinal = ordinal;
}

Чтобы обнаружить эту ситуацию, вы можете использовать метод isEnum() отраженного конструктора и пропустить 2 параметра.

Constructor<?> constructor;

private boolean isEnum() {
    return constructor.getDeclaringClass().isEnum();
}
Другие вопросы по тегам