2014-11-19 3 views
13

निम्नलिखित छोटे उदाहरण पर विचार करें:getDeclaredMethods() बनाम जावा 8 जावा 7 में अलग तरह से व्यवहार कर

package prv.rli.codetest; 

import java.lang.reflect.Method; 

public class BreakingInterfaces { 
    interface Base { 
     BaseFoo foo(); 
     interface BaseFoo {   
     } 
    } 

    interface Derived extends Base { 
     DerivedFoo foo(); 
     interface DerivedFoo extends BaseFoo { 

     } 
    } 

    public static void main(String[] args) {  
     dumpDeclaredMethods(Derived.class); 
    } 

    private static void dumpDeclaredMethods(Class<?> class1) { 
     System.out.println("---" + class1.getSimpleName() + "---"); 
     Method[] methods = class1.getDeclaredMethods(); 
     for (Method method : methods) { 
      System.out.println(method); 
     } 
     System.out.println("----------"); 
    } 
} 

आप jdk1.7.0.55 उत्पादन के साथ ऊपर के उदाहरण संकलन तो है:

---Derived--- 
public abstract BreakingInterfaces$Derived$DerivedFoo BreakingInterfaces$Derived.foo() 
---------- 

लेकिन जब jdk1.8.0.25 उत्पादन का उपयोग कर रहा है:

---Derived--- 
public abstract prv.rli.codetest.BreakingInterfaces$Derived$DerivedFoo prv.rli.codetest.BreakingInterfaces$Derived.foo() 
public default prv.rli.codetest.BreakingInterfaces$Base$BaseFoo prv.rli.codetest.BreakingInterfaces$Derived.foo() 
---------- 

किसी को भी पता है, कि क्या यह jdk1.8.0.25 या क्यों पी में एक बग है सार्वजनिक डिफ़ॉल्ट विधि यहां पुनरुत्थान करता है?

+2

'अनुमान लगा रहा हूं, लेकिन इंटरफ़ेस में विधियों के जावा 8 डिफ़ॉल्ट कार्यान्वयन के साथ ऐसा कुछ हो सकता है। – user902383

उत्तर

14

getDeclaredMethods() सही तरीके से व्यवहार करता है क्योंकि यह आपको कक्षा में जो मिला है उसे बिल्कुल बताता है। यदि आप जावा 7 लक्ष्य (या पुराने कंपाइलर) के साथ संकलित interface में फ़ीड करते हैं तो आपको getDeclaredMethods() के जावा 7 कार्यान्वयन के आउटपुट में कोई अंतर नहीं दिखाई देगा।

यह कंपाइलर है जो अलग-अलग व्यवहार करता है। जावा 8 में ऐसे उप-interface को संकलित करते समय, एक पुल विधि जेनरेट की जाएगी जो जावा 7 लक्ष्य के लिए जेनरेट नहीं की जाएगी क्योंकि यह जावा 7 लक्ष्य के लिए भी संभव नहीं है।

इंटरफ़ेस के लिए पुल विधियों को उत्पन्न करने का कारण यह है कि इंटरफ़ेस में आमतौर पर अधिक कार्यान्वयन कक्षाएं होती हैं, इसलिए इंटरफ़ेस में default पुल विधि होने से आपको प्रत्येक कार्यान्वयन के लिए उस पुल विधि को जोड़ने से बचाता है। इसके अलावा, यह लैम्ब्डा वर्ग पीढ़ी को बहुत आसान बनाता है अगर केवल एक abstract विधि और लागू करने के लिए कोई पुल विधि नहीं है।

एक interface पदानुक्रम पुल तरीकों की आवश्यकता है, लेकिन कोई default रों प्रदान करता है, संकलक हर पुल विधि है कि आवश्यक है निर्दिष्ट करने LambdaMetafactory.altMetafactory बजाय LambdaMetafactory.metafactory का उपयोग कर कोड उत्पन्न करने के लिए है जब।

संबंधित मुद्दे