java कुछ यूनिकोड वर्णों के साथ टिप्पणियों में जावा कोड को क्यों निष्पादित किया जाता है?




ास्की कोड (7)

मैं @zwol से सहमत हूं कि यह एक डिज़ाइन गलती है; लेकिन मैं इससे भी अधिक महत्वपूर्ण हूँ।

\u बच स्ट्रिंग और चार लीटर में उपयोगी है; और यह एकमात्र जगह है कि यह मौजूद होना चाहिए। इसे उसी तरह से हैंडल किया जाना चाहिए जैसे कि अन्य भाग जैसे \n ; और "\u000A" का मतलब बिल्कुल "\n" होना चाहिए

टिप्पणियों में \uxxxx होने का कोई मतलब नहीं है - कोई भी इसे पढ़ नहीं सकता है।

इसी तरह, कार्यक्रम के अन्य भाग में \uxxxx का उपयोग करने का कोई मतलब नहीं है। एकमात्र अपवाद संभवत: सार्वजनिक एपीआई में है, जिसमें कुछ गैर-अस्की चर को समाहित किया जाता है - आखिरी बार हमने क्या देखा है?

1995 में डिजाइनरों के पास इसके कारण थे, लेकिन 20 साल बाद, यह एक गलत विकल्प प्रतीत होता है।

(पाठकों से सवाल - इस सवाल को नए वोट क्यों मिलते रहते हैं? क्या यह सवाल कहीं से जुड़ा है?)

निम्न कोड आउटपुट "हैलो वर्ल्ड!" (नहीं वास्तव में, यह कोशिश)।

public static void main(String... args) {

   // The comment below is not a typo.
   // \u000d System.out.println("Hello World!");
}

इसका कारण यह है कि जावा कंपाइलर एक नई लाइन के रूप में यूनिकोड वर्ण \u000d को पार्स करता है और इसके लिए रूपांतरित हो जाता है:

public static void main(String... args) {

   // The comment below is not a typo.
   //
   System.out.println("Hello World!");
}

इस प्रकार एक टिप्पणी के परिणामस्वरूप "निष्पादित" किया गया।

चूंकि यह दुर्भावनापूर्ण कोड "छिपाने" के लिए इस्तेमाल किया जा सकता है या जो भी एक दुष्ट प्रोग्रामर गर्भ धारण कर सकता है, उसे टिप्पणियों में क्यों अनुमति दी जाती है ?

जावा विनिर्देश द्वारा इसकी अनुमति क्यों है?


यूनिकोड डिकोडिंग किसी अन्य शाब्दिक अनुवाद से पहले होती है। इसका मुख्य लाभ यह है कि यह ASCII और किसी भी अन्य एन्कोडिंग के बीच आगे और पीछे जाने के लिए तुच्छ बनाता है। आपको यह भी पता लगाने की ज़रूरत नहीं है कि टिप्पणियां कहाँ शुरू और समाप्त होती हैं!

जैसा कि JLS धारा 3.3 में कहा गया है, यह किसी भी ASCII आधारित उपकरण को स्रोत फ़ाइलों को संसाधित करने की अनुमति देता है:

[...] जावा प्रोग्रामिंग भाषा यूनिकोड में लिखे गए प्रोग्राम को ASCII में बदलने का एक मानक तरीका बताती है जो प्रोग्राम को एक ऐसे रूप में बदल देती है जिसे ASCII- आधारित टूल द्वारा संसाधित किया जा सकता है। [...]

यह प्लेटफॉर्म की स्वतंत्रता (समर्थित चरित्र सेटों की स्वतंत्रता) के लिए एक मूलभूत गारंटी देता है जो हमेशा जावा प्लेटफॉर्म के लिए एक महत्वपूर्ण लक्ष्य रहा है।

फ़ाइल में कहीं भी किसी भी यूनिकोड के चरित्र को लिखने में सक्षम होना एक साफ-सुथरी विशेषता है, और विशेष रूप से टिप्पणियों में महत्वपूर्ण है, जब गैर-लैटिन भाषाओं में कोड का दस्तावेजीकरण किया जाता है। यह तथ्य कि यह ऐसे सूक्ष्म तरीकों से शब्दार्थों में हस्तक्षेप कर सकता है, बस एक (दुर्भाग्यपूर्ण) दुष्प्रभाव है।

इस विषय पर कई गोचर्स हैं और जोशुआ बलोच और नील गेलर के जावा पज़लर्स में निम्नलिखित संस्करण शामिल हैं:

क्या यह एक कानूनी जावा प्रोग्राम है? यदि हां, तो यह क्या प्रिंट करता है?

\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0020\u0020\u0020
\u0063\u006c\u0061\u0073\u0073\u0020\u0055\u0067\u006c\u0079
\u007b\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0020\u0020
\u0020\u0020\u0020\u0020\u0073\u0074\u0061\u0074\u0069\u0063
\u0076\u006f\u0069\u0064\u0020\u006d\u0061\u0069\u006e\u0028
\u0053\u0074\u0072\u0069\u006e\u0067\u005b\u005d\u0020\u0020
\u0020\u0020\u0020\u0020\u0061\u0072\u0067\u0073\u0029\u007b
\u0053\u0079\u0073\u0074\u0065\u006d\u002e\u006f\u0075\u0074
\u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e\u0028\u0020
\u0022\u0048\u0065\u006c\u006c\u006f\u0020\u0077\u0022\u002b
\u0022\u006f\u0072\u006c\u0064\u0022\u0029\u003b\u007d\u007d

