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


89

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

public static final String SOME_CONST = "SOME_VALUE";

ऐसा करने का पसंदीदा तरीका क्या है?

  1. इंटरफेस
  2. सार वर्ग
  3. फाइनल क्लास

मुझे किसका उपयोग करना चाहिए और क्यों?


कुछ जवाबों के स्पष्टीकरण:

Enums - मैं enums का उपयोग नहीं करने जा रहा हूं, मैं कुछ भी नहीं मान रहा हूं, बस कुछ स्थिरांक एकत्र कर रहा हूं जो किसी भी तरह से एक-दूसरे से संबंधित नहीं हैं।

इंटरफ़ेस - मैं किसी भी वर्ग को एक के रूप में सेट नहीं करने जा रहा हूं जो इंटरफ़ेस को लागू करता है। बस कॉन्स्टैंट को कॉल करने के लिए इंटरफ़ेस का उपयोग करना चाहते हैं जैसे ISomeInterface.SOME_CONST:।


कुछ ऐसी ही चर्चा यहाँ है: stackoverflow.com/questions/320588/… । मैं एक निजी कंस्ट्रक्टर के साथ एक अंतिम वर्ग का उपयोग करूंगा ताकि इसे तत्काल न किया जा सके।
डैन डायर

2
क्षमा करें, लेकिन "मैं एनम का उपयोग नहीं करने जा रहा हूं" इस प्रश्न को "बेवकूफ बनाने का सबसे अच्छा तरीका क्या है?"
क्लेटस

मैं यह नहीं कह रहा हूं कि आप इंटरफ़ेस को लागू करने जा रहे हैं। लेकिन ऐसा करने के लिए इंटरफ़ेस का उपयोग करने का कोई मतलब नहीं है। तो, अंतिम वर्ग के साथ जाएं
:)

Enum के साथ समस्या क्या है? आप इसका उपयोग 'कुछ स्थिरांक जो किसी भी तरह से एक दूसरे से संबंधित नहीं हैं' को इकट्ठा करने के लिए कर सकते हैं। हम्म?
गेदेवन २६'०

5
यदि कॉन्स्टेंट संबंधित नहीं हैं, तो वैचारिक रूप से, एक दुश्मनी एक बुरा विकल्प है। एक एनुम एक ही प्रकार के वैकल्पिक मूल्यों का प्रतिनिधित्व करता है। ये स्थिरांक विकल्प नहीं हैं और वे एक ही प्रकार के भी नहीं हो सकते हैं (कुछ तार, कुछ पूर्णांक, आदि हो सकते हैं)
दान डायर

जवाबों:


92

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

public final class MyValues {
  public static final String VALUE1 = "foo";
  public static final String VALUE2 = "bar";
}

दूसरे वर्ग में:

import static MyValues.*
//...

if(variable.equals(VALUE1)){
//...
}

4
यहाँ एक अलग वर्ग बनाने का लाभ कहाँ है? जबकि मैं आमतौर पर कैलेंडर एपीआई को डिजाइन के एक अच्छे उदाहरण के रूप में नहीं रखता, यह "कैलेंडर से संबंधित स्थिरांक कैलेंडर में हैं" के संदर्भ में ठीक है।
जॉन स्कीट

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

2
आप कोड डुप्लिकेट क्यों करेंगे? बस दूसरे वर्ग को देखें। मुझे यह अपेक्षाकृत दुर्लभ लगता है कि एक स्थिर वास्तव में अकेला खड़ा है।
जॉन स्कीट

14
बेहतर पठनीयता के लिए मेरे पास एक निजी डिफाल्ट कंस्ट्रक्टर है जिसमें कोई बॉडी (और एक मिलान टिप्पणी) नहीं है।
रैन बीरन

5
बहुत पुराना जवाब है, और यह टिप्पणी शायद जगह से बाहर है, लेकिन मैं उपयोग VALUE1.equals(variable)करता हूं क्योंकि यह एनपीई से बचा जाता है।
आकाश

38

आपकी स्पष्टीकरण में कहा गया है: "मैं एनम का उपयोग नहीं करने जा रहा हूं, मैं कुछ भी नहीं मान रहा हूं, बस कुछ स्थिरांक एकत्र कर रहा हूं जो किसी भी तरह से एक दूसरे से संबंधित नहीं हैं।"

