दिलचस्प पोस्ट
क्या पायथन एक सूची में एकाधिक मूल्यों की सदस्यता का परीक्षण कर सकता है? पोर्ट्रेट से लैंडस्केप तक डिफ़ॉल्ट एनीमेशन अक्षम करें पायथन में इवेंट सिस्टम एपीआई स्तर 4 पर है या नहीं, यह कैसे पता लगा सकता है कि स्क्रीन चालू है या बंद है? कोर डेटा के लिए "स्वचालित हल्के प्रवासन" का कार्यान्वयन (आईफ़ोन) दिनांक को परिवर्तित करने के लिए जीएमटी 0 चयनकर्ता H3 क्यों नहीं: nth-child (1): इसमें ('ए') कार्य होता है? क्या वेब नियोजित सेटएक्ल प्रदाता को उप-निर्देशिका पर इस्तेमाल किया जा सकता है? java.io.NotSerializableException एनजी-दोहराने के साथ किसी फ़ंक्शन द्वारा लौटी वस्तुओं के माध्यम से लूप कैसे करें? कैसे वेब अनुप्रयोग में गुण फ़ाइल को पढ़ने के लिए? क्यों मैं "sqrt के लिए अनिर्धारित संदर्भ" त्रुटि प्राप्त कर रहा हूँ भले ही मैं math.h शीर्ष लेख शामिल है? Windows मेजबान फ़ाइल में पोर्ट संख्या का उपयोग करना एक-लाइन सूची की समझ: अगर-दूसरे संस्करण .Net regex: शब्द चरित्र \ w क्या है?

हम एक (गैर-स्थिर) आंतरिक वर्ग में स्थिर विधि क्यों नहीं कर सकते?

हम एक गैर-स्थिर आंतरिक वर्ग में स्थिर विधि क्यों नहीं कर सकते हैं?

अगर मैं भीतर की कक्षा को स्थिर करता हूं तो यह काम करता है क्यूं कर ?

Solutions Collecting From Web of "हम एक (गैर-स्थिर) आंतरिक वर्ग में स्थिर विधि क्यों नहीं कर सकते?"

क्योंकि एक आंतरिक वर्ग का एक उदाहरण इसकी बाहरी कक्षा की आवृत्ति से सम्बद्ध है, यह किसी भी स्थिर तरीके को परिभाषित नहीं कर सकता है चूंकि एक स्थैतिक नेस्टेड क्लास अपने समूहीकृत वर्ग में परिभाषित उदाहरण चर या विधियों को प्रत्यक्ष रूप से नहीं संदर्भित कर सकता है, इसलिए ये केवल एक ऑब्जेक्ट संदर्भ के माध्यम से उपयोग कर सकते हैं, यह एक स्थैतिक नेस्टेड क्लास में स्थिर तरीके घोषित करने के लिए सुरक्षित है।

एक स्थैतिक विधि को गैर-स्थिर आंतरिक कक्षा में अनुमति देने के लिए बहुत कुछ नहीं है; आप इसका उपयोग कैसे करेंगे? आप एक बाहरी क्लास उदाहरण के बिना बिना (कम से कम शुरू में) एक गैर-स्थिर आंतरिक श्रेणी के उदाहरण तक नहीं पहुंच सकते। एक गैर स्थैतिक आंतरिक वर्ग बनाने का कोई विशुद्ध रूप से स्थिर तरीका नहीं है।

बाहरी कक्षा Outer , आप इस तरह एक स्थिर विधि test() उपयोग कर सकते हैं:

 Outer.test(); 

एक स्थैतिक आंतरिक वर्ग के लिए, आप इसके स्थिर तरीके से innerTest() इस तरह से पहुंच सकते हैं:

 Outer.Inner.innerTest(); 

