Thanks Marcelo, for answering that question for me. I was about to
fire up the javadocs to refresh my memory, but, yes,
getGenericAnything() is generally the method to use to get reflective
access to this stuff. It's annoying (in that you need to use a lot of
casts and instanceof checks; most of those methods return a 'Type' and
Type is pretty much a flag interface only, utterly useless on its own.
Ironic isn't it? Generics were meant to reduce casting. And it does,
but there's a lot more of it now when trying to reflect generics info
out).
The general rule of thumb is: Think about the role of the compiler.
Does the compiler need to mention the explicit type in the class file?
If yes, then, you can reflect it.
In:
public List<String> getNames(); - the compiler NEEDS to put that
String in the class file. Otherwise, how would another java source
file, calling this method, know about the String stuff?
in case of:
public <T> List<T> singletonList(T item); - the compiler obviously
needs to say that this method has a 'T', and that the return type is a
List of the same element that you feed into it, but there's no actual
class type (like 'String'), involved here, so obviously it won't be
there.
public List<String> list = new ArrayList<String>(); - in this case,
the FIELD knows about the 'String', but the OBJECT (list) does *NOT*.
Objects never know about their generics. Just Fields and Methods and
Classes.
public class MyList extends AbstractList<String>{}; - yes, you can get
that 'String' with reflection.
Object x = new MyList(); - by using a combo of
x.getClass().getGenericSuperClasses() or whatever the method is
called, you could actually figure this one out, but that's only
because its an instance of a type with an explicit generics parameter.
public class MyList<T> extends AbstractList<T>();
Object x = new MyList<String>(); - you can't get the 'String' part
out. Not even with the .getClass().getGenericSuperClasses() spiel;
you'd just get the information that there's a 'T' involved, not what
it is.
I assume these examples will give you a spot-on gut instinct about
which generics are reflectable and which aren't.
On Sep 6, 11:13 pm, Christian Catchpole <[EMAIL PROTECTED]>
wrote:
> Awesome. I stand corrected. ...i'm going to use that by the way. :)
>
> On Sep 7, 12:40 am, "Marcelo Fukushima" <[EMAIL PROTECTED]> wrote:
>
> > i think you just have to get the Method object and call
> > getGenericReturnType. If its a fixed type (one that is bound at
> > compile time), you can cast it to ParameterizedType and call
> > getActualTypeArguments, witch in turn will return an array with the
> > type parameters as Class objects. Its a really ugly piece of code.
>
> > Method method = Bla.class.getMethod("getStringClasss");
> > ParameterizedType type = (ParameterizedType)
> > method.getGenericReturnType();
> > System.out.println(type.getActualTypeArguments()[0]);
>
> > On Sat, Sep 6, 2008 at 8:57 AM, Christian Catchpole
>
> > <[EMAIL PROTECTED]> wrote:
>
> > > You can? You could reflect the value on the method result, but I
> > > thought you couldn't reflect it on the Method itself. If so, please
> > > demonstrate.
>
> > > On Sep 6, 7:21 am, Reinier Zwitserloot <[EMAIL PROTECTED]> wrote:
> > >> 'annotations are truely retarded'.
>
> > >> Wow, Viktor. You should get that seething bile looked at.
>
> > >> You CAN actually reflect the Blah in:
>
> > >> public Class<Blah> getObjectThingy(Object object);
>
> > >> You cannot reflect the Blah in:
>
> > >> public <Blah> Class<Blah> getObjectThingy(Blah object);
>
> > >> On Sep 5, 9:36 am, "Viktor Klang" <[EMAIL PROTECTED]> wrote:
>
> > >> > Yes Chris, annotations are truely retarded.
> > >> > However, as with all things retarded, they usually have lots of zealous
> > >> > worshippers.
>
> > >> > But like always, Sun does not fix what Sun has broken.
>
> > >> > Cheers
> > >> > Viktor
>
> > >> > On Fri, Sep 5, 2008 at 2:56 AM, Christian Catchpole <[EMAIL PROTECTED]
>
> > >> > > wrote:
>
> > >> > > Don't get me started on Annotations.. what annoys me about them, is
> > >> > > that while they are soft data implemented as first class classes.
> > >> > > Meaning, to inspect a runtime annotation, the annotation must be in
> > >> > > the classpath. You might forgive that (claiming its a dependancy)
> > >> > > Yet the annotation simply contains Strings and/or primitives in some
> > >> > > kind of template Seems to be the worst of both worlds - No real
> > >> > > types
> > >> > > in that you are forced to reference say, class names as Strings, but
> > >> > > the annotation itself is a real type which must resolve. I don't
> > >> > > claim to be an expert on annotations, havent used them that much, but
> > >> > > perhaps they would have been nicer if they were value holders but
> > >> > > simply permitting no code...
>
> > >> > > @ReturnClass( Blah.class )
> > >> > > public Class getSpecialClassThingy(Obect thing) {
>
> > >> > > This is just off the top of my head. Forgive all errors of logic. :)
>
> > >> > > You could return Class<Blah> but that's not reflectable anyway.. but
> > >> > > that another thread.. :)
>
> > >> > > On Sep 5, 8:15 am, Casper Bang <[EMAIL PROTECTED]> wrote:
> > >> > > > We used to say "If it compiles, the crap works". Now a day, with
> > >> > > > all
> > >> > > > the annotation cr... stuff, this doesn't seem to hold true any
> > >> > > > longer.
>
> > >> > --
> > >> > Viktor Klang
> > >> > Rogue Software Architect
>
> > --
> > []'s
> > Marcelo Takeshi Fukushima
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "The
Java Posse" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/javaposse?hl=en
-~----------~----~----~----~------~----~------~--~---