JDK-6594685 : Parameterized enums
  • Type: Enhancement
  • Component: specification
  • Sub-Component: language
  • Affected Version: 6
  • Priority: P5
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_vista
  • CPU: x86
  • Submitted: 2007-08-20
  • Updated: 2016-11-25
  • Resolved: 2007-08-21
Related Reports
Duplicate :  
Relates :  
Description
A DESCRIPTION OF THE REQUEST :
The problem is the lack of support of generics in enums. It seems it has been omitted by accident (maybe due to limited experience with generics?) and it would be a great addition to the language. The fact that generics, as I propose it, can easily be implemented in the Typesafe Enum pattern as described in Item 21 of "Effective Java Programming Language Guide.", on which the implementation of enums in 1.5/5/tiger is based, only seems to enforce this. In any case, it is a small addition, and shouldnt involve much work nor much additional testing.


JUSTIFICATION :
As described above, it seems like a glaring ommission, and would complete the enum feature. The use cases are numerous. The workaround requires a lot of boilerplate code. The number of cases and thereby importance will only grow in time as more people move to 1.5.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
// An example of the suggested enum with generics style. It is expected to
// compile with a modified compiler. How it should work should be apparent
// from the code itself.
    
interface Packet {
    PacketType<?> getType();
}
class Talk implements Packet {
    public PacketType<Talk> getType(){
        return PacketType.TALK;
    }
}
class TalkStart<T extends Packet> implements Packet {
    public PacketType<TalkStart> getType(){
        return PacketType.TALK_START;
    }
}

public enum PacketType<T extends Packet> {
    TALK<Talk>(Talk.class), TALK_START<TalkStart>(TalkStart.class);

    private Class<T> packetClass;

    PacketType(Class<T> packetClass){
        this.packetClass = packetClass;
    }

    Class<T> getPacketClass(){
        return packetClass;
    }
}

// When compiling the enum to a class it could look like the following:
public final class PacketType<T extends Packet>
                                         extends java.lang.Enum<PacketType<T>> {
    
    // As far as I can see, the only difference would be these fields, the two
    // static methods and the constructor.
    public final PacketType<Talk> TALK = new PacketType<Talk>(Talk.class);
    public final PacketType<TalkStart> TALK_START =
                                     new PacketType<TalkStart>(TalkStart.class);
    
    public static PacketType<?> valueOf(String name) {
        // ...
    }
    
    public static PacketType<?>[] values() {
        // ...
    }
    
    // Not sure how name and ordinal is passed to the enum class constructor.
    public PacketType(Class<T> param1){
        // ...
    }
    
    // ... The rest of the compiled body should be the same as far as I can see.
}
ACTUAL -
Compile error. No need to elaborate.

---------- BEGIN SOURCE ----------
// Everything should be listed above. No compilable Java source code can be        // made.
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
A somewhat workable workaround is to create the enum by the Typesafe Enum pattern, as described in the Effective Java book (mentioned above). It would however remove all posibility of using it together with any code built using the new enum keyword although such cases are quite rare in my mind given the nature of enums. The static method valueOf(enumType, name) is however quite difficult to implement without changing all your enums to the Typesafe Enum pattern.

Comments
EVALUATION Most of the evaluation of 6408723 apply here. It is clear that certain use cases are helped by parameterized enums, but it is very unlikely that the feature will be added now.
21-08-2007