2008-10-17 15 views
24

मैं एक सह कार्यकर्ता है कि एक स्थिरांक वर्ग परियोजना भर में उपलब्ध में सेक्या एक खाली स्ट्रिंग स्थिर है?

//in a singleton "Constants" class 
public static final String EMPTY_STRING = ""; 

कसम खाते है। इस तरह, हम

if (Constants.EMPTY_STRING.equals(otherString)) { 
    ... 
} 
बजाय

if ("".equals(otherString)) { 
    ... 
} 

की तरह कुछ लिख सकते हैं मैं कहना है कि यह

  1. इसके लायक नहीं है - यह ढेर/ढेर में किसी भी स्थान बचाने नहीं करता है/स्ट्रिंग पूल,
  2. बदसूरत
  3. एक स्थिरांक वर्ग के दुरुपयोग।

यहां बेवकूफ कौन है?

+0

आप किस भाषा का उपयोग कर रहे हैं? –

+1

जावा (टैग देखें) –

+32

एक गाय ऑकर? एक ओर्क गायों कैसे करता है? =) –

उत्तर

62

स्ट्रिंग शाब्दिक, डिफ़ॉल्ट रूप से प्रशिक्षु कर रहे हैं ताकि कोई फर्क नहीं पड़ता कि आप कितनी बार कोड में करने के लिए "" देखें, वहाँ केवल एक खाली स्ट्रिंग हो जाएगा वस्तु। मुझे EMPTY_STRING घोषित करने में कोई लाभ नहीं दिख रहा है। अन्यथा, आप पूर्णांक अक्षर के लिए एक, दो, तीन, चार, आदि घोषित कर सकते हैं।

बेशक

, आप बाद में EMPTY_STRING का मूल्य बदलना चाहते हैं, यह एक ही स्थान पर यह पाना उपयोगी है;)

+1

क्या वे हमेशा * प्रशिक्षित होते हैं, या सामान्यतः ऐसा करते हैं? क्या आप गारंटी देते हैं कि सभी खाली तार सभी अन्य खाली तारों के बराबर होंगे, यहां तक ​​कि कक्षा और पैकेज सीमाओं में भी? –

+1

सभी खाली स्ट्रिंग * अक्षर *। आप अन्य विशिष्ट स्ट्रिंग ऑब्जेक्ट्स भी बना सकते हैं जो खाली भी हैं। –

+5

"निरंतर अभिव्यक्तियों" के सभी अक्षर और मूल्यों को प्रशिक्षित किया जाता है। JVM spec देखें: http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#20359 –

7

मुझे EMPTY_STRING को देखना पसंद है।

यह अंग्रेजी बनाता है। "" .equals 'EMPTY_STRING.equals की तुलना में अलग-अलग पढ़ता है।

+5

इसके लिए संशोधित करने का कोई कारण नहीं है। –

+1

लेकिन 'EMPTY_STRING' को मनमाने ढंग से परिभाषित किया जा सकता है। अगर मैं स्रोत कोड में ऐसी चीज में आया, तो मुझे इसकी परिभाषा को देखने की आवश्यकता महसूस होगी, खासकर जब यह अंतर्निहित भाषा नहीं है ;-)। – binki

0
  1. हाँ - यह कोई लाभ नहीं देता है।
  2. आपके द्वारा उपयोग किए जाने वाले कार्यों पर निर्भर करता है, मुझे यकीन है।
  3. नहीं, यह सिर्फ एक स्थिर है - दुरुपयोग नहीं।
3

मुझे कोई विकल्प पसंद नहीं है। क्यों नहीं if (otherString.length() == 0)

संपादित करें: मैं वास्तव में हमेशा कोड

if (otherString == null || otherString.length() == 0) 
+1

क्योंकि अगर अन्य स्ट्रिंग शून्य है, तो यह संपादन में तय –

+1

अपवाद का कारण बनता है। मैं वास्तव में केवल लंबाई परीक्षण –

+0

कोड अब 0 होना चाहिए। मुझे परेशान है क्यों मैंने डगलस गिलहरी के जवाब को नहीं देखा। समय होना चाहिए। –

16

