आप जावा में एक वर्ग को स्थिर घोषित करने में सक्षम क्यों नहीं हैं?


459

आप जावा में एक वर्ग को स्थिर घोषित करने में सक्षम क्यों नहीं हैं?


72
प्रति-प्रश्न: यदि आप शीर्ष-स्तरीय वर्ग होने की घोषणा करते हैं, तो आप क्या प्रभाव की उम्मीद करेंगे static?
जोकिम सॉउर

3
नहीं, आप स्थिर आंतरिक कक्षाओं को छोड़कर नहीं कर सकते। लेकिन, आप इसके साथ क्या हासिल करना चाहते हैं?
मनोलोवर

60
@ जोकिम सौर: ठीक है, सी # staticवर्गों की व्याख्या करता है abstract final, अर्थात, उन्हें त्वरित नहीं किया जा सकता है और न ही बढ़ाया जा सकता है। इसका अर्थ है कि वे केवल स्थैतिक सदस्य रख सकते हैं, जो उन वर्गों के लिए उपयोगी है जिनमें केवल सहायक विधियाँ हैं।
13

30
@bcat यह C # के लिए सही है, लेकिन एक जावा वर्ग या तो अमूर्त या अंतिम हो सकता है, दोनों नहीं। किसी वर्ग को तात्कालिक होने से रोकने के लिए, एक निजी निर्माता घोषित कर सकता है।
लोरेंजो पोलिडोरी

7
@JoachimSauer सरल, मैं कक्षा में सभी सदस्यों को स्थिर होने के लिए मजबूर करना पसंद करूँगा (शायद प्रत्येक विधि या संपत्ति पर घोषणा करने के लिए भी)।
hmartinezd

जवाबों:


475

केवल नेस्टेड कक्षाएं स्थिर हो सकती हैं। ऐसा करके आप बाहरी वर्ग के उदाहरण के बिना नेस्टेड क्लास का उपयोग कर सकते हैं।

class OuterClass{
    public static class StaticNestedClass{
    }

    public class InnerClass{
    }

    public InnerClass getAnInnerClass(){
        return new InnerClass();
    }

    //This method doesn't work
    public static InnerClass getAnInnerClassStatically(){
        return new InnerClass();
    }
}

class OtherClass{
    //Use of a static nested class:
    private OuterClass.StaticNestedClass staticNestedClass = new OuterClass.StaticNestedClass();

    //Doesn't work
    private OuterClass.InnerClass innerClass = new OuterClass.InnerClass();

    //Use of an inner class:
    private OuterClass outerclass= new OuterClass();
    private OuterClass.InnerClass innerClass2 = outerclass.getAnInnerClass();
    private OuterClass.InnerClass innerClass3 = outerclass.new InnerClass();
}

स्रोत:

एक ही विषय पर:


3
पहला वाक्यांश सटीक नहीं होने के बावजूद +1। जैसा कि ट्यूटोरियल बताता है कि "गैर-स्थिर नेस्टेड वर्गों को आंतरिक कक्षाएं कहा जाता है।" (जेएलएस: "एक आंतरिक वर्ग एक नेस्टेड वर्ग है जो स्पष्ट रूप से या अंतर्निहित रूप से स्थिर घोषित नहीं किया गया है।")
user85421

74
आप सबसे निश्चित रूप से सही हैं; लेकिन मैं यह नहीं देखता कि यह सवाल का जवाब कैसे देता है
जोएरी हेंड्रिकक्स

2
@Carlos Heuberger, आप सही हैं, मैंने पोस्ट अपडेट कर दी है। @ जॉरी हेंड्रिक, सवाल था, "एक वर्ग को स्थिर क्यों नहीं घोषित किया जा सकता है ..?", वे कर सकते हैं, और [मेरी पोस्ट यहाँ पढ़ें]। यह स्थैतिक कक्षाओं के उपयोग के बारे में स्पष्टीकरण है और उन्हें नेस्टेड-क्लास क्यों होना है।
कोलिन हेबर्ट

1
यहाँ दिए गए समाधान ठीक हैं ... लेकिन मुझे अभी भी आश्चर्य है कि y ppl ने तार्किक रूप से यह नहीं बताया कि java..some OOPs अवधारणा स्पष्टीकरण में स्थिर वर्ग संभव नहीं है, इसका सही उत्तर होगा। मैं इसके लिए इंतजार कर रहा हूं
पुनीथ राज

