pauljwilliams
pauljwilliams

Reputation: 19225

Nesting enums in Java

I want to nest some enums. The object i'm representing are Flags, with a type, and a value. There are a discrete number of types, and each type has a distinct set of possible values.

So if Type A can have values 1, 2 or 3, and Type B can have values 4,5,6, I'd like to be able to do things like:

Flag f = Flag.A.1;

f.getType() - returns "A"

f.getValue() - returns "1"

Flag f2 = Flag.A.4; -- Syntax error.

I'm driving myself crazy trying to nest enums within enums - is what i'm trying possible - do I need to ditch enums altogether and handcraft a static class with static members?

My best effort so far is:

public class Flag {

    enum A extends Flag {
        ONE("ONE"),
        TWO("TWO"),
        THREE("THREE");

        private A(String value) {
            Flag.type = "A";
            Flag.value = value;
        }
    }

        private static String type;
        private static String value;
}

But if I do:

Flag f = Flag.A.ONE;

The types are incompatible.

Upvotes: 11

Views: 11668

Answers (3)

Rostislav Matl
Rostislav Matl

Reputation: 4543

As I understand enums, they are kind of singletons. It means enum X {A,B} has two singleton instances A,B. If you had nested enum A { P, Q }, how you can say if X.A is X.A.P or X.A.Q ? I wish I was able to say it more simply.

Use static class.

Upvotes: 1

Michael Borgwardt
Michael Borgwardt

Reputation: 346260

Nesting enums is not possible. But enums can implement interfaces. Why not have A and B as two different enums that both implement a TypedEnum interface with getType() and getValue() methods?

Upvotes: 3

Peter Lawrey
Peter Lawrey

Reputation: 533492

You cannot have a number as an enum. It has to be an identifier.

You can do this

interface Flag {
    String getType();
    int getValue();
    enum A implements Flag{
        one, two, three;
        String getType() { return getClass().getSimpleName(); }
        int getvalue() { return ordinal()+1; }
    }
    enum B implements Flag{
        four, five, six;
        String getType() { return getClass().getSimpleName(); }
        int getvalue() { return ordinal()+4; }
    }
}

Flag f = Flag.A.one;

However a simpler option may be

enum Flag {
    A1, A2, A3, B4, B5, B6;
    public String getType() { return name().substring(0,1); }
    public int getValue() { return name().charAt(1) - '0'; }
}

Flag f = Flag.A1;

Upvotes: 12

Related Questions