2009-05-12 9 views
8

func3 को नीचे दिए गए कार्यक्रम में निष्पादित क्यों नहीं किया जाता है? Func1 के बाद, func2 को मूल्यांकन करने की आवश्यकता नहीं है लेकिन func3 के लिए, है ना?इस जावा कोड में शॉर्ट सर्किट तर्क के साथ क्या गलत है?

if (func1() || func2() && func3()) { 
     System.out.println("true"); 
    } else { 
     System.out.println("false"); 
    } 
} 

public static boolean func1() { 
    System.out.println("func1"); 
    return true; 
} 

public static boolean func2() { 
    System.out.println("func2"); 
    return false; 
} 

public static boolean func3() { 
    System.out.println("func3"); 
    return false; 
} 
+0

मेरा मानना ​​है कि हर कोई शॉर्ट सर्किट समस्या की जानकारी है, उस मामले में सवाल का संपादित संस्करण निष्पादित करने के लिए नहीं हो सकता है ब्याज नए लोग भी अगर वे तार्किक और& और || के बारे में एक जवाब की तलाश में हैं जावा का मूल्यांकन – DragonBorn

+4

यह इस बात को उठाता है कि इस तरह की गैर-तुच्छ अभिव्यक्ति में, ब्रांड्स के साथ अपना इरादा घोषित करना एक अच्छा विचार है। तो यदि आप (func1() || (func2() && func3()) का इरादा रखते हैं, तो आप इसे प्रोग्रामर के लिए स्पष्ट और स्पष्ट करते हैं जो बाद में आते हैं कि आपका कोड इरादे से काम कर रहा है। – mtruesdell

उत्तर

25

आप एक संक्षिप्त सर्किट का उपयोग कर रहे हैं या। यदि पहला तर्क सत्य है, तो संपूर्ण अभिव्यक्ति सत्य है।

यह अगर मैं अंतर्निहित कोष्ठकों जोड़ने कि संकलक का उपयोग करता है मदद कर सकता है

संपादित: जैसा कि क्रिस जेस्टर-यंग बताया गया है, यह वास्तव में है, क्योंकि तार्किक ऑपरेटरों बाएँ-से-सही संबद्धता के लिए है:

शॉर्ट सर्किट या मूल्यांकन करने के बाद

if (true || (func2() && func3())) 

,:

if (func1() || (func2() && func3())) 

func1 रिटर्न के बाद, यह इस हो जाता है यह हो जाता है:

if (true) 
+13

संदेह से बचने के लिए, यह ऐसा इसलिए है क्योंकि && की तुलना में अधिक प्राथमिकता है। एसोसिएटिविटी, दोनों मामलों में, बाएं से दाएं –

+4

मैं इसका उल्लेख करता हूं क्योंकि अन्यथा यह पोस्ट इस सवाल का कारण बनता है, क्यों (ए || (बी एंड सी)) का विरोध ((ए || बी) और सी) –

+3

(रात के लिए यह महत्वपूर्ण है कि यह प्राथमिकता है जो यहां महत्वपूर्ण है, कोई सहयोगीता नहीं दिखती है। आईएमओ, अभिव्यक्ति जैसे 'ए || बी एंड सी सी 'और' a && b || c' (जो '(a && b) || c) भ्रमित हैं और संकलक शिकायत कर सकते हैं।) –

3

जावा शॉर्ट सर्किट बूलियन एक्सप्रेशन। इसका मतलब है कि, एक बार func1() निष्पादित किया जाता है और true देता है, तो शेष बूलियन इससे कोई फर्क नहीं पड़ता क्योंकि आप or ऑपरेटर का उपयोग कर रहे हैं। कोई फर्क नहीं पड़ता कि func2() && func3() का मूल्यांकन करता है, पूरी अभिव्यक्ति का मूल्यांकन true पर होगा। इस प्रकार, जावा func2() या func3() का मूल्यांकन करने से भी परेशान नहीं है।

1

संक्षिप्त उत्तर: short-circuit evaluation

के बाद से func1() सच yelds वहाँ मूल्यांकन जारी रखने के यह हमेशा सच है के बाद से की जरूरत नहीं है

1

तो समारोह 1 हमेशा रिटर्न सच है, तो जावा को यह निर्धारित करने के लिए शेष अभिव्यक्ति का मूल्यांकन करने की आवश्यकता नहीं है कि पूरी अभिव्यक्ति सत्य होगी।

2

जावा आलसी मूल्यांकन का उपयोग करता है।

चूंकि Func1 हमेशा सत्य लौटाता है, इसलिए संपूर्ण अभिव्यक्ति सत्य होनी चाहिए, इसलिए यह शेष अभिव्यक्ति को शॉर्टकट करता है।

true || (???) 

और

false && (???) 

हमेशा शॉर्टकट होगा।

शॉर्टकट मूल्यांकन बंद करने के लिए, उपयोग करें | और & के बजाय ||

String s; 
if (s != null && !s.equals("")) ... 

मतलब यह है कि अगर रों रिक्त है, हम भी s.equals कॉल करने के लिए कोशिश करने की जरूरत नहीं है, और हम खत्म नहीं होगा: और & &

हम अच्छे प्रभाव के लिए इसका उपयोग कर सकते एक NullPointerException फेंकना

+0

यह हमेशा शॉर्टकट नहीं होगा। यह प्राथमिकता नियमों के अनुसार मूल्यांकन कर रहा है। जावा जावा कंपाइलर आसान नहीं है, लेकिन मेरा मानना ​​है कि (falsefunc() && true1() || true2()) falsefunc का मूल्यांकन करेगा () तो true2()। – DevinB

+0

अच्छा प्वाइंट। इसे ठीक करने के लिए जोड़ा गया कोष्ठक। –

2

आप शॉर्टकट-ऑपरेटरों का उपयोग कर रहे हैं || और & &।यदि परिणाम पहले ही परिभाषित किया गया है, तो ये ऑपरेटर शेष अभिव्यक्ति निष्पादित नहीं करते हैं। || के लिए इसका मतलब है कि अगर पहली अभिव्यक्ति गलत है और & & के लिए पहली अभिव्यक्ति गलत है।

यदि आप अभिव्यक्ति उपयोग के सभी भागों को निष्पादित करना चाहते हैं। और इसके बजाय &, यह शॉर्टकट नहीं है।

5

जावा कार्यों के लिए precedence rules

क्योंकि "& &" "||" की तुलना में अधिक precendence की है अनुसार मूल्यांकन किया जाता है, यह पहली मूल्यांकन किया जाता है क्योंकि आप

तो स्पष्ट पूर्वता सेट करने के लिए किसी भी कोष्ठक नहीं था

(A || B && C) 

की आप अभिव्यक्ति जो

(T || F && F) 
01 है

रूप

(T || (F && F)) 
क्योंकि पूर्वता नियमों का

कोष्ठकों के भीतर है।

के बाद से संकलक, बंद हो जाता है समझता है कि अगर 'ए == सच' यह अभिव्यक्ति के बाकी के मूल्यांकन के परेशान करने के लिए की जरूरत नहीं है यह ए

का मूल्यांकन आप कोष्ठकों के भीतर दर्ज किया था ((A || B) && C) तो यह करने के लिए मूल्यांकन करेंगे, तो बाद असत्य।

संपादित

एक और तरीका है, के रूप में अन्य पोस्टर ने उल्लेख उपयोग करने के लिए है "|" और "&" के बजाय "||" और "& &" क्योंकि यह शॉर्टकटिंग से अभिव्यक्ति को रोकता है। हालांकि, प्राथमिकता नियमों के कारण, अंतिम परिणाम अभी भी वही होगा।

0

यदि आप चाहते हैं सभी कार्यों आप ड्रॉप कर सकते हैं कम कटौती वेरिएंट

if (func1() | func2() & func3()) { 
संबंधित मुद्दे