枚举与其他枚举类型

时间:2018-04-08 22:36:16

标签: java generics parameters enums

我希望有一个这样的枚举:

public enum Type {
    STRING, INTEGER, BOOLEAN, LIST(Type);

    Type t;

    Type() { this.t = this; )
    Type(Type t) { this.t = t; }

}

这样我就可以为Type输入各种LIST,就像能够拨打Type.LIST(STRING)一样。这在Java中是否可行?

1 个答案:

答案 0 :(得分:1)

enum是有限的,您不能拥有未知数量的条目。所以你不能将LIST(LIST(LIST(...)))作为一个单独的Type枚举。你需要一个类,但这并不意味着你必须实例化大量的对象不一定:

可能是过早优化,但您可以使用flyweight模式来确保您不能获得Type的多个实例:

package com.example;

public final class Type {

    public enum LeafType {
        STRING,
        INTEGER,
        BOOLEAN
    }

    //Gives you the familiar enum syntax
    public static final Type STRING = new Type(LeafType.STRING);
    public static final Type INTEGER = new Type(LeafType.INTEGER);
    public static final Type BOOLEAN = new Type(LeafType.BOOLEAN);

    private final LeafType leafType;

    private final Type listType;
    private final Object lock = new Object();
    // This is the cache that prevents creation of multiple instances

    private Type listOfMeType;

    private Type(LeafType leafType) {
        if (leafType == null) throw new RuntimeException("X");
        this.leafType = leafType;
        listType = null;
    }

    private Type(Type type) {
        leafType = null;
        listType = type;
    }

    /**
     * Get the type that represents a list of this type
     */
    public Type list() {
        synchronized (lock) {
            if (listOfMeType == null) {
                listOfMeType = new Type(this);
            }
            return listOfMeType;
        }
    }

    public boolean isList() {
        return listType != null;
    }

    /**
     * If this type is a list, will return what type of list it is
     */
    public Type getListType() {
        if (!isList()) {
            throw new RuntimeException("Not a list");
        }
        return listType;
    }

    /**
     * If this type is a leaf, will return what type of leaf it is
     */
    public LeafType getLeafType() {
        if (isList()) {
            throw new RuntimeException("Not a leaf");
        }
        return leafType;
    }

    @Override
    public String toString() {
        if (isList()) {
            return "LIST(" + getListType() + ")";
        }
        return getLeafType().toString();
    }
}

用法:

简单类型:

Type string = Type.STRING;

列表:

Type stringList = Type.STRING.list();

列表清单:

Type stringListList = Type.STRING.list().list();

你永远不会遇到两个描述相同类型的Type实例的情况,例如:

Type t1 = Type.BOOLEAN.list().list().list();
Type t2 = Type.BOOLEAN.list().list().list();

System.out.println(t1 == t2 ? "Same instance" : "Not same instance");

我添加toString进行调试:

Type listListListInt = Type.INTEGER.list().list().list();
System.out.println(listListListInt);

给出:

LIST(LIST(LIST(INTEGER)))