2010-03-04 5 views
24

यह स्निपेट NullPointerException फेंकता है इस तथ्य के कारण कि यह एक आदिम प्रकार से अनबॉक्स किया गया है और Long.longValue() कहा जाता है, है ना?NullPointerException में लंबे परिणामों के लिए नल-ऑब्जेक्ट को अनबॉक्सिंग, ठीक है?

Thats भी आसान है अगर आप इस तरह की स्निपेट को देखने के लिए:

long propertyValue = (Long) obj.getProperty(propertyModel.getName()); 

तो isn ':

long value = (Long) null; 

लेकिन NullPointerException इस तरह एक अधिक जटिल स्थिति में पाने के लिए और भी कठिन है जावा-कंपाइलर के लिए एक और अधिक आरामदायक अपवाद बनाने के लिए कोई संभावना नहीं है? मैं को जैसे संदेश के साथ पसंद करूंगा "आप एक नल-ऑब्जेक्ट को आदिम प्रकार में डालने की कोशिश कर रहे हैं, यह नहीं किया जा सकता है!"

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

इस प्रश्न का उत्तर है: मैं जानना चाहता हूं कि यह व्यवहार प्राप्त करना संभव है या नहीं!

+0

एनपीई मेरे लिए ठीक लग रहा है Optional.ofNullable है। शून्यता एनोटेशन मदद कर सकता है। (** अन ** मुक्केबाजी, बीटीडब्ल्यू।) –

उत्तर

55

Java language specification के अनुसार, unboxing Number.longValue(), Number.intValue(), आदि बुला के माध्यम से होता है कोई विशेष बाइट कोड हो रहा जादू नहीं है, यह बिल्कुल वैसा ही है जैसे कि आप उन तरीकों मैन्युअल कहते हैं। इस प्रकार, NullPointerExceptionnull (और वास्तव में जेएलएस द्वारा अनिवार्य) को अनबॉक्स करने का प्राकृतिक परिणाम है।

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

+2

यह समझने के लिए एक बड़ा प्लस क्यों होता है - एक विधि जैसे longValue() या doubleValue() को शून्य ऑब्जेक्ट पर बुलाया जाता है। इसी तरह के धागे में बहुत सारे जवाब कहते हैं, "अनबॉक्सिंग NullPointerException फेंकता है" – kiedysktos

1

यह नहीं है कि IllegalArgumentException का अर्थ है। कंपाइलर की कोई गारंटी नहीं है कि रनटाइम तक मान null होगा। यह सब जानता है कि यह प्रकार है, जो आपके उदाहरण में String होने की संभावना है।

निश्चित रूप से रनटाइम पर, जब अपवाद फेंक दिया जाता है, तो संकलक जानता है कि समस्या null मान है। यदि आप डीबगर का उपयोग कर रहे हैं तो आप इसे स्वयं देख सकते हैं। तो एक तकनीकी दृष्टिकोण से - और यहां आपके प्रश्न का संक्षिप्त उत्तर है - हां, यह एक संकलक बनाने के लिए संभव होगा जिसमें त्रुटि विवरण में शामिल होगा। लेकिन अगर आप null मानों के लिए एक विशेष संदेश चाहते हैं, तो अगला क्या है? पूर्णांक के लिए विशेष संदेश जो 10 से अधिक द्वारा स्वीकार्य कुछ स्वीकार्य हैं? माना जाता है कि यह एक मूर्ख उदाहरण है, लेकिन मुझे उम्मीद है कि यह चित्रकारी है।

+0

मेरे उदाहरण में वापसी का प्रकार ऑब्जेक्ट है, क्या यह स्ट्रिंग होगा, मैं Long.valueOf() का उपयोग कर सकता हूं। इसे एक अवैध अर्ग्यूमेंट अपवाद होने के लिए मजबूर नहीं किया गया है। मुझे एक विशेष अपवाद चाहिए क्योंकि लोगों के लिए कुछ जादू किया गया है जो मुक्केबाजी/अनबॉक्सिंग को नहीं जानते हैं। लेकिन ठीक है, यह आपकी राय है :) – codevour

+0

मुझे समझ में नहीं आता कि फोर्सिंग और जादू के बारे में आपका क्या मतलब है, लेकिन यदि आपके पास एक और अधिक विशिष्ट समस्या है, तो कृपया अतिरिक्त नमूना कोड पोस्ट करें। चर के प्रकार की तरह जानकारी विशेष रूप से उपयोगी होगी। – Pops

1

इस तरह के मामलों के लिए एक छोटा निजी सहायक लिखना एक अच्छा विचार है। वे सही कास्ट, त्रुटि संदेश और डिफ़ॉल्ट मानों का उत्पादन कर सकते हैं।

अपवाद में ऑपरेशन के पर्याप्त "राज्य" को रखना अच्छा है (इस मामले में विकल्प का नाम और मान - शायद नहीं मिला तो विकल्प मानचित्र का स्ट्रिंग प्रतिनिधित्व भी हो सकता है)।

कुछ की तरह:

private long safeGetLong(Map<String, Option> options, String name) { 
    if (name == null || options == null) 
    throw new IllegalArgumentExcption("You need to give options and name. (name="+name+", opts=" + options)); 
    Object val = options.get(name); 
    if (val == null) 
    throw new ConfigurationException("The option name="+name+" is unknown"); 
    if (val instanceof Long) 
    return val.longValue(); 

    String strVal = null; 
    try 
    { 
    strVal = val.toString(); 
    return Long.parseValue(strVal); 
    } catch (Exception ex) { 
    throw new ConfigurationException("Cannot parse " + name + "=" + strVal + " into a Long."); 
    } 
} 
पाठ्यक्रम एक विन्यास वस्तु जो टाइप किया उपयोग की अनुमति देता होने के

भी बेहतर है।

कुछ सत्यापन फ्रेमवर्क हैं जो आपके लिए ऐसा कर सकते हैं, लेकिन मैं आम तौर पर कोड लिखना समाप्त करता हूं क्योंकि यह बेहतर रूप से आईएन 8 एल और अपवाद की श्रेणी या आवेदन के लॉगिंग सम्मेलनों में फिट बैठता है। यह सामान्य बनाना मुश्किल है।

0

जावा 8 एसई के बाद से वहाँ भी

long value = Optional.ofNullable(obj.getProperty(propertyModel.getName())).orElse(0L)));