जावा में एक अशक्त के साथ कास्टिंग करते समय कोई अपवाद नहीं है


227
String x = (String) null;

इस कथन में कोई अपवाद क्यों नहीं है?

String x = null;
System.out.println(x);

यह प्रिंट करता है null। लेकिन .toString()विधि को एक शून्य सूचक अपवाद फेंकना चाहिए।


आप किस अपवाद की बात कर रहे हैं, कंपाइलर?
साजन चंद्रन

जवाबों:


323

आप nullबिना किसी अपवाद के किसी भी संदर्भ प्रकार के लिए कास्ट कर सकते हैं।

printlnविधि नल पॉइंटर फेंक नहीं है क्योंकि यह पहली चेकों वस्तु रिक्त है या नहीं। यदि अशक्त है तो यह केवल स्ट्रिंग को प्रिंट करता है "null"। अन्यथा इसे toStringउस वस्तु की विधि कहेंगे ।

अधिक विवरण जोड़ना:String.valueOf(object) इनपुट ऑब्जेक्ट पर आंतरिक रूप से प्रिंट विधि कॉल विधि। और valueOfविधि में, यह चेक अशक्त सूचक अपवाद से बचने में मदद करता है:

return (obj == null) ? "null" : obj.toString();

अपने भ्रम के बाकी के लिए, किसी ऑब्जेक्ट को किसी अशक्त वस्तु पर कॉल करना एक अशक्त सूचक अपवाद को फेंकना चाहिए, यदि कोई विशेष मामला नहीं है।


1
@JunedAhsan क्या विशेष मामलों के कारण यह एनपीई को नहीं फेंक देगा?
होलोवे

@ टेंगोट नीचे दिए गए पीटर के उत्तर में बताए गए एक चेक को देखें।
जून अहसन

144

आप nullकिसी भी संदर्भ प्रकार को कास्ट कर सकते हैं । आप उन तरीकों को भी कॉल कर सकते हैं जो nullएक तर्क के रूप में संभालते हैं , उदाहरण के लिए System.out.println(Object), लेकिन आप एक nullमान को संदर्भित नहीं कर सकते हैं और उस पर एक विधि को कॉल कर सकते हैं ।

BTW एक मुश्किल स्थिति है जहां यह प्रतीत होता है कि आप nullमूल्यों पर स्थिर तरीकों को कॉल कर सकते हैं।

Thread t = null;
t.yield(); // Calls static method Thread.yield() so this runs fine.

12
वाह। अगर पूछा जाए, तो मुझे 100% यकीन होगा कि यह एक अपवाद होगा। वास्तव में एक मुश्किल मामला।
मैगनीलेक्स

2
@Magnilex: बिल्कुल! यह एक विशिष्ट OCPJP परीक्षा ट्रिक प्रश्न है।
ccpizza

3
क्या ऐसा इसलिए नहीं है क्योंकि बायटेकोड में संकलक इसे t.yield() -> Thread.yeld() वैसे भी "अनुकूलित" करता है ? इसी तरह से कैसे final int i = 1; while (i == 1)अनुकूलित किया जाता हैwhile(true)
एसजीएल

@SGal यह और भी बेहतर है क्योंकि दूसरा अनुकूलन AFAIK अनिवार्य नहीं है, जबकि पहला एक थोथा है।
पॉल स्टेलियन

36

यह डिजाइन द्वारा है। आप nullकिसी भी संदर्भ प्रकार को कास्ट कर सकते हैं । अन्यथा आप इसे संदर्भ चर के लिए निर्दिष्ट करने में सक्षम नहीं होंगे।


धन्यवाद! संदर्भ चर को निर्दिष्ट करने के लिए यह नोट वास्तव में उपयोगी है!
मैक्स

22

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

class A {
  public void foo(Long l) {
    // do something with l
  }
  public void foo(String s) {
    // do something with s      
  }
}
new A().foo((String)null);
new A().foo((Long)null);

अन्यथा आप अपनी जरूरत के तरीके को नहीं कह सकते।


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

मजेदार तथ्य: l instanceof Longऔर इन मामलों में s instanceof Stringवापस आ जाएगा false
अत्तिला तानी

7

Println(Object) का उपयोग करता है String.valueOf()

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

Print(String) अशक्त जाँच करता है।

public void print(String s) {
    if (s == null) {
        s = "null";
    }
    write(s);
}

5

