JDK-6507006 : Add language support for abstract Enum's
  • Type: Enhancement
  • Component: specification
  • Sub-Component: language
  • Affected Version: 5.0
  • Priority: P5
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2006-12-21
  • Updated: 2011-02-16
  • Resolved: 2007-06-19
Related Reports
Duplicate :  
Relates :  
Description
A DESCRIPTION OF THE REQUEST :
This would allow developers to govern an interface for an enum to implement. I noticed that you have had a request raised in this department before (6222244) but there is no technical reasons as to why you rejected it. The request, it seems to me, was perfectly valid and did not break any contracts.

JUSTIFICATION :
By not adding this you force development to reject enum architecture and retreat to classes to accomplish the same thing. This seems non nonsensical in that   developers can work-a-round the problem, but this obviously costs in development time and the solution is less elegant.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
[public] abstract enum XYZ {
     
      //NOTE NO ENUM DEFINITIONS ALLOWED

     protected a;
     protected b;

     protected XYZ(a,b) {
     }
}

public enum BLA extends XYZ {
    ENUM1(aVal, bVal),
    ENUM2(aVal, bVal);
}


CUSTOMER SUBMITTED WORKAROUND :
[public] abstact  XYZ  {
     
     a;
     b;

     [public] XYZ(a,b) {
          this.a = a;
          this.b = b;
     }

    //and the usual getters....
}


[public] final class XYZImpl extends XYZ {
     
     [public] XYZ(a,b) {
           super(a,b);
     }
}

public class BLA {
    public static final XYZ ENUM1 = new XYZImpl(aVal, bVal);
    public static final XYZ ENUM2 = new XYZImpl(aVal, bVal);
}

Comments
EVALUATION This request is fairly reasonable on the face of it. The limitation of no enum constants in the abstract enum make it technically possible. Modifying the example from 6222244, you're asking to be able to write: abstract enum MyEnumImpl { private int value; MyEnumImpl(int value) { this.value = value; } public int getValue() { return value; } } enum MyEnum extends MyEnumImpl { MyEnum(int value) { super(value); } ONE(1), TWO(2) } enum YourEnum extends MyEnumImpl { YourEnum(int value) { super(value); } THREE(3), FOUR(4) } This looks substantially like an abstract superclass with non-abstract subclasses. However, some points would have to be considered: 1) Since the constants aren't defined in MyEnumImpl, you always have to fully qualify them with MyEnum or YourEnum. This does produce a slightly odd situation, i.e. you cannot use MyEnumImpl to get a constant itself: MyEnumImpl.ONE // Not allowed but you can use MyEnumImpl to discover the constant's underlying value: MyEnumImpl x = MyEnum.ONE; x.getValue(); 2) I wrote constructors for MyEnum and YourEnum. Your BLA enum magically has an invisible two-arg constructor which calls up to XYZ implicitly; this is not standard operating procedure. 3) Presumably, you could have a hierarchy of abstract enum declarations, each adding methods only, bottoming out with a non-abstract enum that adds constants. 4) An abstract enum, since it has no constants, would be serializable in the same way as an abstract class, whereas non-abstract enums require special handling (as all enums receive today). And there is a conceptual problem. The semantics of an enum type are defined by its constants. Two enum types with different constants have different semantics; they are really unrelated. (Whereas when an abstract superclass is extended by non-abstract subclasses, the subclasses clearly have an is-a relationship in common.) JSR201 was clear that general subtyping of enums was not going to happen, and this particular subclassing mechanism doesn't justify itself either. It may be that, sometimes, there is an opportunity to share code between enum types, but delegating to static methods is a flexible and clear way to achieve that.
03-01-2007