हालांकि, अगर Inner स्थिर नहीं है, तो अब innertest संदर्भ में कोई विशुद्ध रूप से स्थिर तरीका नहीं है। गैर-स्थैतिक आंतरिक कक्षाएं उनके बाहरी वर्ग की एक विशिष्ट उदाहरण से बनी हैं। एक फ़ंक्शन एक निरंतर से भिन्न होता है, जिसमें Outer.Inner.CONSTANT संदर्भ। Outer.Inner.CONSTANT को एक तरह से स्पष्ट रूप से गारंटी दी जाती है कि एक फ़ंक्शन कॉल को Outer.Inner.staticFunction(); फ़ंक्शन Outer.Inner.staticFunction(); नहीं है। मान लें कि आपके पास Inner.staticFunction() जो कि Inner.staticFunction() को कॉल करता है, जिसे Outer में परिभाषित किया गया है यदि आप उस स्थिर फ़ंक्शन को लागू करने का प्रयास करते हैं, तो अब आपके पास इनर क्लास का एक अस्पष्ट संदर्भ है। यही है, आंतरिक वर्ग के किस उदाहरण पर आप स्थैतिक कार्य का आह्वान करते हैं? यह मायने रखता है। देखें, बाह्य वस्तु के अंतर्निहित संदर्भ के कारण, स्थिर विधि का संदर्भ देने के लिए कोई वास्तविक स्थैतिक तरीका नहीं है।

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

यदि आपको वास्तव में एक गैर-स्थैतिक आंतरिक वर्ग पर स्थैतिक तरीकों की आवश्यकता है , तो आपको शायद अपने डिजाइन को फिर से संशोधित करना होगा।

मेरे पास एक सिद्धांत है, जो सही हो सकता है या नहीं।

सबसे पहले, आपको कुछ चीजें जानना चाहिए कि कैसे जावा में आंतरिक कक्षाएं लागू की जाती हैं मान लीजिए आपको यह वर्ग मिल गया है:

 class Outer { private int foo = 0; class Inner implements Runnable { public void run(){ foo++; } } public Runnable newFooIncrementer(){ return new Inner(); } } 

जब आप इसे संकलित करते हैं, तो उत्पन्न बाइटकोड ऐसा दिखेगा जैसा आपने लिखा है:

 class Outer { private int foo = 0; static class Inner implements Runnable { private final Outer this$0; public Inner(Outer outer){ this$0 = outer; } public void run(){ this$0.foo++; } } public Runnable newFooIncrementer(){ return new Inner(this); } } 

अब, यदि हम गैर-स्थिर आंतरिक कक्षाओं में स्थिर तरीके की अनुमति देते हैं, तो आप ऐसा कुछ करना चाह सकते हैं

 class Outer { private int foo = 0; class Inner { public static void incrFoo(){ foo++; } } } 

… जो उचित रूप से उचित लग रहा है, क्योंकि Inner क्लास में प्रत्येक अवतार के प्रति एक अवतार लगता है। लेकिन जैसा हमने ऊपर देखा, गैर-स्थैतिक आंतरिक वर्ग वास्तव में स्थैतिक "इनर" कक्षाओं के लिए वाक्यात्मक चीनी हैं, इसलिए अंतिम उदाहरण लगभग समतुल्य होगा:

 class Outer { private int foo = 0; static class Inner { private final Outer this$0; public Inner(Outer outer){ this$0 = outer; } public static void incrFoo(){ this$0.foo++; } } } 

… जो स्पष्ट रूप से काम नहीं करेगा, क्योंकि this$0 गैर-स्थिर है इस प्रकार का वर्णन है कि स्थैतिक तरीकों की अनुमति क्यों नहीं दी जाती है (हालांकि आप तर्क दे सकते हैं कि जब तक आप संलग्न ऑब्जेक्ट का संदर्भ नहीं देते तब तक आप स्थिर तरीकों की अनुमति दे सकते हैं), और आपको गैर-अंतिम स्थैतिक फ़ील्ड क्यों नहीं मिल सकते हैं ( यह अलग-अलग ऑब्जेक्ट से गैर-स्थिर आंतरिक कक्षाओं के उदाहरणों को "स्थिर राज्य" साझा किए जाने पर) प्रति-सहज ज्ञान युक्त होगा। यह भी बताता है कि अंतिम क्षेत्रों की अनुमति क्यों दी जाती है (जब तक वे संलग्न वस्तु का संदर्भ नहीं देते)।

एकमात्र कारण "नहीं होना चाहिए", इसलिए इसे समर्थन देने के लिए क्यों परेशान?

