4

I stumbled over the following problem that i can't extend and implement from this class which is defined in Java 1.5 (java.lang package)

public abstract class Enum<E extends Enum<E>> {...
}..

The problem i have is to create my own enum type which has different ordinal values. I don't want to implement it by using different name of ordinal like getCode() etc. So i thought i could go the way to extend the above class.

public final class XYZ extends Enum<XYZ> { //Does not work.
  //
  A("A", 1),
  B("B", 7);
  .
}

I know that i can do the following:

public enum NEWEnum {
   A(1),
   B(7);

   private int code;
   private NEWEnum(int code) {
     this.code = code;
   }
   public int getCode() {
     return this.code;
   }
}

I would prefer to have the usual namings in Enum's like ordinal() and name() instead.

khmarbaise
  • 92,914
  • 28
  • 189
  • 235
  • @RayToal I know that `ordinal` and `name` are final. The problem is why can't i extend from the Enum class above..if i could extend i should be able to call the protected constructor which has the parameter for `name` and `ordinal`. – khmarbaise Apr 10 '12 at 08:24

5 Answers5

5

You can't extend Enum like that. It's built in to the compiler, or the runtime (not sure which).

But it looks like you're trying to solve the wrong issue; the ordinal of an enum value is not supposed to have any functional meaning. As soon as you give it one, it should have a different name than 'Ordinal'. Your second code snippet is far superior to your first one.

In general, relying on ordinal for anything is bad practice; it probably never should've been exposed in the first place. The only thing you can rely on is the name, and any value you assign yourself.

If it's that important to you to name your field 'ordinal', just use the typesafe enum pattern (item 21), which Enum is just an implementation of.

Joeri Hendrickx
  • 16,947
  • 4
  • 41
  • 53
  • I know that it is bad practice to rely on ordinal() but i have legacy code and i have to cope with it. So i have to go the enum pattern. – khmarbaise Apr 10 '12 at 08:37
4

Enum gets special treatment by the compiler and classes like EnumSet make assumptions based on this treatment. The behavior of Enum methods like ordinal() and name() is strictly defined and implementing them yourself to replicate this behavior makes no sense. Also the syntax to declare enum values is only valid in an enum and wont compile in a class.

It is important to remember that you should never use ordinal() yourself, so defining it to suit your problem makes no sense.

josefx
  • 15,506
  • 6
  • 38
  • 63
  • I don't want to implement ordinal() neither name() new. I just wan't to be able to extend from the abstract Enum class which seemed to be impossible. The problem with ordinal() is that i have legacy code which i have to be compatible with. I wan't to get rid of the ordinal() but currently i have no chance. – khmarbaise Apr 10 '12 at 08:35
  • @khmarbaise the only way to get a concrete ordinal() value in java is to sort your enum values and maybe add filler values - first value 0 then 1, ... (this is the reason why nobody should use ordinal() directly). The only other way would be to modify the resulting bytecode after compilation with something like ASM or BCEL(never did it myself and likely complicated). – josefx Apr 10 '12 at 08:47
1

The Enum class is special in Java, as it is used to implement the Enum language feature. Thus it is not just a class like any other class in Java, but more special (like String, for which the + operator is overloaded, or like the boxed classes). For these features to work, special requirements are needed for enums (like, I guess, consecutive ordinals). Thus the Java Language Specification explicitly forbids manually inheriting from the Enum class.

Philipp Wendler
  • 11,184
  • 7
  • 52
  • 87
0

Enums have a special meaning in the language core and special uses. Thus you can use them in switch statements, which isn't possible with normal classes.

Thomas
  • 87,414
  • 12
  • 119
  • 157
0

For example,if you implement it explicitly, you don't have to init the property of "name" and "ordinal" in your constructor. It may cause NPE later.

Anderson
  • 2,496
  • 1
  • 27
  • 41