Enum modernization proposal

assembling signals assembling.signals at yandex.ru
Wed Sep 16 21:03:57 UTC 2009


Hello everyone!

I want to propose an enum-enhancing feature, which would not require
any changes to the language spec and would work as a drop-in
replacement for the old pseudo-enum concept (final static int ...)

  (First of all, is this topic the right one for this mailing list?)

General benefits are:
  - Doesn't break API-compatibility: suited as drop-in replacement;
  - Not mandatory: use, if you want it (same as in the type
	annotations proposal, don't know the JSR);
  - Later improvement in usability possible by adjusting tools and
    IDEs, such as checks for legacy code concerning correctness
    of return values;
  - Whole APIs (even the whole JDK) could be enhances using one of
    these proposals.

In the following examples I use an "enum" which declares three values
( SOME_STATE_[ONE|TWO|THREE] )

What do you think of the proposals?
Is it suitable to be considered for JDK7?

Best regards, Ivan G Shevchenko, University of Essen, 2009-09-16.
-- assembling dot signals at yandex dot ru

===== old: ========================================

Declaration:

  public final static int SOME_STATE_ONE = 1;
  public final static int SOME_STATE_TWO = 2;
  public final static int SOME_STATE_THREE = 3;

Usage:

  public void setState(int state){
    System.out.println("state is: " + state);
  }

  public int getState(){
    return state;
  }

Drawbacks:
  - Types not distinguishable during runtime, not even during
    design time;
  - No validation possible.

===== proposal ONE: ========================================

Declaration:

  // CHANGE 1: Use @EnumType for declaration
  @EnumType("StateType")
  public final static int SOME_STATE_ONE = 1;
  @EnumType("StateType")
  public final static int SOME_STATE_TWO = 2;
  @EnumType("StateType")
  public final static int SOME_STATE_THREE = 3;

Usage:

  // CHANGE 2a: Use @EnumArg for argument usage
  public void setState(@EnumArg("StateType") int state){
    System.out.println("state is: " + EnumUtils.nameFor(state));
  }

  // CHANGE 2b: Use @EnumReturn for return value usage
  @EnumReturn("StateType")
  public int getState(){
    return state;
  }

Benefits:
  Using an utility API, following can be done:
  - Enum type's names may be retrieved;
  - Enum values' names may be retrieved;
  - Input arguments can be validated.

===== Proposal TWO: ========================================

Declaration:

  // CHANGE: Use a tag class
  @EnumTypeDecl
  public final class StateType { }

  @EnumType(StateType.class)
  public final static int SOME_STATE_ONE = 1;
  @EnumType(StateType.class)
  public final static int SOME_STATE_TWO = 2;
  @EnumType(StateType.class)
  public final static int SOME_STATE_THREE = 3;

Usage:

  public void setState(@EnumArg(StateType.class) int state){
    System.out.println("state is: " + EnumUtils.nameFor(state));
  }

  @EnumReturn(StateType.class)
  public int getState(){
    return state;
  }

Benefits:
  (same as proposal ONE, plus)
  - Because of the tag class, can be refactored correctly;
  - IDE-helpers such as "go to type" will work, without the need to
    change IDEs.
 
===== Proposal THREE: ========================================

Declaration:

  // CHANGE 1: Use a real enum ("adapter enum") with real enum values
  @EnumTypeDecl
  public enum StateType {
    SOME_STATE_ONE, SOME_STATE_TWO, SOME_STATE_THREE;
  }

  // CHANGE 2: Specify not only the enum type,
  // bus also real values
  @EnumType(StateType.class, StateType.SOME_STATE_ONE)
  public final static int SOME_STATE_ONE = 1;
  @EnumType(StateType.class, StateType.SOME_STATE_TWO)
  public final static int SOME_STATE_TWO = 2;
  @EnumType(StateType.class, StateType.SOME_STATE_THREE)
  public final static int SOME_STATE_THREE = 3;

Usage for legacy code (which requires API commpatibility):

  public void setState(@EnumArg(StateType.class) int state){
    System.out.println("state is: " + EnumUtils.nameFor(state));
  }

  @EnumReturn(StateType.class)
  public int getState(){
    return state;
  }

// CHANGE 3:
Usage for new code:

  public void setState(StateType state){
    System.out.println("state is: " + state);
  }

  public StateType getState(){
    return state;
  }
  
Benefits:
  (same as proposal TWO, plus)
  - New code, using a legacy API "just works" as usual, using the
    adapter enum;
  - Utility API could provide even more convenience when using legacy
    APIs, now that enum values are also named.



More information about the core-libs-dev mailing list