यहाँ कई जवाब पहले से ही उल्लेख है

आप किसी भी संदर्भ प्रकार को अशक्त कर सकते हैं

तथा

यदि तर्क शून्य है, तो "null" के बराबर एक स्ट्रिंग

मैंने सोचा कि यह कहाँ निर्दिष्ट है और इसे जावा विनिर्देशन देखा है:

अशक्त संदर्भ हमेशा किसी भी संदर्भ प्रकार (.25.2, .35.3, )5.5) को सौंपा या डाला जा सकता है।

यदि संदर्भ शून्य है, तो इसे स्ट्रिंग "null" (चार ASCII वर्ण n, u, l, l) में बदल दिया जाता है।


3

जैसा कि दूसरों ने लिखा है, आप हर चीज को शून्य कर सकते हैं। आम तौर पर, आपको इसकी आवश्यकता नहीं होगी, आप लिख सकते हैं:

String nullString = null;

वहाँ कलाकारों को डाले बिना।

लेकिन ऐसे मौके हैं जहां इस तरह की जातियों का मतलब होता है:

क) यदि आप यह सुनिश्चित करना चाहते हैं कि एक विशिष्ट विधि कहा जाता है, जैसे:

void foo(String bar) {  ... }
void foo(Object bar) {  ... }

यदि आप टाइप करते हैं तो इससे फर्क पड़ेगा

foo((String) null) vs. foo(null)

बी) यदि आप कोड बनाने के लिए अपने आईडीई का उपयोग करने का इरादा रखते हैं; उदाहरण के लिए, मैं आमतौर पर इकाई परीक्षण लिख रहा हूँ जैसे:

@Test(expected=NullPointerException.class)
public testCtorWithNullWhatever() {
    new MyClassUnderTest((Whatever) null);
}

मैं टीडीडी कर रहा हूं; इसका मतलब है कि वर्ग "MyClassUnderTest" शायद अभी तक मौजूद नहीं है। उस कोड को लिखकर, मैं अपनी IDE का उपयोग पहली बार नए वर्ग को उत्पन्न करने के लिए कर सकता हूं; और फिर एक "बॉक्स के बाहर" जो भी "तर्क" को स्वीकार करने वाले एक निर्माता को उत्पन्न करता है - आईडीई मेरे परीक्षण से यह पता लगा सकता है कि निर्माणकर्ता को जो भी हो, उसके प्रकार का एक तर्क लेना चाहिए।


2

प्रिंट करें :

किसी वस्तु को छापना। String.valueOf (ऑब्जेक्ट) विधि द्वारा निर्मित स्ट्रिंग बाइट्स में अनुवादित है

मान :

यदि तर्क शून्य है, तो "null" के बराबर एक स्ट्रिंग; अन्यथा, obj.toString () का मान लौटाया जाता है।

यह जब वस्तु होता है तो वैल्यू "नल" के साथ एक स्ट्रिंग लौटाता है null


2

किसी विधि का उपयोग करते समय यह बहुत आसान है जो अन्यथा अस्पष्ट होगा। उदाहरण के लिए: JDialog में निम्नलिखित हस्ताक्षर वाले निर्माता हैं:

JDialog(Frame, String, boolean, GraphicsConfiguration)
JDialog(Dialog, String, boolean, GraphicsConfiguration)

मुझे इस कंस्ट्रक्टर का उपयोग करने की आवश्यकता है, क्योंकि मैं GraphicsConfiguration को सेट करना चाहता हूं, लेकिन मेरे पास इस संवाद के लिए कोई अभिभावक नहीं है, इसलिए पहला तर्क अशक्त होना चाहिए। का उपयोग करते हुए

JDialog(null, String, boolean, Graphicsconfiguration) 

अस्पष्ट है, इसलिए इस मामले में मैं समर्थित प्रकारों में से एक को कॉल करके कॉल को संकीर्ण कर सकता हूं:

JDialog((Frame) null, String, boolean, GraphicsConfiguration)

0

यह भाषा सुविधा इस स्थिति में सुविधाजनक है।

public String getName() {
  return (String) memberHashMap.get("Name");
}

यदि सदस्यHashMap.get ("नाम") शून्य देता है, तो आप अभी भी उपरोक्त विधि को अपवाद के बिना नल को वापस करने के लिए चाहते हैं। कोई फर्क नहीं पड़ता कि कक्षा क्या है, अशक्त है।

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