9
यह सच है, लेकिन आप जिस प्रश्न के बारे में सोच रहे हैं वह आमतौर पर खुद को हल करता है जब आप खुद से पूछना शुरू करते हैं कि "स्थिर वर्ग" क्या होगा। जावा में, एक स्थिर तत्व का मतलब है कि आप इसे संलग्न वर्ग के उदाहरण के बिना एक्सेस / इनवोक कर सकते हैं; यदि आप कीवर्ड को कक्षा में ही लागू करते हैं तो इसका क्या अर्थ हो सकता है? क्या इरादा हे? आप क्या उम्मीद करेंगे? अब जब आपको पता है कि यह क्या हो सकता है, तो मुझे पूरा यकीन है कि यह या तो "वास्तव में कोई मतलब नहीं" होगा या यह "दूर की कौड़ी" होगा (यह समझ में आएगा, लेकिन यह अंत है यह सिर्फ एक विकल्प है जो बनाया गया है)।
कॉलिन हेबर्ट

39

शीर्ष स्तर की कक्षाएं डिफ़ॉल्ट रूप से स्थिर होती हैं। आंतरिक कक्षाएं डिफ़ॉल्ट रूप से गैर-स्थिर होती हैं। आप उन्हें स्पष्ट रूप से स्थैतिक रूप से चिह्नित करके आंतरिक कक्षाओं के लिए डिफ़ॉल्ट बदल सकते हैं। शीर्ष स्तर की कक्षाएं, शीर्ष-स्तरीय होने के आधार पर, गैर-स्थैतिक शब्दार्थ नहीं हो सकते हैं क्योंकि संदर्भित करने के लिए कोई मूल वर्ग नहीं हो सकता है। इसलिए, शीर्ष-स्तरीय कक्षाओं के लिए डिफ़ॉल्ट को बदलने का कोई तरीका नहीं है।


14
»शीर्ष स्तर की कक्षाएं डिफ़ॉल्ट रूप से स्थिर होती हैं।« यह सबसे अच्छा जवाब है। वे स्थिर हैं क्योंकि आपको उन्हें संदर्भित करने के लिए किसी भी चीज़ के किसी भी उदाहरण की आवश्यकता नहीं है। उन्हें कहीं से भी रेफर किया जा सकता है। वे स्थिर भंडारण में हैं (सी भंडारण वर्गों के रूप में)। - जैसा कि अन्य ने नोट किया है (एक अन्य जवाब में टिप्पणी में इयान एल्डर), भाषा डिजाइनरों ने staticएक उच्च-स्तरीय वर्ग पर कीवर्ड को यह बताने और लागू करने की अनुमति दी हो सकती है कि इसमें केवल स्थैतिक सदस्य हो सकते हैं, और तत्काल नहीं; हालाँकि, लोगों को भ्रमित कर सकता staticहै क्योंकि नेस्टेड वर्गों के लिए एक अलग अर्थ है।
लुमी

35

इसलिए, मैं पार्टी के लिए देर से आ रहा हूं, लेकिन यहां मेरे दो सेंट हैं - दार्शनिक रूप से कॉलिन हेबर्ट के जवाब में।

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


1
हाँ। इसे दूसरे तरीके से रखने के लिए, शीर्ष स्तर की कक्षाएं डिफ़ॉल्ट रूप से स्थिर होती हैं, इसलिए कीवर्ड की कोई आवश्यकता नहीं है।
वारेन ड्यू

1
ठीक है, मैं वारेन ड्यू ने कहा कि "स्थैतिक स्तर तक पहुँचने पर शीर्ष स्तर की कक्षाएं डिफ़ॉल्ट रूप से स्थिर होती हैं"।
डेक्सटर

1
अधूरा जवाब। क्लास में हर तरीके को स्टैटिक बनाने के लिए एक नया कीवर्ड और कंस्ट्रक्टर प्राइवेट अच्छा होगा। मैं इसे स्थिर नाम नहीं दूंगा क्योंकि यह सिर्फ भ्रामक है।
G_V

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

29

निजी निर्माता के साथ वर्ग स्थिर है।

अपनी कक्षा को इस तरह घोषित करें:

public class eOAuth {

    private eOAuth(){}

