2015-06-14 8 views
19

यह बिना त्रुटि के संकलित करता है? मेरी समझ के रूप में, कंपाइलर वैरिएबल के प्रकार की जांच करता है (इस मामले में String), फिर देखता है कि दाईं तरफ अभिव्यक्ति का प्रकार चर के प्रकार से मेल खाता है (या कम से कम एक उप प्रकार लेकिन चलिए साधारण मामले में चिपके रहें String कक्षा इसके अंतिम होने के बाद से)।असाइनमेंट अभिव्यक्ति के चर प्रारंभिकरण क्यों होता है [स्ट्रिंग x = (x = y)] संकलित करें?

public class InitClass { 
    public static void main(String[] args) { 
    String str = (str = "hello"); 
    System.out.println(str); 
    } 
} 

मेरा सवाल यह है कि str = "hello" संकलित कैसे करता है? क्या संकलक पहले से ही जागरूक है कि strString प्रकार का होना चाहिए?

+0

(str = "हैलो") स्ट्रिंग "हैलो" देता है। ग्रहण संदेश के साथ इसे हतोत्साहित करता है: "परिवर्तनीय str के असाइनमेंट का कोई प्रभाव नहीं पड़ता है" – LeTex

+3

@LeTex I आमतौर पर ग्रहण को कठोर बनाने के लिए सेट करता है और इन्हें चेतावनियों के बजाए त्रुटियों के रूप में रिपोर्ट करता है। मुझे किसी को भी इस तरह की संरचनाओं का उपयोग करने का कोई कारण नहीं दिखता है, भले ही उन्हें जेएलएस द्वारा अनुमति दी गई हो। – biziclop

+2

उन दिलचस्प प्रश्नों में से एक जहां आप सोच रहे हैं "इस तरह कोड लिख रहा है और क्यों"। निश्चित रूप से अकादमिक, निश्चित रूप से? – TEK

उत्तर

15

होने का मूल्यांकन करते एक assignment expression

पहले, बाएं हाथ संकार्य एक चर उत्पादन करने के लिए मूल्यांकन किया जाता है। यदि यह मूल्यांकन अचानक समाप्त हो जाता है, तो असाइनमेंट अभिव्यक्ति उसी कारण से अचानक समाप्त हो जाती है; दायां हाथ ऑपरेंड मूल्यांकन नहीं किया गया है और कोई असाइनमेंट नहीं होता है।

यह चर str बनाता है। फिर

अन्यथा, दाएं हाथ के ऑपरेंड का मूल्यांकन है। यदि यह मूल्यांकन अचानक समाप्त हो जाता है, तो असाइनमेंट अभिव्यक्ति उसी कारण से अचानक पूर्ण करती है और कोई असाइनमेंट नहीं होता है।

आपके उदाहरण में, दायां हाथ ऑपरेंड स्वयं ही एक और असाइनमेंट अभिव्यक्ति है। इसलिए str, असाइनमेंट ऑपरेटर का दायां हाथ ऑपरेंड, फिर से एक चर, str बनाने के लिए मूल्यांकन किया जाता है। तब

अन्यथा, दायां संकार्य के मूल्य के बाएं हाथ की चर के प्रकार में बदल जाती है, मान सेट रूपांतरण (§5.1.13) उचित मानक मूल्य सेट करने के लिए (के अधीन है विस्तारित-एक्सपोनेंट मान सेट नहीं), और रूपांतरण का परिणाम वैरिएबल में संग्रहीत है।

तो "hello"str में संग्रहित है। And since

रन समय, काम अभिव्यक्ति का परिणाम चर के बाद काम आ गई है का मूल्य है। असाइनमेंट अभिव्यक्ति का परिणाम स्वयं एक चर नहीं है।

str करने के लिए "hello" का काम का परिणाम है, मूल्य "hello" है कि मूल्य फिर से str में संग्रहित है।

0

पहला ऐसा होता है कि संकलक संदर्भ के प्रकार की पहचान करता है और यह जानकर कि स्ट्रिंग असाइन स्ट्रिंग असाइन है "हैलो" मान्य है।

5

आपका मामला

String str; 
str = (str = "hello"); 

के बराबर है हालांकि कार्य अजीब लग रही हैं, धारणात्मक कुछ भी गलत नहीं है।

फिर भी, एक चर प्रारंभिकरण जो संदर्भ स्वयं ही एक अच्छा विचार नहीं है। कंपाइलर उन परिस्थितियों में इसे ध्वजांकित करने का प्रयास करेगा जो प्रोग्रामर त्रुटि की संभावना है; संकलक कुछ बार ऐसा करने में विफल रहता है; और कुछ अन्य समय पर भी जा सकता है।

एक स्थानीय चर के लिए एक कठोर आवश्यकता है (एक फील्ड चर से) - इसे इसके मूल्य का उपयोग करने से पहले पहले असाइन किया जाना चाहिए। उदाहरण के लिए, यह संकलित नहीं होगा, क्योंकि स्थानीय var को असाइन किए जाने से पहले पढ़ा जाता है।

String str; // local variable 
str = str; // error, try to read `str` before it's assigned 

फ़ील्ड चर के पास हमेशा एक डिफ़ॉल्ट प्रारंभिक मान होता है; फिर भी, स्पष्ट programer गलतियों

int x = x+1; // error. x is field variable. 

लेकिन यह भयावह अगर इस तरह की जाँच में विफल रहता है नहीं है, के बाद से x, स्पष्ट असाइनमेंट से पहले एक मूल्य 0 है

int x; 
{ x=x+1; } // ok. x==0, then x==1 after assignment 

लेकिन अगर xfinal है, कोड के लिए संकलक चेकों उपरोक्त विफल रहता है, क्योंकि संकलक को x को x पढ़ने से पहले, स्थानीय चर के लिए एक ही आवश्यकता को पढ़ने से पहले निश्चित असाइनमेंट की आवश्यकता होती है। लेकिन इस चेकिंग, धोखा दिया जा सकता है क्योंकि यह विश्लेषण और यह पूरी तरह से क्षेत्र चर के लिए

final int x = (this).x+1; // compiles! 

कुछ मामलों में रोकने के लिए असंभव है, संकलक पानी में गिर जाता है, कानूनी उपयोग लैम्ब्डा

शामिल
Runnable r1 =()->System.out.println(r1); // r1 is a field variable 

कुछ भी नहीं है मामलों को रोकने के इस उपयोग के मामले में अवधारणात्मक समस्याग्रस्त; इसे (this). द्वारा भी घुमाया जा सकता है।

+1

आपके उत्तर का अंतिम भाग बहुत ही रोचक है, +1 – user2336315

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