(यह कार्यक्रम एक सादे "हैलो वर्ल्ड" कार्यक्रम के रूप में सामने आया।)

गूढ़ व्यक्ति के समाधान में, वे निम्नलिखित बातें बताते हैं:

अधिक गंभीरता से, यह पहेली पिछले तीन के पाठों को सुदृढ़ करने का कार्य करती है: यूनिकोड से बचना आवश्यक है, जब आपको उन पात्रों को सम्मिलित करने की आवश्यकता होती है जिन्हें आपके कार्यक्रम में किसी अन्य तरीके से प्रस्तुत नहीं किया जा सकता है। अन्य सभी मामलों में उनसे बचें।

स्रोत: जावा: टिप्पणियों में निष्पादन कोड ?!


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

इस कार्यक्रम में एक एकल यूनिकोड एस्केप (\ u000d) शामिल है, जो इसकी एकमात्र टिप्पणी में स्थित है। जैसा कि टिप्पणी आपको बताती है, यह पलायन लाइनफीड चरित्र का प्रतिनिधित्व करता है, और संकलक टिप्पणी को छोड़ने से पहले इसका विधिवत अनुवाद करता है।

यह प्लेटफॉर्म पर निर्भर है। कुछ प्लेटफार्मों पर, जैसे UNIX, यह काम करेगा; दूसरों पर, जैसे कि विंडोज, यह नहीं होगा। हालांकि आउटपुट नग्न आंखों के समान हो सकता है, यह आसानी से समस्याओं का कारण बन सकता है अगर इसे एक फ़ाइल में सहेजा गया या बाद के प्रसंस्करण के लिए किसी अन्य प्रोग्राम में पाइप किया जाए।


यह एक जानबूझकर डिजाइन पसंद था जो जावा के मूल डिजाइन पर वापस जाता है।

उन लोगों के लिए जो पूछते हैं "जो यूनिकोड टिप्पणी में भागना चाहते हैं?", मुझे लगता है कि वे ऐसे लोग हैं जिनकी मूल भाषा लैटिन वर्ण सेट का उपयोग करती है। दूसरे शब्दों में, यह जावा के मूल डिज़ाइन में अंतर्निहित है कि लोग एक यूनिकोड वर्णों का उपयोग कर सकते हैं जहाँ कोई जावा प्रोग्राम में कानूनी रूप से, सबसे अधिक टिप्पणियों और तार में।

यह निश्चित रूप से उन कार्यक्रमों में कमी है (जैसे आईडीई) स्रोत पाठ को देखने के लिए उपयोग किया जाता है कि ऐसे कार्यक्रम यूनिकोड से बच नहीं सकते हैं और संबंधित ग्लिफ़ को प्रदर्शित कर सकते हैं।


\u000d बचना एक टिप्पणी को समाप्त कर देता है क्योंकि \u एस्केप प्रोग्राम के टोकन होने से पहले समान रूप से यूनिकोड वर्ण में परिवर्तित हो जाते हैं। आप एक टिप्पणी शुरू करने के लिए // बजाय समान रूप से \u0057\u0057 उपयोग कर सकते हैं।

यह आपके IDE में एक बग है, जिसे यह स्पष्ट करने के लिए लाइन को सिंटैक्स-हाइलाइट करना चाहिए कि \u000d टिप्पणी समाप्त होती है।

यह भाषा में एक डिज़ाइन त्रुटि भी है। इसे अब ठीक नहीं किया जा सकता है, क्योंकि यह उन कार्यक्रमों को तोड़ देगा जो इस पर निर्भर हैं। \u एस्केप को या तो कंपाइलर द्वारा संबंधित यूनिकोड चरित्र में केवल संदर्भों में परिवर्तित किया जाना चाहिए, जहां "समझ में आता है" (स्ट्रिंग शाब्दिक और पहचानकर्ता, और शायद कहीं और) या उन्हें U + 0000- में वर्ण उत्पन्न करने के लिए मना किया जाना चाहिए था 007F रेंज, या दोनों। या तो उन शब्दार्थों ने टिप्पणी को \u000d एस्केप द्वारा समाप्त होने से रोका होगा, उन मामलों के साथ हस्तक्षेप किए बिना, जहां \u एस्केप उपयोगी हैं - ध्यान दें कि टिप्पणियों के अंदर \u एस्केप का उपयोग शामिल है एक टिप्पणी में एनकोड करने के तरीके के रूप में -लिटिन स्क्रिप्ट, क्योंकि टेक्स्ट एडिटर व्यापक दृष्टिकोण ले सकता है जहां कंपाइलर की तुलना में \u एस्केप महत्वपूर्ण हैं। (मैं किसी भी संपादक या आईडीई के बारे में नहीं जानता जो किसी भी संदर्भ में संबंधित पात्रों के रूप में प्रदर्शित होगा, हालांकि)

