स्ट्रिंग्स की दुश्मनी पैदा करने का सबसे अच्छा तरीका?


364

एक enumप्रकार के तार का एक सेट का प्रतिनिधित्व करने का सबसे अच्छा तरीका क्या है ?

मैंने यह कोशिश की:

enum Strings{
   STRING_ONE("ONE"), STRING_TWO("TWO")
}

फिर मैं उनका उपयोग कैसे कर सकता हूं Strings?

जवाबों:


605

मुझे नहीं पता कि आप क्या करना चाहते हैं, लेकिन इस तरह से मैंने वास्तव में आपके उदाहरण कोड का अनुवाद किया है ...।

package test;

/**
 * @author The Elite Gentleman
 *
 */
public enum Strings {
    STRING_ONE("ONE"),
    STRING_TWO("TWO")
    ;

    private final String text;

    /**
     * @param text
     */
    Strings(final String text) {
        this.text = text;
    }

    /* (non-Javadoc)
     * @see java.lang.Enum#toString()
     */
    @Override
    public String toString() {
        return text;
    }
}

वैकल्पिक रूप से, आप के लिए एक गेट्टर विधि बना सकते हैं text

अब आप कर सकते हैं Strings.STRING_ONE.toString();


3
मुझे नहीं पता कि यह एक संकलक की आवश्यकता है, लेकिन private String textअंतिम होना चाहिए।
जोनाथन

7
@ टामस नारोस हां, आप अभी भी कंस्ट्रक्टर में इसे असाइन कर सकते हैं, जब तक आप इसे अंतिम घोषित नहीं करते हैं।
जोनाथन

28
@ द एलीट जेंटलमैन यह बुरा होगा यदि रनटाइम के दौरान एक एनम स्थिरांक का मूल्य बदल जाए, तो भी यदि आवश्यक नहीं है, finalतो यह सबसे अच्छा होगा।
जोनाथन

8
यह मत भूलो कि एनम का निर्माण कंस्ट्रक्टर के साथ नहीं किया जा सकता newहै private। अनिवार्य रूप से, वस्तु निर्माण निषिद्ध है और finalवास्तव में इस मामले में आवश्यक नहीं है।
बुहके सिंडी

6
@BuhakeSindi: यह सच है, लेकिन गलती से किसी को एनम पर डालने की इच्छा हो सकती है setText(String)और वह नरक में प्रवेश कर सकता है :) इस finalतरह के दस्तावेज़ आपके इरादे कि यह कंपाइलर समर्थन के साथ एक निरंतर है। यदि आप Stringस्थिरांक का उपयोग करने के लिए थे, तो आप इसे public static Stringसही घोषित नहीं करेंगे ?
टीडब्लूआरआरओबी

104

Enum के लिए कस्टम स्ट्रिंग मान

से http://javahowto.blogspot.com/2006/10/custom-string-values-for-enum.html

जावा एनम के लिए डिफ़ॉल्ट स्ट्रिंग मान इसका अंकित मूल्य या तत्व नाम है। हालाँकि, आप स्ट्रिंग को ओवरराइडिंग () विधि द्वारा कस्टमाइज़ कर सकते हैं। उदाहरण के लिए,

public enum MyType {
  ONE {
      public String toString() {
          return "this is one";
      }
  },

  TWO {
      public String toString() {
          return "this is two";
      }
  }
}

निम्नलिखित परीक्षण कोड चलाने से यह उत्पादन होगा:

public class EnumTest {
  public static void main(String[] args) {
      System.out.println(MyType.ONE);
      System.out.println(MyType.TWO);
  }
}


this is one
this is two

16
यह ऐसा करने का एक कुशल तरीका नहीं है । यह गणना में हर मूल्य के लिए एक नया कस्टम वर्ग बनाता है। उपरोक्त उदाहरण में, आप निम्नलिखित को binनिर्देशिका में देखेंगे : EnumTest $ MyType.class EnumTest $ MyType $ 1.class EnumTest $ MyType $ 2.class जो वास्तविक त्वरित जोड़ देगा । एनम कंस्ट्रक्टर के मूल्यों में उत्तीर्ण होकर, इसे अपेक्षित उत्तर के रूप में करना सबसे अच्छा है। मैं वास्तव में ओवरराइडिंग से असहमत हूं toString(); मेरा मानना ​​है कि एक स्पष्ट गटर का उपयोग करना बेहतर है getKey()क्योंकि ओवरराइडिंग एनम के toString()किसी अन्य उपयोगकर्ता द्वारा अप्रत्याशित हो सकती है।
मैट क्विगले

