Java。在枚举中使用泛型获取特定类型

Java. Get specific type using generics in enum

这是一些使用 get() 方法的枚举。

public class ZooTest {

    public enum Animals {

        CHLOE("cat"),
        MOLLY("dog"),
        LUNA("cat"),
        TOBY("dog"),
        ZOE("parrot"),
        SNICKERS("cat");

        private final String type;

        Animals(String type) {
            this.type = type;
        }

        public class Animal {
        }

        public class Cat extends Animal {
        }

        public class Dog extends Animal {
        }

        public class Parrot extends Animal {
        }

        public Animal get() {
            return "cat".equals(type)
                    ? new Cat()
                    : "dog".equals(type)
                            ? new Dog()
                            : new Parrot();
        }
    }

    @Test
    public void shouldReturnSpecificClass() {
        assertTrue(Animals.CHLOE.get() instanceof Cat);
    }

    @Test(expectedExceptions = {ClassCastException.class})
    public void shouldReturnSpecificClass2() {
        Dog dog = (Dog) Animals.CHLOE.get();
    }
}

问题是如何在不使用枚举外部类型转换的情况下将其改进为 return 特定类型的动物。当然我可以使用像

这样的方法
public <T extends Animal> T get(Class<T> clazz) { return (T) get(); } 

但也许还有更笨拙的方法。

您可以创建一个抽象方法get,每个 Animals 实例都必须实现:

 public enum Animals {

        CHLOE("cat") {
           @Override
           public Animal get() { return new Cat(); }
        },
        MOLLY("dog") {
           @Override
           public Animal get() { return new Dog(); }
        }
        //... and so on

        public abstract Animal get();
    }

你有两个枚举使用错误。第一个枚举实体必须提供类似于类型而不是实例的东西(它如何指向 Quirliom),然后你的 Animal 枚举必须包含猫、狗等成员。不幸的是,第二个你不能扩展任何 class 来自枚举。

此答案基于以下假设:您实际上不需要 Cat 的单独实例用于 CHLOE、LUNA 或 SNICKERS。此外,由于您的 Animals 没有任何方法或状态,因此看起来您并不真的需要它们作为单独的 类。所以也许像这样的事情会更容易:

public enum AnimalType {
    Cat, Dog, Parrot;
}

public enum Animals {

    CHLOE(AnimalType.Cat),
    MOLLY(AnimalType.Dog),
    LUNA(AnimalType.Cat),
    TOBY(AnimalType.Dog),
    ZOE(AnimalType.Parrot),
    SNICKERS(AnimalType.Cat);

    private final AnimalType type;

    Animals(AnimalType type) {
        this.type = type;
    }

    public AnimalType get() {
        return type;
    }
}