簡體   English   中英

任何擴展的通用枚舉類型

[英]Generic Enum Type for anything extended

我喜歡制作一個可以接受任何東西的通用枚舉。

對於這個例子,我使用 TaskStatus,但在未來,我更喜歡使用 Generic Enum; StudentStatus,這個學生身份可以自己帶一個id和描述,它會自動轉換。 而且,迭代每一個object,最后自動返回。 我有機會成功嗎?

 @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;
        }

我不確定你到底想要什么。 您可以在枚舉上使用接口,然后您可以將接口用作狀態,而不必關心 class 究竟是什么狀態。

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;
    }
}

通過 id 查找狀態的通用方法

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()));
    }
}

如果您使用低於 8 的 JAVA:

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

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

} 

狀態工具:

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;
}

} 測試:

    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());
    }
}

當枚舉具有相同的方法並且您需要通用接口時,您可以使用它

您的枚舉實際上是final的(不允許子類)

顯然你在問是否可以對TaskStatus枚舉進行子類化。 例如制作一個繼承自StudentStatusTaskStatus

➥ 不,Java 中的枚舉不能被子類化。

您的 enum 定義實際上是Enum的子類。 這發生在后台,由編譯器神奇地處理 inheritance 停在那里。 您的枚舉定義實際上是final ,不允許進一步的子類。

枚舉定義可以實現接口 來自多個枚舉定義的實例可以被視為同一個接口的所有對象。 請參閱Victor1125 的回答

Java 中的枚舉是自動實例化一個或多個名稱對象的便捷方式,以表示在編譯時已知的一組有限值。 當它們的定義 class 由Java 類加載器加載時,這些實例都會出現。 這些對象保留在 memory 中。

您不能在運行時動態添加更多實例。 枚舉對象的整個域是在編譯時定義的。 (例外:一些瘋狂的扭曲反射/內省代碼可能能夠創建更多實例,但我不會 go 那里。)

如果您想要 inheritance 或動態創建的實例,請不要使用枚舉。 使用常規類和子類,收集到集合或列表中。 集合或列表可以用 generics 標記 ( < … > ) 以允許其包含元素的超類。 例如Set< Animal >可以包含子類DogCatBird的對象。

By the way, you can now define an enum in 3 places: its own class, nested within another class, and now in Java 16 (previewed in Java 15), locally inside a method.

提示:無需在您的枚舉名稱中添加“枚舉”。 努力為您的枚舉 class 和自然讀取的枚舉對象發明名稱。 他們碰巧是一個枚舉的事實應該消失在背景中。 例如:參見Month ( Month.JANUARY ) 和DayOfWeek ( DayOfWeek.MONDAY )。

如何處理 StatusUtil.class 上的 null 點

狀態工具:

公共抽象 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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM