2014-04-17 5 views
10

मैं एक एनोटेशनjava8 - तुलनीय <T> की compareTo <T> व्याख्या compareTo (वस्तु ओ)

package javaannotationtest; 

import java.lang.annotation.*; 

@Target({ElementType.METHOD}) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface CustomAnnotation { 
} 

इस वर्ग

package javaannotationtest; 

public class Customer implements Comparable<Customer>{ 
    @Override 
    @CustomAnnotation 
    public int compareTo(Customer o) { 
     return 0; 
    } 
} 

वर्ग निम्नलिखित में compareTo को लागू किया जाता है करने के लिए एनोटेशन कहते हैं अलग परिणाम देता है जावा -7 और जावा -8 संकलित कोड के साथ।

जावा 7

1.7.0_45 -> public int javaannotationtest.Customer.compareTo(javaannotationtest.Customer) 
has annotation of type javaannotationtest.CustomAnnotation 
1.7.0_45 -> public int javaannotationtest.Customer.compareTo(java.lang.Object) 
has no annotation of type javaannotationtest.CustomAnnotation 

ध्यान दें कि compareTo (वस्तु) एनोटेशन जरूरत नहीं है।

जावा 8

1.8.0 -> public int javaannotationtest.Customer.compareTo(javaannotationtest.Customer) 
has annotation of type javaannotationtest.CustomAnnotation 
1.8.0 -> public int javaannotationtest.Customer.compareTo(java.lang.Object) 
has annotation of type javaannotationtest.CustomAnnotation 

जावा 8 एनोटेशन compareTo(java.lang.Object) विधि

यहाँ करने के लिए जोड़ा गया है संस्करण जावा 8 के साथ संकलित के लिए javap से उत्पादन होता है (शायद प्रासंगिक नहीं, यह पता चलता एनोटेशन को जोड़ा गया दोनों विधियों)

Classfile /C:/code/java8annoation/out/production/java8annoation/javaannotationtest/Customer.class 
    Last modified 17 Apr, 2014; size 719 bytes 
    MD5 checksum 678e0371f5f9ed5666b513c940f365a7 
    Compiled from "Customer.java" 
public class javaannotationtest.Customer extends java.lang.Object implements java.lang.Comparable<javaannotationtest.Customer> 
    Signature: #20       // Ljava/lang/Object;Ljava/lang/Comparable<Ljavaannotationtest/Customer;>; 
    SourceFile: "Customer.java" 
    minor version: 0 
    major version: 52 
    flags: ACC_PUBLIC, ACC_SUPER 
Constant pool: 
    #1 = Methodref   #4.#23   // java/lang/Object."<init>":()V 
    #2 = Class    #24   // javaannotationtest/Customer 
    #3 = Methodref   #2.#25   // javaannotationtest/Customer.compareTo:(Ljavaannotationtest/Customer;)I 
    #4 = Class    #26   // java/lang/Object 
    #5 = Class    #27   // java/lang/Comparable 
    #6 = Utf8    <init> 
    #7 = Utf8    ()V 
    #8 = Utf8    Code 
    #9 = Utf8    LineNumberTable 
    #10 = Utf8    LocalVariableTable 
    #11 = Utf8    this 
    #12 = Utf8    Ljavaannotationtest/Customer; 
    #13 = Utf8    compareTo 
    #14 = Utf8    (Ljavaannotationtest/Customer;)I 
    #15 = Utf8    o 
    #16 = Utf8    RuntimeVisibleAnnotations 
    #17 = Utf8    Ljavaannotationtest/CustomAnnotation; 
    #18 = Utf8    (Ljava/lang/Object;)I 
    #19 = Utf8    Signature 
    #20 = Utf8    Ljava/lang/Object;Ljava/lang/Comparable<Ljavaannotationtest/Customer;>; 
    #21 = Utf8    SourceFile 
    #22 = Utf8    Customer.java 
    #23 = NameAndType  #6:#7   // "<init>":()V 
    #24 = Utf8    javaannotationtest/Customer 
    #25 = NameAndType  #13:#14  // compareTo:(Ljavaannotationtest/Customer;)I 
    #26 = Utf8    java/lang/Object 
    #27 = Utf8    java/lang/Comparable 
{ 
    public javaannotationtest.Customer(); 
    descriptor:()V 
    flags: ACC_PUBLIC 
    Code: 
     stack=1, locals=1, args_size=1 
     0: aload_0  
     1: invokespecial #1     // Method java/lang/Object."<init>":()V 
     4: return   
     LineNumberTable: 
     line 3: 0 
     LocalVariableTable: 
     Start Length Slot Name Signature 
      0  5  0 this Ljavaannotationtest/Customer; 

    public int compareTo(javaannotationtest.Customer); 
    descriptor: (Ljavaannotationtest/Customer;)I 
    flags: ACC_PUBLIC 
    Code: 
     stack=1, locals=2, args_size=2 
     0: iconst_0  
     1: ireturn  
     LineNumberTable: 
     line 7: 0 
     LocalVariableTable: 
     Start Length Slot Name Signature 
      0  2  0 this Ljavaannotationtest/Customer; 
      0  2  1  o Ljavaannotationtest/Customer; 
    RuntimeVisibleAnnotations: 
     0: #17() 

    public int compareTo(java.lang.Object); 
    descriptor: (Ljava/lang/Object;)I 
    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 javaannotationtest/Customer 
     5: invokevirtual #3     // Method compareTo:(Ljavaannotationtest/Customer;)I 
     8: ireturn  
     LineNumberTable: 
     line 3: 0 
     LocalVariableTable: 
     Start Length Slot Name Signature 
      0  9  0 this Ljavaannotationtest/Customer; 
    RuntimeVisibleAnnotations: 
     0: #17() 
} 

कोई जावा 8 में प्रासंगिक परिवर्तनों को समझा सकता है? (योग्य होने पर बाउंटी की पेशकश करेगा)।

+0

मुझे प्रश्न समझ में नहीं आता है। आप किस प्रासंगिक परिवर्तन के बारे में पूछ रहे हैं? इस संबंध में, एनवाटेशन दोनों जावा संस्करणों में दोनों विधियों पर है। –

+0

सं। जावा 7 में, java8.Customer.compareTo (java.lang.Object) में एनोटेशन नहीं है। (यह स्पष्ट करने के लिए प्रश्न संपादित करना) – Jayan

उत्तर

8

इस परिवर्तन को JDK-6695379 - Copy method annotations and parameter annotations to synthetic bridge methods पर वर्णित किया गया है। इस सुविधा के बारे में ज्यादा चर्चा नहीं होती है लेकिन अनुरोध और औचित्य मुझे समझ में आता है।

अनुरोध का एक वर्णन: जब एक वर्ग के एक सामान्य कक्षाओं का विस्तार या एक सामान्य इंटरफ़ेस लागू करता है, सिंथेटिक विधि विधि के बीच पाटने के विशिष्ट मानदंडों/वापसी और सुपर वर्ग में से एक लेने उत्पन्न किया जा सकता है/अंतरफलक के कारण ऑब्जेक्ट्स के साथ परिभाषित इंटरफ़ेस। जावा भाषा विशिष्टता के अनुसार, एक पुल विधि कॉल को वास्तविक विधि पर रीडायरेक्ट करता है। हालांकि पुल विधि में मूल विधि और इसके पैरामीटर के लिए परिभाषित एनोटेशन की कमी है।

जस्टिफिकेशन: रन-टाइम पर ऐसी विधि के एनोटेशन को पुनर्प्राप्त करने का प्रयास करते समय समस्या उत्पन्न होती है। चूंकि विश्वसनीय वर्गों को सामान्य मानकों को प्रतिस्थापित करने के लिए असंभव रूप से पता लगाना असंभव है, इसलिए हम सही तरीके से प्राप्त करने के लिए getMethod (...) को भेजने के लिए पैरामीटर को नहीं जानते हैं। ऑब्जेक्ट.क्लास भेजते समय (जेनेरिक पैरामीटर एक अलग वर्ग है) getMethod पुल विधि वापस कर देगा, जिसमें मूल विधि एनोटेशन के बारे में जानकारी नहीं होगी।

