Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #25803 > unrolled thread

limitations on using enum as generic parameter

Started by"dalamb@cs.queensu.ca" <david.alex.lamb@gmail.com>
First post2011-02-08 09:50 -0800
Last post2011-02-08 10:38 -0800
Articles 8 — 7 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  limitations on using enum as generic parameter "dalamb@cs.queensu.ca" <david.alex.lamb@gmail.com> - 2011-02-08 09:50 -0800
    Re: limitations on using enum as generic parameter Lew <noone@lewscanon.com> - 2011-02-11 07:36 -0500
    Re: limitations on using enum as generic parameter Daniele Futtorovic <da.futt.news@laposte.net.invalid> - 2011-02-08 20:36 +0100
    Re: limitations on using enum as generic parameter Ken Wesson <kwesson@gmail.com> - 2011-02-08 19:46 +0100
    Re: limitations on using enum as generic parameter Roedy Green <see_website@mindprod.com.invalid> - 2011-02-10 22:50 -0800
    Re: limitations on using enum as generic parameter Roedy Green <see_website@mindprod.com.invalid> - 2011-02-10 22:47 -0800
    Re: limitations on using enum as generic parameter markspace <nospam@nowhere.com> - 2011-02-08 10:34 -0800
      Re: limitations on using enum as generic parameter Lew <lew@lewscanon.com> - 2011-02-08 10:38 -0800

#25803 — limitations on using enum as generic parameter

From"dalamb@cs.queensu.ca" <david.alex.lamb@gmail.com>
Date2011-02-08 09:50 -0800
Subjectlimitations on using enum as generic parameter
Message-ID<76e9be77-f846-4559-82ec-1d774a8a6a0b@q36g2000yqn.googlegroups.com>
I am playing around with using enums and generics together in Java 1.5
(yes, I know it's in end-of-life, but it would be a bit of trouble
right now to go to 1.6 let alone 1.7).  Having figured out some simple
situations, I tried writing a generic class that takes an enum as a
type parameter.  Unfortunately I don't seem to be able to invoke the
enum's values() method -- javac says "Cannot find symbol: method
values()".  (the reference to Enum.valueof later also gets errors,
which is why I commented it out to simplify the test).

Is there any way around this, or is there just no way to refer to an
enum's values() method when the enum is a generic parameter?

Here's the code; interface MessageCode should be irrelevant because it
could be any old interface for the purposes of this example:

public class EnumCodeSet<E extends Enum & MessageCode>
				   //    implements MessageCodeSet
{
    private E[] enums;
    public EnumCodeSet() {
	enums = E.values();
    }

    public MessageCode get(int index)
	throws IndexOutOfBoundsException
    {
	return enums[index];
    } // get

    public MessageCode valueOf(String name)
	throws IllegalArgumentException, NullPointerException
    {
	// return Enum.valueof(E,name);
    } //
} // end class EnumCodeSet

[toc] | [next] | [standalone]


#25849

FromLew <noone@lewscanon.com>
Date2011-02-11 07:36 -0500
Message-ID<ij3af9$d2i$1@news.albasani.net>
In reply to#25803
"dalamb@cs.queensu.ca" wrote, quoted or indirectly quoted someone who said :
>> (yes, I know it's in end-of-life, but it would be a bit of trouble
>> right now to go to 1.6 let alone 1.7

Roedy Green wrote:
> It is actually surprisingly easy. Just download the JDK. Install,
> uninstall the old JDK, set JAVA_HOME, optionally recompile the
> universe. Tell your IDE where your new JDK is.  I have yet to find a
> JDK 1.5 program that won't compile and run just fine under JDK 1.6.

It can happen and I've seen it, but they're rare.  A couple of the interfaces 
have changed, notably 'javax.sql.RowSet' and 'java.sql.ResultSet'.  Code that 
implements that interface for Java 5 will not compile correctly for 6 unless 
you implement the new methods.  Also, '@Override' raises a warning if the 
supertype is an interface in 5, but omitting it in that situation raises a 
warning in 6.

It is quite rare to run into the former (most people don't compile their own 
JDBC code, but some do).  The latter is a minor annoyance.

I haven't run into other scenarios where the transition is difficult. 
Normally it's as transparent as Roedy indicates.

> I generate 1.5 class files using the JDK 1.6 compiler with -target
>
> see http://mindprod.com/jgloss/jdk.html

-- 
Lew
Ceci n'est pas une fenêtre.
.___________.
|###] | [###|
|##/  | *\##|
|#/ * |   \#|
|#----|----#|
||    |  * ||
|o *  |    o|
|_____|_____|
|===========|

[toc] | [prev] | [next] | [standalone]


#25874

FromDaniele Futtorovic <da.futt.news@laposte.net.invalid>
Date2011-02-08 20:36 +0100
Message-ID<iis5v1$6o3$2@news.eternal-september.org>
In reply to#25803
On 08/02/2011 19:38, Lew allegedly wrote:
>
> Also, generics and arrays don't mix.  So don't mix them.

While that is perfectly true, I think it's mostly misleading in this 
context. Arrays of enum instances are fine.

-- 
DF.

[toc] | [prev] | [next] | [standalone]


#25903

FromKen Wesson <kwesson@gmail.com>
Date2011-02-08 19:46 +0100
Message-ID<4d518f96$1@news.x-privat.org>
In reply to#25803
On Tue, 08 Feb 2011 09:50:32 -0800, dalamb@cs.queensu.ca wrote:

> Is there any way around this, or is there just no way to refer to an
> enum's values() method when the enum is a generic parameter?
> 
>     public EnumCodeSet() {
> 	enums = E.values();
>     }

That's not going to work. It's a static method of a class that isn't 
determined at this point in the code, so the compiler simply has no clue 
what to call. Hence the error message.

If you really need to do something like this, you'll need to use 
reflection on a class object. Giving your class's constructors an added 
Class<E> argument that gets stored in a type_token field and gets used 
for reflection will work.

Reflection is slow, so the constructor should probably grab the values 
and store them in an instance field. It looks like you were calling 
values in your constructor anyway, so it turns from

public EnumCodeSet() {
    enums = E.values();
}

to

public EnumCodeSet (Class<E> type_token) {
    enums = type_token.getMethod("values").invoke(null);
}

Of course, when you make an EnumCodeSet you now have to pass the enum 
class as a parameter to the constructor, e.g. new EnumCodeSet
(MyEnum.class).

You'll have to do something similar at the other site where you had an 
error, or (better) store the reflectively-obtained result in an instance 
field in the constructur and use the new instance field where you had the 
error.

[toc] | [prev] | [next] | [standalone]


#25937

FromRoedy Green <see_website@mindprod.com.invalid>
Date2011-02-10 22:50 -0800
Message-ID<ftm9l65p83614vkg8cllgv0i9jjcmovgo6@4ax.com>
In reply to#25803
On Tue, 8 Feb 2011 09:50:32 -0800 (PST), "dalamb@cs.queensu.ca"
<david.alex.lamb@gmail.com> wrote, quoted or indirectly quoted someone
who said :

>javac says "Cannot find symbol: method
>values()".  (the reference to Enum.valueof later also gets errors,
>which is why I commented it out to simplify the test).

