Generi c Enum Type для любого расширенного - PullRequest
0 голосов
/ 11 июля 2020

Мне нравится создавать обобщенное c перечисление, которое принимает все что угодно.

В этом примере я использую TaskStatus, но в будущем я предпочитаю использовать Generi c Enum, например; StudentStatus, этот статус студента может принимать идентификатор и описание, и он будет преобразован автоматически. Более того, перебираем каждый объект и, наконец, автоматически возвращаемся. Есть ли шанс, что я смогу это сделать?

 @Getter
 @AllArgsConstructor(access = AccessLevel.PRIVATE)
  public enum TaskStatusEnum{
    
        READY(1, "Ready"),
        ON_GOING (2,"On going");
        
        private final long id;
        private final String description;
        
        
        public static TaskStatusEnum get (long id)
        {
            for (TaskStatusEnum status : TaskStatusEnum.values()) {
                if (status.id == id) {
                    return id;
                }
            }
            return null;
        }

Ответы [ 3 ]

2 голосов
/ 11 июля 2020

Я не уверен, что именно вы хотите. Вы можете использовать интерфейс в перечислении, затем вы можете использовать интерфейс в качестве статуса, и вам все равно, что такое класс статуса.

public interface Status<E extends Enum<E> & Status<E>> {

    public long getId();
    public String getDescription();

}

статус студента:

public enum StudentStatus implements Status<StudentStatus>{

    NEW(0, "new");

    ;

    private long id;
    private String description;

    private StudentStatus(long id, String description) {
        this.id=id;
        this.description = description;
    }

    @Override
    public long getId() {
        return id;
    }

    @Override
    public String getDescription() {
        return description;
    }

}

статус задачи:

public enum TaskStatus implements Status<TaskStatus>{

    OPEN(0, "open");

    ;

    private long id;
    private String description;

    private TaskStatus(long id, String description) {
        this.id=id;
        this.description = description;
    }

    @Override
    public long getId() {
        return id;
    }

    @Override
    public String getDescription() {
        return description;
    }
}

generi c метод определения статуса по идентификатору

public abstract class StatusUtil {

public static <E extends Enum<E> & Status<E>> E get(Class<E> statusClass, long id) {
        return Arrays.asList((E[]) statusClass.getEnumConstants())
            .stream()
            .filter(item -> item.getId() == id)
            .findAny()
            .orElse(null);
    }
}

пример использования:

public class Test {

    public static void main(String... args) {
        StudentStatus studentStatus = StatusUtil.get(StudentStatus.class, 0);
        TaskStatus taskStatus = StatusUtil.get(TaskStatus.class, 0);
    
        List<Status> statusList = Arrays.asList(studentStatus, taskStatus);
        statusList.forEach(status -> System.out.println(status.getClass().getName()+"\t"+status.getId()+"\t"+status.getDescription()));
    }
}

если вы используете JAVA ниже 8:

public interface Status<E extends Enum<E>> {

    public long getId();
    public String getDescription();

} 

statusUtil:

public abstract class StatusUtil {

    public static <E extends Enum<E>> E get(Class<E> statusClass, long id) {
    for(E item: (E[]) statusClass.getEnumConstants()) {
        if(item.getId() == id) {
            return item;
        }
    }
    return null;
}

} ​​test:

    public static void main(String... args) {
    StudentStatus studentStatus = StatusUtil.get(StudentStatus.class, 0);
    TaskStatus taskStatus = StatusUtil.get(TaskStatus.class, 0);
    
    List<Status> statusList = Arrays.asList(studentStatus, taskStatus);
    for(Status status: statusList) {
        System.out.println(status.getClass().getName()+"\t"+status.getId()+"\t"+status.getDescription());
    }
}

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

0 голосов
/ 13 июля 2020

Как обрабатывать нулевую точку в StatusUtil.class

StatusUtil:

publi c абстрактный класс StatusUtil {

 public static <E extends Enum<E>> E get(Class<E> statusClass, long id) {
    for(E item: (E[]) statusClass.getEnumConstants()) {
        if(item.getId() == id) {
            return item;
        }
    }
    return null;
}
0 голосов
/ 11 июля 2020

Ваше перечисление эффективно final (подкласс не допускается)

По-видимому, вы спрашиваете, может ли TaskStatus перечисление быть подклассом. Например, создание StudentStatus, наследуемого от TaskStatus.

➥ Нет, перечисления в Java не могут быть подклассами.

Ваше определение перечисления фактически является подклассом Enum. Это происходит в фоновом режиме, волшебным образом обрабатывается компилятором . На этом наследование заканчивается. Ваше определение перечисления фактически final, не разрешая дальнейшие подклассы.

Определение перечисления может реализовать интерфейс . Экземпляры из нескольких определений перечислений можно рассматривать как все объекты одного интерфейса. См. Ответ от Victor1125 .

Перечисление в Java - удобный способ автоматического создания экземпляров одного или нескольких объектов имени для представления ограниченного набора значений, известных во время компиляции. Все эти экземпляры появляются, когда их класс определения загружается загрузчиком классов Java . Эти объекты остаются в памяти.

Вы не можете динамически добавлять новые экземпляры во время выполнения. Весь домен объектов перечисления определяется во время компиляции. (Исключение: какой-то сумасшедший код отражения / интроспекции может создать больше экземпляров, но я бы не go там.)

Если вы хотите наследование или динамически созданные экземпляры, не используйте перечисления. Используйте обычные классы и подклассы, собранные в наборы или списки. Наборы или списки могут быть помечены (< … >) с помощью обобщений, чтобы позволить суперклассу содержащихся в них элементов. Например, Set< Animal > может содержать объекты подклассов Dog, Cat и Bird.

Кстати, теперь вы можете определить перечисление в 3 местах: собственный класс, вложенный в другой класс, и теперь в Java 16 (предварительно просмотрен в Java 15), локально внутри метода.

Совет: нет необходимости помещать «Enum» в имя вашего перечисления. Постарайтесь придумать имена для вашего класса enum и объектов enum, которые читаются естественно. Тот факт, что они оказались перечислением, должен отойти на второй план. Например: см. Month (Month.JANUARY) и DayOfWeek (DayOfWeek.MONDAY).

...