क्यों पृथ्वी पर आप जावा में एक वैश्विक चर चाहेगा? जेम्स गोस्लिंग ने वास्तव में उनसे छुटकारा पाने की कोशिश की; कृपया उन्हें वापस मत लाओ, कृपया।

या तो

0 == possiblyEmptyString.length() 

या

possiblyEmptyString.isEmpty() // Java 6 only 

बस के रूप में स्पष्ट हैं।

+0

और थोड़ा तेज, भी, जैसा कि कार्ल बताता है। –

+9

यदि संभवतः EmptyString शून्य है, तो आपको एक एनपीई – tuler

+0

मिलता है, मुझे लगता है कि यह कुछ परिदृश्यों में, लेंस की जांच करते समय स्ट्रिंग मान को ट्रिम करने के लिए भी समझ में आता है, इस तरह कुछ: 0 == संभवतः लक्षण-स्ट्रिंग.ट्रिम() लंबाई() मुझे लगता है कि यह कुछ परिदृश्यों में समझ में आता है, यदि किसी भी कारण से, संभवतः लक्षण-स्ट्रिंग चर के पास यह मान है, "lenght वापस आ जाएगा 3. बेशक मैं जावा 1.5 का उपयोग करने पर विचार कर रहा हूं, जैसा कि आपने बताया है, जावा 6 isEmtpy() विधि है। –

7

विडंबना यह है कि स्थिरांक का पूरा बिंदु उन्हें आसानी से बदलने योग्य बनाना है। इसलिए जब तक आपका सहकर्मी EMPTY_STRING को रिक्त स्ट्रिंग के अलावा कुछ और करने के लिए पुन: परिभाषित करने की योजना नहीं बनाता है - जो वास्तव में एक बेवकूफ चीज होगी - एक स्थिर निश्चित निर्माण जैसे "स्थिर" को कास्टिंग करना एक बुरी चीज है।

दान डायर कहते हैं, इसके निरंतर परिभाषित होने के लिए की तरह 1: यह पूरी तरह से व्यर्थ है और पूरी तरह से भ्रमित हो सकता है - अगर किसी को यह नए सिरे से परिभाषित - संभावित जोखिम भरा।

+0

एक और बिंदु "जादू" शब्दलेखन दस्तावेज करना है। लेकिन इस मामले में ... –

+0

यह एक उचित बिंदु जॉन है। –

2

वही तर्क समय (जहां पहले से ही वहाँ है एक केवल पढ़ने के लिए स्थिर क्षेत्र string.Empty) समय पर .NET में आ जाती है। यह स्वाद का विषय है - लेकिन व्यक्तिगत रूप से मुझे कम घुसपैठ मिलती है।

+2

बेशक, आप गलती से रखे गए ड्रैटेड स्पेस पर स्कैन करना चाहते हैं। – tvanfosson

0

हम्म, नियम सही हैं लेकिन एक अलग अर्थ में लिया जा रहा है! आइए कारण देखें, सबसे पहले जावा में सभी ऑब्जेक्ट संदर्भ बराबर() द्वारा चेक किए जाते हैं। इससे पहले, कुछ भाषाओं में यह '==' ऑपरेटर का उपयोग करके किया गया था, अगर दुर्घटना से किसी ने '=' '==', एक आपदा का उपयोग किया। अब कंप्यूटर के लिए जादू संख्या/स्थिरांक का प्रश्न सभी स्थिरांक/संख्याएं समान हैं। 'Int ONE = 1' के बजाय कोई निश्चित रूप से 1 का उपयोग कर सकता है, लेकिन क्या यह डबल पीआई = 3.141 ... के लिए सच होगा? क्या होता है यदि कोई व्यक्ति कुछ समय बाद परिशुद्धता को बदलने की कोशिश करता है।

