2009-03-11 34 views
41

मैं कल्पना नहीं की थी कि मैं अब और इस स्तर पर जावा में मौलिक नई वाक्य रचना का सामना होगा, लेकिन लो और निहारना, मैं तो बस का सामना करना पड़ा कुछ:अजीब वाक्य रचना

सटीक संदर्भ और क्या नीचे दिया गया कोड बहुत अप्रासंगिक है - यह सिर्फ कुछ प्रकार का संदर्भ देने के लिए है।

मैं कृत्रिम आईटी मिल टूलकिट में ईवेंट बनाने के लिए कोशिश कर रहा हूँ, इसलिए मैं लाइन के इस प्रकार लिखा है:

buttonClick(new Button.ClickEvent(button)); 

लेकिन, ग्रहण मुझे निम्न त्रुटि संदेश देता है:

प्रकार बटन का कोई संलग्न उदाहरण सुलभ नहीं है। प्रकार बटन के एक संलग्न उदाहरण के साथ आवंटन अर्हता प्राप्त करनी चाहिए (उदा। X.new ए() जहां एक्स बटन का एक उदाहरण है)।

जब मैं इस प्रकार के ऊपर लाइन को फिर से लिखने, इसे अब और शिकायत नहीं करता है:

buttonClick(button.new ClickEvent(button)); // button instanceof Button 

तो, मेरे सवाल यह है: क्या उत्तरार्द्ध वाक्य रचना का क्या मतलब है, वास्तव में, और क्यों नहीं है पहला स्निपेट काम करता है? जावा किस बारे में शिकायत कर रहा है, और यह दूसरे संस्करण में क्या कर रहा है?

पृष्ठभूमि जानकारी: Button और Button.ClickEvent दोनों गैर-सार्वजनिक सार्वजनिक कक्षाएं हैं।

+0

दिलचस्प सवाल है, लेकिन शीर्षक हो सकता है और अधिक परिष्कृत हो सकता है। – mafu

+0

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

उत्तर

69

इनर वर्गों (जैसे Button.ClickEvent) बाहरी वर्ग का एक उदाहरण के लिए एक संदर्भ की जरूरत है (Button)।

यह वाक्यविन्यास Button.ClickEvent का एक नया उदाहरण बनाता है जिसमें बाहरी कक्षा संदर्भ button के मान पर सेट है।

यहाँ एक उदाहरण है - कैप्सूलीकरण आदि की कमी पर ध्यान न दें, यह सिर्फ प्रदर्शन के प्रयोजनों के लिए है:

class Outer 
{ 
    String name; 

    class Inner 
    { 
     void sayHi() 
     { 
      System.out.println("Outer name = " + name); 
     } 
    } 
} 

public class Test 
{ 
    public static void main(String[] args) 
    { 
     Outer outer = new Outer(); 
     outer.name = "Fred"; 

     Outer.Inner inner = outer.new Inner(); 
     inner.sayHi(); 
    } 
} 

भीतरी वर्गों और enclosing उदाहरणों के बारे में अधिक के लिए section 8.1.3 of the spec देखें।

+7

यदि आंतरिक वर्ग को बाहरी वर्ग के संदर्भ में कार्य करने की आवश्यकता नहीं है, तो आप आंतरिक कक्षा घोषणा में स्थैतिक कीवर्ड का उपयोग करके इस आवश्यकता को समाप्त कर सकते हैं - उपर्युक्त उदाहरण में स्थिर वर्ग आंतरिक - हालांकि स्पष्ट रूप से आपके पास पहुंच नहीं होगी Outer.name संपत्ति के लिए ...! –

+0

@ जोन एक गैर स्थैतिक आंतरिक वर्ग उदाहरण बनाने के इस मूर्खता के लिए कोई विशिष्ट तकनीकी नाम है? – Inquisitive

+0

@ पूछताछ: यह सिर्फ एक आंतरिक वर्ग का एक उदाहरण है। –

9

बटन .क्लिकवेन्ट एक गैर स्थैतिक आंतरिक वर्ग है, इसलिए इस वर्ग का एक उदाहरण केवल बटन के उदाहरण में संलग्न हो सकता है।

अपने दूसरे कोड उदाहरण में आप बटन का एक उदाहरण है और आप इस बटन उदाहरण में संलग्न ClickEvent का एक उदाहरण बनाने ...

8

जावा में एक गैर स्थैतिक आंतरिक कक्षा में एक छिपी संदर्भ है जो बाहरी वर्ग के उदाहरण के लिए इंगित करता है। इसलिए मूल संदेश आपको मूल रूप से बता रहा है कि आप आंतरिक का एक नया उदाहरण नहीं बना सकते बिना किसी वर्ग के बाहरी वर्ग का एक उदाहरण निर्दिष्ट किए बिना कक्षा भी।

संभवतः आपने उस वाक्यविन्यास को पहले नहीं देखा है कि आंतरिक वर्ग अक्सर बाहरी वर्ग की विधि में आवंटित होते हैं, जहां संकलक स्वचालित रूप से इसका ख्याल रखता है।

3

इस दुर्लभ रूप से उपयोग की जाने वाली सुविधा के साथ स्वयं और साथी प्रोग्रामर को भ्रमित करने से बचने के लिए आप हमेशा आंतरिक कक्षाएं स्थिर बना सकते हैं।

यदि बाहरी वर्ग के संदर्भ की आवश्यकता है तो आप इसे स्पष्ट रूप से निर्माता में पास कर सकते हैं।

+0

या आंतरिक कक्षाएं निजी बनाएं, और इसे निहित करने के लिए चिपके रहें। –

-1

आपका कोड संकलन हैं, तो आप

buttonClick(new Button().ClickEvent(button)); 
बजाय

buttonClick(new Button.ClickEvent(button));

एक निर्माता एक तरीका है के रूप में आपके द्वारा लिखा गया था और जब आप जावा में एक विधि कॉल आप की सूची से गुजरना होगा तर्क, भले ही यह खाली हो।

+0

असल में, नहीं, यह काम नहीं करता है, क्योंकि यह उस के साथ ClickEvent (बटन) विधि को कॉल करने का प्रयास करता है, जो इसे नहीं मिला ... –

+0

नया बटन() नया क्लिकएवेंट (बटन)? –

1

आप वास्तव में है कि कर सकते हैं, लेकिन आप staticButton अंदर के रूप में ClickEvent घोषित करने के लिए है, और फिर आप आप उपयोग कर कोई समस्या नहीं चाहिए sintax:

buttonClick(new Button.ClickEvent(button)); 

मूल रूप से static वर्ग में आता है ClickEventButton के विशिष्ट उदाहरण (यानी new Button()) के बजाय सीधे Button वर्ग से संबंधित है।


@Jon स्कीट उदाहरण के बाद:

// Button.java 
class Button 
{ 

    public static class ClickEvent 
    { 
     public ClickEvent(Button b) 
     { 
      System.out.println("Instance: " + this.toString()); 
     } 
    } 
} 

// Test.java 
public class Test 
{ 
    public static void main(String[] args) 
    { 
     Button button = new Button(); 
     buttonClick(new Button.ClickEvent(button)); 
    } 

    public static void buttonClick (Button.ClickEvent ce) { 
    } 
} 
संबंधित मुद्दे