सवाल जावा - कॉमन गॉटचास [बंद]


अन्य प्लेटफार्मों की एक ही भावना में, इस सवाल का पालन करने के लिए तार्किक लग रहा था: जावा में सामान्य गैर-स्पष्ट गलतियां क्या हैं? चीजें जो लगती हैं उन्हें काम करना चाहिए, लेकिन नहीं।

मैं दिशानिर्देश नहीं दूंगा कि उत्तरों को कैसे व्यवस्थित किया जाए, या "बहुत आसान" को गोचा माना जाने वाला क्या है, क्योंकि मतदान यही है।

यह भी देखें:


48
2017-10-04 05:41


मूल




जवाब:


वस्तुओं का उपयोग कर समानता की तुलना == के बजाय .equals() - जो primitives के लिए पूरी तरह से अलग व्यवहार करता है।

यह गोचा सुनिश्चित करता है कि जब नवागंतुकों को परेशान किया जाता है "foo" == "foo" परंतु new String("foo") != new String("foo")


34
2017-10-04 06:09



दिलचस्प बात यह है कि ग्रोवी '==' का उपयोग मूल्य तुलना के रूप में करती है और पहचान तुलना की वस्तु नहीं करती है। प्रतिलिपि बनाते समय सावधान रहें! - Michael Easter
इस से पालन करने के लिए ... स्ट्रिंग जे = "foo"; System.out.println (j == "foo"); // प्रिंट सच है - blitzen
अंगूठे का नियम: यदि चर के पास है equals() विधि, इसका इस्तेमाल करें। - noamtm


"a,b,c,d,,,".split(",").length

रिटर्न 4, नहीं 7 जैसा आप कर सकते हैं (और मैं निश्चित रूप से किया) उम्मीद है। split सभी पिछली खाली स्ट्रिंग वापस अनदेखा करता है। इसका मत:

",,,a,b,c,d".split(",").length

रिटर्न 7! "कम से कम आश्चर्यजनक" व्यवहार के रूप में मैं क्या सोचूंगा, आपको कुछ आश्चर्यजनक करने की ज़रूरत है:

"a,b,c,d,,,".split(",",-1).length

7 पाने के लिए।


33
2017-09-09 14:39



यह भी ध्यान दें split एक रेगेक्स लेता है, इसलिए डॉट पर विभाजित करने के लिए आपको करना होगा "a.b".split("\\.") - Christophe Roussy


ओवरराइडिंग बराबर () लेकिन हैशकोड नहीं है ()

नक्शे, सेट या सूचियों का उपयोग करते समय यह वास्तव में अप्रत्याशित परिणाम हो सकता है।


30
2017-10-04 08:37



मैंने इन दिनों हैशपैप्स के साथ कुछ बेवकूफ किया, मैं मानचित्र के लिए कुंजी के रूप में कुछ हैश का उपयोग कर रहा था, न कि ऑब्जेक्ट स्वयं। मेरे पहले हैश टकराव पर मुझे समस्याएं मिलीं क्योंकि पूर्णांक के बराबर विधि सही हो जाएगी, भले ही ऑब्जेक्ट के बराबर विधि झूठी हो जाए। - Ravi Wallau
मूर्खतापूर्ण चीज पहिया को पुनर्जीवित कर रही थी (और संभवतः समयपूर्व अनुकूलन); java.util.HashMap प्रभावी रूप से कुंजी (दक्षता उद्देश्यों के लिए) के रूप में किसी ऑब्जेक्ट के हैश का उपयोग करता है, लेकिन बाल्टी का उपयोग करके टक्कर को ठीक से संभालता है। हमेशा एक मौजूदा कक्षा की तलाश करें जिसमें वांछित कार्यक्षमता पहले हो! - Andrzej Doyle
उल्लेख नहीं है: ओवरराइडिंग equals गलत हस्ताक्षर के साथ। public boolean equals(MyStuff other) ... के बजाय public boolean equals(Object other) ... - Dirk


मुझे लगता है कि एक बहुत चुस्त है String.substring तरीका। यह वही अंतर्निहित उपयोग करता है char[] एक अलग के साथ मूल स्ट्रिंग के रूप में सरणी offset तथा length