सिंथेटिक रूप से, स्थैतिक सदस्यों के होने से आंतरिक कक्षा को प्रतिबंधित करने का कोई कारण नहीं है। यद्यपि Inner का एक उदाहरण Outer साथ जुड़ा हुआ है, लेकिन अभी भी Outer का उपयोग करना संभव है। Inner Outer.Inner.myStatic एक स्थिर सदस्य को Inner का संदर्भ Outer.Inner.myStatic लिए अगर जावा ऐसा करने का निर्णय करता है।

यदि आपको Inner सभी उदाहरणों में कुछ साझा करने की आवश्यकता है, तो आप उन्हें केवल Outer सदस्यों के रूप में स्थैतिक सदस्यों के रूप में रख सकते हैं। यह आप के Inner स्थिर सदस्यों का उपयोग करने से भी बदतर नहीं है, जहां Outer भी Inner किसी भी निजी सदस्य का उपयोग कर सकते हैं (इनकैप्सुलेशन सुधार नहीं)।

यदि आपको एक outer वस्तु द्वारा निर्मित Inner के सभी उदाहरणों में कुछ साझा करने की आवश्यकता है, तो इसे सामान्य वर्ग के रूप में Outer कक्षा में डालना अधिक समझ में आता है।

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

संक्षेप में उत्तर: मानसिक मॉडल सबसे प्रोग्रामर के पास है कि कैसे स्कोप काम करता है, यह जावा के द्वारा उपयोग किए जाने वाले मॉडल नहीं है। अधिक सहज ज्ञान युक्त मॉडल के मिलान के लिए जवैक कैसे काम करता है यह एक बड़ा बदलाव की आवश्यकता होगी।

मुख्य कारण यह है कि आंतरिक कक्षाओं में स्थिर सदस्य वांछनीय हैं कोड सफाई के लिए – बाहरी वर्ग में रखा जाने के बजाय एक अंदरूनी कक्षा द्वारा प्रयोग किया जाने वाला एक स्थैतिक सदस्य इसे अंदर रहने चाहिए। विचार करें:

 class Outer { int outID; class Inner { static int nextID; int id = nextID++; String getID() { return outID + ":" + id; } } } 

विचार करें कि GetID () में क्या हो रहा है जब मैं अयोग्य पहचानकर्ता "outID" का उपयोग करता हूं इस आइडेंटिफ़ायर में दिखाई देने वाला दायरा ऐसा कुछ दिखता है:

 Outer -> Inner -> getID() 

यहां, फिर से क्योंकि यह सिर्फ जवैक कैसे काम करता है, गुंजाइश के "बाहरी" स्तर में बाह्य के स्थिर और उदाहरण दोनों सदस्यों में शामिल हैं यह भ्रमित है क्योंकि हमें आमतौर पर एक वर्ग के स्थैतिक भाग के बारे में सोचने के लिए कहा जाता है जो कि गुंजाइश का एक अन्य स्तर है:

 Outer static -> Outer instance -> instanceMethod() \----> staticMethod() 

इसके बारे में सोचने के इस तरीके में, निश्चित रूप से स्थिर मोड () केवल बाहरी के स्थिर सदस्य देख सकते हैं लेकिन अगर ये जावा कैसे काम करता है, तो एक स्थैतिक विधि में एक इंस्टेंस वैरिएबल को संदर्भित करते हुए "नाम हल नहीं किया जा सकता" त्रुटि हो सकती है वास्तव में ऐसा होता है कि नाम का दायरा में पाया जाता है, लेकिन फिर जांच के एक अतिरिक्त स्तर में किक करता है और पता चलता है कि नाम एक संदर्भ में घोषित किया गया था और इसे एक स्थिर संदर्भ से संदर्भित किया जा रहा है।

ठीक है, यह कैसे आंतरिक कक्षाओं से संबंधित है? Naively, हमें लगता है कि कोई कारण नहीं है आंतरिक कक्षाओं में एक स्थैतिक गुंजाइश नहीं हो सकती है, क्योंकि हम इस तरह काम करने वाले कार्य को चित्रित कर रहे हैं:

 Outer static -> Outer instance -> Inner instance -> getID() \------ Inner static ------^ 