हम एक जांच सूची के साथ आने के लिए गए थे, तो क्या नियम को संबोधित सामान्य दिशानिर्देश यह नहीं है हो सकता है? मेरा कहना है कि नियमों की सहायता करना है, हम निश्चित रूप से नियमों को झुका सकते हैं जब हम उन्हें बहुत अच्छी तरह जानते हैं। सामान्य ज्ञान प्रचलित है। जैसा कि मेरे एक दोस्त ने सुझाव दिया है, 0/1 जैसे प्रोग्राम स्थिरांक जो बाहर निकलने की स्थितियों को इंगित करते हैं, उन्हें हार्ड कोड किया जा सकता है और इसलिए जादू संख्या सिद्धांत लागू नहीं होता है। लेकिन उन लोगों के लिए जो तार्किक जांच/नियमों में भाग लेते हैं, उन्हें बेहतर कॉन्फ़िगर करने योग्य स्थिरांक के रूप में रखें।

1

हम सिर्फ इस तरह की स्थितियों के लिए निम्न कार्य करें:

public class StaticUtils 
{ 
    public static boolean empty(CharSequence cs) 
    { 
     return cs == null || cs.length() == 0; 
    } 

    public static boolean has(CharSequence cs) 
    { 
     return !empty(cs); 
    } 
} 

तो बस import static StaticUtils.*

+0

एक 'शून्य' स्ट्रिंग एक खाली स्ट्रिंग के समान नहीं है। –

4

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

Fwiw, सी # सिर्फ इस उद्देश्य के लिए एक स्थिर संपत्ति string.Empty है और मुझे लगता है कि यह बेहद कोड की पठनीयता में सुधार।

+1

यदि आप एक मोनोस्पेस फ़ॉन्ट के साथ प्रोग्रामिंग नहीं कर रहे हैं, तो आप इसे गलत कर रहे हैं। यदि आप हैं, तो "" और "" के बीच एक स्पष्ट अंतर है। –

+1

'" और '" '' '' के बीच इतना स्पष्ट अंतर नहीं है, हालांकि, जब जल्दी स्कैनिंग हो। –

2

एक मामले में जहां यह समझ बनाने के रिक्त स्ट्रिंग के मूल्य के साथ एक निरंतर है करने के लिए करता है जब आप नाम मूल्य के शब्दों को दर्शाता है। उदाहरण के लिए:

if (Constants.FORM_FIELD_NOT_SET.equals(form.getField("foobar"))) { 
    ... 
} 

यह (तर्क से अलग है कि एक बेहतर डिजाइन विधि जाँच एक क्षेत्र प्रपत्र पर ही करने के लिए सेट कर दिया जाता है कि क्या जोड़ना है) कोड अधिक आत्म दस्तावेज़ीकृत कर बनाता है।

6

ठीक है, मैं भी लगता है कि हो सकता है, लेकिन मैं एक त्वरित परीक्षण किया था ... लगभग धोखा दे की तरह ...

एक मनमाना स्ट्रिंग विभिन्न तरीकों का उपयोग कर चेक किया गया है। (कई पुनरावृत्तियों)

परिणाम बताते हैं कि लक्षण() दोनों तेज़ और वास्तव में अधिक पठनीय है; यदि लक्षण है() उपलब्ध नहीं है, लंबाई() एक अच्छा विकल्प है।

स्थिरता का उपयोग करना शायद इसके लायक नहीं है।

 
"".equals(someString())  :24735 ms 
t != null && t.equals("") :23363 ms 
t != null && t.equals(EMPTY) :22561 ms 
EMPTY.equals(someString()) :22159 ms 
t != null && t.length() == 0 :18388 ms 
t != null && t.isEmpty()  :18375 ms 
someString().length() == 0 :18171 ms 

इस परिदृश्य में;

 
"IAmNotHardCoded".equals(someString()) 

मैं सभी स्थिरांक के लिए एक आर ई एल ई एक n t जगह वी में एक निरंतर परिभाषित करने, एक वैश्विक कक्षा के बाद से सुझाव है कि वास्तव में बेकार है। अगर कोई प्रासंगिक है, तो आप शायद कुछ और गलत कर रहे हैं ...

 
Customer.FIELD_SHOE_SIZE //"SHOE_SIZE" 

एक प्रासंगिक जगह पर विचार किया जा सकता है, जहां के रूप में;

 
CommonConstants.I__AM__A__LAZY__PROGRAMMER // true 

नहीं है।

