简体   繁体   English

任何扩展的通用枚举类型

[英]Generic Enum Type for anything extended

I like to make a generic enum that accepts anything.我喜欢制作一个可以接受任何东西的通用枚举。

For this example I use TaskStatus, but in the future, I like to use Generic Enum for example;对于这个例子,我使用 TaskStatus,但在未来,我更喜欢使用 Generic Enum; StudentStatus, this student status can take an id and description itself and it will convert automatically. StudentStatus,这个学生身份可以自己带一个id和描述,它会自动转换。 Moreover, iterate every object and finally automatically return.而且,迭代每一个object,最后自动返回。 Is there any chance I can make it?我有机会成功吗?

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

I'm not sure what exactly you want.我不确定你到底想要什么。 You can use interface on enum, then you can use interface as status and dont care what exactly status class is.您可以在枚举上使用接口,然后您可以将接口用作状态,而不必关心 class 究竟是什么状态。

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

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

}

student status:学生身份:

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

}

task status:任务状态:

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

generic method to find out status by id通过 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);
    }
}

example how use:示例如何使用:

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

if you use JAVA below 8:如果您使用低于 8 的 JAVA:

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

This you can use in cases, when enums has this same methods and you need common interface当枚举具有相同的方法并且您需要通用接口时,您可以使用它

Your enum is effectively final (no subclass allowed)您的枚举实际上是final的(不允许子类)

Apparently you are asking if TaskStatus enum can be subclassed.显然你在问是否可以对TaskStatus枚举进行子类化。 For example making a StudentStatus that inherits from TaskStatus .例如制作一个继承自StudentStatusTaskStatus

➥ No, enums in Java cannot be subclassed. ➥ 不,Java 中的枚举不能被子类化。

Your enum definition actually is a subclass of Enum .您的 enum 定义实际上是Enum的子类。 That happens in the background, magically handled by the compiler .这发生在后台,由编译器神奇地处理 The inheritance stops there. inheritance 停在那里。 Your enum definition is effectively final , not allowing further subclasses.您的枚举定义实际上是final ,不允许进一步的子类。

An enum definition can implement an interface .枚举定义可以实现接口 Instances from multiple enum definitions can be treated as all being objects of the same interface.来自多个枚举定义的实例可以被视为同一个接口的所有对象。 See Answer by Victor1125 .请参阅Victor1125 的回答

An enum in Java is a convenient way to automatically instantiate one or more name objects, to represent a limited set of values known at compile time. Java 中的枚举是自动实例化一个或多个名称对象的便捷方式,以表示在编译时已知的一组有限值。 Those instances all pop into existence when their definition class is loaded by the Java classloader .当它们的定义 class 由Java 类加载器加载时,这些实例都会出现。 Those objects remain in memory.这些对象保留在 memory 中。

You cannot add more instances dynamically at runtime.您不能在运行时动态添加更多实例。 The entire domain of the enum's objects is defined at compile time.枚举对象的整个域是在编译时定义的。 (Exception: Some crazy twisted reflection/introspection code may be able to create more instances, but I would not go there.) (例外:一些疯狂的扭曲反射/内省代码可能能够创建更多实例,但我不会 go 那里。)

If you want inheritance, or dynamically created instances, do not use enums.如果您想要 inheritance 或动态创建的实例,请不要使用枚举。 Use regular classes and subclasses, collected into sets or lists.使用常规类和子类,收集到集合或列表中。 The sets or lists can be marked ( < … > ) with generics to allow the superclass of their contained elements.集合或列表可以用 generics 标记 ( < … > ) 以允许其包含元素的超类。 For example Set< Animal > can contain objects of the subclasses Dog , Cat , and Bird .例如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. 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.

Tip: No need to put "Enum" within the name of your enum.提示:无需在您的枚举名称中添加“枚举”。 Endeavor to invent names for your enum class and enum objects that read naturally.努力为您的枚举 class 和自然读取的枚举对象发明名称。 The fact that they happen to be an enum should fade into the background.他们碰巧是一个枚举的事实应该消失在背景中。 For example: See Month ( Month.JANUARY ) and DayOfWeek ( DayOfWeek.MONDAY ).例如:参见Month ( Month.JANUARY ) 和DayOfWeek ( DayOfWeek.MONDAY )。

How to handle null point on StatusUtil.class如何处理 StatusUtil.class 上的 null 点

StatusUtil:状态工具:

public abstract class StatusUtil {公共抽象 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