2015-03-11 9 views
28

मैं अपने codebase में एक बग का सामना किया है में टाइप है, मैं क्या इस व्यवहार की वजह से अधिक संकीर्ण है। पहला टेस्ट केस विफल रहता है, जबकि अंतिम दो सफल होते हैं।अशक्त जावा

@Test 
public void testBooleanNull1() { 
    Boolean nullB = null; 
    assertFalse(Boolean.valueOf(nullB)); 
} 

@Test 
public void testBooleanNull2() { 
    String nullS = null; 
    assertFalse(Boolean.valueOf(nullS)); 
} 
@Test 
public void testBooleanNull3() { 
    assertFalse(Boolean.valueOf(null)); 
} 

मुझे पता है कि Boolean.valueOf दो वेरिएंट के साथ एक ओवरलोड विधि एक एक String लेता है और अन्य प्रकार boolean की एक आदिम लेता है।

मुझे लगता है कि यह स्वत: मुक्केबाजी की वजह से हो रहा है, लेकिन मुझे लगता है कि यदि यह मामला है यकीन नहीं है, इसके अलावा मैं क्यों null एक Boolean करने के लिए परिवर्तित किया जा रहा है पता नहीं है के रूप में तक मुझे पता है null एक नहीं है मान्य primitive प्रकार।

मैं Apache Commons से उपयोग करने के लिए आगे बढ़ गया हूं, मैंने यह बेहतर तरीके से समझने के लिए कहा कि व्यवहार इस तरह क्यों है।

+0

यह भी देखें http://stackoverflow.com/questions/2707322/what-is-null-in-java – cymatist

उत्तर

31

यह

Boolean.valueOf(nullB) 

Boolean#valueOf(boolean) की एक मंगलाचरण है।

यह विफल रहता है क्योंकि Boolean मान nullB का अनबॉक्सिंग NullPointerException के साथ विफल रहता है। दूसरे शब्दों में, यह हो जाता है

boolean val = nullB.booleanValue(); // at runtime nullB stores the value null 
Boolean.valueOf(val) 

इस प्रक्रिया JLS में वर्णन किया गया here

तो r प्रकार Boolean के लिए एक संदर्भ है, तो unboxing रूपांतरण धर्मान्तरित rr.booleanValue()

में यह

Boolean.valueOf(null) 

overloaded version that accepts a String का आविष्कार कर रहा है (nullboolean प्रकार की वैध अभिव्यक्ति नहीं है)।

निर्दिष्ट स्ट्रिंग द्वारा प्रतिनिधित्व किए गए मान के साथ Boolean देता है। बूलियन लौटा true मान का प्रतिनिधित्व करता है यदि स्ट्रिंग तर्क null नहीं है और स्ट्रिंग "true" पर केस को अनदेखा कर बराबर है।

1

क्यों दूसरा एक सफल होगा? public static Boolean valueOf(String s) के दस्तावेज़ को देखें:

निर्दिष्ट स्ट्रिंग द्वारा प्रतिनिधित्व किए गए मान के साथ एक बूलियन लौटाता है। बूलियन लौटे एक सच्चे मूल्य का प्रतिनिधित्व करता है, तो स्ट्रिंग तर्क रिक्त नहीं "सही" है और बराबर है, मामले की अनदेखी कर स्ट्रिंग के लिए,।

आपने null पास किया है, तो यह false वापस आ जाएगा।

5

अतिभारित विधि संकल्प JLS में वर्णित है:

15.12.2। संकलन समय चरण 2: निर्धारित विधि हस्ताक्षर

...

  1. (§15.12.2.2) पहले चरण मुक्केबाजी या unboxing रूपांतरण या वैरिएबल arity विधि मंगलाचरण के उपयोग की अनुमति के बिना अधिभार संकल्प प्रदर्शन करती है। यदि इस चरण के दौरान कोई लागू विधि नहीं मिलती है तो प्रसंस्करण दूसरे चरण तक जारी रहता है।

हमारे मामले में, Boolean.valueOf(boolean) और के बीच Boolean.valueOf(String) संकलक चुनने valueOf(String) क्योंकि यह unboxing आवश्यक नहीं है चुनता है।

+0

यह उत्तर सिर पर कील हिट करता है! –

2

वर्ग Boolean

public static Boolean valueOf(String s) { 
    return toBoolean(s) ? TRUE : FALSE; 
} 

के स्रोत कोड पर एक नज़र ले रहा है .. और फिर:

private static boolean toBoolean(String name) { 
    return ((name != null) && name.equalsIgnoreCase("true")); 
} 

तो स्ट्रिंग तर्क Boolean.valueOf(String s) के लिए null है, यह गलत है, इसलिए दूसरे वापस आ जाएगी मामला सफल

public static Boolean valueOf(boolean b) 

Returns a Boolean instance representing the specified boolean value. If the specified boolean value is true, this method returns Boolean.TRUE; if it is false, this method returns Boolean.FALSE. If a new Boolean instance is not required, this method should generally be used in preference to the constructor Boolean(boolean), as this method is likely to yield significantly better space and time performance. 

Parameters: 
b - a boolean value. 
Returns: 
a Boolean instance representing b. 

पैरामीटर यहाँ आवश्यक एक boolean मूल्य जो True या स्वीकार करता है:

पहले मामले में, जो यहाँ बूलियन के रूप में डेटा प्रकार लेता है, Boolean.valueOf के उपयोग पर प्रलेखन क्या कहा गया है False और Boolean मान जो True, False या null स्वीकार करता है। चूंकि आपने Boolean मान पास किया है और boolean मान नहीं है, मुझे लगता है कि यही कारण है कि यह विफल हो जाता है।

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