JDK 8 reflection changes (compared to JDK 7)
Pavel Bucek
pavel.bucek at oracle.com
Tue Jan 28 03:33:14 PST 2014
Thanks Paul, that's exactly what I was looking for :)
have a nice day,
Pavel
On 28/01/14 12:16, Paul Sandoz wrote:
> Hi Pavel,
>
> The second method is a bridge method (m.isBridge() == true).
>
> You can use javap to see the byte code generated by the Java 8
> compiler on the Test.B class:
>
> public void method(java.lang.Object);
> flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
> Code:
> stack=2, locals=2, args_size=2
> 0: aload_0
> 1: aload_1
> 2: checkcast #2 // class java/lang/String
> 5: invokevirtual #3 // Method
> method:(Ljava/lang/String;)V
> 8: return
> LineNumberTable:
> line 67: 0
> LocalVariableTable:
> Start Length Slot Name Signature
> 0 9 0 this LTest$B;
> RuntimeVisibleAnnotations:
> 0: #22()
>
>
> Consider this code:
>
> B b = new B();
> A a = b; // raw type for A
> a.method("FOO"); // will invoke the bridge
> a.method(new Integer(1)); // ClassCastException
>
> It was a bug that was fixed in 8:
>
> https://bugs.openjdk.java.net/browse/JDK-6695379
>
> but has not been backported to a 7 update release, and i dunno if it will.
>
> Often for EE/reflection-based frameworks it is sufficient to ignore
> and filter out the bridge methods when processing the classes to find
> invocation points of user classes to be invoked by the framework (IIRC
> that is what Jersey did).
>
> Hth,
> Paul.
>
> On Jan 28, 2014, at 11:40 AM, Pavel Bucek <pavel.bucek at oracle.com
> <mailto:pavel.bucek at oracle.com>> wrote:
>
>> Hi all,
>>
>> I hope this is correct mailing list - if not, please feel free to
>> point me to different one.
>>
>> Consider following code:
>>
>> @Retention(RetentionPolicy.RUNTIME)
>> @Target(ElementType.METHOD)
>> @interface C { }
>>
>> abstract class A<T> {
>> public abstract void method(T arg);
>> }
>>
>> class B extends A<String> {
>> @Override
>> @C
>> public void method(String arg) { }
>> }
>>
>> public static void main(String[] args) {
>> for(Method m : B.class.getMethods()) {
>> if(m.isAnnotationPresent(C.class)) {
>> System.out.println(m);
>> }
>> }
>> }
>>
>> When executed on JDK8 (1.8.0-ea-b124), it prints out two methods:
>>
>> public void
>> org.glassfish.tyrus.test.standard_config.GenericClientEndpointTest$B.method(java.lang.String)
>> public void
>> org.glassfish.tyrus.test.standard_config.GenericClientEndpointTest$B.method(java.lang.Object)
>>
>> result on JDK7 (just one method):
>>
>> public void
>> org.glassfish.tyrus.test.standard_config.GenericClientEndpointTest$B.method(java.lang.String)
>>
>> Why is the method with Object param added to result set? And why it
>> does have @C annotation declared? If this is intentional, is there
>> any way how I could reliably filter out method with Object as
>> parameter to get same result as on JDK7?
>>
>> Thanks and regards,
>> Pavel
>>
>
More information about the jdk8-dev
mailing list