सी परिवार में एक समान डिजाइन त्रुटि है, 1 जहां बैकस्लैश-न्यूलाइन को टिप्पणी सीमाओं को निर्धारित करने से पहले संसाधित किया जाता है, इसलिए उदाहरण के लिए।

// this is a comment \
   this is still in the comment!

मैं इसे स्पष्ट करने के लिए लाता हूं कि यह विशेष रूप से डिज़ाइन त्रुटि करना आसान होता है, और यह महसूस नहीं करना कि यह एक त्रुटि है जब तक कि इसे ठीक करने के लिए बहुत देर हो चुकी है, यदि आप टोकन के बारे में सोचने और कंपाइलर प्रोग्रामर के सोचने के तरीके के बारे में सोचते हैं टोकन और पार्सिंग के बारे में। मूल रूप से, यदि आपने पहले से ही अपने औपचारिक व्याकरण को परिभाषित कर लिया है और फिर कोई व्यक्ति एक विशेष वाक्य-विशेष, ट्रिग्राफ, बैकस्लैश-न्यूलाइन के साथ आता है, तो ASCII तक सीमित स्रोत फ़ाइलों में मनमाने ढंग से यूनिकोड वर्णों को कूटबद्ध करना, जो भी - जिसको भी इसमें करने की आवश्यकता है, यह आसान है। टोकेनाइज़र से पहले एक परिवर्तन पास को जोड़ने की तुलना में उस टोकन को फिर से परिभाषित करना है जहां इस विशेष मामले का उपयोग करने के लिए समझ में आता है।

1 बालकों के लिए: मुझे पता है कि C का यह पहलू 100% जानबूझकर था, औचित्य के साथ - मैं इसे नहीं बना रहा हूं - कि यह आपको पंच कार्डों पर मनमाने ढंग से लंबी लाइनों के साथ यंत्रवत्-फिट कोड की अनुमति देगा। यह अभी भी एक गलत डिजाइन निर्णय था।


केवल वे लोग ही जवाब दे सकते हैं कि यूनिकोड के पलायन को क्यों लागू किया गया क्योंकि वे ऐसे लोग थे जिन्होंने विनिर्देश लिखा था।

इसका एक प्रशंसनीय कारण यह है कि पूरे बीएमपी को जावा स्रोत कोड के संभावित पात्रों के रूप में अनुमति देने की इच्छा थी। हालांकि यह एक समस्या प्रस्तुत करता है:

  • आप किसी भी BMP वर्ण का उपयोग करने में सक्षम होना चाहते हैं।
  • आप किसी भी BMP charater को आसान तरीके से इनपुट करने में सक्षम होना चाहते हैं। ऐसा करने का एक तरीका है यूनिकोड बच जाता है।
  • आप मनुष्यों के पढ़ने और लिखने के लिए शाब्दिक विनिर्देशन को आसान रखना चाहते हैं, और यथोचित रूप से लागू करना आसान है।

यह अविश्वसनीय रूप से मुश्किल है जब यूनिकोड बच जाता है तो मैदान में प्रवेश करता है: यह नए लेसर नियमों का एक पूरा भार बनाता है।

इसका आसान तरीका यह है कि दो चरणों में लेक्सिंग करें: पहले खोज करें और सभी यूनिकोड को उस वर्ण के साथ भाग दें, जो इसके द्वारा निरूपित होता है और फिर परिणामी दस्तावेज़ को पार्स करता है जैसे कि यूनिकोड बचता नहीं है।

इसका उल्टा यह है कि यह निर्दिष्ट करना आसान है, इसलिए यह विनिर्देशन को सरल बनाता है, और इसे लागू करना आसान है।

नकारात्मक पक्ष यह है, ठीक है, आपका उदाहरण।


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

जावा स्रोत में कोड \ u000d हर तरह से एक ASCII CR वर्ण के बराबर है। यह जहां कहीं भी होता है, एक लाइन समाप्त करने वाला, सादा और सरल होता है। प्रश्न में प्रारूपण भ्रामक है, वर्णों का वह क्रम वास्तव में किसके अनुरूप है:

public static void main(String... args) {
   // The comment below is no typo. 
   // 
 System.out.println("Hello World!");
}

IMHO सबसे सही उत्तर इसलिए है: कोड निष्पादित होता है क्योंकि यह एक टिप्पणी में नहीं है; यह अगली पंक्ति पर है। जावा में "टिप्पणियों में निष्पादन की अनुमति नहीं है", जैसे आप उम्मीद करेंगे।

अधिकांश भ्रम इस तथ्य से उपजा है कि सिंटैक्स हाइलाइटर्स और आईडीई इस स्थिति को ध्यान में रखने के लिए पर्याप्त परिष्कृत नहीं हैं। वे या तो यूनिकोड से बचने की प्रक्रिया नहीं करते हैं, या वे पहले के बजाय कोड को पार्स करने के बाद ऐसा करते हैं, जैसे कि javac करता है।





comments