2012-10-22 7 views
25

चलें कहते हैं कि हम इन पैकेजों और वर्गों है:समान नामों के साथ स्थिर विधियों के स्थिर आयात क्यों वैध हैं?

package p1; 

public class A1 { 
    public static void a() {} 
} 

package p2; 

public class A1 { 
    public static void a() {} 
} 

package p3; 

import static p1.A1.a; 
import static p2.A1.a; 

public class A1 { 
    public static void test() { 

    } 
} 

मैं सोच रहा हूँ, क्यों तरीकों में से स्थिर आयात कानूनी है (संकलन समय त्रुटि का कारण नहीं बनेगा) पैकेज p3 में? हम उन्हें test() विधि में आगे उपयोग करने में सक्षम नहीं होंगे क्योंकि इस तरह के उपयोग के परिणामस्वरूप संकलन समय त्रुटि होगी।

यह कक्षाओं के सामान्य आयात के समान क्यों नहीं है। कहते हैं कि चलो हम p3 में संकुल p1 और p2 से कक्षाएं A1 आयात करना चाहते हैं:

package p3; 
import p1.A1; 
import p2.A1; 

इस तरह के आयात अवैध है और संकलन समय त्रुटि का परिणाम देगा।

+0

क्योंकि पैकेज और वर्ग संयोजन विशिष्ट रूप से दूसरे से एक विधि को अलग करता है। – duffymo

+0

@ डफिमो - वह विशेष रूप से पूछ रहा है कि विधियों को स्थिर रूप से आयात किए जाने पर कोई नाम संघर्ष क्यों नहीं होता है, जिसे आप संबोधित नहीं करते हैं। – DaveRlz

+0

मुझे लगता है कि मैं करता हूं। मुझे betweek a.b.c और a.d.c को अलग करने में कोई समस्या नहीं है; न ही संकलक करता है। – duffymo

उत्तर

35

विधियों के स्थैतिक आयात की अस्पष्टता विधि आमंत्रण के बिंदु पर हल की जा सकती है। आप तर्क पर आधारित है,

void frobnicate(int i); 
// and 
void frobnicate(boolean b); 

तो फिर तुम आयात और दोनों इस्तेमाल कर सकते हैं क्योंकि संकलक बता सकते हैं जो एक का उपयोग करने,:

उदाहरण के लिए अगर आप दो तरीकों कि इस तरह दिखेगा के लिए एक स्थिर आयात किया था पास (frobnicate(1) पहले कॉल करता है, frobnicate(true) दूसरा कॉल करता है)।

कक्षाओं के साथ, यह संभव नहीं है: Foobar a; अकेले आपको यह बताने के लिए पर्याप्त नहीं है कि आप कौन से Foobar कक्षाएं चाहते हैं।

यह भी ध्यान दें कि एकल स्थिर आयात एकाधिक नाम आयात कर सकता है। relevant section of the JLS (जोर मेरा) के अनुसार:

एक एकल स्थिर आयात घोषणा आयात एक प्रकार से किसी दिए गए सरल नाम के साथ सभी सुलभ स्थिर सदस्य हैं।

उदाहरण के लिए यदि जहां एक ही कक्षा में स्थित उपरोक्त दो frobnicate तरीकों, एक भी static आयात उन दोनों को आयात कर सके।

+0

+1 - मैंने आज कुछ नया सीखा! –

+0

मजेदार तथ्य: ग्रोवी इसे भी अनुमति देता है, हालांकि रनटाइम पर यह 'groovy.lang.MissingMethodException: विधि का कोई हस्ताक्षर नहीं' फेंक देगा यदि आप मेरे जैसे पर्याप्त सावधान नहीं हैं। यह त्रुटि संदेश में 'संभावित समाधान' भी सूचीबद्ध करेगा और इसमें उस विधि का नाम होगा जो उस स्थान को छुपाता है जिसे आपने पहली बार कॉल करने का प्रयास किया है। इसे समझने के लिए मुझे एक घंटा लगा। –

+0

प्रश्न यह बनी हुई है कि संकलक इसे क्यों अनुमति देता है, जब यह "जानता है" कि उसी नाम वाले दो स्थिर तरीकों में एक ही हस्ताक्षर है। –

2

ऐसा इसलिए है क्योंकि आपने इन सभी वर्गों को एक ही चीज़ नाम दिया है। हर बार जब आप इस स्थैतिक विधि को कॉल करते हैं तो यह सबसे स्थानीय वर्ग में देख रहा है, जो इस मामले में पी 3 में ए 1 है जिसमें स्थैतिक विधि एक() नहीं है। हमेशा याद रखें कि एक वर्ग का नाम अद्वितीय होना चाहिए और कभी भी एक जैसा नहीं होना चाहिए।

0

मुझे लगता है कि भाषा की कल्पना से समर्थित नहीं है, कि विधियों को अधिभारित किया जा सकता है, लेकिन फ़ील्ड/प्रकार नहीं कर सकते हैं; इसलिए जावा विभिन्न वर्गों से समान नाम के तरीकों को आयात करने की अनुमति देता है।

हालांकि उसी वर्ग में एक ही हस्ताक्षर के दो तरीके मौजूद नहीं हो सकते हैं; उन्हें आयात से अनुमति नहीं दी जानी चाहिए।

भले ही दोनों विधियों के अलग-अलग हस्ताक्षर हों, फिर भी यह एक बुरा विचार है। नाम का अर्थ बहुत महत्वपूर्ण है, इसमें स्पष्टता होनी चाहिए। हम 1 वर्ग से ओवरलोडेड विधियों को संभाल सकते हैं, लेकिन कक्षा में "ओवरलोडिंग" एक खिंचाव है।

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