बिगइंटर और इसी तरह की चीज़ के लिए, मैं स्थानीय रूप से अंतिम स्थिर परिभाषित करना समाप्त कर देता हूं; जैसे:

 
private final static BigDecimal ZERO = new BigDecimal(0); 
private final static BigDecimal B100 = new BigDecimal("100.00"); 

कीड़े Thats मुझे और यह BigInts और BigDecimals के लिए कुछ चीनी के साथ अच्छा नहीं होगा ...

2

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

3

प्रश्न के स्पर्श के रूप में, मैं आम तौर पर एक उपयोगिता फ़ंक्शन का उपयोग करने की अनुशंसा करता हूं जब आप वास्तव में जांच कर रहे हैं, विशेष रूप से खाली स्ट्रिंग के बजाय "कोई उपयोगी मूल्य" नहीं है। सामान्य तौर पर, मैं का उपयोग करते हैं:

import org.apache.commons.lang.StringUtils; 

// Check if a String is whitespace, empty ("") or null. 
StringUtils.isBlank(mystr); 
// Check if a String is empty ("") or null. 
StringUtils.isEmpty(mystr); 

अवधारणा जा रहा है कि इसके बाद के संस्करण दो:

  • अशक्त सुरक्षित किया जा रहा सहित विभिन्न अन्य मामलों में, की जाँच करें, और (अधिक महत्वपूर्ण)
  • बता देते हैं क्या आप इसका परीक्षण करने के बजाय परीक्षण करने की कोशिश कर रहे हैं।
0

स्ट्रिंग का उपयोग करना बेहतर क्यों है। सी # में लक्षण और इसलिए अन्य भाषाओं में सार्वजनिक स्थिरता यह है कि स्थिरांक स्थिर हैं, इसलिए केवल स्मृति में एक उदाहरण लेते हैं।

हर बार जब आप कुछ इस तरह करते हैं: -

stringVariable = ""; 

आप एक अशक्त स्ट्रिंग का एक नया उदाहरण बना रहे हैं तथा stringVariable साथ यह की ओर इशारा करते।

इसलिए हर बार जब आप एक चर (पॉइंटर) को असाइनमेंट करते हैं, तो "" नल स्ट्रिंग एक नया स्ट्रिंग उदाहरण है जब तक कि इसमें अब कोई पॉइंटर असाइनमेंट न हो।

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

यह मामूली लग सकता है, लेकिन स्ट्रिंग्स बनाना और नष्ट करना पॉइंटर्स (चर) बनाने और उन्हें मौजूदा स्ट्रिंग पर इंगित करने से अधिक संसाधन गहन है।

const String EMPTY_STRING = ""; 
String variable1 = EMPTY_STRING; 
String variable2 = EMPTY_STRING; 
String variable3 = EMPTY_STRING; 
String variable4 = EMPTY_STRING; 
String variable5 = EMPTY_STRING; 

आप 5 स्ट्रिंग संकेत पैदा की है बजाय लेकिन केवल 1 स्ट्रिंग

: - -:

String variable1 = ""; 
String variable2 = ""; 
String variable3 = ""; 
String variable4 = ""; 
String variable5 = ""; 

स्ट्रिंग प्रारंभ आम है, यह अच्छा करने के लिए अभ्यास है आपने 5 स्ट्रिंग पॉइंटर्स और 5 अलग नल स्ट्रिंग बनाए हैं।

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

बेशक, कई स्थिर तारों को निर्धारित करने और डुप्लिकेट का पुन: उपयोग करने के लिए संकलक पर्याप्त चालाक होना चाहिए, लेकिन क्यों मानते हैं?

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

myvariable = " "; 
While (myVariable == ""){ 
... 
} 

जबकि ब्लॉक के अंदर कोड पहुंच योग्य नहीं है क्योंकि मेरा वैरिएबल पहले पुनरावृत्ति पर शर्त को पूरा नहीं करेगा। के साथ "" के बदले "आरंभ की त्रुटि" याद करने के लिए आसान है, जबकि: -

myvariable = EMPTY_STRING; 
While (myVariable == EMPTY_STRING){ 
... 
} 

..., कम करने के लिए क्रम त्रुटियां होने की संभावना है, खासकर के रूप में गलत वर्तनी EMPTY_STRING बजाय करने के लिए होने का एक संकलन त्रुटि उत्पन्न होगा रन टाइम पर त्रुटि पकड़ो।

सबसे साफ समाधान, एक स्थिर वर्ग बनाना होगा जिसमें आपको आवश्यक सभी प्रकार के स्ट्रिंग स्थिरांक के सदस्य शामिल हों, क्या आपको केवल खाली स्ट्रिंग से अधिक की आवश्यकता होनी चाहिए।

public static class StringConstants{ 
    public static String Empty = ""; 
    public static String EMail = "mailto:%s"; 
    public static String http = "http://%s"; 
    public static String https = "https://%s"; 
    public static String LogEntry = "TimeStamp:%tYmdHMSL | LogLevel:%s| Type:%s | Message: '%s'"; 

} 

String myVariable = StringConstants.Empty; 

आप अपनी भाषा के आधार पर मूल स्ट्रिंग ऑब्जेक्ट का विस्तार करने में भी सक्षम हो सकते हैं।

+0

लेकिन स्ट्रिंग इंटर्निंग ... "लेकिन दर्जनों कक्षाओं में कोड की हजारों लाइनों में, यह अनावश्यक मेमोरी कचरा और प्रोसेसर उपयोग है, एक और नल स्ट्रिंग वैरिएबल बना रहा है" - प्रोबेलिबल कम कंपाइलर चक्र का उपयोग जावा कंपाइलर में खाली स्ट्रिंग को प्रशिक्षित करने के लिए किया जाता है निरंतर विस्तार करने के लिए। लेकिन मैंने जांच नहीं की है: क्या आप? – binki

+0

प्रश्न सी # के बारे में नहीं है। और: "[उसने कहा _pointer_!] (Https://www.youtube.com/watch?v=MIaORknS1Dk)"। ;) –

2

डेविड Arno में कहा गया है: -

विडंबना यह है कि स्थिरांक के पूरे मुद्दे

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

यह बहुत दुर्लभ है कि निरंतर मूल्य बदल जाते हैं (इसलिए नाम)। यह अक्सर होता है कि कॉन्फ़िगरेशन मान बदल जाते हैं, लेकिन कहीं भी डेटा (जैसे कॉन्फ़िगरेशन फ़ाइल या रजिस्ट्री प्रविष्टि)

प्रारंभिक प्रोग्रामिंग के बाद से, स्थिरांकों को क्रिप्टिक हेक्स मानों जैसे 0xff6d8da412 जैसे चीजों को मानव रूप से पठनीय में बदलने के लिए उपयोग किया गया है बिना के बिना मूल्यों को बदलने का इरादा रखते हैं।

const int MODE_READ  = 0x000000FF; 
const int MODE_EXECUTE = 0x00FF0000; 
const int MODE_WRITE  = 0x0000FF00; 
const int MODE_READ_WRITE = 0x0000FFFF; 
+2

"स्थिरांक का पूरा बिंदु एक ही मूल्य का पुन: उपयोग और अधिक पठनीयता के लिए है।" साथ ही, वे टाइपो से संबंधित बग से बचने में मदद करते हैं क्योंकि कंपाइलर द्वारा स्थिरांक की जांच की जाती है, जबकि शाब्दिक मूल्य नहीं होते हैं। –

0

आप हर ओरेकल में एक नल स्ट्रिंग कॉलम में "खाली" तार स्टोर करने के लिए चाहते हैं, आप "की तुलना में" अन्य कुछ होने EMPTY_STRING की परिभाषा को बदलने के लिए होगा! (मुझे याद है कि आखिरी बार मुझे ओरेकल का उपयोग करने के लिए मजबूर होना पड़ा था कि यह एक खाली स्ट्रिंग और शून्य स्ट्रिंग के बीच का अंतर नहीं जानता)।

हालांकि यह आपके डेटा एक्सेस लेयर में किया जाना चाहिए ताकि बाकी ऐप को इसके बारे में पता न हो, और/या अपने डेटा मॉडल को सॉर्ट करें ताकि आपको खाली स्ट्रिंग और नल स्ट्रिंग्स को स्टोर करने की आवश्यकता न हो स्तंभ।

संबंधित मुद्दे