पूरी तरह से @MattQuigley से सहमत हैं। ऐसा करने से उपयोगकर्ताओं को उन चीजों के लिए उपयोग करने के लिए प्रोत्साहित करना चाहिए जिनके लिए इसका उपयोग नहीं किया जाना चाहिए। यदि आपको एक लेबल की आवश्यकता है, तो आप एक लेबल विशेषता जोड़ेंगे
सेबस्टियन लॉर्बर

इसके अलावा, दूसरे रास्ते पर जाने के लिए कोई रास्ता नहीं है (एक स्ट्रिंग से एनम ऑब्जेक्ट तक) जो शायद किसी बिंदु पर आवश्यक होने जा रहा है।
एड्रियन स्मिथ

ओवरराइडिंग स्ट्राइडिंग से valueOf () प्रभावित नहीं होता है, क्या यह?
Dmitriusan

69

इसकी name()विधि का उपयोग करें :

public class Main {
    public static void main(String[] args) throws Exception {
        System.out.println(Strings.ONE.name());
    }
}

enum Strings {
    ONE, TWO, THREE
}

पैदावार ONE


17
हाँ, लेकिन Strings.STRING_ONE.name()"STRING_ONE" पैदावार, "एक" नहीं। यह बस एक अच्छा जवाब नहीं है। आपके पास कोई स्ट्रिंग नहीं है जो एक मान्य जावा पहचानकर्ता नहीं होगा, आदि
मार्क पीटर्स

2
@ मर्क, सच है, यह किसी भी चरित्र को संभाल नहीं सकता है। अगर ओपी सिर्फ एक ही चर चाहता है, तो यह समाधान द एलीट जेंटलमैन सुझाव से अधिक सीधे है। लेकिन वास्तव में: यदि वर्णों की सीमा एक से अधिक वैध जावा पहचानकर्ता के पास हो सकती है, तो यह एक नहीं है। अच्छी बात।
बार्ट कीर्स

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

17
से परिणाम name()एक ऑबफ्यूज़र प्रोग्राम से प्रभावित हो सकता है। मैं थोड़ी देर पहले इसी तरह की समस्या में भाग गया था। उदाहरण के लिए, Proguard के साथ आपको इसके आसपास काम करने की आवश्यकता है। प्रोसेसिंग एन्यूमरेशन क्लासेस
noisecapella

यह उत्कृष्ट है। मानों के साथ काम करता है जैसे: var_name, var_superlong_but_not_toooooo_long_name, इत्यादि (यहां तक ​​कि ट्रिपल डॉट्स के बिना)

18

या तो एनम नाम को उसी स्ट्रिंग के रूप में सेट करें जो आप चाहते हैं या अधिक, आमतौर पर, आप अपने ड्यूम मानों के साथ मनमानी विशेषताओं को जोड़ सकते हैं:

enum Strings {
   STRING_ONE("ONE"), STRING_TWO("TWO");
   private final String stringValue;
   Strings(final String s) { stringValue = s; }
   public String toString() { return stringValue; }
   // further methods, attributes, etc.
}

शीर्ष पर स्थिरांक होना आवश्यक है, और नीचे स्थित विधियाँ / विशेषताएँ।


और एक निजी कंस्ट्रक्टर भी है।
बुहके सिंडी

1
Enum कन्स्ट्रक्टर्स डिफ़ॉल्ट रूप से निजी हैं और उन्हें किसी एक्सेस मॉडिफायर की आवश्यकता नहीं है। लेकिन यह सामान्य रूप से एक्सेस संशोधक के बारे में एक अच्छा बिंदु है, मैंने उन्हें विशेषता और एक्सेसर में जोड़ने के लिए अपना कोड अपडेट किया है।
एड्रियन स्मिथ

