简体   繁体   English

如何指定枚举构造函数

[英]How to specify enum constructor

At present I have a class called TestEnum . 目前,我有一个名为TestEnum的类。 In my main method I can work with firstEnum and secondEnum without needing to specify that firstEnum belongs to GroupA and secondEnum belongs to GroupB - the code in TestEnum sorts this out. 在我的main方法,我可以工作firstEnumsecondEnum而无需指定firstEnum属于GroupAsecondEnum属于GroupB -代码TestEnum排序了这一点。

Suppose that either firstEnum or secondEnum could be associated with any of the three SubGrouping enum . 假设firstEnumsecondEnum可以与三个SubGrouping enum任何一个关联。 I want to be able to make this association from within my main method. 我希望能够从我的main方法中进行这种关联。 It is clear I can't use the same approach as with Grouping since GroupA is allocated to firstEnum from within TestEnum . 很明显,我不能使用相同的方法与Grouping ,因为GroupA被分配到firstEnum从内部TestEnum

public enum TestEnum {
    firstEnum (Grouping.GroupA),
    secondEnum (Grouping.GroupB);


    private Grouping group;
    TestEnum(Grouping group) {
        this.group = group;
    } 

    public enum Grouping {
        GroupA, GroupB;
    }
    public enum SubGrouping {
        SubGroup1, SubGroup2, SubGroup3;
    }
}

How do I do this? 我该怎么做呢? To be more concrete, it would be good to construct an object such as: 更具体地说,构造一个对象,如:

TestEnum enumWithinMainMethod = TestEnum.firstEnum(SubGrouping.SubGroup1)

The desired behaviour of this instance is that it belongs to both SubGroup1 as well as GroupA . 这种情况下的期望的行为是属于两个SubGroup1以及GroupA Then from such an instance it would be good to have the functionality, for example: 然后从这样的实例中,最好具有功能,例如:

switch(enumWithinMainMethod) {
    case firstEnum:
        // Do something associated with firstEnum
    case secondEnum:
        // Do something associated with secondEnum
    default:
        // ...
}

Double think before going this approach. 在采用这种方法之前,请三思。 Enum is aimed to be static, constant and with finite set of values. 枚举的目的是静态的,固定和有限的价值观。 What you are doing here is making Enum no longer constant (as you are changing/initializing it in runtime). 您在这里所做的就是使Enum不再恒定(因为在运行时更改/初始化它)。

I believe there are other way to do, for example, review if it is actually required to have the relationship determined in runtime? 我认为还有其他方法可以执行,例如,检查是否确实需要在运行时确定关系? Can't it be defined in compile-time? 不能在编译时定义它吗? You may also having a TestEnum-to-SubGroup map, instead of dynamically construct the content of TestEnum. 您可能还具有一个TestEnum-to-SubGroup映射,而不是动态构造TestEnum的内容。

Anyway, although it is not preferable, it is technically possible in Java. 总之,虽然它是不可取的,在技术上可以在Java中。

Of course you cannot delay the "construction" of enum until your main() logic, but you can have enum constructed as normal, and change the internal state. 当然,你不能耽误枚举的“建设”,直到你的main()的逻辑,但你可以有枚举构造正常,改变内部状态。

// Mind the naming convention
public enum TestEnum {
    FIRST_ENUM(Grouping.GROUP_A),
    SECOND_ENUM (Grouping.GROUP_B);


    private Grouping group;
    private SubGrouping subGrouping;

    TestEnum(Grouping group) {
        this.group = group;
    } 

    public void setSubGrouping(SubGrouping subGrouping) {
        this.subGrouping = subGrouping;
    }

    public enum Grouping {
        GROUP_A, GROUP_B
    }

    public enum SubGrouping {
        SUB_GROUP_1, SUB_GROUP_2, SUB_GROUP_3;
    }
}

Then in your main() , do something like 然后在您的main() ,执行类似

TestEnum.FIRST_ENUM.setSubGrouping(TestEnum.SubGrouping.SUB_GROUP_1);
TestEnum.SECOND_ENUM.setSubGrouping(TestEnum.SubGrouping.SUB_GROUP_2);

By doing so, you can define the subgrouping of your enum in your main() 这样,您可以在main()定义枚举的子分组。

Once again, this is NOT PREFERABLE. 再一次,这是不可预测的。

You cannot call enum constructors from outside of an enum . 你不能调用enum从外部构造enum You could use a class to get this behaviour. 您可以使用一个类来获取此行为。

How about something like this? 这样的事情怎么样? (The generics are not required, but it does open up the Groupable class to multiple types of groupings.) (不是必需的泛型,但它确实将Groupable类开放给多种类型的分组。)

public enum Grouping { GroupA, GroupB; }
public enum SubGrouping { SubGroup1, SubGroup2, SubGroup3; }
public class SubGroupable<G extends Enum<G>,S extends Enum<S>> {
    private G mainGroup;
    private S subGroup;
    public Groupable(G group, S subGroup) {
        this.mainGroup = group;
        this.subGroup = subGroup;
    }
    public G getGroup() { return mainGroup; }
    public S getSubGroup() { return subGroup; }
}

Usage 用法

SubGroupable<Grouping, SubGrouping> g 
        = new SubGroupable<>(Grouping.GroupA, SubGrouping.SubGroup2);
switch (g.getGroup()) {
case Grouping.GroupA: 
    //
    break;
case Grouping.GroupB:
    //
    break;
}

You could also create two final groupings: 您还可以创建两个最终分组:

public final Grouping FIRST_GROUP = Grouping.GroupA;
public final Grouping SECOND_GROUP = Grouping.GroupB;

This way you can use those constants in your case blocks. 这样,您可以在case块中使用这些常量。

switch (g.getGroup()) {
case FIRST_GROUPING: // etc
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM