|
Comments
|
Submitted On 03-JAN-2001
Deca15
I don't think Java should be changed for this. You can
create something as good or better than a C enum using Java
classes ... the previous author's Workaround should not be
derided, it should be embraced.
Submitted On 04-JAN-2001
M.R.Atkinson
As for implementation:
enum Location { NORTH, SOUTH, WEST, EAST };
can be automagically translated by the java compiler into
the equivalent in the class file of:
interface Location {
static final int NORTH = 0;
static final int SOUTH = 1;
static final int WEST = 2;
static final int EAST = 3;
}
with an extra bit set to say that it is really an enum. This is compatible with
existing JVMs and compilers, so that enumerated types in class files can be
backwards-compatibly used with old compilers. When the enum aware compiler
sees an interface with this bit set it knows to treat it like an enum.
The compiler would translate code like:
Location position = NORTH;
position = Location.enumof(val);
switch (position) {
case EAST: break;
default:
}
into code like:
int position = Location.NORTH;
position = (val<0 || val>3) ? throw new EnumerationError("Enumeration out of range") : val;
switch (position) {
case 3: break;
default:
}
Submitted On 08-JAN-2001
scottganyo
NO NO NO NO. Instead of messing around with useless stuff
like this, put effort into generics and C#-like "boxing"
and "unboxing" of primitives!
Submitted On 08-JAN-2001
jtr
I won't vote for this, but I do believe it would be a good idea
to add a standard enum class (or set of classes with an interface)
to the core API. There needs to be an easy way to create an enumerated
type so new code, especially the Java APIs will start using them.
Note that this does not require a language change, just another utility class
along the lines of Observer, HashMap, and List.
Submitted On 10-JAN-2001
bohuslavroztocil
I recommend Pascal enums (which are NOT masquaraded ints)
rather then C++ ones. Classic Java workarounds are either
too heavy (classes) or not type-safe (int "constants"). I
miss enums very hard.
Submitted On 10-JAN-2001
jtr
If you have an aversion to adding the kitchen sink into
the JLS, but still want a standard way of expressing
enumerated types, vote for bug 4403347.
Submitted On 14-JAN-2001
martinpaulo
Please add enums - I used to work with Delphi, and found
Pascal enums to be a huge time saver. Using the class
declaration work around is exactly what it says - a work
around for a deficiency in the language.
Submitted On 15-JAN-2001
fmarx2000
I think Java should have Enums (typesafe) like C.
I think it is very usefull to have things like this, at the
moment we are allways running into this problem.
With enum's you can have constructs like:
enum Color {red,green,blue}
Color c = red; // ok
Color c = yellow; // not ok
you cannot have this with public final static int members
of classes.
So I think enum's are a good thing in JAVA for the future.
Submitted On 15-JAN-2001
ebdon99
The typesafe enum pattern used as a workaround does not
allow for a switch statement. A good reason to add
enumerated types and avoid the public static final int mess.
Submitted On 16-JAN-2001
meangene
The beauty of (most things) in Java is that it lets you
think about your work, your application, your business
logic without having to spend lots of time thinking about
the language and weird programming issues. Looking at
the workarounds for enums should make it clear to anyone
that a simpler solution should be found. I vote for enums.
damn the religious purists. And then lets move on to
boxing and unboxing of primitives!
Submitted On 25-JAN-2001
hwc
"enums are a valuable feature": agreed
"creaping featurism" is to be avoided: agreed
So we all end up implementing our own enum
using the design pattern mentioned in the RFE.
I agree with JTR: surely Sun can provide a
suitable base class, including toString etc.
Of course, this would be even more useful if
the language was changed to allow objects in
switch statements.
Submitted On 26-JAN-2001
schapel
Let me get this straight, hwc. You agree creaping featurism
is to be avoided, and yet you want to allow non-constant
values in switch statement labels in order to support an
enum API?
Instead of adding an awkward enum API, then adding language
features in order to make the awkward API more useful, let's
actually avoid the creaping featurism and simply add enums
to the Java language. If done correctly, they'd combine the
simplicity and speed of static final ints with the type
safety of proprietary enum classes.
Of course, those who disagree and want an enum API instead
can go and vote for bug 4403347.
Submitted On 30-JAN-2001
jarrodhroberson
Why waste time with this when you can just implement a
TypeSafeEnum class as listed below and move on to something
really useful like typesafe collections. Below this class
is an example on how to extend it. You get an int value, a
way to look them up, you can even add an iterator to list
them out or whatever.
Don't vote for this one.
import java.util.*;
import java.io.Serializable;
/**
* This is the abstract base class that all type safe Enums
inherit from.<p> this should never be instantiated
itself.<p>
* all custom enums should extend this class and provide
custom implemenations over this basic functionality
* @author jroberson
*/
abstract public class Enum implements Comparable,
Serializable
{
/** this is the name of the enum that is returned by
the toString function that is overridden */
private String name;
/** this constructor is protected so that only sub-
types can call it.<p> */
protected Enum( String name )
{
this.name = name;
}
/** this returns the name and the ordinal position of
the enum. */
public String toString()
{
return "NAME: " + this.name + " ORDINAL: "
+ this.getOrdinal();
}
/** accessor function to return the ordinal for a
instance of an enum */
public abstract int getOrdinal();
/** accessor function to return the name for an
instance of an enum */
public String getName()
{
return this.name;
}
/** support for the comparable interface */
public int compareTo( Object o )
{
int result = 0;
if ( ( ( Enum )o ).getOrdinal() ==
this.getOrdinal() )
{
result = 0;
}
else if ( ( ( Enum )o ).getOrdinal() >
this.getOrdinal() )
{
result = 1;
}
else if ( ( ( Enum )o ).getOrdinal() <
this.getOrdinal() )
{
result = -1;
}
return result;
}
public int hashCode()
{
return this.getOrdinal();
}
}
and an implementation extending this.
import java.util.*;
/**
* this represents all the United States states and
territories and their associated data.<p>
* this object allows for static data such as this to
reside natively in the code and reduces round trips to the
persistance
* mechanisim.<p> more importantly it allows for type safe
parameter passing without an explosion of objects.
* @author jroberson
*/
public class UnitedStatesEnum extends Enum
{
/** this holds the next ordinal sequence number
that is incremented each time a new enum is defined and
allocated. */
private static int nextOrdinal = 0;
/** this holds the ordinal sequence number for the
current instance of a given enum */
private final int ordinal = nextOrdinal++;
private String abbreviation;
private static HashMap statesByAbbrev = new HashMap
(55);
private static HashMap statesByName = new HashMap
(55);
public static UnitedStatesEnum getByAbbreviation
(String abbreviation)
{
return (UnitedStatesEnum)statesByAbbrev.get(
abbreviation.trim().toUpperCase() );
}
public static UnitedStatesEnum getByName( String
name )
{
return (UnitedStatesEnum)statesByName.get(
name.trim().toUpperCase() );
}
protected UnitedStatesEnum( String name, String
abbreviation )
{
super( name );
this.abbreviation = abbreviation;
UnitedStatesEnum.statesByAbbrev.put(
this.getAbbreviation(), this );
UnitedStatesEnum.statesByName.put(
this.getName(), this );
}
public int getOrdinal()
{
return this.ordinal;
}
public String getAbbreviation()
{
return this.abbreviation;
}
public static final UnitedStatesEnum
ALABAMA = new UnitedStatesEnum
( "ALABAMA", "AL" );
public static final UnitedStatesEnum
ALASKA = new UnitedStatesEnum
( "ALASKA", "AK" );
Submitted On 30-JAN-2001
hwc
I had in mind static final references to objects but you are right, these
are not constants to the compiler, even though they are at run time.
> You can vote for bug 4276296 if you still think it would be useful,
> though...
Which makes the same mistake!
Submitted On 01-FEB-2001
wwk_killer
jarrodhroberson, you think it is useful??? Or efficient???
I doubt it:
ResultSet rs = "select * from customer"; // 1 000 000
records
while( rs.next()) {
UnitedStatesEnum state = Xlate( rs.getString( 2));
switch( state) { // business logic
case NY:
case WA:
case CA:
// special cases
case ...
}
}
Submitted On 11-FEB-2001
kamtsa
jarrodhroberson, with all the respect, how can you compare
that monster to Pascal style enums (not to mention runtime
efficiency since).
Submitted On 12-FEB-2001
AlecC
I don't think that the enum in its pure, as opposed to its
C/C++ form, is mere syntactic sugar. The problem is the
assumption that enums sit on top of integers - which is
what they do in C/C++.
The Enumeration is actually a much lower level Computer
Science entity. It lies *under* ints, not above them. I.e
the concepts of first, second and third are deeper concepts
than those of 1, 2, and 3, which are essentially the
intervals in the former series. It would be more correct to
describe the integer type and operators as syntactic sugar
on the underlying enumaration class.
Just as all Objects extend java.lang.Object, all
Enumerations should extend java.lang.Enumeration, which
encapsulates the null list of values. This could then be
extended by users, and re-extended by other users. The
underlying implementation might be integer but should be
invisible to the user.
The boolean operators for enumerations are obvious - the
usual set. It is debatable what operators would be allowed.
In the simplest case, no operators are needed. I view the
Pacal pred() and succ() as either too little or too much.
If operators are allowed, they should include + and - of
integers i.e. step-by-two. In this case, should they not
wrap around the set (Friday+2 = Monday)?
Submitted On 16-FEB-2001
KizubM
The only operators enums needs are casts to and from int.
Again, those casts may be implemented as static methods of
corresponded enum class, like
enum Colors { red, green, blue };
->
interface Colors {
int red = 0;
int green = 1;
int blue = 2;
public static int checkCast(int val) {
switch (val) {
case red:
case green:
case blue:
return val;
}
throw new ClassCastException("...");
}
}
The same (static methods of a class) may be used for
toString methods and others helper methods.
If you wish write
if (Monday+day == Friday) ...
it will be translated into something like
if (WeekDays.checkCast(1+day) == 5) ...
and so on.
Submitted On 19-FEB-2001
hwc
Picking up on AlecC's point, I'm not sure this RFE does request enumeration
in the mathematical sense, just a set; the workaround doesn't imply any sense
of ordering, just =, toString() and hashCode(), no >, <, pred() or succ().
What I would like to see, though, is to be able to extend an "enum" type,
to create a new type, e.g. sevenDays extends weekDays. Until this RFE
supports that, I'll stick with 4403347.
Submitted On 01-MAR-2001
clx
I agree with the people above that enums should be more
like Pascal enums. Enums are not just a convenient way of
defining a set of constants but a way of writing more type
safe code.
Pascal goes further than C in that enums define the types
of array dimensions.
A Java example would look something like this
enum Car {ford, volvo, jaguar};
enum Color {red, green, blue};
Object[Car][Color] cars = new [Car][Color]; // Cars
indexed by make and color
To access the array you must use legal indexes
a = car[volvo][red];
So the following statements the compiler would flag as
illegal
a = cars[1][2]; // 1 is not a Car 2 is not a Color.
b = cars[red][Volvo]; // Got the indexes the
wrong way round
This is really handy for checking index variables
for(Car car = ford; c < Volvo; car++) {
for(Color color = red; color < blue; color++) {
a = car[color][car];
yourclass.java Error # 6000 : sorry mate you’ve got your
index variables the wrong way round at column 10 line 3
}
}
The other feature of enums is that like boolean (which is
an enumeration) they should not be castable.
Car a;
Color b = green;
a = (Car) b; // Illegal cast;
a = (Car) 1; // Another illegal cast
Casting does not make sense. In the above example a car is
not a color and never will be. Pascal does provide a
function to return the ordinal value of an enumeration of
type int but you cannot go the other way.
The only ++ and -- should be allowed to increament and
decrement the values of enums. Other operators * / + and –
don’t realy have any meaning. Surely red + green = yellow!
Also the compiler should stop enums rolling off the end of
their definitions
a = jaguar++;
yourclass.java Error # 6001 : Enumeration out of range
column 5 line 1
Submitted On 04-MAR-2001
ejp
I do not agree with the evaluation, and even less with its tone.
I have been a compiler writer since 1976; I do agree that less is more;
and I further agree that everything including the kitchen sink should
not be thrown into Java.
Yet I support this proposal.
Submitted On 05-MAR-2001
meissner-sd
“syntactic sugar” hmmmm
Let me take your argument and extend it further.
enums are syntactic sugar because you could implement them
using public static class functions.
Keep the language simple and don’t implement them.
for loops are syntactic sugar because you could implement
them using while loops.
Keep the language simple and don’t implement them.
switches are syntactic sugar because you could implement
them using if else if else…
Keep the language simple and don’t implement them.
Classes are syntactic sugar because you could implement
them using structs, type ids and arrays of pointers to
functions (in C )
Keep the language simple and don’t implement them.
Nope I don’t buy it. These patterns were added because
they were used over and over by programmers everywhere.
Putting them in the language allowed the programmer to
express intentions in the code.
This will reduced the number of bugs.
Which is one of the driving forces behind Java. Making
the programmer safe by strengthening the language. So I
vote for enums.
Karl
Submitted On 07-MAR-2001
tbreuel
If you are going to add enums, please add them in the form
of type unions or tagged unions; you get these in languages
like SML. They give you all the expressive power of C/C++
enums and C/C++ unions, but they are also type-safe and even
allow the compiler to check for overlooked cases. Adding
C/C++-style unions themselves seems like way too much
trouble for very little benefit.
Submitted On 19-MAR-2001
althaus
Enums are elegant, simple and easy for programmers to use.
"I think the available idioms for simulating enum and
:keywords are fairly lame. (There's no way for the compiler
to issue that life-saving warning, ``enumeration value `x'
not handled in switch'', for example.)
They go to the trouble of building a single two-element
enumerated type into the language (Boolean) but won't give
us a way to define our own? "
http://www.jwz.org/doc/java.html
Submitted On 20-MAR-2001
andythomascramer
To the evaluator:
If enums are syntactic sugar, please explain how to
achieve type-checked set values that can be used in a
switch statement in current Java. And then explain why
Sun's own java.awt.GridBagConstraints doesn't use your
method.
Submitted On 28-MAR-2001
lotusalife
The evaluation suggests that Sun engineers should be
identified as the authors of these reports. Perhaps
then they would not make such inflammatory comments.
Submitted On 28-MAR-2001
vjave
I'm a little doubtful about the future of this bug-report,
because too many people are expressing a desire for an
overly complex version of enumerations. If there is going
to be any chance of enums being put into Java, it will
happen with an extremely simple enum type like the boolean
type, so I believe we should throw our voices behind that
simplest solution rather than these very long and involved
solutions/proposals.
Also, I think it's interesting that no opposing voice to
this (or other similar bug-reports) has offered a
reasonable explanation as to why enums are bad except to
make snide remarks and point to the ridiculous workarounds.
I think it is clear that this is a needed and wanted
feature, and the lack of it is a very real deficiency in
the language.
Submitted On 04-APR-2001
phillip2
Syntactic sugar? Very strange. This is an enhancement to
Java's rather poor type system, which would increase the
number of errors that can be picked up at compile time. I
would consider this to be very useful. Enums are no more
syntactic sugar than any other aspect of the type system,
and would be a valuable addition to Java.
As for "less is more", if this really is a good maxim, quite
why are sun producing API's at the rate that they are?
Submitted On 05-APR-2001
CChrisB
Why not just add a toInt (or toLong) method to Java
objects, the default could just be the same as hashCode.
This could act like the toString as an "automatic
conversion" which would allow any objects to be used in a
case statement.
This would make a class based solution better
Submitted On 06-APR-2001
KizubM
You approach is not possible - for switch cases we need
_compile-time_ constants int value, not run-time.
Submitted On 09-APR-2001
jdcjdc
Object-oriented programming is nothing but procedural programming (C, Pascal)
with syntactic sugar -- adding a 'this' parameter to a function makes it a method,
and adding a pointer to an array of function pointers transforms a C struct into an object.
Since the difference is pure syntax, why should programmers use OO languages like
C++/Java? We might as well use simple C and avoid all the OO's syntactic, feature-creepin' sugar.
This deep resistance by Sun to add 'essential features' is what's holding Java back.
Other features would be:
1. Design by contract
2. Operator overloading
3. Properties
The 'less is more' philosophy does not apply to the real-world, or
we'd all be using Turing machines.
Submitted On 10-APR-2001
KizubM
All features you've enumerated already implemented in some
compilers that extends java, and work on top of JVM... For
example - kiev compiler, that have all you enumerated. But
peoples use pure java. Why?
Submitted On 14-APR-2001
jdcjdc
Why? I'm looking for professional solutions and languages like kiev provide
um, somewhat crude and hacky ones.
Look at C#, it is 95% Java + 5% Microsoft extensions to Java (enums, op overloading,
props, multi-language support etc). C# is a Java clone, albeit a very good one.
Why can't Sun copy those 5% extensions and 'improve' Java?
In case you're wondering what 95% I'm speaking of, look at C#/.net and Java comparison:
C# ---> clone of Java language (JLS)
CLR (common language runtime) ---> clone of JVM
.net framework ---> clone of the large and powerful Java class library
Submitted On 18-APR-2001
mgibbons
The tone of this response is poor to say the least. Whilst I generally agree with the philosophy of 'less is
more' with regard to languages I think the 'only commonly used' (i.e. RISC) is more appropriate. Enumerated
types are used by every programmer I have come across and they should not have to reinvent the wheel
every time. Ditto parameterised types.
Submitted On 30-APR-2001
KizubM
To jdcjdc:
Probably, Sun doesn't with to add those 5% because then it
will be C#, not Java, and it will be CLI, not JVM.
Advokating Java, Sun and java developers say, that you wish
add 5%, another one wish to add 5%, and yet another one
wish add his 5% - in result we'll have C++... or kiev ;-)
.NET developers try to prove that languages and virtual
platforms need to grow in time, and try to make next
generation of OO language and VM.
Who's right? I don't know.
Maybe, let Java be Java and let MS develop C# - and we'll
see the answer in future?
Submitted On 01-MAY-2001
yonis
Who ever wrote the "evaluation" section for this RFE
clearly didn't have a first clue about type systems. I
sincerely hope that the key decision makers at Sun are
doing a better job than the engineers posting responses on
these boards.
Obviously, I think enumerations are an essential component
of a good type system. A very good example of enumerations
is Ada's enumerations.
Submitted On 02-MAY-2001
eengele
Enums are essential. They are not just syntactic sugar.
They allow compiler to distinguiss between many 'static
final int' and to restrict usage to only meaning ones.
Furthermore, it allow compiler to perform more
optimization.
Submitted On 03-MAY-2001
Ixchel
I'll second the recommendation of Ada's type system for
strongly typed integers. I think that they did a good job,
and their solution bears careful examination.
Submitted On 08-MAY-2001
MiguelM
The the evaluator: When did type safety become creeping featurism?
Submitted On 10-MAY-2001
npalombo
Just my vote.
Submitted On 11-MAY-2001
paulhussein
Enumerated types in Ada are one if its greatest assets and
are sorely missed in Java. To be able to define a type
type FruitType is ( Nil, Apple, Orange, Pear, Nil )
FruitArray : array ( FruitType ) of INTEGER :=
INTEGER'first;
for Fruit in FruitType'range loop
text_io.put ( INTEGER'image ( FruitArray ( Fruit ) );
end loop;
And manipulate it in such an elegant way.
In Java, most people do a list of static ints and an array
of strings to try and achieve the same sort of
functionality. It takes too long and is very inelegant.
My vote is for language support something similar to that
of Ada. The C/C++ support is too weak.
Submitted On 25-MAY-2001
wwk_killer
Regarding that object constants are just magic numbers and
are efficient enough, enums would be useful if:
1. switch statement can be used (yes, I know of interfaces
and polymorphysm; just look at Sun's
HTMLEditorKit.HTMLFactory code -- if's used instead of
switch and this isn't elegant).
2. Coverage audit must be present (if requested). This is a
really useful asset to robustness.
3. Useful thing would be enumeration.
I think this is behaviour many people will agree upon.
My suggestions:
First, there should be language support. Dont cry, this
could be just java.lang.Enum interface or class. So
compiler can recognize this item just like it does for
String '+' and allow its usage by compiler in switch() --
p.1. (Sure, to be translated as for if statement)
Enum can be extended by StrictEnum for coverage analisys --
p.2.
And, finally, if Enum were class, there could be embedded
sugar for constructors (with String, int and void
parameters), toInt() translator and enumerators as somebody
likes.
I regard that similar approach to Enum is used by Sun
engineers and many others. So why make copies of this code?
What do you people all think about this kind?
Submitted On 29-MAY-2001
MichaelFranz
Got to admit that I don't see an overwealming need for this. Before turning to Java I'd spent a number of
years working with languages which included enumerations (Pascal, Modula II). The design of the the
enum-support here was, of course, far more elegant than C/C++, and was a feature that we all used - and
enjoyed. So why don't I miss it in Java? In a word: polymorphism.
Enums quickly become a pain for clients (the enum's users), as soon as code maintenance stipulates
modification or enhancement of the enum. Features like Ada's "range" help prevent clients hard-coding enum
values, but it's still very easy for dependencies to arise.
I'm not saying enums wouldn't be useful at all, but I have my doubts that all the extra baggage implied by
full blow enum support is worthwhile. In 6 years of some pretty intensive client-server Java development I
reckon I could count the number of occasions I've hand-coded enumerations on just two hands. For these
rare occasions, I can live with having to code a dumb little class and a bunch or constants, which hold the
class instances.
Submitted On 01-JUN-2001
kabalOfIsonumerics
I hope, by now, that the evaluator would wish to rewrite the evaluation. I'm flummoxed by that kind of
response (cf. multiple inheritance). Does the evaluator not understand the concept? Or do they have a real
reason? Maybe they like being annoying?
Several languages use "enums" (ick. let's NOT go the C++ route) for a reason. See Lisp, Newtonscript, most
functional languages, etc. You get type safety, avoid typing tediousness, avoid typing mistakes (oops, both
"const" are == 4).
I'd be more impressed with the less-is-more argument if we there was more of an advantage: how easy is
static analysis? why isn't the compiler even remotely able to optimise (e.g. "a" + "b"!)? A better argument
would be about priorities, we know there are limited resources.
(pardon the email non-link, I don't need no more spam)
Submitted On 03-JUN-2001
eckely
Dear anonymous evaluator, first, I hope you understand that
the maxim "less is more" is not a paradox, is very
intuitive and simply means that "less complicated is more
usable", nothing more or less. Second, less complicated
should be understood from the user's (programmer’s) point
of view. Third, Pascal-style enums are much less
complicated than columns of Java static finals, that are
used commonly (e.g. by Sun), and thus are more usable.
Fourth, such enums are not syntactic sugar (by definition)
because they cannot be fully mimicked using current
language features. Conclusions: 1). enums are "more" and
should be voted for, 2). the evaluator is “less” and should
be taught some logic, good manners and an introduction to
language design.
Submitted On 04-JUN-2001
noelos
Just like to add my voice to the crowd commenting on the
arrogance and blinkered vision of the evaluator. This is
not creeping featurism. This is a simple extension that
helps ensure strong typing and simplicity for Java
developers - note the emphasis on developers rather than
Java implementors. That should be the maxim of whether a
feature should go in - if it makes developers' lives easier
and assists them in writing better quality code. Same goes
for paramaterised types and properties. And what's wrong
with syntactic sugar anyway? Anything that makes code more
readable and maintainable may well be useful.
Submitted On 07-JUN-2001
ipreuss
I think the need for Enums is a code smell
(http://c2.com/cgi/wiki?CodeSmells).
If you feel the need for enums, I humbly suggest to
reconsider your design. See
http://www.refactoring.com/catalog/replaceTypeCodeWithClass.
html
http://www.refactoring.com/catalog/replaceTypeCodeWithStateS
trategy.html
and
http://www.refactoring.com/catalog/replaceTypeCodeWithSubcla
sses.html
for hints on alternatives.
Submitted On 09-JUN-2001
jdcjdc
A real-world example of why static final ints are bad substitutes for enums is
the java.util.Calendar class. It mixes 'field types', 'days of week', 'months' etc.
together so that you can't easily figure out what static int to use for methods.
Consider the Calendar method:
int get(int field)
Calendar.AM_PM is a valid value for field, but Calendar.AM is not.
If you're not careful you could accidentally put the wrong value for field.
Enums would eliminate this problem:
class Calendar {
enum FieldType { AM_PM, DATE, DAY_OF_MONTH, DAY_OF_WEEK, etc. };
// old way -- not type safe
int get(int field) { ... }
// new way -- type safe
int get(FieldType field) { ... }
...
}
----------------------
Now there are at least two ways to implement enums in Java:
1) The C# way -- each item inside an enum is associated with a number similar
to the C enum. However, it is much more type safe than the 'final static ints' hack of Java.
Also, the enum items can be used in case for switch statements. The downside is,
the Java language and VM have to be updated to implement this style of enum.
// C#
enum Vehicle { CAR, BIKE, TRUCK };
2) Protected/private constructors style enums:
// Java
class Vehicle {
public final static Vehicle CAR = new Vehicle(0);
public final static Vehicle BIKE = new Vehicle(1);
public final static Vehicle TRUCK = new Vehicle(2);
public int getValue() { return value; }
protected/private Vehicle(int val) { value = val; }
int value;
}
The protected attribute for the constructor allows this Vehicle enum to
be extended. Normal enums can't do this. This style doesn't require any change
to Java.
The disadvantages of this style are:
* Requires too much typing compared to a C# enum -- lazy programmers will use static ints instead
* Enum items can't be used in switch statements
* More overhead than C# enum items which are just ints.
In either case, I think we can all agree that 'static final int' style enums
are evil and should not be used. Instead, one of the above
styles should be used.
Submitted On 11-JUN-2001
Walter_Braeu
javax.swing.SwingConstants clearly shows that enumerations are necessary.
When calling routines, it is quite easy to confuse SwingConstants.TOP and
SwingConstants.NORTH, and no compiler can help.
This also shows that not even the Swing developers used the "easy" workaround.
Submitted On 14-JUN-2001
wwk_killer
I meant Car example just below beginning of comments.
Submitted On 14-JUN-2001
wwk_killer
MichaelFranz told that "... enum-support here was, ... a
feature that we all used - and enjoyed. So why don't I miss
it in Java? In a word: polymorphism."
This is true if your cases/choices are really represent
objects with some complex behaviour around and their set
can change. See, f.e., Car sample just below -- this is
really not needed.
If we deal with "just tokens" of fixed set, like days of
week, sides of rectangle,
or something abstract or lightweight like:
java.sql.Types, java.math.BigDecimal's ROUNDING mode,
java.net.SocketOptions, java.awt.GraphicsDevice device
type,
it would be inefficient and error-prone to create separate
class for each constant value.
Submitted On 15-JUN-2001
bb112493
TESTING!! TESTING!!
Submitted On 15-JUN-2001
objectivelogic
I vote for enums because I think that they are a good
feature, that's probably why most other languages
implemented them. Even those who don't think they should be
included do realise that they are an important element of
anyo language. I thought one of the design objectives
behind java was to inherit the good features of languages
like C++ and Smalltalk. For those who think that enums
shouldn't be included, they should convince us that this
wonderful language construct is useless or that it defeats
a particular design objective of the java language.
Otherwise merely providing complex work-arounds just
doesn't make any sense,because 90% of developers just don't
use your complex work-arounds. This sounds more like
someone telling me there's no need to get a car to travel
from my apartment to work since I can always walk there.
Submitted On 20-JUN-2001
caes
I totally agree with eckely.
Submitted On 20-JUN-2001
ipreuss
Again, I don't think that an enum type is a usefull feature
in an oo-language.
I recently had to implement an admin-interface for a server
product. Besides other things, it had to show the state of
the server, therefore I needed some type of error-codes
(perfect opportunity for an enum, right?).
Well, I decided to try the class-workaround for this. As I
wanted to show some text depending on the state, I put this
text into the state-object. I decided to differentiate
states by different colors and put this in the state class,
too. When I had to enable or disable a button depending on
the state - well, you guess where I put this information...
Two weeks later, I wanted to add another state. All I had
to do was to define another constant of the class and
return it at the appropriate place. It instantly worked,
without searching for where the code accesses the state
information. I don't have any switch-statement in the code;
if I want to differentiate behaviour on account of state, I
just 'ask the state how to behave'. It's rather cool and
amazingly maintainable and extensible.
Since then I am convinced that I never ever would use an
enum type, even if I could.
Submitted On 20-JUN-2001
ipreuss
If you are interested, here is what the state-class looks
like:
public class ServerState {
final static ServerState UNKNOWN = new ServerState
("unbekannt", Color.black, false);
final static ServerState UNKNOWN_HOST = new
ServerState("Host nicht gefunden", Color.red, false);
final static ServerState IO_ERROR = new ServerState
("Kommunikationsfehler", Color.red, true);
final static ServerState TIMEOUT = new ServerState
("Zeitbeschränkung überschritten", Color.red, true);
final static ServerState SECURITY_ERROR = new
ServerState("Zugriff nicht erlaubt", Color.red, false);
final static ServerState NOT_FOUND = new ServerState
("nicht gefunden", Color.red, false);
final static ServerState ONLINE = new ServerState
("online", Color.green, true);
private final String message;
private final Color messageColor;
private final boolean isOnline;
private ServerState(String message, Color messageColor,
boolean isOnline) {
this.message = message;
this.messageColor = messageColor;
this.isOnline = isOnline;
}
public String getMessage() {
return message;
}
public Color getMessageColor() {
return messageColor;
}
public boolean isOnline() {
return isOnline;
}
}
Submitted On 29-JUN-2001
MichaelDJames
I agree the Java language designers should look at Ada's
strong typing more closely. In Ada it is poor form to use
the base types in an API -- base types are traditionally
used only to define specific types for specific purposes.
A method should accept parameters such
as "Lattitude, "Longitude" rather than "float, float."
Unfortunately, real Java methods (even those from Sun)
usually have parameter profiles like "int, int, String,"
etc. Sun's own stuff often uses antipatterns I think
we all disagree with. Junior developers often use Sun's
code as example code, and so the cancer spreads.
There are cumbersome workarounds to not having an enumerated
type, but from what we've seen in real life most developers
won't bother with them.
I vote for this RFE.
Submitted On 02-JUL-2001
JoieVS
I totally agree with eckely.
Submitted On 02-JUL-2001
jplarose
I find it ironic that Java not only has a case system for
some primitive types, but also one for types (in the guise
of Exception handling), and yet does not have such a system
for objects.... Go figure.
Here's an idea (I haven't actually tried this) : Create a
class which extends Throwable, (nested) subclasses each of
which is a singleton. Instead of using switch, use try and
throw inside the try block. Substitute case statements
with the catch blocks for the singletons, and you can use
the superclass as a substitute for default. The main
weakness with this solution compared to switch is that it's
impossible to "fall through".
Admittedly this is somewhat convoluted, and really should
be used for an enumerated type which is used in many
different places. But I see no reason why this couldn't
work. Of course, this is suboptimal compared to language
support for enums.
What do you people think?
Submitted On 03-JUL-2001
MichaelDJames
I agree the workaround above is interesting, but I hope
no-one uses it. Apart from being convoluted, throwing
exceptions is expensive!
Submitted On 05-JUL-2001
tedbigham
I agree that "less is more". Java has no constructs for
user defined types, that aren't objects. Although this
would be a simple change to the language, it would be a
vast change to the "API based" paradigm that Java has
created.
enums are really just objects anyway (each element is).
They all implement the same interface, but it cant be
extended. The biggest benefit is that the compiler does
some translating for you, and saves some typing. What
happens when you want to implement ford.getModel() in your
cars enumeration. From the sound of a few peoples
comments, you might run the variable through a switch
statement. That's not a very object oriented approach. No
offence to anyone, but polymorphism should have eliminated
99% of the switch statements out there). If cars was a
base class, and ford was a subclass, or instance, the
getModel() method would have a home.
Using an enum instead of real objects seems to show a lack
of vision. There's probably always a greater use for your
list of whatevers. Make them objects like they should be,
so your not stuck in the future. Even months has more than
one implementation from calendar to calendar.
If you think enum are more elegant, compare these.
public static person getFather(person dude)
{
switch(dude) {
case george_bush_jr:
return george_bush_sr;
case luke_skywalker:
return darth_vader;
case pebbles_flintstone:
return fred_flintstone;
default:
throw new Exception("don't know the
father");
}
}
public static person getFather(person dude)
{
return dude.getFather();
}
Both are type safe, but the enum version
The looping version of enum looks more elegant in for
statements, because method calls are pretty ugly mixed in
between those parenthesis. Not enough to justify it for me.
-------------
What effects would enums have on externalized data, and
version changes? Doesn't enum type safety really get lost
anyway in a shared environment like java? I'd hate to have
to recompile old code (or 3rd party code) when a public
enum gets an extra element added to it. Or worse, one
removed.
It seems like the only enums guaranteed to never change,
are already implemented in java (int, long, boolean)
Submitted On 08-JUL-2001
jtr
For those that suggest that OO polymophism should be used
instead of enumerated types, I agree. For some design
decisions, this is a great idea (see _Java Design_, Coad and
Mayfield).
However, I also agree that we need some /standard/ for
enumerated types. Right now, the Java APIs use ints
(SwingConstants, Font, GridBagConstraints, etc...). The
advantage of using enumerated types over OO polymophism is
that enumerated types are lighter weight physically (memory,
initialization time) and mentally (do we really want as many
additional methods added to GridBagLayout as
GridBagConstraints supplies?). So, enums are quite useful
and carry their weight. The bad news is that coders who are
not used to writing OO code may fall back to procedural
code when given enums.
Given that enums really are useful, we need to find a
standard expression for them. Using ints is one expression,
but that is, as others mentioned, not type-safe.
I do like Joshua Bloch's (in _Effective Java_)enumerated
types. If there were some way to push those into the APIs,
I'd be happy.
Submitted On 10-JUL-2001
hwc
If the main aim of this RFE is to define a type-safe way of passing parameters,
perhaps what need is a strictly enforced typdef, e.g.
typdef int Apples; // define a new type with int sematics
typdef int Oranges; // define another type with int sematics
typdef String Name; // another type, based on java.lang.String
void ff( Apples a, Oranges o, Name n )
{
// ….
}
Apples x = 12; // some people may prefer a warning here
Oranges y = 5; // some people may want an explicit cast
Name z = "Nick";
ff( y, x, z ); // error: Apples and Oranges are different
In effect, this allows sub-classing of the basic types although the type information
is lost at run-time for backwards compatibilty.
Submitted On 14-JUL-2001
ipreuss
Some more links to discussions regarding this subject:
http://c2.com/cgi/wiki?EnumeratedTypesInJava
http://c2.com/cgi/wiki?JavaLostEnumeratedTypes
http://c2.com/cgi/wiki?AvoidFinalStringsForUniqueTypes
http://c2.com/cgi/wiki?SillyJavaEnumerationRefactorings
Submitted On 19-JUL-2001
Omeyer
How do I check a switch statemant for completness (handling
all cases) at compiletime whithout enums?
I'd be glad to receive an answer on this. Use the link
below.
Submitted On 19-JUL-2001
Omeyer
The evaluation is embarrassing. Does this mean: "Vote for
this and
throw your vote away?" It extends the requested feature in
an
inappropriate way. Voting for this means: "I want typesafe
enumeration." nothing more, nothing less. Not "the whole
kitchen
sink".
Submitted On 23-JUL-2001
igarn
Get the compiler implement the workaround and generate the classes automatically ?
Submitted On 24-JUL-2001
thomas.sievers@gmx.de
Who's that poor freak who wrote the text in header
at 'Evaluation'? Seems to be another C-hacking guy who does
not have any idea what's behind the term 'building RELIABLE
software' (could be one of the Windows95 development crew).
Enumeration types are not some sugar or a kitchen sink or
whatever poor comparison, it's an essential component of a
strongly typed programming language. Whoever has a
different opinion, tell me what's the sense (or nonsense)
behind a method like:
setDay(INT day)
(have a close look at the word INT), instead of
setDay(DayOfWeek day)
Remember that using ints is sun's preferred way to
substitute the missing (yes!) expressive power of Java.
Clearly, it's a funny thing to call
setDay(4711)
and to look forward what might happen during runtime (not
compile time...).
It would be a great step forward towards reliability to
adapt the ADA concept of enumeration types. Shortly
described, it works as follows:
TYPE DayOfWeek IS (Monday, Tuesday, Wednesday, Thursday,
Friday, Saturday, Sunday);
Implementation details, like whether this type is
implemented by using ints or whatever, is hidden to the
programmer and, by the way, totally unimportant. Of course
compile-time type checking is provided, and furthermore,
one can use operands like first, last, next... on variables
of enumeration types.
in ADA there are not only the above mentioned enumeration
types, there is also support to reliably use a switch
command on a variable of that kind:
oneDay : DayOfWeek;
case oneDay:
when Monday => do_something
when Tuesday => do_something_else
....
when others => do_nothing
It's a compile-time error not to handle all of the possible
values of the enumeration type (by listing all values
explicitly or by using the 'others' keyword). That's a way
to achieve reliable software. Java looks somewhat poor in
this respect.
Submitted On 30-JUL-2001
br29operrd
NO - please do not add this. The typesafe enum pattern (and
advantages over C style enums) is eloquently described in
Essential Java. Using this pattern goes beyond what is
achievable with regualr enums (suchas as associating
functionality with each constant in the enum). I have also
seen a version where are the constants are added into a
List using reflection (so you can simply add/remove
constants into the class to have them automatically added
to the List). The sort of flexibility to do this would be
ignored if developers are given an LCD approach to enums.
TO summarize, the Enum Pattern is more lable to be
refactored into more powerful solutions when necessary. I
do not believe this is as likely with C - style enums.
Finally, I strongly agree with the evaluation that "less
is more". Evey feature that is added to java has a very
hard to percieve/very easy to ignore cost. Please think
twice before voting for this (and many other language
enhancements) - there are more important things that Java
needs.
Submitted On 07-AUG-2001
blackrob
I'm trying to overload the GregorianCalendar add method
with some new "fields" like "WEEKDAY" or "BUSINESSDAY".
Because there are no enum's I have to get the source code
and find out what the maximum static int that this function
knows about. The I have to add on a bit to allow for any
enhancement of the parent class. I also have to check the
integer value I receive to see if I should handle this or
the parent class.
The workaraounds suggest that enums should be defined in
classes or interfaces. If this is an acceptable alternative
why was it not used for the system classes I am trying to
overload.
This seems like a reasonable and relativly trivial request.
Why make life so hard?
Submitted On 27-AUG-2001
pmurray
M.R Atkinson's post:
"enum Location { NORTH, SOUTH, WEST, EAST };
can be automagically translated by the java compiler into
the equivalent in the class file of:
interface Location {
static final int NORTH = 0;
static final int SOUTH = 1;
static final int WEST = 2;
static final int EAST = 3;
}"
implies, interestingly, that an enum class is actually a
subclass of int. One can freely use an enum "object"
wherever one can use an int, but there is type-safety.
In our project we user the "maximal" solution. We have a
SafeEnumeratedType which our various enums extend. Our
types have a code, description and ordinal field. It's
nasty, but matches what we are modelling - reference tables
in a database.
Submitted On 06-SEP-2001
Spaceman40
Ahh, enums. Back to the days of C. I remember in BASIC,
where we didn't have enums. No sir. I had to write out
all my consts by hand - typing so much just to tell basic
what certain things meant to me so that I didn't have to
remember all those weird numbers that went with my array
indexes and everything else.
Ever used a bean editor? You know, like Forte's or
NetBeans's editor. Sure, they're great - use NetBeans for
all my development. However, if you want to change a
property that is usually changed by accessing a static
const final int (long stuff to type compared to BASIC), you
need to know what the constant is called or know what the
int is, or hope that the IDE you're using has that
information stored somewhere. Unfortunately, most of the
time it doesn't, and so you have to guess at the ints, or
type in a const name that might be way off, and all of this
interferes with development time. Enums solve this problem
by giving a number of names that can be used in such a
thing.
Sure there are workarounds. I use my "public static final
int" workaround all the time. It's great, as long as I
don't care how the actual words are arranged in the
source. If I want to place a word between two others, to
maintain order, for example, all the numbers must be
rearranged. But that's ok, isn't it? How about a class,
where everything is set up right, nothing complicated:
public class Enum
{
private static int lastNum = 0;
private int myNum; // Even make this public and final
public Enum(int reset)
{
num = reset;
lastNum = reset + 1;
}
public Enum()
{
Enum(lastNum);
}
public boolean equals(Enum b)
{
return (b.num == num);
}
}
And then when extending this class, just write a class like
this:
public class Car // To use an old example
extends Enum
{
public static final Car FORD = new Car();
.
.
.
}
Oh, but even in this wonderful, typesafe workaround, there
is still that horribly long "public static final" to
write. What to do...
Hope that evaluator is not extremely hurt at all the flames
s/he's been getting. Still, after saying
that "[enumerations] are just one more form of syntactic
sugar", when they are present (in workaround form, of
course) in almost all of the Swing and AWT classes, and
most of the others as well....
Maybe Java needs a little bit of sugar - I don't drink my
coffee black anyways...
Submitted On 06-SEP-2001
ebdon99
To all the (few) people opposed to adding enums...I ask you
why. Adding enums does not prevent you from using
your "patterns" if you want to. The rest of us will be
happy not typing the extra garbage.
Submitted On 10-SEP-2001
Ixchel
My biggest gripe with the various patterns for representing
enums as types is that they effectively make 'null' into a
value of every enumerated type (!). Not only is it a value -
- it's the default value for every uninitialized instance
of that type.
This means that to write robust code, one has to do things
like:
void foo(MyEnum bar) {
if (bar == null)
throw new IllegalArgumentException();
if (bar == MyEnum.MY_VALUE)
do_whatever();
}
This sort of thing (testing for null) effectively has to
happen every time one passes an enum as a parameter! It's
especially dangerous that code which compares enumerators
often won't even detect this problem, since 'null' can be
compared perfectly well with other values -- it just always
returns false! Not even a NullPointerException will save
you from this error.
Also, using the enum patterns, although it is nice to be
able to add various features to the individual enumerators
using subclassing, like:
public static final MyEnum VALUE_1 = new MyEnum() {
public void doSomething() { do_something(); }
}
this in no way makes up for the absence of switch
statements, since it makes the enumerated type dependent on
the context in which it is used (!) which is a design
nightmare. If the type is used in more than one context,
this rapidly becomes a disaster. Can you imagine all the
methods that an object in an enum like "enum
CompassDirections { NORTH, SOUTH, EAST, WEST }" would have
if it had to have additional methods added to it each time
someone came up with a new use for a compass direction? Now
consider what happens if the enumeration CompassDirection
is in a sealed JAR file that you don't have source for that
was provided to you by a third party. You can't extend and
modify it every time you want to do the equivalent of
a 'switch' statement.
Your alternative in such a case is a bunch of cascading
if...else statements or some similarly inefficient
construct. (Note that 'switch' statements can use function-
table dispatch and/or binary-tree search to match the case
statements faster than just testing them one by one in
order.)
There really is still a use for the equivalent of switch
statements on enumerated types. The enumeration patterns do
not really do away with this need except in certain limited
cases -- typically those cases in which the type is used
only by a single client and can therefore be specialized to
meet exactly the needs of that one client. To do a proper
job of this, IMHO, a language extension is required in
order to make 'switch' or something like it support
enumerated types properly and efficiently. Class libraries
just won't do the job by themselves.
Gosling has an interesting paper on his website describing
the concept of 'immutable types' and how they could deal
with at least the null-comparison issue, raised above.
Submitted On 18-SEP-2001
dkf
One alternative would be to just have a way of being able to
'switch' on static final fields that contain objects. *How*
you'd do this is, perhaps, to force all enumeration objects
to be instances (of a subclass?) of a new Enumeration class
that has a final hashCode method and switch on the results
of that. Add a few obvious type restrictions and some
syntactic sugar (again, that's obvious stuff) and you can
get enumerations without any VM changes at all.
My idea is that typing:
public enumeration FooBar { foo, bar }
will be roughly equivalent to doing:
public class FooBar extends java.lang.EnumerationType {
public static final FooBar foo = new FooBar();
public static final FooBar bar = new FooBar();
public static final int foo__hashcode = foo.hashCode();
public static final int bar__hashcode = bar.hashCode();
}
(Well, maybe the __ should be some symbol that cannot be
generated from conventional Java source.)
Then, you can translate:
switch (foobarVariable) {
case foo: /* blah */
case bar: /* blahblah */
}
into:
switch (foobar.hashCode()) {
case FooBar.foo__hashcode: /* blah */
case FooBar.bar__hashcode: /* blahblah */
}
Which should be good enough for most purposes.
Submitted On 18-SEP-2001
dkf
Hmm. Thinking a bit more about my suggestion above, there
is something of a problem with ordering (serialization is
easily fixable; the APIs already exist) but it shouldn't be
too hard to do (next() and prev() methods?) As it is, what
I suggest does not work because the compiler won't compile
it (it has different ideas about what is a constant expr...)
C/C++ enums are not a good idea though. If you really just
want a way to declare a bunch of values with names, the
conventional Java way with 'static final int' should be
enough.
Submitted On 03-OCT-2001
jqb
The "evaluation" is arrogant, ideological, ignorant, and immature, and reflects very badly on Sun,
suggesting that Sun personnel aren't capable of or interested in rational discussion of the relative merits and
demerits of various proposals. The author seems to think that he/she is one of the "very few people" who
have it right, as opposed to the "many programmers" with faulty thinking. This is self-serving egoistic
claptrap. The "evaluation" should be replaced by a more professional comment by someone with more
expertise, who is familiar with the many arguments on both sides, instead of offensive derision of such
strawmen as "creaping feasturism", and "kitchen sink".
Submitted On 17-OCT-2001
bengber
Wow, that's quite a condescending evaluation. I think I'll
vote for this bug now.
Java is successful ONLY because it solves a business need.
All the talk about purity and expressive power is great
until you have to write a real-world application and lose a
half hour a day creating subclasses of your Enum class.
Also, the Java 1.0 beta documentation I have
describes "enum" as a reserved word for future use. Seems
like it's not just us wacky users who have been thinking
about this for the past 6 years.
It also seems a little hypocritical to suggest that we
don't understand the Java truth that "less is more" when
each release adds 55 new packages to the core API...
Submitted On 24-OCT-2001
jirihana
Dear Sun, could you please provide a less arogant
evaluation of this RFE.
Submitted On 29-OCT-2001
sean.shubin
Although I agree with Sun's decision not to support enums,
I find their "syntactic sugar" argument rather pathetic.
A more convincing argument would be for Sun to lead by
example.
Take JSplitPane.VERTICAL_SPLIT and
JSplitPane.HORIZONTAL_SPLIT as an example of what could be
implemented as an enum.
Instead of what Sun is using in JDK1.3:
public final static int VERTICAL_SPLIT = 0;
public final static int HORIZONTAL_SPLIT = 1;
public JSplitPane(int newOrientation) {
this(newOrientation, false);
}
public void setDividerLocation(double
proportionalLocation) {
if (proportionalLocation < 0.0 ||
proportionalLocation > 1.0) {
throw new IllegalArgumentException
("proportional location must " +
"be between
0.0 and 1.0.");
}
if (getOrientation() == VERTICAL_SPLIT) {
setDividerLocation((int)((double)(getHeight() -
getDividerSize()) *
proportionalLocation));
} else {
setDividerLocation((int)((double)(getWidth() -
getDividerSize()) *
proportionalLocation));
}
}
Sun should use something like:
public class Orientation {
public static final Orientation VERTICAL_SPLIT =
new Orientation() {
public void setDividerLocation(double
proportionalLocation) {
setDividerLocation((int)((double)
(getHeight() - getDividerSize()) *
proportionalLocation));
}
}
public static final Orientation HORIZONTAL_SPLIT =
new Orientation() {
public void setDividerLocation(double
proportionalLocation) {
setDividerLocation((int)((double)(getWidth
() - getDividerSize()) *
proportionalLocation));
}
}
private Orientation(){}
}
public JSplitPane(Orientation newOrientation) {
this(newOrientation, false);
}
public void setDividerLocation(double
proportionalLocation) {
if (proportionalLocation < 0.0 ||
proportionalLocation > 1.0) {
throw new IllegalArgumentException
("proportional location must " +
"be between
0.0 and 1.0.");
}
getOrientation().setDividerLocation
(proportionalLocation);
}
Notice that all of the same code is there, it has just been
moved around is such a way as to give us type safety.
Also note that with enums, I could not have used
the "Replace Conditional with Polymorphism" refactoring, as
I did here.
Submitted On 06-NOV-2001
liebelt
If you really adhere to the OO programming paradigm there
is no place for enums. If you use the OO techniques like
inheritance the way you should, the need for enumerations
will get VERY rare in your program. Example: Many
programmers use enumerations to actively control the
behaviour of objects. This is not OO programming -
different behaviour should (usually) be provided by some
form of polymorphism.
What is left are very few "enum" candidates. These should
be represented as objects of mature classes because it is
probable that you want to add some additional information
retrievial method to it in the future. At least a "toString
()" method for tracing purposes. Example: "monday" should
be an object of a "DayOfWeek" class. It could have a method
to retrieve the localized (american/european) number of the
day within the week. It also could be added another one to
get a localized string representation for it any time in
the future.
I recommend everybody to have a look on this topic in the
book "Effective Java" by Joshua Bloch. It is a joy to read
this book!
Submitted On 09-NOV-2001
fiontan
This RFE needs a few more pro-OO comments.
I'd like to put my voice amongst those advocating an OO
approach to these problems. Since reading Joshua
Bloch's "Effective Java", I have little doubt that the
Typesafe Enum pattern is superior to the typesafe enum
language construct in most (all?) cases.
I recently refactored some of my code into this pattern
(From the static final int workaround), and it became
infinitely more readable and extensible. Moving
the 'switching' code into the enum class reduced code size
and eliminated error cases.
As to why "You can't extend and
modify it every time you want to do the equivalent of
a 'switch' statement" (Ixchel, Sep 10), I challenge why
not? What desired use for a Direction enumeration (for
example) would it be infeasible to use a local Typesafe
Enum class?
Having to update local code if the enumeration list changes
is an issue common to both approaches - the switch
statement would fall through to the default case, while the
local enum class simply wouldn't have an equivalent
value... warnings in both cases.
Lack of typesafe enums in the Java APIs is unfortunate...
there is no way to fix this (?) without breaking
compatibility with previous versions.
So be it if enumerations are added as a language
construct. I just thought Java was an Object Oriented
language.
Submitted On 12-NOV-2001
wwk_killer
There is some "OO-purist" people. Do they think many here
is so... disabled... to understand virtual methods?
The use of enum is:
If we deal with "just tokens" of RE set, like days of
week, sides of rectangle parser states, etc, it would be
too much work.
Also, please suggest what to do with null values?
Submitted On 18-NOV-2001
jtr
While I'm all for the typesafe enum pattern in _Effective
Java_, it is telling that the pattern is unused in the JDK APIs.
Submitted On 23-NOV-2001
finking
Why not give switch statments the ability to take a final
object as an argument and match it against final objects in
the cases. The compiler can do type checking. This would
allow Bloch style typesafe enums (which I personally think
are the way forward) to be used in a switch. There current
inability to be used in this way is their one drawback from
my point of view, and it's a biggy. Fix this and you have a
near perfect enum. The only (minor) problem left is
counterintuitive specialisation properties, but the
implementation is so attractive in every other way, I can
live with that.
Submitted On 27-NOV-2001
delft
The Pizza language extends Java with algebraic types. A
special case of these types are enums.
See
http://lampwww.epfl.ch/pizza/Docs/Tutorial/week3/week3.html#
algebraictypes
Algebraic types offer more than just enums; see for instance
the source code of the Pizza compiler:
http://sourceforge.net/projects/pizzacompiler/
Submitted On 04-DEC-2001
tupari
Note: just because an Object is final doesn't mean that its
value can't change, and therefore can't be used in switch
statements. If an Object is final that means the refrence
can't be changed, i.e. you can't to myobj = null but you can
do myobj.setValue(3).
Submitted On 10-DEC-2001
GarretWilson
Since when is typesafeness "syntactic sugar?" Is it too
much to ask to be able to do the following?
public setFlavor(Flavor newFlavor)
{
switch(newFlavor)...
}
If I want the compiler to stop me from calling setFlavor
(metal) or setFlavor(tree), why is that syntactic sugar?
Refusing to allow a Map to be passed to component.setSize()
seems to be just as much syntactic sugar. No, this is very
much about semantics.
The workarounds are horrendous---why do I want to allocate
a big hunk of memory on the heap and do all sorts of method
calls (involving stack pushes and pops and exception
checking and virtual table whateverness) when I just want
to pass an typed integer value?
Let's have this already---it's been years, and it's still
not here. (Well, I guess it *is* here now, in a way---it's
called C#.)
Submitted On 15-DEC-2001
peets
I want them! Macho purists can continue to employ their
workarounds. Gimme the darned sugar.
Enums should:
- represent a fixed set of values
- work in a switch statement
- be type safe (generate an error when passed to a method
that expects different enum type)
- support set membership operations
Submitted On 15-DEC-2001
peets
...and yeah, that evaluation really pisses me off, too.
Submitted On 18-DEC-2001
lshearer
I vote for enums.
Submitted On 24-DEC-2001
oojika
Enumerated types are rather useful. I believe that they
should become part of Java. I find it interesting that
Sun's own classes often suffer from the use of ints where
some stronger typing would be appropriate.
Do we have to take this over to the JCP ourselves? That
may be the only way to get action on this one.
In the meantime, maybe Sun can provide a competent person
to rewrite than embarrassing evaluation.
Submitted On 26-DEC-2001
italianCoffee
Just adding my .02 since SUN listens to the people.
1. Sure, there are workarounds. As long as you are Turing
compatible, I guess you can always find a workaround to all
solvable problems. The issue here is not one of necessity,
but one of expressivity.
2. Since there exist work-arounds, it follows that you may
not feel the necessity for enums. Again, I think nobody
here wanted to say that without enums the language is
crippled.
3. If you think you don't really care for enums, but every
time you work on a project you
a- use static final int values as internal codes for
specific conditions, or
b- create a number of error classes to recognize the
error conditions encountered,
(and these are only two dumb examples)
well... you should review your idea: even if you don't
realize it, enums would make your life easier.
4. Why? Possible reasons that depend on your style:
a- it's a natural way to describe a bounded domain for
some variables
b- if you have a C++, Pascal (and I'm sure many other
languages should be added here) background, you are used to
use the enums
Undeniable reason:
Aside from everything else, if you can quickly define an
enum data type and use it, you will type a lot less further
down the code. Less typing -> less likely to #include
<typo> :-), and if you haven't noticed yet, Java statements
appear a lot longer, in average, than other language's (or
at least, they have the potential for that, given inline
declarations, anonimous classes, etc etc... you know what I
mean if you've found yourself in front of an un-interrupted
sequence of 4+ closing parenthesis, of different kind...).
So, unless one has a good reason not to add such a feature
to Java, one should plug it in!
Oh, right... enums as masked-ints are unsafe. Sure. And I
guess real enums will probably require overhead, and might
slow down the language... hmmm... well, have everyone vote,
recount the ballots a thousand times, and see if people
will give up some clock cycles to have the enums. I know
I'd love to have them... at least I wouldn't find those x
lines at the top of all of my classes where I define those
dangerous, *very* dangerous int constants...
Submitted On 26-DEC-2001
hajolemcke
As I just posted on JDC, I see a couple of good points for
integrating enums into the language itself.
I'm currently rewriting some source code from C to Java. In
C I have lots of code fragments like:
<---- cut here ---------->
typedef enum { CP_NOPROP,
CP_ALIGN, CP_APPEARANCE, CP_BACKGROUNDCOLOR,CP_BGCOL,
CP_BORDER_WIDTH,CP_BOTTOM, CP_CENTER, CP_COLOR,
... , CP_COUNT
} CP_PROPERTY ;
// and a corresponding array of strings
const char * CssProperty[ CP_COUNT ] =
{ "", "align", "appearance",
"backgroundcolor", "bgcol", "border-
width", "bottom", "center", "color", ... };
<---- cut here ---------->
Advantages are:
1. You can define variables of type 'CP_PROPERTY' and the
compiler checks all assignments and comparisons
2. Its very easy to insert a new entry into this structure,
because you do not need to reassign all constants
3. You can use strings in a form like: "CssProperty[
CP_ALIGN ]"
4. You can use the automatically enumerated constants e.g.
in switch statements:
switch ( myprop ) {
case CP_ALIGN:
...
It seems to me, this feature is completely missing in
Java ?!?
Submitted On 29-DEC-2001
weitzman_d
I might as well include some code I wrote after reading
_Effective Java_:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* A typesafe enumeration of the months.
*
* Immutable, Thread safe, and resolves properly on
deserialization.
*
* @version 1.0
* @author David Weitzman
*/
public final class Month implements Comparable,
java.io.Serializable {
// Tests
public static void main(String[] arguments)
throws IOException, ClassNotFoundException {
System.out.println(MONTHS);
for (Iterator i = MONTHS.iterator();
i.hasNext();) {
Month m = (Month) i.next();
System.out.println(
m.getName()
+ " (" + m.getAbbev() + ")"
+ ", month " + m.getNumber
() + ","
+ " has " + m.getDays() + "
days.");
}
PipedOutputStream pout = new
PipedOutputStream();
PipedInputStream pin = new PipedInputStream
(pout);
ObjectOutputStream out = new
ObjectOutputStream(pout);
ObjectInputStream in = new ObjectInputStream
(pin);
out.writeObject(FEB);
out.close();
Object feb = in.readObject();
System.out.println("feb == FEB: " + (feb ==
FEB));
System.out.println("JAN == FEB: " + (JAN ==
FEB));
}
// Public constants
public static final Month JAN = new Month
("January");
public static final Month FEB = new Month
("February", 28);
public static final Month MAR = new Month("March");
public static final Month APR = new Month("April",
30);
public static final Month MAY = new Month("May");
public static final Month JUN = new Month("June",
30);
public static final Month JUL = new Month("July");
public static final Month AUG = new Month("August");
public static final Month SEP = new Month
("September", 30);
public static final Month OCT = new Month
("October");
public static final Month NOV = new Month
("November", 30);
public static final Month DEC = new Month
("December");
private static final Month[] MONTH_ARRAY =
{ JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG,
SEP, OCT, NOV, DEC };
public static final List MONTHS =
Collections.unmodifiableList(Arrays.asList
(MONTH_ARRAY));
// Month implementation
// count will be seen as zero despite its value
unless it's before the
// public constant declarations
private static int count = 0;
final String name;
final int number;
final int days;
private Month(String name) {
this(name, 31);
}
private Month(String name, int days) {
this.name = name;
this.days = days;
this.number = ++count;
}
public String getName() {
return name;
}
public String getAbbev() {
return name.substring(0, Math.min(3, getName
().length()));
}
public int getNumber() {
return number;
}
public int getDays() {
return days;
}
public String toString() {
return name;
}
public int compareTo(Object o) {
return getNumber() - ((Month) o).getNumber
();
}
/**
* @throws ArrayIndexOutOfBoundsException
* someone tried to
deserialize a fake <code>Month</code>
*/
Object readResolve() throws
java.io.ObjectStreamException {
return MONTH_ARRAY[number - 1];
}
}
Submitted On 29-DEC-2001
weitzman_d
The book _Effective Java_ explains how to do enums in
Java. It's a great book that everybody should read.
Submitted On 03-JAN-2002
martinpaulo
Compare the length of the suggested work arounds with the
following Delphi code:
type
// declare.months
Months = (January, February, March, April, May, June,
July, August,
September, October, November, December);
Surely the Delphi approach is more readable, compact, less
prone to error and much, much more productive? Or should I
say that C# is more compact, less prone to error and much,
much more productive than Java, as I believe it will have
Delphi style enumerations... It may be 'syntactic sugar',
but it is sugar that boosts my throughput.
Please remove the blinkers from your eyes and allow me to
be as productive as my C# counterparts - put type safe
Delphi style enumerations into Java now!
Martin
PS: Here are some examples of Delphi enumerations in use:
// following will only accept and work with months...
procedure doSomethingWithMonths(m: Months);
begin
case m of // can only be a Month type used in this
switch!
January: {some work done here} ;
February: {some work done here} ;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
m: Months;
begin
for m := January to March do begin
doSomethingWithMonths(m);
end;
// following will not compile! It yields: [Error] Unit1.pas
(40): Incompatible types: 'Months' and 'Integer'
doSomethingWithMonths(1);
end;
Submitted On 03-JAN-2002
bcuocci
The more arrogant and condescending a programmer, the less
likely he is to have any real skill, talent, or
understanding of the issues.
With that in mind, I'm forced to wonder whether the writer
of that Evaluation has managed to stay employed for the
year since he wrote it.
Submitted On 08-JAN-2002
scolebourne
Enumerated types are a basic requirement for any enterprise
scale system. Personally, I don't care whether it is
implemented by the compiler to generate classes or typesafe
ints. I do however want the ability to extract a String
from the enumeration and create the correct enumeration
from a String (for conversion to XML).
The principal case in my mind for doing this is that every
Java shop is currently creating their own way of doing
this. Some will use static final ints, some static final
Strings and some will use JavaWorld style classes. Madness!
I also found the comment from Sun offensive, and it
suggests that the comment came from someone who has never
developed in the real world of projects.
Submitted On 08-JAN-2002
martinpaulo
Hallelujah! A convert! And if I may quote the end of the
referenced article: “As such, the pattern is an unreliable
substitute for a basic feature that the Java language
lacks: a compiler-supported enum feature. In many cases,
you're better off using the good old set-of-static-
primitive-values enumeration.”
I see that this RFE has got to number 6 on the RFE list. It
is now a year since it originally submitted. Is anything
being done about it, or is it being ignored?
Submitted On 08-JAN-2002
fiontan
I find myself forced to reconsider my stance in this
issue. Not only would the inclusion of language support
for enumerations ease conversion of code from other
languages, but the Typesafe Enum pattern is not appropriate
in all cases.
I still think that good code in the Java language should
follow good OO principles, but there are cases where having
an almost-primitive type ease implementation where the pure-
OO approach would be insane.
http://www.javaworld.com/javaworld/javatips/jw-
javatip122.html?
Submitted On 11-JAN-2002
streissel
Typesafe enums is really a needed feature.
It make code more beautifull, easier to maintain.
It is one of the last arguments that C++ developper have to
reject java.
Please add enums!
Submitted On 12-JAN-2002
scolebourne
I hope that I speak for many in appreciating Sun's new
input to this discussion.
My interest in this comes as I try to develop a framework
for enterprise value objects. During my research through
net searches I came accross at least 4 public open source
variations on the Enumeration base class. Thus even a Sun
standard base class would be an improvement.
In terms of implementation, for the work I do, I require an
enumeration where null is a possible value (to represent
that we don't know the value). This indicates that the
enumeration implementation must be an object. However, it
does not preclude having Enumeration class wrap primitive
enum in the way that the Integer class wraps the primitive
int.
Submitted On 24-JAN-2002
wwk_killer
hajolemcke and many others,
I think your sample is just impure, you may as well have
HashMap <Integer, String> arrayLike = new ...
static{
arrayLike.add( new Integer(73), "Magic word");
//...
}
...
String s = arrayLike.get( new Integer( i));
Sun have to develop some kind of base class
package java.lang;
public abstract class Enum <ItemType, NameType> {
private static Collection storage;
/** Use to add your constants like add().add().add() */
static Enum add( Object key, NameType optName);
/** Allow ADA's item'NEXT functionality. */
static public Enum getNext( Object item);
/** Pascal's 'in' functionality. */
static public boolean contains( Object item);
}
public abstract class IntEnum <NameType>
extends Enum <Integer, NameType> {
static protected add( int i, NameType optName);
}
user's code:
public class RectSides extends IntEnum<String> {
static {
add( 1, "Left").add( 2, "Top").add( 3, "Right")
.add( 4, "Bottom");
}
}
and MAYBE provide compiler support for shortening:
public typedef<int> RectSides {
Left = 1, Top = 2, Right = 3, Bottom = 4
} // the same as use class by hands; will be translated to
my class above.
Submitted On 29-JAN-2002
vegala
Here is a simple way to do an enums in Java:
/**
* Enum definition:
* enum ColorEnum { RED, GREEN, BLUE };
*/
public class ColorEnum
{
// Using a "short" to minimize memory usage
public static final short RED_COLOR_VALUE = 0;
public static final short GREEN_COLOR_VALUE = 1;
public static final short BLUE_COLOR_VALUE = 2;
public static final ColorEnum RED = new ColorEnum(
RED_COLOR, "red");
public static final ColorEnum GREEN = new ColorEnum(
GREEN_COLOR, "green");
public static final ColorEnum BLUE = new ColorEnum(
BLUE_COLOR, "blue");
private int enumValue;
private String strValue;
private void ColorEnum(int value, String str)
{
enumValue = value;
strValue = str;
}
// Returns the "primitive" value of the enum object
public int getValue() { return enumValue; }
// Returns a String representation of the the enum object
public String toString() { retun strValue; }
}
********************
By using this method you will have the benefit of compile
time type checking as well as great fexibility at runtime
since you can use the enum value in a switch statement:
ColorEnum red = ColorEnum.RED;
switch( red.getValue() )
{
case ColorEnum.RED_COLOR_VALUE:
//Do something
break;
case ColorEnum.GREEN_COLOR_VALUE:
//Do something
break;
default:
//Do something
break;
}
Please remember that Java is an OO language. It is not
supposed to be another version of C/C++.
Submitted On 31-JAN-2002
jaypac1000
One other thing. (Sarcasm intended). Since the interest is
to keep Java simple. I think several features should be
removed. In fact the only neccessary features are if
statements, while loops, and goto statments. If we could
reduce the language to those three things programmers could
do whatever they wanted and the language would be simple.
Submitted On 31-JAN-2002
wwk_killer
Vegala,
All what is needed is MINIMIZING the efforts:
1. Base (generic?) class with framework (goodies from other
PLs borrowed included);
2. Very likely, compiler change (enum{} and emulated switch
()).
3. In the case it wont be too much efforts, HotSpot
optimization (final objects like int's, right?)
Submitted On 31-JAN-2002
jaypac1000
Problem with workaround given in this RFE. The official
workaround given above is bad. If you use your "enum"
members as hash table keys you will be burned. It says to
override equals. This should never ever be done without
also overriding hash code. The general contract given in
the documentation for the Object class gives more
information as to why this is true. Furthermore there is
actually no reason to override equals because using the
pattern they describe, as long as each public static "enum"
instance contains a different String or int or Integer then
all instances will be unequal and the default equals and
hashCode methods will work fine.
Submitted On 08-FEB-2002
dkf
weitzman_d: While the Typesafe Enum pattern is all very
well, it is not appropriate in all cases. Months are a
classic example (building on your code here) since suppose I
have some use for months which you did not anticipate (e.g.
a getNumBusinessDays() or getFiscalQuarter() method or
something like that) then I would either need to cooperate
with you on getting the new method added (but who's to say
that would happen if we weren't in the same organization),
subclass your class (Whoops! Doesn't work for all sorts of
reasons), create my own Month class (duplicating all the
work; imagine this multiplied up to a large piece of
software), or call the getNumber() method and switch on that
(which gets us virtually back to square one by stripping out
the type-safety and making me know the order and value of
all the instances of the class, which sucks, and IIRC I
couldn't use Java to extract that stuff for me because the
values aren't sufficiently constant for the compiler to be
pulled out into 'static final' variables and used as case
tags.) This sucks so much, it is clear that the solution
needs to be more subtle and better integrated with the
language.
(And your implementation's fragile too; robust code stores
the name of each enumeration element, not number, so
insertions into the middle of the sequence don't break the
save format. Sure, in an ideal world that wouldn't happen,
but who said the world was ideal..?)
Submitted On 08-FEB-2002
jkolb
Using vegala's example as a basis and assuming the Java
enumeration has a fuction similar to the following:
public Color getColor() {
return color; // Set when static instances are constructed
}
In C/C++ (using pseudo code)
void setColor(ColorEnum color)
switch (color)
{
case RED:
window.setColor(new Color([whatever gives Red]));
break;
case GREEN:
window.setColor(new Color([whatever gives Green]));
break;
case BLUE:
window.setColor(new Color([whatever gives Blue]));
break;
default:
window.setColor(new Color([whatever gives Default]));
break;
}
}
Same function in Java:
void setColor(ColorEnum color)
{
window.setColor(color.getColor());
}
This seems a bit easier to me than the C/C++ way and is
more object oriented (the reason we are using Java in the
first place). Anything related to the color is contained in
the Java enumeration, in the C/C++ version the information
is separate and scattered.
If I add a new color to the C/C++ code you just type a new
constant on the end of the enumeration, but then you have
to update any switch statements scattered through the
entire program to handle the new option. In Java I just add
the new color to the enumeration, and any places that use
my enumeration in the code are already done. This is the
basis for good design and reuse. Why shoot yourself in the
foot by coding against these quailities?
Enumerations are easy to setup in C/C++ but end up being
more difficult to use (and less object oriented). But once
you have a good enumeration class implemented in Java you
can extend it without the possibility of rewriting a good
chunk of your entire program.
Some people above object to having to handle null cases
with this type of Java enumeration. Well I'm assuming they
must ignore all the other places that a
NullPointerException can be thrown. Every single place you
use an object as a parameter you have the potential for
this. This is not something specific to this way of
implementing enumerations, it is a fact of Java coding. So
in effect is irrelevant to the discussion.
As mentioned above get the book Effective Java, it will be
the best money you have ever spent on a Java book.
Submitted On 11-FEB-2002
Ixchel
Just a note that RFE #4617197 ("Add Immutable Types to
Java") is tangentially related to this one, and should
probably be part of this discussion.
Submitted On 11-FEB-2002
dkf
I don't really think of colours as a natural enumerated
type, unless it has a *really* large number of items in it
(this machine can show 2**24 colours, and then there's
aliasing, etc.) By comparison, the number of days in the
week can be expected to be small and constant... :^)
Submitted On 13-FEB-2002
RhysP
Work! Work! Work!
So much work to do something SO simple!
Actually, I think it would be better to make it more Pascal-
like. Number ranges, for example.
Don't turn Java into C++!
Submitted On 20-FEB-2002
mkistler
I agree that there are many cases where enums are best
replaced by a class(-hierarchy), but please don't forget
the simple cases. For example, I often see boolean used as a
substitute for an enum with two values. To use classes in
these cases would be overkill.
Submitted On 21-FEB-2002
eca2503
Isn't this problem the same as 4093668, reported as of Nov
97?
Anyway, I voted for both !
Please fix in Java 1.5!!!
Submitted On 06-MAR-2002
evanmclain
Why not just add a typesafe enum class to java.util? No
need to put it in the language.
Submitted On 07-MAR-2002
davidtribble
There appear to be three reasons for adding enumerated types to Java:
1. Allows related sets of constants to be logically grouped together as a single
type. For example:
enum WeekDay
{
SUN, MON, TUE, WED, THU, FRI, SAT
}
Constants 'SUN' through 'SAT' (which are simply integer values) can only be
assigned to objects of type 'WeekDay' without using an explicit typecast
(to byte/int/short/long). This type-safety makes it easier to catch errors
when the wrong integer constants are assigned to variables or passed as
method arguments.
2. Allows methods to be overloaded on multiple user-defined integer types.
For example:
enum WeekDay { ... }
enum Color { ... }
void setAttribute(WeekDay wkday);
void setAttribute(Color col);
void setAttribute(int size);
Currently, methods can only be overloaded on four integer types, none of
which have minimum/maximum value ranges.
3. Allows for runtime verification that a given object (integer) of enum type
has a value that is within the defined range of its type. Consider:
enum Position { UP, DOWN, LEFT, RIGHT }
private Position m_pos = UP;
void setPos(int p)
{
m_pos = (Position) p; // [A]
m_pos++; // [B]
}
The JRE is free to throw a runtime exception (perhaps 'EnumOutOfRangeError')
at statements [A] and [B] if the value of member 'm_pos' exceeds the value
of 'RIGHT' or becomes negative.
The only drawback I see to enumerated types is the same drawback they
have in C++, which is that they are not complete first-class object types.
That is to say, they are not class types in and of themselves (being rather
a subset of the integer types). As such, enum types cannot be subclassed
and do not comprise an inheritance hierarchy. But I don't think this is a major
limitation.
Eiffel allows enumerated constants of a base class to be effectively "extended"
in derived classes, which might also be useful in Java. For example:
class Vehicle
{
enum Type
{
CAR, BOAT, AIRPLANE
}
}
class Automobile extends Vehicle
{
enum Type extends Vehicle.Type // [E]
{
COMPACT, MIDSIZE, COUPE, SEDAN, TRUCK
}
}
Classes 'Vehicle' and 'Automobile' both define an enum type named 'Type',
but the derived subclass adds more constants to its enum set. Thus enum
type 'Vehicle.Type' defines three constants, and 'Automobile.Type' defines
eight constants (three of which are inherited). The integer value of
'COMPACT' is 'AIRPLANE+1'. In addition, constants of type 'Vehicle.Type' are
assignable to variables of both type 'Vehicle.Type' and 'Automobile.Type',
but constants of type 'Automobile.Type' are only assignable to variables of
type 'Automobile.Type' (or any enum types derived from it).
The syntax shown at [E] is only a suggestion; the syntax and semantics need
to be worked out in more detail.
Submitted On 13-MAR-2002
daniel7
Regarding Ada's enumeration types, note that run-time values
used to implement values of enumeration types can be mapped
to and from the compile-time name of the enumeration value.
(I believe the syntax is roughly:
string := MyEnumType'IMAGE( myEnumTypeVariable );
and:
myEnumTypeVariable := MyEnumType'VALUE( string );
)
Also, I've implemented a C code generator for VHDL, a
language derived from Ada, and don't recall any performance
problems for enumeration types. At run time, enumeration
values were represented as integer values.
Now if only Java had scalar subtypes...
Submitted On 22-MAR-2002
walpj
In bugid 4487555, josgood points to a proposal from an IBM
research group for providing enumerations as a type of
lightweight class. The drawback, of course, is that it
allows operator overloading, which seems to be anathema to
business system developers.
[1]
http://www.research.ibm.com/people/d/dfb/papers/Bacon01Kava.
pdf
Submitted On 24-APR-2002
dleuck
Developers need better syntactic economics for type safe
enums. The private constructor approach is a joke. Its
so verbose even Javasoft developers consider it unusable
(as is evident in its absence from the Java libraries.)
Submitted On 24-APR-2002
MiguelM
If we get Enum support, could we please have support for using enumerated values in switch statements?
Thanks. I consider that to be the major drawback of the classes that have been written to workaround the
Enum problem.
Submitted On 25-APR-2002
zulfi_s
Yes, It's good to have enum in Java...Very much like to!!!
Submitted On 07-MAY-2002
zorc3
dleuck has a point. If the writing a class with a private
constructor is the "correct" way to do this then why doesn't
SwingConstants for instance do that? Instead like almost all
the AWT it uses int's. If the core Java classes don't do
this, honestly, who expects developers to?
Submitted On 15-MAY-2002
dkgibson
While I support adding enums to Java, here's what I use in
the interim:
abstract public class Enum extends Vector {
public class Value {
final public int value = Enum.this.size();
protected Value(){
Enum.this.add( this );
}
}
}
Now, maybe this is not as bulletproof as it should be, but
it's simple. Here's a usage:
class Color extends Enum {
final Value black = new Value(),
blue = new Value(),
red = new Value(),
//...
green = new Value();
}
Color color = new Color();
Color.Value borderColor = color.green;
If you need to associate additional value(s) at the POINT
OF DEFINITION (VERY IMPORTANT for maintainability) with a
Color.Value, subclass Enum.Value in Color:
class Color extends Enum {
class Value extends Enum.Value {
final String name;
Value( String name ){
this.name = name;
}
}
final Value black = new Value( "Black" ),
blue = new Value( "Blue" ),
red = new Value( "Red" ),
//...
green = new Value( "Green" );
}
Now, if Sun would just extend the switch statement to allow
non-integral objects, we'd be done.
Submitted On 16-MAY-2002
dkgibson
Whoops, the class Enum above should be:
abstract public class Enum extends Vector {
protected class Value {
final public int value = Enum.this.size();
public Value(){
Enum.this.add( this );
}
}
}
This is typesafe and provides a numeric value, iterators,
and enumerations.
Submitted On 13-JUN-2002
jessh
Given nice, simple stuff like dkgibson's, I'm not at all
convinced we need this as much as reduced memory
consumption and stability.
Submitted On 14-JUN-2002
dkgibson
"... extend HashSet. That way you can avoid duplication."
I don't understand; duplication of what? Hopefully the
enum values are unique. Extending Enum from HashSet would
make the Enum modifyable, which I didn't want, but I'll be
glad to listen to any arguments about why HashSet is better.
Submitted On 14-JUN-2002
dkgibson
See my enhanced version at
http://www.ultimeth.com/java/Enum.html, which everyone is
free to copy.
Given the flexibility of my Enum class, I'm removing my
vote for this RFE, although I still think Java should
extend the "switch" statement to allow objects.
Submitted On 14-JUN-2002
MiguelM
I wonder why dkgibson is extending Vector. It might make
more sense, and is probably a lot more efficient, to extend
HashSet. That way you can avoid duplication.
Submitted On 16-JUN-2002
martinpaulo
To dkgibson: Have you read all the comments made here? And
if so does your code address some of the problems raised,
especially the ones referenced in:
http://www.javaworld.com/javaworld/javatips/jw-
javatip122.html
??? I tried to look for myself, but your web pages do not
allow people in the pacific region to access them, giving
the following error: "Due to the amount of spam from Asia-
Pacific users, that entire region has been blocked"...
I would contact you directly, but you fail to give an e-
mail contact address...
I am also curious - given the fact that the code you have
submitted here had an error in it that needed correction,
and given its verbosity (see the references to Delphi style
type safe enums), do you really believe that your solution
saves developers time and effort?
Martin
Submitted On 18-JUN-2002
dkgibson
Whoops! Sorry about the blocked web site; I've removed
the Asia-Pacific web block for link I gave to
http://www.ultimeth.com/java/Enum.html (note that eMail
from Asia-Pacific is still blocked). This link directly
includes the source code I use, and as such, it is
occasionally updated. The source code now includes
solutions to the problems raised in
http://www.javaworld.com/javaworld/javatips/jw-
javatip122.html.
To Martin Paulo:
I don't know whether my code saves OTHER developers time
and effort, but it saves ME time and effort. I don't
consider it as compact as a C/C++ enum, but I don't
consider USING it all that verbose, either.
Dean
Submitted On 18-JUN-2002
shrink_laureate
The typesafe enum pattern would be simplified a little if
the RFE on language-level singletons was implemented.
http://developer.java.sun.com/developer/bugParade/bugs/47017
98.html
Submitted On 26-JUN-2002
martinpaulo
To dkgibson: I would really love to discuss this elsewhere,
but since you choose to bounce e-mail from Asia/Pacific
here goes: With your code, how would you stop the following?
<pre>
AllColors colors1 = new AllColors(); // creates one enum
AllColors colors2 = new AllColors(); // creates another
enum!
if (colors1.blue == colors2.blue) {
System.out.println("blue == blue");
} else {
System.out.println("blue != blue"); // This is printed!!
}
</pre>
Submitted On 02-JUL-2002
dnoyeB
I don't need type safe Enums. But I would use them if they
were here.
They will put sun in a pickle. If they make type-safe
enums people will wonder why they aren't using them.
But consider the hit Sun would take by turning "ints"
into "Objects..."
Submitted On 04-JUL-2002
dkgibson
Having to construct a container object that contains the
enumeration objects is probably a necessary byproduct of
using inheritance for the AbstractList and solving the
serialization problem. Off the top of my head, the way I'd
solve the problem Martin Paulo raises below is to either:
1. make the derived constructor throw an exception if it
is called more than once (requires a static member in the
derived class); or
2. write a static factory method in the derived class which
does the same thing.
However, sometimes I want to be able to (and I do)
construct multiple AllColors enum collections, and I don't
intend for them to match (they have other values associated
with them that don't match, even though they have the same
variable name). Thus, the solution I propose above is
probably best left to the individual derived class
definition (which I agree makes it slightly more verbose):
private static int instantiationCount = 0;
...
if ( instantiationCount++ > 0 ){
throw DuplicateEnumException();
}
Submitted On 06-JUL-2002
dkgibson
Yes, type-safe enums would be nice. However, in almost
every case of declaring an enum, there is other data
associated with the enum (e.g., the definitiion of
a "color", or the number of days in a month, etc.). I've
always thought that separating the declaration of enum
values from the declaration of the associated data is a bad
idea; it makes maintenance of the two lists (enums and
data) error-prone. With my definition of the Enum class
(see previous posting above), this problem is solved.
Submitted On 11-JUL-2002
NguyenQ
Include it, because it's so natural.
Submitted On 29-JUL-2002
bugleboy
Any solution that is:
a) typesafe
b) at its core a native type, with native-type efficiency
c) usable as native, esp. for switch statements
d) easily convertable to a numeric value for persistence in
databases, etc.
Less important but also highly relevant:
ability to assign specific numeric values that must be unique.
This way it is reasonable to protect and preserve persisted
values in storage while extending the set of enums.
Submitted On 09-AUG-2002
jacyg
I find it most distressing to read the comments of some
people who suggest that this and other features should be
there b/c "C# has it". There are some intriguing features
in C#, but there are also some good arguments for the "less
is more" crowd as well. Personally, I think that C#'s
treatment of enums does actually amount to "something" b/c
of the extra type-safety it introduces when properly used.
That said, I think that this and many of the other arguments
in the RFEs would be better framed in terms of fundamental
goals. I would posit that the fundamental goal we should be
pursuing as software engineers is to write verifiably
correct, bug-free code that is easy to maintain and
understand. Attempts should be made to adopt those language
features that further that goal, and other features, even if
they can be nifty, should be rejected.
When looking at it in this light, I think that a clear
argument can be made for enums. They give compile-time
safety, and they also make libraries easier to understand.
If you have a library class that has a method which takes an
int, and you intend it to be one of several public static
final ints, how is an external developer to know this? By
reading the documentation, presumably; but this puts more of
a burden on the documentation that it should be made to
bear. If, instead, your method takes an enum argument, it
is immediately clear to the external developer what the
valid values are. These are two very good reasons that are
consistent with the fundamental goal stated above.
This argument can not be made for some other features
mentioned by others on this page, such as properties and
operator overloading. Both do not do anything to further
the stated goal. Instead, they are both just an alternate
syntax for methods--and it can easily be argued that having
too many ways of doing the same thing makes for less
understandable and less maintainable code. This is
particularly true for operator overloading, but is also true
for properties as well.
The world is drowning in buggy, poorly engineered code. I,
for one, am all for anything that furthers Java as the
language best suited to software engineering rather than
just writing code....
Submitted On 14-AUG-2002
hopfen
A primative enumeration type allows you to catch errors at
compile time. A non-primative enumeration type can't be
caught at compile time. There are workarounds but all
workarounds come with some maintenance cost and chance
for abuse. If you aren't trying to mimic primative enumeration
types, you're doing something naughty.
The big debate, I suppose, would be the type of operations
that you would allow on enums and the syntax.
Submitted On 21-AUG-2002
viperizer
I dont have much to say about my experience or qualification
I have but personally I think Java should implement enum
simply because:
1. It provides a standard way, like most of the Java library
did.
2. Home grown enum type (type safe) will incure runtime
overhead and raise other issue (e.g. Serialization). While
nontype safe will keep us worry that some one (or ourself)
will break our code without us knowing.
3. Code will be clearer and more straightforward. Enum means
enum and static final means CONSTANT.
With the reason above, you got my vote here.
Submitted On 22-AUG-2002
dkf
There are two uses for 'static final int's, only one of
which is addressed by having enums. The first is to provide
a set of distinct values for where creating new objects is
either overkill or otherwise unlikely to help (sometimes it
is easier to make the major axis of functionality go along a
different part of the class structure.) The second is to
provide a set of independent flags (e.g. a singing *and*
dancing Foo instance) where it is clear that the entire set
of flags is not known currently. I've seen both used by C
programmers, and I get the impression that many people
involved in Java have that sort of heritage...
Enumerations should only really tackle the first of these.
OK, C can use them for both (the second would force support
for control of the integer value for a particular enum
value) but that's one of the suckier features of C...
Submitted On 10-SEP-2002
sarge_chris
Using static final ints is nasty.
Type-safe enumeration 'pattern' is OK but cumbersome.
Java needs enum support built-in, if only to stop the endlessly
repeated discussions re. enumerations on the forums!
- sarge
Submitted On 02-OCT-2002
liebelt
I would strongly prefer that java is not enhanced with stuff
like that. The "pollution factor" isn't worth the benefit.
Introduction of C++-like enums will mainly support people to
program in a non OO way using switch statements instead of
polymorphism to realize different behaviours. If you do
program in an object oriented way there pretty seldom
occurs the need for enums. Most of the enumeration-like
things I found in existing code fall into the following two
categories:
1. Sometimes one might want to use enums as parameters to
control the behaviour of methods. If a redesign does not
solve the situation or is not appropriate, most of the times
you can still get around here elegantly by using one or more
boolean parameters. If you do it that way, you typically get
more readable code. No need for a language extension from
that aspect.
2. If you want to implement state machines you typically
have some behaviour associated with the states. If you do it
OO like you would have to implement the states as separate
(e.g. anonymous) classes and implement at least part of the
behaviour by overriding/implementing some methods of a base
class/an interface of a general "state". Therefore C++-like
enums are not appropriate here. No need for a language
extension from that aspect, too.
Even in the cases where enums are appropriate in fact - e.g.
when implementing an enumeration of some colors - they are
better represented by the typesafe enum pattern because by
doing so you provide an appropriate place for future
extensions like e.g. a method to retrieve the RGB color value
of any color. I think this outweighs the few extra characters
you have to type. Extensibility is a major design goal - saving
some characters isn't.
By the way: Serialization of REFERENCES TO enum members
DOES work automatically if you have at least one instance
variable (e.g. a number) with a unique content per enum
entry and implement and use equals() for all comparisons.
This is completely sufficient for most situations. It is not
necessary to serialize the typesafe enum class itself (nor is
this possible in C++).
Submitted On 09-OCT-2002
scolebourne
Due to Sun's inaction, an Enum class based implementation
has been added to Apache Jakarta Commons Lang -
http://jakarta.apache.org/comms/lang.html - a general
purpose library of language extensions.
Submitted On 09-OCT-2002
MDECOSTER
For a good quality of a development, it is necessary to have
the code more clearer and more straightforward. So I think
that static final means constant and can't be used as enums.
Therefore I think that Java should implement enum.
Submitted On 04-NOV-2002
bestsss
This is the second time I like to vote AgainsT. Please add
an option.
I, myself, ain't a fan of "Effective Java" 's TypeSafe enums
'cause the pattern is so ineffective on (de)serialization.
In the momment I am quite happy w/ Java functionality.
<<"I don't know why less is more and love is blind.">>
Submitted On 14-NOV-2002
dkf
Deserialization should be possible, but it requires writing
extra methods to force the singleton-ness of enums. And you
still can't switch(){...} on them.
Submitted On 02-DEC-2002
bestsss
yes, dkf! that's why I call it ineffective (both
serialization/deser.)
Submitted On 04-DEC-2002
shrink_laureate
It's happening! JSR 201! It's real!
Submitted On 17-DEC-2002
p.lavarre
Nuts, wrong link, sorry, JSR 201 combines much, I meant:
http://jcp.org/aboutJava/communityprocess/
jsr/tiger/enum.html
Submitted On 17-DEC-2002
p.lavarre
JSR 201 differs from others having a clear detailed
explanation available online:
http://jcp.org/en/jsr/detail?id=201
http://jcp.org/aboutJava/communityprocess/
jsr/tiger/autoboxing.html
Submitted On 17-DEC-2002
Majeed_Arni
Sun need to add enum feature with better type checking that
C++.
enum XYZ = { X, Y, Z } ;
Now I should be able to switch on that, have method foo(
XYZ param) take as parameter, able to convert other type to
XYZ. Since this is a new feature, it should not impact other
Java core code.
Submitted On 28-JAN-2003
pmurray
I participated in a system that made heavy use of enum
classes in EJBs to represent databse columns that always had
one of a small set of values.
The real power of this is being able to add methods to the
class.
class FeeType {
// ... private instance variables etc
public static FeeType YEARLY = new FeeType
("Y", "Yearly");
public static FeeType WEEKLY = new FeeType
("W", "Weekly");
public static FeeType AS_REQD = new FeeType("R", "As
Required");
public static FeeType ONE_OFF = new FeeType("O", "Initial
Only");
public boolean isPeriodic() {
return equals(YEARLY) || equals(MONTHLY);
}
}
Using this pattern, one can write
if(customer.getFeeType().isPeriodic()) {
// check date due for next payment
}
and so on. It's really very handy and far more expressive than
an enum that mimicks a primitive type.
Submitted On 11-FEB-2003
shrink_laureate
pmurray, read the JSR. You'll find it allows you to do almost
exactly what you wrote:
enum FeeType {
YEARLY ("Y", "Yearly"),
WEEKLY ("W", "Weekly");
AS_REQD ("R", "As Required");
ONE_OFF ("O", "Initial Only");
FeeType(String code, String meaning) { ... }
public boolean isPeriodic() {
return equals(YEARLY) || equals(MONTHLY);
}
}
Submitted On 11-FEB-2003
shrink_laureate
Ok, my typing was sloppy. Those should have been commas,
not semi-colons:
YEARLY ("Y", "Yearly"),
WEEKLY ("W", "Weekly"),
AS_REQD ("R", "As Required"),
ONE_OFF ("O", "Initial Only");
Submitted On 21-FEB-2003
dkf
And it's even better than that, as it fixes it so that you can
use these enums in a switch()...
Now all we need is an option to make the enums whistle Dixie
while we're using them... :^)
Submitted On 04-MAR-2003
JMikus
<AlexC>The Enumeration is actually a much lower level
Computer Science entity. It lies *under* ints, not above
them. I.e the concepts of first, second and third are deeper
concepts than those of 1, 2, and 3, which are essentially the
intervals in the former series. It would be more correct to
describe the integer type and operators as syntactic sugar
on the underlying enumaration class.<AlexC>
Now here is someone with math base. Great! Totally agree. In
any case, look on Pascal sets for inspiration, not on C enums.
Submitted On 19-MAY-2003
jimoore
The article at the following link provides a mini-language
for defining enums and a small "compiler" that translates
this mini-language into Java source code. You may find this
useful while waiting for version 1.5, or even after the
release of 1.5 where upgrading is not practical.
http://www.onjava.com/pub/a/onjava/2003/04/23/jenum.html
Submitted On 08-SEP-2003
dkf
Ah, so it is going in? Excellent!
Submitted On 15-NOV-2003
alidemir
It is nowadays common practice for in many APIs to throw in
an Interface that declares ALL Integer constants that the
methods in the API take as parameter or return as result.
Immediate example is the SWT class. When it is time to call a
function that takes an int as a parameter, there is no way to
know which one of these constants are meaningful to pass in.
This is not syntactic sugar. This is one of the most necessary
features a language must have. Who cares if there is GC,
when I spend 10 hours a day looking for non-existing
documentation to figure out what the hell that integer
constant I am supposed to pass in is. I would rather spend
time managing my own memory. Would enums not provide
enough expressive power? You want me to create classes and
instances just so that a stupid GC algorithm wastes half its
time trying to figure out if they are in use or not? What are
you gonna do when memory size grows faster than CPU
speed?
Submitted On 15-NOV-2003
alidemir
So much said, so little accomplished. Life without enums is
not worth living.
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|