15

"स्ट्रिंग्स के रूप में उनका उपयोग करें" से आपका क्या मतलब है, इस पर निर्भर करते हुए, आप यहां एक एनम का उपयोग नहीं करना चाहते हैं। ज्यादातर मामलों में, द एलीट जेंटलमैन द्वारा प्रस्तावित समाधान आपको उनके स्टर्लिंग-तरीकों के माध्यम से उन्हें उपयोग करने की अनुमति देगा, जैसे कि System.out.println(STRING_ONE)या String s = "Hello "+STRING_TWO, लेकिन जब आपको वास्तव में स्ट्रिंग्स (जैसे STRING_ONE.toLowerCase()) की आवश्यकता होती है , तो आप उन्हें स्थिरांक के रूप में परिभाषित करना पसंद कर सकते हैं:

public interface Strings{
  public static final String STRING_ONE = "ONE";
  public static final String STRING_TWO = "TWO";      
}

5
वास्तव में यह वही है जो मैं बचने की कोशिश कर रहा हूं ...!
डोरी

दरअसल, अगर वे भी toLowerCase()मेरे समाधान पर चाहते हैं, तो वे जा सकते हैं Strings.STRING_TWO.toString().toLowerCase()
बुहके सिंडी

ज़रूर, लेकिन यह उनका उपयोग नहीं कर रहा है जैसा कि मैंने इसकी व्याख्या की थी। जैसा कि Rrackham को उस उपयोग की आवश्यकता प्रतीत नहीं होती है, उसे निश्चित रूप से प्रस्तावित enum समाधान का उपयोग करना चाहिए।
hd42

6
आपको निर्माता के साथ वर्ग के interfaceस्थान पर उपयोग नहीं करना चाहिए । यह हतोत्साहित करने वाला अभ्यास है। finalprivate
एलेक्स एन।

1
@ mils, enums का उपयोग करने वाले समाधान बस एक स्विच में काम करते हैं। मैं इस समाधान का सुझाव केवल तभी दूंगा जब स्ट्रिंग्स की सीधे जरूरत हो।
hd42

8

आप स्ट्रिंग Enum के लिए उपयोग कर सकते हैं

public enum EnumTest {
    NAME_ONE("Name 1"),
    NAME_TWO("Name 2");

    private final String name;

    /**
     * @param name
     */
    private EnumTest(final String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

और मुख्य विधि से कॉल करें

public class Test {
    public static void main (String args[]){
        System.out.println(EnumTest.NAME_ONE.getName());
        System.out.println(EnumTest.NAME_TWO.getName());
    }
}

5

यदि आप कंस्ट्रक्टर का उपयोग नहीं करना चाहते हैं , और आप विधि के लिए एक विशेष नाम रखना चाहते हैं, तो यह कोशिश करें:

public enum MyType {
  ONE {
      public String getDescription() {
          return "this is one";
      }
  },    
  TWO {
      public String getDescription() {
          return "this is two";
      }
  };

  public abstract String getDescription();
}

मुझे संदेह है कि यह सबसे तेज समाधान है। चर अंतिम का उपयोग करने की कोई आवश्यकता नहीं है ।


लेकिन इसके साथ आपको अभी भी getDescription () कॉल करना होगा, जिसमें से पूछने वाला व्यक्ति One को कॉल करना चाहता है या इसे कंटीन्यू के रूप में एक्सेस कर सकता है।
kinsley kajiva

यह मेरे लिए ज़्यादा प्रधान है। यदि अधिक informations को स्वीकार करने की आवश्यकता है तो क्या होगा? इस समाधान के साथ बस संरक्षित अमूर्त विधियों को जोड़ें और इसे खत्म करें। अधिक नहीं toString () विधि को ओवरराइड करने की आवश्यकता है। इसका स्वच्छ और सर्वश्रेष्ठ उत्तर के रूप में स्वीकार किया जा सकता है।
अरुणदेव

0

डिफ़ॉल्ट मानों के साथ प्राप्त करें और सेट करें।

public enum Status {

    STATUS_A("Status A"),  STATUS_B("Status B"),

    private String status;

    Status(String status) {
        this.status = status;
    }

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