Signature of MethodHandleInfo.reflectAs is not specific enough

Peter Levart peter.levart at
Mon Nov 11 07:14:39 UTC 2013

On 11/11/2013 02:24 AM, Ali Ebrahimi wrote:
> This is another workaround:
> public <T extends Member&AnnotatedElement, R> R reflectAs(Class<? 
> super T> expected, Lookup lookup);
> info.reflectAs(Member.class, lookup);//works
> info.reflectAs(AnnotatedElement.class, lookup);//works
> info.reflectAs(Member.class, lookup);//works
> info.reflectAs(AnnotatedElement.class, lookup);//works
> info.reflectAs(Object.class, lookup);doesn't work.
> info.reflectAs(Other.class, lookup);doesn't work.
> with this does not need to your javadoc and is more type safe. .

Hm... it doesn't look very compile-time type-safe:

     String s = info.reflectAs(Method.class, lookup); // compiles !!!

IMO, I would rather remove the Class parameter altogether. It serves no 
purpose in the method implementation other than to perform a cast-check 
on the returned object. The method could simply be:

     public <T extends Member> T reflect(Lookup lookup);

This would not solve the problem Remi put forward. I.e. this would not 

     AnnotatedElement ae = info.reflect(lookup);

But with an explicit cast, It compiles:

     AnnotatedElement ae = (AnnotatedElement) info.reflect(lookup);

And compared to what we would have with Class parameter and loosened 
compile-time type-safety as per Remi's suggestion, it is still shorter:

     AnnotatedElement ae = info.reflectAs(AnnotatedElement.class, 
lookup); // this is longer!

A type-unsafe variant is possible too (I'm not advocating it):

     public <T> T reflect(Lookup lookup);

Now that Generalized Target-Type Inference 
<> is part of Java 8, 
using Class<T> parameters just as hints to the compiler is not needed in 
many cases. But if one needs to hint the compiler, explicit type 
parameters can be used as an escape hatch as always:

     Object o = info.<Method>reflect(lookup);

Regards, Peter

> On Mon, Nov 11, 2013 at 1:59 AM, Remi Forax <forax at 
> <mailto:forax at>> wrote:
>     The is a stupid issue with the signature of
>     MethodHandleInfo.reflectAs,
>     j.l.r.Field, Method or Constructor implement two interfaces Member and
>     AnnotatedElement, with the current signature, the code
>        info.reflectAs(Member.class, lookup)
>     works but the code
>        info.reflectAs(AnnotatedElement.class, lookup)
>     doesn't work.
>     Because there is no way to do an 'or' between several bounds of
>     a type variable, I think that the signature of reflectAs should be
>     changed from :
>        public <T extends Member> T reflectAs(Class<T> expected, Lookup
>     lookup);
>     to
>        public <T> T reflectAs(Class<T> expected, Lookup lookup);
>     and the javadoc should be modified to explain that a Member or
>     AnnotatedElement are
>     valid bounds of T.
>     As a side effect, the signature of MethodHandles.reflectAs(Class<T>,
>     MethodHandle)
>     should be updated accordingly.
>     There is a workaround, one can write:
>        (AnnotatedElement)info.reflectAs(Member.class, lookup)
>     but it's at best weird.
>     cheers,
>     Rémi
>     _______________________________________________
>     mlvm-dev mailing list
>     mlvm-dev at <mailto:mlvm-dev at>
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at

More information about the core-libs-dev mailing list