यह बहुत मुश्किल से देखने वाली स्मृति समस्याओं का कारण बन सकता है। उदाहरण के लिए, आप बहुत बड़ी फाइलों को पार्स कर सकते हैं (XML शायद) कुछ छोटे बिट्स के लिए। अगर आपने पूरी फाइल को एक में बदल दिया है String (इस्तेमाल किए जाने के बजाय Reader फ़ाइल पर "चलना" करने के लिए) और उपयोग करें substring अपनी इच्छित बिट्स को पकड़ने के लिए, आप अभी भी पूर्ण फ़ाइल आकार के आसपास ले जा रहे हैं char[] दृश्यों के पीछे सरणी। मैंने देखा है कि यह कई बार होता है और इसे खोजना बहुत मुश्किल हो सकता है।

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


30
2017-10-04 09:30



स्मृति को बचाने के लिए यह भी बहुत उपयोगी है, जब आप एक बड़ी स्ट्रिंग को कई सबस्ट्रिंग में विभाजित करने जा रहे हैं। - Stephen Denne
जावा की कक्षा पुस्तकालय के लिए स्रोत कोड हमेशा एक आकर्षक पढ़ा जाता है, भले ही बेहतर या बदतर हो। ;) - Chris Mazzola
कोई एक वीएम ऑप्टिमाइज़ेशन की कल्पना कर सकता है जहां इस तरह की एक सरणी आंशिक रूप से जीसी: एड हो सकती है अगर भागों को पहुंच योग्य साबित किया जा सकता है। - John Nilsson
कृपया ध्यान दें कि यह उत्तर अब आंशिक रूप से अप्रचलित है। नए जेडीके में, सबस्ट्रिंग इस तरह कार्य नहीं करता है। प्रासंगिक संबंधित उत्तर। - Denys Séguret
परिवर्तन जेडीके 7u6 में था, जिसे चिह्नित किया गया था बग संख्या 4513622। - FilipK


SimpleDateFormat थ्रेड सुरक्षित नहीं है।


25
2017-10-04 11:25



यह भी बहुत धीमी है - David Plumpton


पढ़ने का प्रयास करें जावा पज़लर जो डरावनी चीजों से भरा है, भले ही इसमें से अधिकतर सामान आप हर दिन टक्कर न लें। लेकिन यह भाषा में आपके आत्मविश्वास को नष्ट कर देगा।


21
2017-10-04 05:57



यह पढ़ने के लिए किताबों की मेरी todo सूची पर है। - Alan
यह एक महान किताब है लेकिन पहेली में अधिकांश "बग" चीजें हैं जो बस हैं मत बनो प्रयोग में। वे बेहद गूढ़ किनारे-मामले हैं जो मुझे यह कहते हुए छोड़ देते हैं कि "धरती पर कौन लिखा होगा!" - oxbow_lakes
अधिकांश बग बग रिपोर्ट से हैं, इसलिए स्पष्ट रूप से लोग इन चीजों में आते हैं, और फिर बहुत भ्रमित हो जाते हैं। (मैंने पुस्तक (नाम के अलावा) में अंतिम कार्यक्रम लिखा था, लेकिन जानबूझ कर।) - Tom Hawtin - tackline
जावा के खिलाफ दस्तक के रूप में जावा पज़लर मत लें। "जावा टूटा हुआ है" की बजाय वहां की अधिकांश चीजें "जावा यह सही से दूर है" जैसी हैं। अन्य भाषाएं आपको कहीं अधिक समस्या-भ्रम पैदा कर सकती हैं। - TREE
'काम पर कोडर' में जोश ब्लोश के साथ वार्तालाप को स्पष्ट करने के लिए। जेबी: 'सी पज़लर' नामक पुस्तक क्यों नहीं है? लेखक: क्योंकि यह सभी गूढ़ व्यक्ति है। जेबी: यह सही है, हर भाषा में किनारे के मामले हैं। यह जावा का श्रेय है कि उन्हें एक छोटी किताब में सूचीबद्ध किया जा सकता है - Chip McCormick


दो ऐसे हैं जो मुझे काफी परेशान करते हैं।

