Generic (parametrized) enums

Hi,

I have just read generics FAQ by Angelika Langer and I am wondering

why it is not allowed to have generic enums. I understand, that the only

problem is it doesn't make any sense to use a generic type in a static context

(at least in "normal" generic types). However, considering that it doesn't make

any sense to instantiate two (or more) the same enum types (and it is illegal),

it is perfectly safe to let static fields use type parameters. So I suppose the only

problem Sun had was how to implement it. That would probably caused a lot of

changes in the compiler implementation. What do you think about it ?

Cheers,

Adrian

[701 byte] By [AdrianSosialuka] at [2007-11-27 4:53:00]
# 1
have you read this: http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html
suparenoa at 2007-7-12 10:07:13 > top of Java-index,Core,Core APIs...
# 2
@supareneo: why should the introduction to enum help?@Adrian: which part exactly of Angelika's FAQ on generic enums did you not understand? The example seems glassy to me.
stefan.schulza at 2007-7-12 10:07:13 > top of Java-index,Core,Core APIs...
# 3
> @supareneo: why should the introduction to enum> help?@stefan.schulz:it will show him how to use enum...
suparenoa at 2007-7-12 10:07:13 > top of Java-index,Core,Core APIs...
# 4

It's not that I didn't understand something Stefan.

Have a look at this:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6408723

That seems to be reasonable, although it's got some drawbacks as well.

Now Angelika says true:

"Example (of an illegal generic enum type):

public enum Tag<T> { // illegal, but assume we could do this

good, bad;

private T attribute;

public void setAttribute(T arg) { attribute = arg; }

public T getAttribute() { return attribute; }

}

This enum type would be translated to a class that roughly looks like this:

public class Tag<T> extends Enum<Tag><T>> {

public static final Tag< ? > good;

public static final Tag< ? > bad;

private static final Tag $VALUES[];

private T attribute;

private Tag(String s, int i) { super(s, i); }

static {

good= new Tag("good", 0);

bad= new Tag("bad" , 1);

$VALUES = (new Tag[] { good, bad });

}

public void setAttribute(T arg) { attribute = arg; }

public T getAttribute() { return attribute; }

}

"

Let's see why it is a bad idea to use type parameters in static context:

MyClass<T> {

public static void doSomething(T t) {...}

}

...

MyClass<Integer> m1=new MyClass<Integer>();

MyClass<String> m2=new MyClass<String>();

MyClass.doSomething(?); // <-- what are we supposed to pass

// in here - Integer or String ?

Now one could say that we could do something like this:

MyClass.<String>doSomething(stringRef);

but it hasn't got much sense since we are not using the type parameter

taken from initialization of the class.

As for enums, what we could do is:

enum Tag<T> {

First<T>, Second<T>

}

which would be translated into something like this:

class Tag<T> extends Enum<Tag><T>> {

public static final Tag<T> First;

public static final Tag<T> Secons;

}

Why it would be possible ? How do we create enums ? We do:

enum Tag<String> {First<String>, Second<String>}

The point is, that we can't make another enum Tag - there is

only one class Tag, so we wouldn't be able to do something like this anyway:

enum Tag<Integer> {First<Integer>, Second<Integer>}

That's where we get type safety and are not interfering with static

context problem. The only problem to overcome would be to code

it somehow into a class by the compiler not to have this static context

problem (or treat it in a special way by the compiler, so it could say:

"ok - this is enum, so I allow to use class' type parameter in a static

context - but this is only here where it can be done.")

I hope that I have expressed what I wanted to say in a better way now ;)

Thanks,

Adrian

AdrianSosialuka at 2007-7-12 10:07:13 > top of Java-index,Core,Core APIs...
# 5

enum values are globally static instances of subclasses of the Enum class. They are created once, and there is only one instance of that subclass for each value. Who and where should the generic parameter be set and to what value?

You don't create enums, enums are created by the compiler for you. There is actually no use to introduce generic parameters, as you cannot instantiate an enum and, thus, give it a different type than already known at compile time.

stefan.schulza at 2007-7-12 10:07:13 > top of Java-index,Core,Core APIs...
# 6

Hi,

Thanks for quick answer.

You are right - it doesn't make any sense. One could try to do it

that way:

public enum UserInfo<T> {

FirstName<T>,

LastName<T>,

UserSince<T>,

LastLogin<T>;

}

public <T> void setUserInfo( UserInfo<T> infoType, T infoValue ) {}

so you could call this method like:

setUserInfo(FirstName<String>, "Name"); // <-- that should be ok

setUserInfo(UserSince<Date>, "31/12/2003"); // <-- that should issue an error

but since you would have to explicitly provide the type, safety is no longer safe ... :/

And if you would be able to instantiate it like this:

public enum Something<String> {ONE, TWO, THREE}

then that would mean that all the static fields would have to be the same

type, which doesn't make any sense again ... (because as you said it's

not me who instantiate the class, but the compiler). We would have to have

some kind of a factory method there to be able to do such thing. I wonder

if that would help in any way ...

I give up - I couldn't expect to be smarter then the developers team at Sun ... ;)

Thanks for explanation and good point :)

Cheers,

Adrian

AdrianSosialuka at 2007-7-12 10:07:13 > top of Java-index,Core,Core APIs...