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]