दूसरे शब्दों में, बाहरी कक्षा में आंतरिक घोषणाओं में स्थिर घोषणाएं और आंतरिक वर्ग के उदाहरण के संदर्भ में मौके दोनों ही हैं, लेकिन इनमें से कोई भी वास्तव में अन्य में नेस्टेड नहीं है; दोनों की बजाय बाह्य की स्थिर दायरे में नेस्टेड हैं

यह सिर्फ जवैक का काम नहीं करता है – स्थिर और उदाहरण दोनों सदस्यों के लिए गुंजाइश का एक स्तर है, और गुंजाइश हमेशा सख्ती से घोंसले होती है। यहां तक ​​कि विरासत को शाखाओं के बजाय उप-कक्षा में घोषणाओं की प्रतिलिपि बनाने और सुपरक्लास क्षेत्र की खोज के द्वारा कार्यान्वित किया जाता है।

आंतरिक कक्षाओं के स्थैतिक सदस्यों को समर्थन देने के लिए या तो स्थैतिक और आवृत्ति वाले स्कोप को विभाजित करना होगा और शाखाओं का समर्थन करना और गुंजाइश पदानुक्रम को फिर से जोड़ना होगा, या सभी स्तरों पर संदर्भ के प्रकार को ट्रैक करने के लिए इसे बदलने के लिए अपने सरल बूलीयन "स्थिर संदर्भ" विचार का विस्तार करना होगा वर्तमान गुंजाइश में नेस्टेड क्लास का

हम एक गैर-स्थिर आंतरिक वर्ग में स्थिर विधि क्यों नहीं कर सकते हैं?

नोट: एक गैर-स्थिर नेस्टेड क्लास को आंतरिक श्रेणी के रूप में जाना जाता है ताकि आपके पास non-static inner class न हो जैसे कि।

एक आंतरिक वर्ग के उदाहरण के बिना बाहरी अस्तित्व के किसी भी उदाहरण के बिना अस्तित्व है एक आंतरिक वर्ग समय के स्थिर संकलन के अलावा अन्य स्थिर सदस्यों को घोषित नहीं कर सकता। अगर इसे अनुमति दी गई थी तो static अर्थ के बारे में अस्पष्टता होती। उस मामले में कुछ भ्रम हो गए होंगे:

  1. क्या इसका मतलब है कि वीएम में केवल एक उदाहरण है?
  2. या बाहरी ऑब्जेक्ट के लिए केवल एक उदाहरण?

यही कारण है कि डिजाइनरों ने शायद इस मुद्दे को बिल्कुल भी न निपटने का निर्णय लिया।

अगर मैं भीतर की कक्षा को स्थिर करता हूं तो यह काम करता है क्यूं कर ?

फिर आप किसी आंतरिक कक्षा को स्थिर नहीं बना सकते हैं बल्कि आप नेस्टेड के रूप में एक स्थिर वर्ग घोषित कर सकते हैं। उस स्थिति में यह नेस्टेड क्लास वास्तव में बाहरी कक्षा का हिस्सा है और बिना किसी भी मुद्दे के स्थैतिक सदस्य हो सकते हैं।

एक आंतरिक वर्ग एक स्थिर नेस्टेड वर्ग से कुछ अलग है, हालांकि दोनों सिंटैक्स में समान हैं स्थिर नेस्टेड क्लास केवल समूह के लिए एक माध्यम हैं, जबकि आंतरिक कक्षाओं में मजबूत सहयोग है – और सभी मूल्यों तक पहुंच – उनकी बाहरी कक्षा। आपको सुनिश्चित करना चाहिए कि आप आंतरिक कक्षा का उपयोग क्यों करना चाहते हैं और फिर इसे बहुत स्वाभाविक रूप से आना चाहिए जो आपको उपयोग करना है यदि आपको एक स्थिर विधि घोषित करने की आवश्यकता है तो संभवतः वह एक स्थिर नेस्टेड क्लास है जिसे आप वैसे भी चाहते हैं

इस विषय ने कई लोगों से ध्यान आकर्षित किया है, फिर भी मैं शब्दों की सबसे सरलतम में व्याख्या करने का प्रयास करूंगा