    public final static int    ECodeOauthInvalidGrant = 0x1;
    public final static int    ECodeOauthUnknown       = 0x10;
    public static GetSomeStuff(){}

}

और आप बिना आरंभीकरण के उपयोग कर सकते हैं:

if (value == eOAuth.ECodeOauthInvalidGrant)
    eOAuth.GetSomeStuff();
...

3
यह स्थिर नहीं है, लेकिन इसमें स्थिर गुण हैं। यदि आप सार्वजनिक अंतिम int ECodeOauthUnogn = 0x10 लिखते हैं; यह अब स्थिर नहीं है।
user1883212

9
यदि कोई सोच रहा है कि यहाँ क्या चल रहा है, तो यह "स्थिर वर्ग" की C # परिभाषा से मेल खाता है - msdn.microsoft.com/en-us/library/79b3xss3%28v=vs.90%29.aspx । "स्थिर वर्ग" की जावा परिभाषा को देखते हुए, सभी गैर-आंतरिक वर्ग स्थिर हैं (भाई के उत्तर देखें)।
कैलम

1
इसके अलावा @ user1883212 सही है, मैं यहां तक ​​कहूंगा कि यह उत्तर पाठक को भ्रमित करता है कि निजी कंस्ट्रक्टर किसी तरह यहां महत्वपूर्ण है, जबकि यह वास्तव में बिल्कुल भी मायने नहीं रखता है।
tlwhitec

