2010-10-05 7 views
10

मैं आज कोड के इस ब्लॉक में भाग गया, और मुझे नहीं पता कि यह कैसे काम करता है। मुझे पता है कि अज्ञात वर्ग कैसे बनाना है, लेकिन मुझे एक विधि हस्ताक्षर देखने के लिए उपयोग किया जाता है न कि ब्रेसिज़ की एक जोड़ी। क्या उन ब्रेसिज़ के बीच कोड एक स्थिर ब्लॉक में डाल दिया गया है? क्या यह कन्स्ट्रक्टर में जाता है? या यह पूरी तरह से कुछ और है?जावा सिंटेक्टिक शुगर

conext.checking(new Expectations() { 
    { // <- what does this pair of braces do? 
     oneOf(alarm).getAttackAlarm(null); 
    } 
}); 

उत्तर

15

यह एक उदाहरण प्रारंभकर्ता है जो कोड को बनाए गए ऑब्जेक्ट के संदर्भ में कॉल करता है।

यह

Expectations exp = new Expectations(); 
exp.oneOf(alarm).getAttackAlarm(null); 
conext.checking(exp) 

जो कोई भी लिखा था यह सोचा होगा कि वह एक चर (सच नहीं) की घोषणा नहीं द्वारा और अधिक कुशल जा रहा था या कि यह क्लीनर कोड (मैं सहमत नहीं) था के बराबर है।

Map map = new HashMap() {{ 
    put("key1", "value1"); 
    put("key2", "value2"); 
}}; 

जो मैं वास्तव में लगता है कि थोड़ा और अधिक पठनीय है:

प्राथमिक जगह है कि इन initializers इस तरह उपयोगी होते हैं जब instantiating नक्शे, यानी है।

+1

की तरह कुछ है यह एक "उदाहरण के प्रारंभकर्ता" कहा जाता है है, नहीं एक "स्थिर प्रारंभकर्ता" (बाद में स्पष्ट कारणों से 'यह' नहीं होगा)। यह भी देखें http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.6 –

+1

यह एक स्थिर प्रारंभकर्ता नहीं है, केवल एक (उदाहरण) प्रारंभकर्ता है। वह ब्लॉक * हर बार चलाया जाएगा * वह कोड चलाया जाएगा, न केवल पहली बार एक स्थिर प्रारंभकर्ता के साथ होगा। –

+0

अच्छा नोट, मैंने इसे सही किया .... –

0

यह प्रारंभकर्ता ब्लॉक है। मैं यह नहीं बता सकता कि यह शेष कोड को देखे बिना क्या करता है। के साथ "वर्ग कुछ उम्मीद फैली" प्रतिस्थापित

चाल "() नई उम्मीद" की कल्पना करना है।

0

क्या हो रहा है? बाहरी ब्रेसिज़ अपवाद से व्युत्पन्न एक नया अनाम वर्ग बनाते हैं। आंतरिक ब्रेसिज़ प्रारंभिक परिभाषित करते हैं और oneOf() आदि सेट करते हैं

ऐसा क्यों करें? यह एक वर्ग के उदाहरण बनाने और शुरू करने के लिए एक लाइनर चाल है। ई। आप कभी-कभी ऐसा कुछ देखते हैं:

new Set<String>(){{add("one");add("two")}} 

संग्रह की सामग्री आरंभ करने के लिए।

डाउनसाइड्स? चूंकि आप युक्त कक्षा के भीतर एक अज्ञात वर्ग बना रहे हैं, इसलिए अज्ञात वर्ग में बाहरी वर्ग के लिए यह संदर्भ शामिल है। आम तौर पर एक समस्या नहीं है, लेकिन यह समस्याएं पैदा कर सकती है अगर (कहें) आप इस तरह के एक वर्ग को क्रमबद्ध करना चाहते हैं।

+0

एक * स्थिर * प्रारंभकर्ता नहीं। – DJClayworth

+0

आह। मेरी गलती। –

3

यह एक प्रारंभिक ब्लॉक है, लेकिन यह आवश्यक नहीं है कि स्थिर प्रारंभकर्ता ब्लॉक। यह प्रभावी रूप से अज्ञात आंतरिक वर्ग के लिए एक कन्स्ट्रक्टर है। आप आमतौर पर इस "डबल ब्रेस आरंभीकरण" पैटर्न आसानी से बना सकते हैं और संग्रह को भरने के लिए देखेंगे:

private final Collection<Integer> FIXED_COLLECTION = Collections.unmodifiableCollection(new HashSet<Integer>() 
{ // first set of braces declares anonymous inner class 
    { add(1); add(2); add(3); } // second set is initializer block 
}); 
+0

को ठीक किया गया है, मुझे जावा प्रोग्रामिंग के 15 वर्षों में कहना है, मैंने पहले कभी ऐसा प्रारंभिक प्रारंभकर्ता नहीं देखा है। अज्ञात वर्गों के बाहर उपयोग को नोट करने के लिए – dty

3

यह एक उदाहरण initialiser (नहीं एक स्थिर initialiser) है।

पर विचार करें getDefaultValue() करने के लिए एक वर्ग

public class Foo { 
    private int i = getDefaultValue(); 

    private static int getDefaultValue() { 
     return 5; 
    } 
} 

कॉल की परिभाषा है कि i initalises अनिवार्य रूप से एक कोड ब्लॉक है कि हर बार फू का एक उदाहरण का निर्माण किया है चलाता है। नोटेशन उस जटिल कार्य को अधिक जटिल प्रारंभिक अनुमति देने के लिए बढ़ाता है। जैसे

public class Foo { 
    private int i; 

    { 
     int z = 4 + 5; 
     i = z + getDefaultValue(); 
    } 

    private static int getDefaultValue() { 
     return 5; 
    } 
} 

जिस तरह से साथ यह JMock में प्रयोग किया जाता है एक चाल उम्मीदों को बंद करने की निर्माण के रूप देने के लिए है।

+0

+1। मुझे बंद करने के संदर्भ भी पसंद है! :-) – dty

0

अनैतिक आंतरिक कक्षाओं में कोई कन्स्ट्रक्टर नहीं है, इसलिए आप इस तरह एक उदाहरण initilizer परिभाषित कर सकते हैं यानी ब्रेसिज़ के आंतरिक सेट उदाहरण प्रारंभकर्ता हैं।

new Expectations() { 
    { 
     oneOf(alarm).getAttackAlarm(null); 
    } 
} 
+1

यह वाक्यविन्यास अज्ञात वर्ग तक ही सीमित नहीं है। हालांकि इसका उपयोग एक नियमित वर्ग में अनावश्यक और भ्रमित है। – dty

0

इसके पीछे प्राथमिक प्रेरणा, मेरा मानना ​​है कि, एक नया नाम अंतरिक्ष, जिसमें Expection में परिभाषित नाम और अधिक आसानी से संदर्भित किया जा सकता बनाने के लिए है।

उदाहरण के लिए, मान लीजिए java.lang.Math अंतिम नहीं है,

new Math() 
{{ 
    double x = sin(23.65); 
    double y = log(x); 
    ... 
}}; 

यह लगभग रूप में अगर हम

with names from Math 
{ 
    double x = sin(23.65); 
    double y = log(x); 
    ... 
} 
संबंधित मुद्दे