2009-07-25 12 views
5

के इन तरीकों के बीच अंतर है। या उस मामले के लिए किसी अन्य प्रकार। क्या एक दूसरे की तुलना में तेज़ है? या क्या मुझे यहां कुछ और लाभ याद आ रहा है।जावा: क्या क्या पर्यवेक्षकों ArrayList आरंभ के इन दो विधियों के बीच अंतर है निर्माण

class Publisher implements Observerable 
{ 
    private ArrayList observers = new ArrayList(); 
} 

class Publisher implements Observerable 
{ 
    private ArrayList observers; 

    public Publisher() 
    { 
     observers = new ArrayList(); 
    } 
} 

उत्तर

13

वे समकक्ष हैं। वास्तव में, यदि आप दो संकलन आपको लगता है कि वे ठीक उसी बाइट कोड उत्पन्न देखेंगे:

Publisher(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: aload_0 
    5: new  #2; //class java/util/ArrayList 
    8: dup 
    9: invokespecial #3; //Method java/util/ArrayList."<init>":()V 
    12: putfield  #4; //Field observers:Ljava/util/ArrayList; 
    15: return  
} 

कि वे एक ही कोड कर रहे हैं को देखते हुए, वहाँ स्पष्ट रूप से किसी भी गति अंतर :)

नहीं किया जा सकता

ध्यान दें कि सी # में वे काफी बराबर नहीं कर रहे हैं - सी # में observers के लिए प्रारंभकर्ता आधार निर्माता कॉल करने से पहले चल पाएंगे; जावा में वे वास्तव में वही हैं।

आप किसका उपयोग स्वाद की बात है। यदि आपके पास कई अलग-अलग रचनाकार हैं जो सभी एक वैरिएबल को उसी तरह शुरू करते हैं, तो पहले फॉर्म का उपयोग करना समझ में आता है। दूसरी ओर, यह आम तौर पर एक अच्छा विचार है अगर आपके पास कई निर्माताओं है उनमें से ज्यादातर एक "मूल" निर्माता जो वास्तविक काम करता है फोन करने की कोशिश करने के लिए है।

+1

जॉन स्कीट का संपादन फिर –

+1

हड़ताल तुम भी एक उदाहरण प्रारंभकर्ता के साथ एक ही बाईटकोड मिलता है:

public static void main(String[] args) { new TestSub("super constructor"); } 

परिणाम इस प्रकार हैं? मुझे लगता है कि जवाब हाँ है। –

+1

@mmyers: हाँ, बिल्कुल वही। –

4

वे समान हैं, लेकिन: त्रुटि हैंडलिंग आदि

1

वहाँ वास्तव में कोई अंतर नहीं है: अंतर यह है कि पिछले उदाहरण में, आप और अधिक उन्नत आरंभीकरण तर्क ऐसा करने में सक्षम होने का लाभ प्राप्त है। पहला तरीका का एक लाभ यह है कि यदि आप एक से अधिक निर्माताओं है, तो आप उन सभी को में observers प्रारंभ करने में याद करने की जरूरत नहीं है।

दूसरे उदाहरण में, यदि आप निर्माता के तर्कों के आधार पर मान समायोजित करना चाहते हैं, तो आप अधिक लचीला हो सकते हैं।

2

संचालन के क्रम में एकमात्र वास्तविक अंतर है। कक्षाओं के निर्माता के नाम से पहले उनके घोषणा में शुरू किए गए फ़ील्ड का मूल्यांकन किया जाता है। इस तरह से उप-वर्ग में शुरू किए गए फ़ील्ड का मूल्यांकन सुपर के कन्स्ट्रक्टर के पूरा होने के बाद किया जाएगा लेकिन उप-वर्ग के निर्माता को बुलाए जाने से पहले।

निम्न उदाहरण पर विचार करें:

public class Tester { 
    Tester (String msg) { 
     System.out.println(this + ":" + msg); 

    } 
} 

मैं एक सुपर वर्ग है:

public class Test { 

    protected Tester t1 = new Tester("super init block"); 

    Test (String constructorMsg) { 
    new Tester(constructorMsg); 
    } 
} 

और मैं एक उपवर्ग है:

Public class TestSub extends Test { 

    private Tester t2 = new Tester("sub init block"); 

    TestSub(String constructorMsg) { 
     super(constructorMsg); 
     new TTester("sub constructor"); 
    } 

} 

मैं एक परीक्षण वर्ग है

मेरी 01 मेंविधि, मैं TestSub का एक उदाहरण बनाने के लिए:

[email protected]:super init block 
[email protected]:super constructor 
[email protected]:sub init block 
[email protected]:sub constructor 
+0

जो सभी कहते हैं, प्रश्न में दिखाए गए उदाहरण के लिए, कोई अंतर नहीं है * - क्योंकि दूसरे संस्करण में कन्स्ट्रक्टर में पहले संस्करण में फील्ड प्रारंभकर्ता के समान कॉल होता है। महत्वपूर्ण बात यह है कि फील्ड प्रारंभकर्ता को सुपरकॉन्स्ट्रक्टर के बाद * पहले नहीं कहा जाता है। –

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