सबसे पहले, http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1 के संदर्भ में, एक क्लास या इंटरफ़ेस पहली घटना के पहले ही तुरंत इनिशियलाइज़ किया जाता है किसी भी सदस्य का जो कि स्थिर कीवर्ड द्वारा आगे बढ़ता है।

  1. इसलिए, यदि हम एक आंतरिक सदस्य के भीतर एक स्थैतिक सदस्य के साथ डालते हैं, तो यह आंतरिक कक्षा के प्रारंभिक रूप से आगे बढ़ेगा, जरूरी नहीं कि बाहरी / संलग्न वर्ग। इसलिए, हम क्लास इनिशियलाइज़ेशन क्रम को बाधित करते हैं।

  2. इसके अलावा इस तथ्य पर विचार करें कि एक गैर-स्थिर आंतरिक कक्षा एक संलग्न / बाहरी वर्ग के उदाहरण के साथ जुड़ा हुआ है। इसलिए, उदाहरण के साथ जोड़कर इसका अर्थ होगा कि आंतरिक वर्ग बाहरी कक्षा के उदाहरण में मौजूद होगा और उदाहरणों में अलग होगा।

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

मान लीजिए कि बाहरी कक्षा के दो उदाहरण हैं और दोनों ने आंतरिक कक्षा को इन्स्तांत किया है। अब अगर आंतरिक कक्षा में एक स्थैतिक सदस्य है तो वह उस सदस्य की केवल एक हीपी को ढेर क्षेत्र में रखेगा। इस मामले में बाहरी वर्ग के दोनों ऑब्जेक्ट यह देखेंगे एक कॉपी और वे इसे एक साथ बदल सकते हैं। इस वजह से "डर्टी पढें" स्थिति पैदा हो सकती है इसलिए इस प्रतिबंध को लागू करने के लिए जावा ने इस प्रतिबंध को लागू किया है। इस तर्क का समर्थन करने के लिए एक और मजबूत बिंदु यह है कि जावा यहां अंतिम स्थैतिक सदस्यों की अनुमति देता है, जिनके मूल्य नहीं हो सकते बाहरी वर्ग ऑब्जेक्ट के दोनों में से बदल दिया कृपया मुझे बताओ अगर मैं गलत हूँ।

सबसे पहले क्यों कोई स्थिर सदस्य को एक गैर-स्थैतिक आंतरिक वर्ग में परिभाषित करना चाहता है? जवाब है, ताकि बाहरी कक्षा सदस्य उन स्थैतिक सदसियों को भीतर के वर्ग के नाम के साथ ही इस्तेमाल कर सकें, है ना?

लेकिन इस मामले के लिए हम सीधे सदस्य को बाहरी कक्षा में परिभाषित कर सकते हैं। जो आंतरिक कक्षा के सभी ऑब्जेक्ट के साथ संबद्ध होगा, बाहरी क्लास इंस्टालेशन के भीतर।

जैसे कोड नीचे,

 public class Outer { class Inner { public static void method() { } } } 

इस तरह लिखा जा सकता है

 public class Outer { void method() { } class Inner { } } 

इसलिए मेरी राय में कोड को जटिल नहीं करने के लिए जावा डिज़ाइनर इस कार्यक्षमता की अनुमति नहीं दे रहा है या हम कुछ और सुविधाओं के साथ भविष्य की रिलीज में यह कार्यक्षमता देख सकते हैं।

कक्षा को सामान्य क्षेत्र के रूप में व्यवहार करने का प्रयास करें, तो आप समझेंगे।

 //something must be static. Suppose something is an inner class, then it has static keyword which means it's a static class Outer.something 

आंतरिक वर्ग के सदस्य स्थिर होने के लिए बेकार है क्योंकि आप उनसे पहले स्थान पर नहीं पहुंच पाएंगे।

इसके बारे में सोचो, एक स्थैतिक सदस्य तक पहुंचने के लिए, आप हमारे नाम, className.memberName का उपयोग करते हैं, यह होना चाहिए outerclassName.innerclassName.memberName ,,, अब आप देखते हैं क्यों innerclass स्थिर होना चाहिए ….

आपको स्थैतिक नेस्टेड कक्षाओं पर स्थैतिक तरीकों की अनुमति है। उदाहरण के लिए

 public class Outer { public static class Inner { public static void method() { } } }