Even though enums are under the hood implemented as nested classes,
the Java language does think of enums as being classes or inheriting
from anything.  You are trying to use them as if they were ordinary
classes.

To pull that off you would have to re-invent enums as ordinary
classes.  To do that, have a look at the various enum decompilations I
have posted at http://mindprod.com/jgloss/enum.html

-- 
Roedy Green Canadian Mind Products
http://mindprod.com
Your top priority should be fixing bugs. If you carry on development,
you are just creating more places you will have to search for them.

[toc] | [prev] | [next] | [standalone]


#25988

FromRoedy Green <see_website@mindprod.com.invalid>
Date2011-02-10 22:47 -0800
Message-ID<pjm9l6t5ag5r0jub4tn1votfl8llcqk3jl@4ax.com>
In reply to#25803
On Tue, 8 Feb 2011 09:50:32 -0800 (PST), "dalamb@cs.queensu.ca"
<david.alex.lamb@gmail.com> wrote, quoted or indirectly quoted someone
who said :

>(yes, I know it's in end-of-life, but it would be a bit of trouble
>right now to go to 1.6 let alone 1.7

It is actually surprisingly easy. Just download the JDK. Install,
uninstall the old JDK, set JAVA_HOME, optionally recompile the
universe. Tell your IDE where your new JDK is.  I have yet to find a
JDK 1.5 program that won't compile and run just fine under JDK 1.6.

I generate 1.5 class files using the JDK 1.6 compiler with -target 

see http://mindprod.com/jgloss/jdk.html
-- 
Roedy Green Canadian Mind Products
http://mindprod.com
Your top priority should be fixing bugs. If you carry on development,
you are just creating more places you will have to search for them.

[toc] | [prev] | [next] | [standalone]


#25996

Frommarkspace <nospam@nowhere.com>
Date2011-02-08 10:34 -0800
Message-ID<iis2c4$egq$1@news.eternal-september.org>
In reply to#25803
On 2/8/2011 9:50 AM, dalamb@cs.queensu.ca wrote:

> situations, I tried writing a generic class that takes an enum as a
> type parameter.  Unfortunately I don't seem to be able to invoke the
> enum's values() method -- javac says "Cannot find symbol: method


Yes, values() and valueOf(String) are /static/ methods.  They don't 
appear on the Enum interface so the compiler doesn't know about them.

You can try object.getClass().getEnumConstants() to get the constants 
themselves in order.

Also you should probably be declaring you enum as <E extends Enum<E> & ...>.

Untested:

public class EnumCodeSet<E extends Enum<E> & MessageCode>
{
   private final E[] enums;

   public EnumCodeSet( E anEnum ) {
     enums = anEnum.getClass().getEnumConstants);
   }

   public MessageCode index( int i ) {
     return enums[i];
   }

   //... etc.
}

[toc] | [prev] | [next] | [standalone]


#26226

FromLew <lew@lewscanon.com>
Date2011-02-08 10:38 -0800
Message-ID<c93f15ae-9766-42f3-9bb0-18cea537e111@u14g2000vbg.googlegroups.com>
In reply to#25996
On Feb 8, 1:34 pm, markspace <nos...@nowhere.com> wrote:
> On 2/8/2011 9:50 AM, dal...@cs.queensu.ca wrote:
>
> > situations, I tried writing a generic class that takes an enum as a
> > type parameter.  Unfortunately I don't seem to be able to invoke the
> > enum's values() method -- javac says "Cannot find symbol: method
>
> Yes, values() and valueOf(String) are /static/ methods.  They don't
> appear on the Enum interface so the compiler doesn't know about them.
>
> You can try object.getClass().getEnumConstants() to get the constants
> themselves in order.
>
> Also you should probably be declaring you enum as <E extends Enum<E> & ...>.
>
> Untested:
>
> public class EnumCodeSet<E extends Enum<E> & MessageCode>
> {
>    private final E[] enums;
>
>    public EnumCodeSet( E anEnum ) {
>      enums = anEnum.getClass().getEnumConstants);
>    }
>
>    public MessageCode index( int i ) {
>      return enums[i];
>    }
>
>    //... etc.
>
>
>
>

Also, generics and arrays don't mix.  So don't mix them.

--
Lew

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web