Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiletime validation of enum parameters

There is a constructor with three parameters of type enum:

public SomeClass(EnumType1 enum1,EnumType2 enum2, EnumType3 enum3)
{...}

The three parameters of type enum are not allowd to be combined with all possible values:

Example:

EnumType1.VALUE_ONE, EnumType2.VALUE_SIX, EnumType3.VALUE_TWENTY is a valid combination.

But the following combination is not valid:

EnumType1.VALUE_TWO, EnumType2.VALUE_SIX, EnumType3.VALUE_FIFTEEN

Each of the EnumTypes knows with which values it is allowed to be combined:

EnumType1 and the two others implement a isAllowedWith() method to check that as follows:

public enum EnumType1 {

VALUE_ONE,VALUE_TWO,...;

    public boolean isAllowedWith(final EnumType2 type) {
    switch (this) {
        case VALUE_ONE:
            return type.equals(Type.VALUE_THREE);
        case VALUE_TWO:
            return true;
        case VALUE_THREE:
            return type.equals(Type.VALUE_EIGHT);
        ...
    }
}

I need to run that check at compile time because it is of extreme importance in my project that the combinations are ALWAYS correct at runtime.

I wonder if there is a possibility to run that check with user defined annotations?

Every idea is appreciated :)

like image 219
SixDoubleFiveTreeTwoOne Avatar asked Oct 16 '12 15:10

SixDoubleFiveTreeTwoOne


1 Answers

The posts above don't bring a solution for compile-time check, here's mine:

Why not use concept of nested Enum.

You would have EnumType1 containing its own values + a nested EnumType2 and this one a nested EnumType3.

You could organize the whole with your useful combination. You could end up with 3 classes (EnumType1,2 and 3) and each one of each concerned value containing the others with the allowed associated values.

And your call would look like that (with assuming you want EnumType1.VALUE_ONE associated with EnumType2.VALUE_FIFTEEN) :

EnumType1.VALUE_ONE.VALUE_FIFTEEN  //second value corresponding to EnumType2

Thus, you could have also: EnumType3.VALUE_SIX.VALUE_ONE (where SIX is known by type3 and ONE by type1).

Your call would be change to something like:

public SomeClass(EnumType1 enumType)

=> sample:

SomeClass(EnumType1.VALUE_ONE.VALUE_SIX.VALUE_TWENTY) //being a valid combination as said

To better clarify it, check at this post: Using nested enum types in Java

like image 76
Mik378 Avatar answered Sep 30 '22 07:09

Mik378