public class Npe {
static class Thing {
long value;
}
public static Map<Thing, Long> map;
public static void main(String[] args) {
Thing thing = new Thing();
method(null); // returns -1
method(thing); // returns 0
map = new HashMap<Thing, Long>();
method(null); // returns -1
method(thing); // NullPointerException thrown inside this method call
}
public static long method(Thing thing) {
if (thing == null) {
return -1;
}
Long v = (map == null) ? thing.value : map.get(thing); // NPE here
if (v == null) {
v = thing.value;
}
return v;
}
}
method()
को 4 कॉल पर मैं एक NullPointerException
method()
अंदर संकेत लाइन पर फेंक दिया मिलता है। अगर मैंयह असाइनमेंट एनपीई क्यों करता है?
Long v;
if (map == null) {
v = thing.value;
} else {
v = map.get(thing);
}
को
Long v = (map == null) ? thing.value : map.get(thing);
से कि लाइन refactor मुझे कोई NullPointerException
हो और एकदम सही ढंग से विधि व्यवहार करता है। सवाल यह है: क्यों ??
यह संकलक की तरह मुझे लग रहा है की उम्मीद है, जिससे कि वह (Long
से long
को अवनत) map.get(thing)
करने के लिए कॉल (जो null
वापस आ सकते हैं और इसलिए एक फेंक का परिणाम unboxing है ?
ऑपरेटर का परिणाम long
होने के लिए NullPointerException
)। आईएमएचओ को ?
ऑपरेटर के परिणाम Long
और ऑटोबॉक्सिंग (long
से Long
) thing.value
के परिणामस्वरूप होने की उम्मीद करनी चाहिए।
और भी बेहतर, अगर मैं इस बयान refactor:
Long v = (map == null) ? thing.value : map.get(thing);
इस के लिए
(Long
को long
कास्टिंग स्पष्ट रूप से):
Long v = (map == null) ? (Long)thing.value : map.get(thing);
मेरी आईडीई (इंटेलीजे) का कहना है कि कलाकारों बेमानी है, लेकिन संकलित कोड अपेक्षित काम करता है और NullPointerException
फेंक नहीं देता है! ,
(map == null) ? thing.value : map.get(thing)
कि अभिव्यक्ति का परिणाम long
होगा, क्योंकि thing.value
के प्रकार long
है: :-D
[बूलियन, सशर्त ऑपरेटर और ऑटोबॉक्सिंग] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/3882095/booleans-conditional-operators-and-autoboxing) –
@DwB आपकी टिप्पणी प्रासंगिक नहीं है क्योंकि मैं नहीं हूं कनिष्ठ प्रोग्रामर। और आपका सुझाव "टर्नरी ऑपरेटर का उपयोग नहीं" करने के लिए भी मूर्खतापूर्ण है। सिर्फ इसलिए कि कुछ जटिल या भ्रमित हो सकता है जिसका मतलब यह नहीं है कि आपको इसका उपयोग नहीं करना चाहिए। इसका मतलब यह है कि आपको सावधान रहना होगा और पता होना चाहिए कि आप क्या कर रहे हैं। यदि डेवलपर्स ने जटिल या संभावित रूप से भ्रमित करने वाली किसी भी चीज का कभी भी उपयोग नहीं किया है, तो वे सभी प्रोग्रामर के बजाय पेंटर्स या स्ट्रीट स्वीपर या गार्डनर्स होंगे ;-) –
यदि आप 'टर्नरी ऑपरेटर को नहीं समझते हैं, तो, विश्वास करें या नहीं, आप अभी भी जूनियर हैं जावा। साथ ही, तथ्य यह है कि कुछ जटिल, उलझन में है, और कोई मूल्य प्रदान नहीं करता है इसका उपयोग करने का एक बड़ा कारण नहीं है। यदि डेवलपर्स ने कभी भी जटिल और संभावित रूप से भ्रमित करने वाली किसी भी चीज का उपयोग नहीं किया है, तो वे कोड उत्पन्न करेंगे जो कम अनावश्यक रूप से जटिल और भ्रमित है। – DwB