.NET दुनिया में, यदि कोई वर्ग अमूर्त और अंतिम ( static classC # में एक घोषणा के प्रभाव ) दोनों को चिह्नित करता है , तो कंपाइलर कोड को उस प्रकार के चर घोषित करने की अनुमति नहीं देगा, और न ही इसे सामान्य प्रकार के पैरामीटर के रूप में उपयोग करेगा। एक वर्ग में सुलभ कंस्ट्रक्टरों की कमी है, जो या तो तत्काल या विरासत में मिला हो सकता है, उस प्रकार के चर की घोषणा को नहीं छोड़ेंगे, न ही एक सामान्य प्रकार के पैरामीटर के रूप में इसका उपयोग।
सुपरकैट

यह उत्तर पूरी तरह से गलत है। निजी निर्माणकर्ताओं का इससे कोई लेना-देना नहीं है। कोड केवल एक वर्ग का एक उदाहरण है जिसमें कुछ भी स्थिर विशेषताओं और तरीकों के साथ नहीं है। इसका स्थैतिक वर्गों से कोई लेना-देना नहीं है।
लोर्ने

13

यकीन है कि वे कर सकते हैं, लेकिन केवल आंतरिक नेस्टेड कक्षाएं। वहां, इसका मतलब है कि नेस्टेड वर्ग के उदाहरणों को बाहरी वर्ग के एक संलग्न उदाहरण की आवश्यकता नहीं है।

लेकिन शीर्ष स्तर की कक्षाओं के लिए, भाषा डिजाइनर कीवर्ड के साथ कुछ भी उपयोगी नहीं सोच सकते, इसलिए इसकी अनुमति नहीं है।


पहला वाक्यांश सटीक नहीं होने के बावजूद +1। जैसा कि जेएलएस कहता है: "एक आंतरिक वर्ग एक नेस्टेड वर्ग है जो स्पष्ट रूप से या स्पष्ट रूप से स्थिर घोषित नहीं किया गया है।" (बस शब्दावली, मुझे पता है ...)
14:85 पर user85421

7
यद्यपि एक शीर्ष-स्तरीय वर्ग घोषित नहीं किया जा सकता है static, यह कभी-कभी समझ में आता है। उदाहरण के लिए, केवल स्थिर सहायक विधियों वाली एक क्लास का तात्कालिक होने का कोई मतलब नहीं है, लेकिन जावा भाषा आपको ऐसा करने से नहीं रोकती है। आप डिफ़ॉल्ट निर्माणकर्ता को घोषित करके अन्य वर्गों के लिए वर्ग को गैर-तात्कालिक (और व्यावहारिक रूप से 'स्थिर') बना सकते हैं private, जो तात्कालिकता को मना करता है क्योंकि कोई भी निर्माता दिखाई नहीं देता है।
इयान सैमुअल मैकलीन एल्डर

12

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

public enum MyUtilities {;
   public static void myMethod();
}

25
एक प्रकार के रूप में एक संलयन एक विशिष्ट अपेक्षा है: यह मदों की गणना है। इसे "यूटिलिटी क्लास" के लिए उपयोग करना, जब आप अन्यथा एक निजी कंस्ट्रक्टर के साथ एक क्लास कर सकते हैं, शब्दार्थ भ्रमित है।
दूरदर्शी सॉफ्टवेयर समाधान

5
@VisionarySoftwareSolutions मेरे लिए, यह विशिष्टता कहती है कि इस वर्ग के कोई उदाहरण नहीं हैं, बल्कि अप्रत्यक्ष रूप से एक वर्ग के उदाहरणों को बनाना असंभव है।
पीटर लॉरी

8
public class Outer {
   public static class Inner {}
}

... इसे तब तक स्थिर घोषित किया जा सकता है - जब तक यह एक सदस्य वर्ग है।

JLS से:

सदस्य कक्षाएं स्थिर हो सकती हैं, जिस स्थिति में उनके पास आसपास के वर्ग के उदाहरण चर तक पहुंच नहीं है; या वे आंतरिक वर्ग (.18.1.3) हो सकते हैं।

और यहाँ:

स्थैतिक कीवर्ड एक गैर-आंतरिक वर्ग T के शरीर के भीतर एक सदस्य प्रकार C की घोषणा को संशोधित कर सकता है। इसका प्रभाव यह घोषित करना है कि C एक आंतरिक वर्ग नहीं है। जिस तरह T की एक स्थिर विधि के शरीर में T का कोई मौजूदा उदाहरण नहीं है, C के पास T की कोई वर्तमान आवृत्ति नहीं है, और न ही इसका कोई शाब्दिक रूप से संलग्न उदाहरण है।

एक स्थैतिक कीवर्ड किसी शीर्ष स्तर वर्ग के लिए कोई मतलब नहीं होगा, सिर्फ इसलिए कि एक शीर्ष स्तर वर्ग में कोई संलग्न प्रकार नहीं है।


अगर यह आंतरिक नहीं है तो इसे क्यों कहें Inner? Nestedकम भ्रमित करने वाला विकल्प होता।
लोरेन

5

जैसा कि ऊपर बताया गया है, एक वर्ग स्थिर नहीं हो सकता जब तक कि वह किसी अन्य वर्ग का सदस्य न हो।

यदि आप एक वर्ग "डिजाइन करना चाह रहे हैं, जिसमें" कई उदाहरण नहीं हो सकते ", तो आप" सिंगलटन "डिजाइन पैटर्न को देखना चाहते हैं।

शुरुआती सिंगलटन जानकारी यहाँ

चेतावनी:

यदि आप सिंगलटन पैटर्न का उपयोग करने के बारे में सोच रहे हैं, तो अपनी सभी क्षमताओं का विरोध करें। यह समझने में सबसे आसान DesignPatterns में से एक है, शायद सबसे लोकप्रिय है, और निश्चित रूप से सबसे अधिक दुरुपयोग है। (स्रोत: ऊपर दिए गए लिंक के अनुसार JavaRanch)


4

जावा स्थिर आंतरिक कक्षाओं को कैसे परिभाषित करता है, इसके अलावा, C # दुनिया [1] के अनुसार स्थिर कक्षाओं की एक और परिभाषा है । एक स्थिर वर्ग वह है जिसमें केवल स्थिर विधियाँ (कार्य) हैं और यह प्रक्रियात्मक प्रोग्रामिंग का समर्थन करने के लिए है। ऐसी कक्षाएं वास्तव में ऐसी कक्षाएं नहीं हैं जिनमें वर्ग का उपयोगकर्ता केवल सहायक कार्यों में रुचि रखता है और वर्ग के उदाहरण बनाने में नहीं। जबकि स्थिर वर्ग C # में समर्थित हैं, जावा में ऐसा कोई प्रत्यक्ष समर्थन मौजूद नहीं है। हालाँकि आप जावा में C # स्टेटिक क्लास की नकल करने के लिए enums का उपयोग कर सकते हैं ताकि एक उपयोगकर्ता किसी दिए गए वर्ग (यहां तक ​​कि प्रतिबिंब का उपयोग करके) के उदाहरण न बना सके [2] :

public enum StaticClass2 {
    // Empty enum trick to avoid instance creation
    ; // this semi-colon is important

    public static boolean isEmpty(final String s) {
        return s == null || s.isEmpty();
    }
}

3

हम जावा में जो कुछ भी कोड करते हैं वह एक कक्षा में जाता है। जब भी हम एक क्लास चलाते हैं तो JVM किसी ऑब्जेक्ट को इंस्टेंट करता है। जेवीएम कई वस्तुओं का निर्माण कर सकता है, परिभाषा के अनुसार स्टेटिक का मतलब है कि आपके पास सभी वस्तुओं के लिए कॉपी का एक ही सेट है।

इसलिए, यदि जावा ने जब भी आप प्रोग्राम बनाते हैं, तो टॉप क्लास को स्टैटिक होने की अनुमति दी होती है, जो ऑब्जेक्ट बनाता है और उसी मेमोरी लोकेशन पर ओवरराइड करता रहता है।

यदि आप हर बार वस्तु को प्रतिस्थापित कर रहे हैं, तो आप इसे बनाने का क्या मतलब है?

यही कारण है कि जावा को शीर्ष-स्तरीय कक्षा के लिए स्थैतिक से छुटकारा मिला।

अधिक ठोस कारण हो सकते हैं लेकिन इसने मुझे बहुत तार्किक अर्थ दिया।


3
आंतरिक कक्षाएं बाहरी कक्षाओं से जुड़ी होती हैं और यही कारण है कि वे स्थिर हो सकती हैं, क्योंकि आपके पास निर्भर करने के लिए एक अलग वस्तु है।
user2626445

1
आपका मतलब है 'यही कारण है कि वे स्थिर नहीं हो सकते हैं ।'
लोरेन

2

केवल वही वर्ग जो स्थिर हो सकते हैं वे आंतरिक वर्ग हैं। निम्न कोड ठीक काम करता है:

public class whatever {
    static class innerclass {
    }
}

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


1
'स्टैटिक इनर' शब्दों में एक विरोधाभास है। 'स्थिर' और 'आंतरिक' परस्पर अनन्य हैं। आप जिस शब्द की तलाश कर रहे हैं वह 'नेस्टेड' है, 'इनर' नहीं।
लोरेन

1

मुझे लगता है कि यह एक गिलास कॉफी पीने जितना आसान है! जरा इस पर गौर करें। हम क्लास को परिभाषित करते समय स्पष्ट रूप से स्थिर कीवर्ड का उपयोग नहीं करते हैं।

public class StaticClass {

    static private int me = 3;
    public static void printHelloWorld() {
       System.out.println("Hello World");
    }



    public static void main(String[] args) {
        StaticClass.printHelloWorld();
        System.out.println(StaticClass.me);
    }
}

क्या यह स्थिर वर्ग की परिभाषा नहीं है? हम सिर्फ एक वर्ग के लिए बंधे फ़ंक्शन का उपयोग करते हैं। सावधान रहें कि इस मामले में हम उस नेस्टेड में एक अन्य वर्ग का उपयोग कर सकते हैं। इसे देखो:

class StaticClass1 {

    public static int yum = 4;

    static void  printHowAreYou() {
        System.out.println("How are you?");
    }
}

public class StaticClass {

    static int me = 3; 
    public static void printHelloWorld() {
       System.out.println("Hello World");
       StaticClass1.printHowAreYou();
       System.out.println(StaticClass1.yum);
    }



    public static void main(String[] args) {
        StaticClass.printHelloWorld();
        System.out.println(StaticClass.me);
    }
}

मुझे लगता है कि हम स्थैतिक वर्ग की परिभाषा के आधार पर ऐसी कक्षाओं को स्थैतिक वर्ग की परिभाषा के रूप में देख सकते हैं, न कि केवल स्थैतिक कीवर्ड को क्वालीफायर के रूप में उपयोग करके।
इरफानकैम

एक निजी कंस्ट्रक्टर बनाने के लिए सुनिश्चित करें, अन्यथा आप कहने में सक्षम होंगे new StaticClass()और यह वास्तव में बहुत मायने नहीं रखता है। एक निजी कंस्ट्रक्टर के साथ यह इसके उदाहरणों की अनुमति नहीं देगा।
13

1

एक PlatformUIग्रहण में एक वर्ग के लिए स्थिर तरीकों और निजी निर्माणकर्ता को अंतिम रूप से देखा जा सकता है।

public final class <class name>
{
   //static constants
   //static memebers
}

0

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.