0

I have an interface ServiceArgument which defines a size() promise.

public interface ServiceArgument {
    public int size ();
}

Some of my enum types implement this interface

public enum StringCode implements ServiceArgument {
    FOO,
    BAR,
    BACON,

    public int size() {
        return values().length;
    }
}

Some of my class follow a EnumService abstract class.

public abstract class EnumService {
    abstract void query (Enum<? extends ServiceArgument> e);
}

And to wrap it up, some class extends this abstract class :

public class ServiceTranslation extends EnumService implements Serializable {
/**some code and ctors and transient stuff etc **/

    @Override
    void query (Enum<? extends ServiceArgument> e) {
//line that matters :
        if (e.ordinal() >= e.size()) {
            throw InvalidStringCodeAsked();
    }
}

My problem is, I can't use e.size() at the last line, because I wouldn't use FOO.size() in my example enumeration. Is there a way to, either :

1) specialise what the query method accepts as a parameter in the concrete implementations of EnumService

2) get the concrete type of the Enum called in ServiceTranslation.query(MYSTERIOUS.ENUM), in order to be able to call ConcreteENUM.size(). or even ConcreteEnum.values().length, it's the same.

3) even filter everything that is not from the right enumerated type to throw directly a InvalidEnumeratedTypeException through method override, but i'm not familiar with multiple overriding.

4) something I didn't think of

Edit : @shmosel in the comment is right, even if I get the wrong enumeration as argument, it will never be greater than its size. No point in comparing it to its size.

Pierre-Antoine Guillaume
  • 1,047
  • 1
  • 12
  • 28
  • How would `e.ordinal() >= e.size()` ever be possible? Also, I don't see why you need each constant to return the enum size, when you could get it from `e.getClass().getEnumConstants().length`. – shmosel Apr 27 '16 at 08:42
  • In case someone gives the wrong enumerated type as argument :/ And thank you, that's a part of what I need. – Pierre-Antoine Guillaume Apr 27 '16 at 08:43
  • Not sure what you mean by "wrong enumerated type". You're comparing whichever type was passed in against *its own* enum size. It'll never fail. – shmosel Apr 27 '16 at 08:46
  • If your intent is to restrict implementations of `EnumService` to a specific enum, you'll need to parameterize the class with that type (and possibly pass in the class object for more info). For example: `abstract class EnumService & ServiceArgument> { abstract void query(T arg); } }` – shmosel Apr 27 '16 at 08:53
  • I can't understand that easily, have you any documentation on the subject ? – Pierre-Antoine Guillaume Apr 27 '16 at 08:55
  • 1
    Not really. But you can try playing with my example to get an idea. The subclass would look like this: `class ServiceTranslation extends EnumService { void query(StringCode arg) { ... } }` – shmosel Apr 27 '16 at 08:58

1 Answers1

2

How about this one?

public abstract class EnumService {
    abstract <T extends Enum<T> & ServiceArgument> void query (T e);
}

public class ServiceTranslation extends EnumService implements Serializable {
    @Override
    <T extends Enum<T> & ServiceArgument> void query (T e) {
       if (e.ordinal() >= e.size()) {
            throw InvalidStringCodeAsked();
       }
    }
}
gudok
  • 4,029
  • 2
  • 20
  • 30