दिनांक / कैलेंडर

सबसे पहले, जावा तिथि और कैलेंडर कक्षाएं गंभीर रूप से गड़बड़ कर दी गई हैं। मुझे पता है कि उन्हें ठीक करने के प्रस्ताव हैं, मुझे उम्मीद है कि वे सफल होंगे।

कैलेंडर.get (कैलेंडर। DAY_OF_MONTH) 1-आधारित है
कैलेंडर.जेट (कैलेंडर.एमओएनटीएच) है 0-आधारित

ऑटो-मुक्केबाजी सोच को रोकना

दूसरा इंटीजर बनाम int है (यह किसी ऑब्जेक्ट के किसी भी आदिम संस्करण के लिए जाता है)। इंटेल से अलग इंटीजर के बारे में सोचने के कारण यह विशेष रूप से एक परेशानी होती है (क्योंकि आप ऑटो-मुक्केबाजी के कारण उन्हें उतनी ही समय में इलाज कर सकते हैं)।

int x = 5;
int y = 5;
Integer z = new Integer(5);
Integer t = new Integer(5);

System.out.println(5 == x);     // Prints true
System.out.println(x == y);     // Prints true
System.out.println(x == z);     // Prints true (auto-boxing can be so nice)
System.out.println(5 == z);     // Prints true
System.out.println(z == t);     // Prints SOMETHING

चूंकि ज़ेड और टी ऑब्जेक्ट्स हैं, फिर भी वे एक ही मान रखते हैं, वे (ऑब्जेक्ट्स) की अधिकतर वस्तुएं हैं। आप वास्तव में क्या मतलब है:

System.out.println(z.equals(t));   // Prints true

यह ट्रैक करने के लिए एक दर्द हो सकता है। आप कुछ डीबगिंग करते हैं, सब कुछ ठीक दिखता है, और अंततः आप यह पता लगाना चाहते हैं कि आपकी समस्या 5 है! = 5 जब दोनों वस्तुएं हैं।

कहने में सक्षम होना

List<Integer> stuff = new ArrayList<Integer>();

stuff.add(5);

है इसलिए अच्छा। इसने जावा को उन सभी "नए इंटीजर (5)" और "((इंटीजर) list.get (3)) को रखने की आवश्यकता नहीं है। IntValue ()" सभी जगहों पर लाइनें। लेकिन उन लाभों को इस गोचा के साथ आते हैं।


21
2017-10-04 22:16



मुझे यह पता लगाने में दो 8 घंटे का समय लगा कि हमारी सारी तिथियां एक महीने क्यों थीं ... मैं अपने बालों को खींच रहा था! - Knobloch
0-आधारित माह एक पॉज़िक्स (और सी लाइब्रेरी) चीज है। सिर्फ इसलिए कि यह एक मानक है, इसका मतलब यह नहीं है कि इसे हमेशा पालन किया जाना चाहिए। - Tom Hawtin - tackline
z == टी हमेशा झूठा है। दो अलग-अलग वस्तुओं की अलग-अलग वस्तु पहचान होती है। दूसरी तरफ, यदि आपने दोनों मामलों में Integer.valueOf (5) कहा है, तो वे एक ही ऑब्जेक्ट होंगे: -128 और 127 के बीच मान कैश किए गए मानों के रूप में माना जाता है। - Chris Jester-Young
यदि x == z या 5 == z सत्य है, तो यह ऑटो-unboxing ज़ेड पर, ऑटो-मुक्केबाजी के किसी भी प्रकार का नहीं। Integer.valueOf (5)! = नया इंटीजर (5) (किसी अन्य ऑब्जेक्ट के बारे में मेरी पिछली टिप्पणी को याद रखना जिसमें किसी अन्य अलग-अलग नई ऑब्जेक्ट को अलग पहचान है)। - Chris Jester-Young
-1। आप के बारे में गलत हैं z == t उदाहरण के रूप में, @ क्रिस जेस्टर-यंग का वर्णन करता है। शायद आप इसे .NET में एक समान उदाहरण के साथ भ्रमित कर रहे हैं z == t  कर सकते हैं सच हो। - finnw