Unfortunately, the short answer is that you can't. The compiler will yell at you about class literals for generics because in Java they are implemented using erasure. This is in contrast to C# (which is where I first learned how to use generics) and annoys many people to no end. It was done to maintain binary compatibility between generic and non generic versions of classes and to ensure generic classes could run on JVMs that have no concepts of generics. The compiler basically makes all your generic methods use Object and inserts casts that are garneted to be safe by the compiler.
At run time the method Optional opt = composite.<Optional> getFeature(); Looks like Optional opt = (Optional) composite. getFeature(); To the JVM (more or less) T.class doesn't work because class literals are resolved at runtime (even though as a programmer you know what they are at compile time). Since a T type is really an Object type, T.class makes no sense and doesn't give you the object you want. For the method you describe, you can still avoid the casts using generics but you need a parameter that takes an object representing a type, not a parameter that IS a type, since type parameters aren't really method parameters in the normal sense. public <T> T getFeature(Class<T> clazz) { return aggregators.get( clazz ); } Then you can call the method like so Optional opt = composite.getFeature( Optional.class ); And there are no casts required. This comes from the fact that class objects are now parameratized to there class. So for example: String.class Will return a Class<String> object. It doesn't seem ideal but it's as close as you can get with the way Generics are implemented in Java. You will have problems though if the caller of your method uses type parameters instead of explicit types. For example: public class OptionWrapper<T> { private final Composite composite; public OptionWrapper(Composite composite) { this.composite = composite; } public T getOpt() { //needs a class object! T opt = composite. getFeature(); return opt; } } Hope this helps. -----Original Message----- From: nicolas de loof [mailto:[EMAIL PROTECTED] Sent: September 28, 2007 4:54 AM To: Struts Users Mailing List Subject: Re: [ot] help on generics... Thanks a lot for those detailed examples ! I don't want to setup a factory, but to expose internals as optional features : my class is a composite, with a map of "features", where the key is the feature interface ( Map<Class, Object>) I'd like to get an optional feature using : Optional opt = composite.getFeature( Optional.class ); The generics way seems to be : Optional opt = composite.<Optional> getFeature(); How can I then get the Class object used as generics type, to get it from the map ? public <T> T getFeature() { return aggregators.get( T.class ); // Doesn't work } 2007/9/27, Engelking, Nicholas <[EMAIL PROTECTED]>: > > Specifically, you could use > > public <T> T getInstance(Class<T> clazz) > throws InstantiationException, IllegalAccessException{ > return clazz.newInstance(); > } > > The Class<T> object has a method newInstance() that creates an instance of a > class with the default constructor. The exceptions it throws represent cases > where you don't have visibility permissions for the constructor, there is no > default constructor, the class is abstract, or the constructor call throws an > error (which is then wrapped and rethrown). The method outlined above is just > a wrapper - if you already have the class object you can just instantiate it. > If you need to not use the default constructor, try something like: > > public <T> T getInstance(Class<T> clazz) > throws IllegalArgumentException, > SecurityException, > InstantiationException, > IllegalAccessException, > InvocationTargetException, > NoSuchMethodException { > return clazz > .getConstructor( > Parameter1Type.class, > Parameter2Type.class) > .newInstance( > parameter1, > parameter2); > } > > The getConstructor methods takes all they types for it's parameters in > declaration order. This is to resolve the method signature. In this class > your class would have a constructor: > > MyClass(Parameter1Type parameter1, Parameter2Type parameter2){ > // constructor stuff here > } > > The newInstance method takes the actual parameters to pass to the > constructor. In this example, they are parameter1 (which is a Parameter1Type) > and parameter2 (which is a Parameter2Type). The errors occur if the > constructor doesn't exist, the arguments are the wrong type, the caller > doesn't have visibility permissions, the class is abstract, or the > constructor throws an error (which is then wrapped and rethrown). > > You could also pass the parameters into the getInstance method and pick out > the constructer dynamically like so: > > public <T> T getInstance(Class<T> clazz, Object... args) > throws InvocationTargetException { > T newObject = null; > for (java.lang.reflect.Constructor<T> c : > clazz.getConstructors()) { > // try creating objects with the passed > // args until one works. > try { > newObject = c.newInstance(args); > break; > } catch (IllegalArgumentException e) { > } catch (InstantiationException e) { > } catch (IllegalAccessException e) { > } > } > return newObject; > } > > This method returns an instance of the class passed created with the > constructor parameters passed. If the constructor throws an error it is > wrapped in an InvocationTargetException and rethrown. If no constructor > matches the method returns null. > > > -----Original Message----- > From: Giovanni Azua [mailto:[EMAIL PROTECTED] > Sent: September 27, 2007 11:56 AM > To: Struts Users Mailing List > Subject: Re: [ot] help on generics... > > how about: > > public static <T> T > getInstance(Class<T> aClass) > { > // TODO: > } > > regards, > Giovanni > > nicolas de loof wrote: > > Hello, > > > > my question is fully off topic, but Struts2 is the only java5 project I > > know. > > > > I'd like a method to return an instance of a class passed as parameter : > > > > public Object getInstance( Class clazz ) > > > > I'd like to use generics to make the return type in sync with the > > class type. Is this possible ??? > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: [EMAIL PROTECTED] > > For additional commands, e-mail: [EMAIL PROTECTED] > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > > ******************** > NOTICE OF CONFIDENTIALITY > This communication including any information transmitted with it is > intended only for the use of the addressees and is confidential. > If you are not an intended recipient or responsible for delivering > the message to an intended recipient, any review, disclosure, > conversion to hard copy, dissemination, reproduction or other use > of any part of this communication is strictly prohibited, as is the > taking or omitting of any action in reliance upon this communication. > If you receive this communication in error or without authorization > please notify us immediately by return e-mail or otherwise and > permanently delete the entire communication from any computer, > disk drive, or other storage medium. > > If the above disclaimer is not properly readable, it can be found at > www.td.com/legal > > AVERTISSEMENT DE CONFIDENTIALITE > Ce courriel, ainsi que tout renseignement ci-inclus, destiné uniquement > aux destinataires susmentionnés, est confidentiel. Si vous > n'êtes pas le destinataire prévu ou un agent responsable de la > livraison de ce courriel, tout examen, divulgation, copie, impression, > reproduction, distribution, ou autre utilisation d'une partie de ce > courriel est strictement interdit de même que toute intervention ou > abstraction à cet égard. Si vous avez reçu ce message par erreur ou > sans autorisation, veuillez en aviser immédiatement l'expéditeur par > retour de courriel ou par un autre moyen et supprimer immédiatement > cette communication entière de tout système électronique. > > Si l'avis de non-responsabilité ci-dessus n'est pas lisible, vous > pouvez le consulter à www.td.com/francais/legale > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]