Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inner class for each member of enum?

Not sure if what I want is possible but I am trying to create an enum in which each member has its own inner class. These inner classes will all have the same name Context but will be implemented individually.

Ideally I would like them to be usable as such:

private handleType (MyEnum type) {
    switch (type) {

        case ENUM_VAL1:
            MyEnum.ENUM_VAL1.Context context = new MyEnum.ENUM_VAL1.Context();
            handleContext1(context);
            break;

        case ENUM_VAL2:
            MyEnum.ENUM_VAL2.Context context = new MyEnum.ENUM_VAL1.Context();
            handleContext2(context);
            break;

        case ENUM_VAL3:
            MyEnum.ENUM_VAL3.Context context = new MyEnum.ENUM_VAL1.Context();
            handleContext3(context);
            break;

        default:
            break;
}

Open to other way of implementing this. But basically I need a switchable enum where each member has a "value" (1,2,3...) and also a means of associating said enums with a unique class with constructor.

EDIT: Some background. This is to be used between two services who communicate via JSON http requests. The requests will contain some metadata, one field of which is an integer that maps to the enum. The context is a POJO, but is different for each ENUM_VALUE. Essentially, the context will be constructed and serialized into JSON. This json will effectively be just a String field called context within the top level json request. On the receiving service, there will be a switch on ENUM_VALUE, where the context is decoded appropriately and then dispatched to its appropriate handler.

EDIT2: This enum will be shared between the two services.

EDIT3: Here is a more explicit explanation of what I am attempting to do.

MyServiceRequest:

public class MyServiceRequest {
    String meta1;
    String meta2;
    int typeID;
    String context;
}

generating request:

MyServiceRequest req = new MyServiceRequest();
req.meta1 = ...
req.meta2 = ...
req.typeID = MyEnum.ENUM_VALUE.getCode(); // int

MyEnum.ENUM_VALUE.Context context = new MyEnum.ENUM_VALUE.Context(); // factory would be fine as well
... // populate context
req.context = toJSON(context);
requestJSON = toJSON(req);
post(requestJSON);

decoding request:

MyServiceRequest req = ...
MyEnum type = new MyEnum(req.typeID);
switch(type) {
    case ENUM_VALUE:
        MyEnum.ENUM_VALUE.Context context = fromJSON(req.context, MyEnum.ENUM_VALUE.Context.class);
        doSomething(context);
like image 606
thedarklord47 Avatar asked Nov 09 '17 19:11

thedarklord47


People also ask

Can an enum be an inner class?

Yes, we can define an enumeration inside a class. You can retrieve the values in an enumeration using the values() method.

How do enums work internally?

Each enum constant becomes a static final constant within that class. Then, an array $VALUES is created with all of the enum constants, in order of declaration. You can disassemble the code using the command javap -p -c Ordinals (on the compiled . class file) to find out the details.

What is inside enum?

An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it. Common examples include compass directions (values of NORTH, SOUTH, EAST, and WEST) and the days of the week.

Can inner class have static members?

Inner Classes As with instance methods and variables, an inner class is associated with an instance of its enclosing class and has direct access to that object's methods and fields. Also, because an inner class is associated with an instance, it cannot define any static members itself.


1 Answers

One think you could do instead is have your enum implement Supplier<Context>. Now each item would have to declare a get() method to create the individual Context sub type.

enum MyEnum implements Supplier<Context>{
   FOO{ @Override public Context get(){ return new FooContext(); } },
   BAR{ @Override public Context get(){ return new BarContext(); } }
}

which would make your client code much simpler:

private void handleType (MyEnum type) {
    handleContext(type.get());
}
like image 130
Sean Patrick Floyd Avatar answered Oct 08 '22 07:10

Sean Patrick Floyd