[英]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.