यदि स्थिरांक एक-दूसरे से संबंधित नहीं हैं, तो आप उन्हें एक साथ क्यों इकट्ठा करना चाहते हैं? प्रत्येक स्थिरांक को उस कक्षा में रखें, जिसका वह सबसे निकट से संबंधित है।


2
जॉन - वे इस अर्थ से संबंधित हैं कि वे सभी एक ही कार्यक्षमता से संबंधित हैं। हालांकि, वे किसी भी चीज़ का प्रतिज्ञान नहीं हैं ... वे संपत्ति नहीं रखते हैं कि एक वस्तु "उन चीजों में से एक" है।
युवल एडम

13
ठीक है। उस स्थिति में उन्हें सिर्फ उस कक्षा में रखें जो उस कार्यक्षमता से निकटतम है जिनसे वे संबंधित हैं।
जॉन स्कीट

26

मेरे सुझाव (वरीयता के घटते क्रम में):

1) यह मत करो । वास्तविक वर्ग में स्थिरांक बनाएं जहां वे सबसे अधिक प्रासंगिक हैं। 'स्थिरांक' वर्ग / इंटरफ़ेस का बैग होना वास्तव में OO सर्वोत्तम प्रथाओं का पालन नहीं करता है।

मैं, और बाकी सभी, समय-समय पर # 1 को अनदेखा करते हैं। यदि आप ऐसा करने जा रहे हैं:

2) निजी कंस्ट्रक्टर के साथ अंतिम वर्ग यह कम से कम किसी को अपने 'स्थिरांक के बैग' को गाली देने से रोक देगा / स्थिर करने के लिए इसे आसानी से प्राप्त करने के लिए लागू करेगा। (मुझे पता है कि आपने कहा था कि आप ऐसा नहीं करेंगे - लेकिन इसका मतलब यह नहीं है कि कोई आपके साथ नहीं आएगा)

3) इंटरफ़ेस यह काम करेगा, लेकिन मेरी प्राथमिकता # 2 में संभावित दुरुपयोग का उल्लेख नहीं है।

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


2
1 की समस्या यह है कि कभी-कभी आप अपने कोड में निरंतरता लाने के लिए किसी अन्य श्रेणी के लिए कुछ निर्भरता को इंजेक्ट करेंगे।
amdev

एक इंटरफेस में सभी क्षेत्र स्पष्ट रूप से सार्वजनिक, स्थिर और अंतिम हैं
कोडेबेटर

@Kodebetter लेकिन अधिक फ़ील्ड जोड़ने के लिए इंटरफ़ेस को बढ़ाया / कार्यान्वित किया जा सकता है।
विट

12

जोशुआ बलोच ने प्रभावी जावा में नोट किए:

  • इंटरफेस का उपयोग केवल प्रकारों को परिभाषित करने के लिए किया जाना चाहिए,
  • अमूर्त वर्ग अस्थिरता को नहीं रोकते हैं (उन्हें उपवर्गित किया जा सकता है, और यहां तक ​​कि सुझाव दिया जाता है कि उन्हें उपवर्ग के रूप में डिजाइन किया गया है)।

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

class SomeConstants
{
    // Prevents instanciation of myself and my subclasses
    private SomeConstants() {}

    public final static String TOTO = "toto";
    public final static Integer TEN = 10;
    //...
}

फिर, जैसा कि पहले ही कहा गया है, आप अपने स्थिरांक का उपयोग करने के लिए स्थैतिक आयात का उपयोग कर सकते हैं।


7

मेरा पसंदीदा तरीका ऐसा नहीं है। जब जावा 5 ने टाइपफुल एनम पेश किया तो कॉन्स्टेंट्स की उम्र काफी कम हो गई। और इससे पहले भी जोश बलोच ने उस का एक (थोड़ा और अधिक बुरा) संस्करण प्रकाशित किया था, जो जावा 1.4 (और पहले) पर काम करता था।

जब तक आपको कुछ विरासत कोड के साथ इंटरऑपरेबिलिटी की आवश्यकता होती है, तब वास्तव में स्ट्रिंग / पूर्णांक स्थिरांक नाम का उपयोग करने का कोई कारण नहीं है।


2
अच्छा जवाब, एक उदाहरण बेहतर होगा।
amdev

3

बस अंतिम वर्ग का उपयोग करें।

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

यह एक इंटरफेस का उपयोग करने के लिए बहुत अधिक समझ में नहीं आता है, एक इंटरफ़ेस अनुबंध को निर्दिष्ट करने वाला है। आप बस कुछ निरंतर मूल्यों की घोषणा करना चाहते हैं।



