Thanks a lot.
Nico.

2007/9/28, Engelking, Nicholas <[EMAIL PROTECTED]>:
> 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]
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to