[英]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
枚舉進行子類化。 例如制作一個繼承自StudentStatus
的TaskStatus
。
➥ 不,Java 中的枚舉不能被子類化。
您的 enum 定義實際上是Enum
的子類。 這發生在后台,由編譯器神奇地處理。 inheritance 停在那里。 您的枚舉定義實際上是final
,不允許進一步的子類。
枚舉定義可以實現接口。 來自多個枚舉定義的實例可以被視為同一個接口的所有對象。 請參閱Victor1125 的回答。
Java 中的枚舉是自動實例化一個或多個名稱對象的便捷方式,以表示在編譯時已知的一組有限值。 當它們的定義 class 由Java 類加載器加載時,這些實例都會出現。 這些對象保留在 memory 中。
您不能在運行時動態添加更多實例。 枚舉對象的整個域是在編譯時定義的。 (例外:一些瘋狂的扭曲反射/內省代碼可能能夠創建更多實例,但我不會 go 那里。)
如果您想要 inheritance 或動態創建的實例,請不要使用枚舉。 使用常規類和子類,收集到集合或列表中。 集合或列表可以用 generics 標記 ( < … >
) 以允許其包含元素的超類。 例如Set< Animal >
可以包含子類Dog
、 Cat
和Bird
的對象。
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.