यह भी JDK 8 compatibility guide में दर्ज है:

क्षेत्र: उपकरण/javac

सार
इस रिलीज के रूप में, पैरामीटर और विधि एनोटेशन सिंथेटिक पुल को कॉपी कर रहे हैं तरीकों।

@Target(value = {ElementType.PARAMETER}) 
@Retention(RetentionPolicy.RUNTIME) 
@interface ParamAnnotation {} 

@Target(value = {ElementType.METHOD}) 
@Retention(RetentionPolicy.RUNTIME) 
@interface MethodAnnotation {} 

abstract class T<A,B> { 
    B m(A a){return null;} 
} 

class CovariantReturnType extends T<Integer, Integer> { 
    @MethodAnnotation 
    Integer m(@ParamAnnotation Integer i) { 
     return i; 
    } 

    public class VisibilityChange extends CovariantReturnType {} 

} 

प्रत्येक उत्पन्न पुल विधि विधि को रीडायरेक्ट के सभी एनोटेशन होगा: यह ठीक जैसे कार्यक्रमों के लिए है कि अब निकलता है। पैरामीटर एनोटेशन की भी प्रतिलिपि बनाई जाएगी। व्यवहार में यह परिवर्तन कुछ एनोटेशन प्रोसेसर या सामान्य रूप से एनोटेशन का उपयोग करने वाले किसी भी एप्लिकेशन को प्रभावित कर सकता है।

असंगत होने
व्यवहार

RFE की प्रकृति
6695379

+0

@ कपाप, बस उत्सुक, आप कैसे पता लगाया कि यह विशिष्ट परिवर्तन था? –

+0

@vrz इसे खोजने में कुछ समय लगा :) चेंजलॉग में एनोटेशन के बारे में बहुत कुछ नहीं था और पर्याप्त विस्तृत नहीं थे। बाइटकोड में 'ACC_BRIDGE, ACC_SYNTHETIC' झंडे ने मुझे उत्सुक बना दिया और वे प्रासंगिक लग रहे थे। मुझे लगता है कि मैंने सिंथेटिक तरीकों पर 'जावा 8 एनोटेशन' जैसी कुछ चीज बनाई है। – Kapep

+0

@kappep, मैं देखता हूं, आपके उत्तर के लिए धन्यवाद। मैं आपके उत्तर में संदर्भित परिवर्तन का लेखक हूं। मैं यह जानना चाहता था कि बाहरी उपयोगकर्ताओं को दिए गए परिवर्तन को खोजने का कार्य कैसे आसान हो सकता है। ऐसा लगता है कि परिवर्तन/कोड में और टिप्पणियां जोड़ने से मदद मिल सकती है लेकिन मैं सुगंध/विचारों के लिए खुला हूं। –

3

@kapep: बहुत अच्छा जवाब। मैं इस मुद्दे के बारे में कुछ पूरक जानकारी जोड़ना चाहता हूं। न केवल पुल विधि में एनोटेशन की प्रतिलिपि बनाई गई है। पैरामीटर नाम भी कॉपी किए गए हैं। यदि आप -परमीटर कंपाइलर विकल्प के साथ उदाहरण संकलित करते हैं तो आपको यह जैवप आउटपुट मिलता है:

public int compareTo(Customer); 
descriptor: (LCustomer;)I 
flags: ACC_PUBLIC 
Code: 
    stack=1, locals=2, args_size=2 
    0: iconst_0  
    1: ireturn  
    LineNumberTable: 
    line 11: 0 
MethodParameters: 
    Name       Flags 
    o        
RuntimeVisibleAnnotations: 
    0: #15() 

public int compareTo(java.lang.Object); 
descriptor: (Ljava/lang/Object;)I 
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 Customer 
    5: invokevirtual #3     // Method compareTo:(LCustomer;)I 
    8: ireturn  
    LineNumberTable: 
    line 7: 0 
MethodParameters: 
    Name       Flags 
    o        synthetic <-- see the name copied to the bridge method 
RuntimeVisibleAnnotations: 
    0: #15() 
संबंधित मुद्दे