简体   繁体   中英

Java enum instances with different number of arguments

Is there any way by which I can have an Enum in Java to accept different number of arguments so as to achieve this without using varargs.

public enum ValueType {
    LITERAL() {
        @Override
        String getRepresentation(String... args) {
            return MvelStringUtil.representAsLiteral(args[0]);
        }
    },

    NUMBER() {
        @Override
        String getRepresentation(String... args) {
            return args[0];
        }
    },

    //converts a string representation of a date to a java.util.Date representation, because this is what is required
    DATE() {
        @Override
        // should have two params, 1- date in string, 2- format of the passed string
        String getRepresentation(String... args) {
            // DateUtil.parse accepts dateInString and dateFormat.
            return DateUtil.parse(args[0], args[1]).toString();
        }
    };

    abstract String getRepresentation(String... args);
}

Here, LITERAL and NUMBER accept only one argument, that is, the target value, whereas the DATE instance accepts two. I went through several questions only to find out that this cannot be achieved using Generics since enums do not really support Generics upto that extent.

Also, from a design perspective could I just not have all the types in an Enum rather have them in a class with some workarounds, keeping in mind that this ValueType instance needed to be unmarshalled from a json and getRepresentation method would be called on the unmarshalled enum instance to get the actual representation of the target value.

This is not possible because LITERAL, NUMBER and DATE conform to the interface of the enum ValueType. If it were possible, type safety would be violated here:

LITERAL()
{
    @Override
    String getRepresentation(String args) {
        return MvelStringUtil.representAsLiteral(arg);
    }
}    
...
ValueType x = ValueType.LITERAL;
x.getRepresentation("a","b"); // the compiler could not know whether this is syntactically correct

As other answers say, it is not possible. Goal is to make sure you won't get wrong number of arguments for given type, so that bugs in calling code will be apperent soon, right?

I'd go with simple validation in each getRepresentation method implementation. Check the array length and throw exception if incorrect .

That way validity rules are kept close to the subject, which is readable. You won't know mistakes at compile time, but at least you'll know them early in runtime.

Ad design perspective - I'd keep enum. Ammount of types is limited, known at compile time and from quick inspection of the enum everyone will know what possibilities are there...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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