2015-09-24 3 views
3

Как я знаю, Enum это абстрактный класс, я пишу Enum, то я javap команду, я получил:Java Enum является абстрактным классом, как создать свой собственный экземпляр

public abstract class com.tonyzhai.homework.TestEnum extends java.lang.Enum<com.tonyzhai.homework.TestEnum> { 
    public static final com.tonyzhai.homework.TestEnum a; 

    public static com.tonyzhai.homework.TestEnum[] values(); 
    Code: 
     0: getstatic  #2     // Field $VALUES:[Lcom/tonyzhai/homework/TestEnum; 
     3: invokevirtual #3     // Method "[Lcom/tonyzhai/homework/TestEnum;".clone:()Ljava/lang/Object; 
     6: checkcast  #4     // class "[Lcom/tonyzhai/homework/TestEnum;" 
     9: areturn 

    public static com.tonyzhai.homework.TestEnum valueOf(java.lang.String); 

так, он не может конкретизации, мой вопрос в том, что абстрактный должен быть не имеет экземпляра, поэтому, если использование Enum реализует шаблон Singleton, как он создает свой собственный экземпляр?

+0

Это помогло бы, если бы вы указали исходный код Java ... Простой enum не создает генерации абстрактного класса, насколько мне известно. –

+2

Почему вы смотрите на выход дизассемблера java? Что такое исходный код? –

+0

экземпляры Enum в Java всегда создаются при их объявлении (это когда вызывается конструктор). –

ответ

1

Когда вы объявляете enum, компилятор заполнит определенные аспекты для выполнения контракта. Например. он добавит YourEnumType[] values() и метод YourEnumType valueOf(String).

Это также сделает ваш конструктор private, независимо от того, объявлена ​​ли вы его, и это добавит неявные int и String параметры, аргументы получить передается в супер конструктор Enum(String, int). Они соответствуют имени и порядку, а компилятор также вставляет соответствующие аргументы при создании констант.

Например:

public enum Axis { 
    HORIZONTAL(true), VERTICAL(false); 

    private boolean isHorizontal; 

    Axis(boolean horizontal) { 
     isHorizontal=horizontal; 
    } 
    public Axis getOther() { 
     return isHorizontal? VERTICAL: HORIZONTAL; 
    } 
    public static void main(String... arg) { 
     for(Method m: Axis.class.getDeclaredMethods()) 
      System.out.println(m); 
     System.out.println("constructor:"); 
     System.out.println(Axis.class.getDeclaredConstructors()[0]); 
    } 
} 

напечатает

public static void Axis.main(java.lang.String[]) 
public static Axis[] Axis.values() 
public static Axis Axis.valueOf(java.lang.String) 
public Axis Axis.getOther() 
constructor: 
private Axis(java.lang.String,int,boolean) 

Итак, вы видите компилятора добавлены методы в а также конструктор будучи private и имеющий дополнительные параметры. Обратите внимание, однако, что это зависит от компилятора, где и в каком порядке он добавляет эти два параметра. Поскольку конструктор равен private и используется только внутри самого класса, не существует требования совместимости о том, как точно работает инициализация.

Кроме того, получение Constructor рефлексивно не позволяет создавать дополнительные экземпляры. Реализация Reflection признает, что это enum и отклоняет такие попытки. Вам придется взломать глубже в реализацию, чтобы сделать такие вещи возможными, но это все равно противодействует намерению enum.

+0

Я добавляю пустой конструктор в свой Enum, тогда я отражаю и вызываю метод newInstance(), но он бросает NoSuchMethodException, он говорит, что у меня есть только enmu (String, int) constructor, но мой пустой конструктор – Tony

+0

В этом суть. У вас всегда будут два дополнительных параметра, независимо от того, как вы определили свой конструктор. Но в принципе нет никакого стандарта относительно итоговой подписи. Теоретически существуют другие возможности реализовать его на двоичном уровне. Так или иначе, вы не можете вызвать конструктор. – Holger

3

Да Enum является абстрактным, но вы не можете продлить его, за исключением особых обстоятельств, см. here для получения дополнительной информации.

+0

Все перечисления неявно расширяют 'java.lang.Enum'. –

+1

Да, вы правы, но это немного отличается от того, что делает класс, который расширяет Enum. – patrick96

Смежные вопросы