3

enums ठीक हैं IIRC, प्रभावी जावा में एक आइटम (दूसरा संस्करण) में किसी भी मूल्य के लिए enum[जावा कीवर्ड] interfaceको लागू करने वाले मानक विकल्पों की गणना की जाती है ।

मेरी प्राथमिकता एक [जावा कीवर्ड] उपयोग करने के लिए है interfaceएक से अधिक final classस्थिरांक के लिए। आप स्पष्ट रूप से प्राप्त करते हैं public static final। कुछ लोग यह तर्क देंगे कि interfaceबुरे प्रोग्रामर इसे लागू करने की अनुमति देते हैं , लेकिन बुरे प्रोग्रामर कोड लिखने जा रहे हैं जो आपके लिए कोई फर्क नहीं पड़ता।

कौन सा बेहतर लग रहा है?

public final class SomeStuff {
     private SomeStuff() {
         throw new Error();
     }
     public static final String SOME_CONST = "Some value or another, I don't know.";
}

या:

public interface SomeStuff {
     String SOME_CONST = "Some value or another, I don't know.";
}

लेकिन बुरे प्रोग्रामर कोड लिखने जा रहे हैं जो आपको कोई फर्क नहीं पड़ता कि बेकार है। यह केवल इतना सच है। यदि आप खराब प्रोग्रामिंग को कम करने, या इसे पूरी तरह से समाप्त करने के लिए कदम उठा सकते हैं, तो आपके पास ऐसा करने की थोड़ी ज़िम्मेदारी है; जितना संभव हो उतना स्पष्ट हो। एक बुरा प्रोग्रामर एक अंतिम वर्ग का विस्तार नहीं कर सकता है।
liltitus27

1
@ liltitus27 कुछ हद तक मैं सहमत हूं। लेकिन क्या आप वास्तव में बदसूरत कोड चाहते हैं कि खराब प्रोग्रामर खराब कोड लिखने के एक तरीके को रोक दें? वे कोड का उत्पादन अभी भी निराशाजनक होगा, लेकिन अब आपका कोड कम पठनीय है।
टॉम हॉल्टिन -

1

या 4. उन्हें कक्षा में रखें जिसमें तर्क है जो स्थिरांक का सबसे अधिक उपयोग करता है

... क्षमा करें; प्रतिरोध नहीं कर सका ;-)


3
यह एक अच्छा विचार नहीं है। यह उन वर्गों के बीच निर्भरता पैदा करता है जिनके पास कोई नहीं होना चाहिए।
युवल एडम

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

यदि स्थिरांक का उपयोग करने वाला केवल एक वर्ग था, तो यह समझ में आ सकता है।
टॉम हॉल्टिन -

-1
  1. निजी कंस्ट्रक्टर के नुकसान में से एक यह है कि विधि का अस्तित्व कभी भी परीक्षण नहीं किया जा सकता है।

  2. विशिष्ट डोमेन प्रकार में लागू करने के लिए प्रकृति अवधारणा द्वारा अच्छा लगता है, इसे विकेन्द्रीकृत स्थिरांक पर लागू करें पर्याप्त अच्छा नहीं लग रहा है

Enum की अवधारणा है "Enumerations बारीकी से संबंधित वस्तुओं के सेट हैं"।

  1. एक स्थिर इंटरफ़ेस का विस्तार / कार्यान्वयन एक बुरा अभ्यास है, इसे सीधे संदर्भित करने के बजाय एक अपरिवर्तनीय स्थिरांक का विस्तार करने की आवश्यकता के बारे में सोचना मुश्किल है।

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


1
"निजी कंस्ट्रक्टर विधि के अस्तित्व का परीक्षण कभी नहीं किया जा सकता है": सच नहीं है। यदि आप (या आपके बॉस) कोड कवरेज रिपोर्टों के बारे में 100% होने के लिए वास्तव में पागल हैं, तो आप अभी भी प्रतिबिंब का उपयोग करके और कंस्ट्रक्टर थ्रो को सुनिश्चित करके इसका परीक्षण कर सकते हैं। लेकिन, IMHO, यह केवल औपचारिकता है और वास्तव में परीक्षण करने की आवश्यकता नहीं है। यदि आप (या टीम) वास्तव में केवल वही देखते हैं जो वास्तव में महत्वपूर्ण है, तो 100% लाइन कवरेज आवश्यक नहीं है।
एल। होलांडा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.