0. क्या दोनों त्रुटियों में कोई अंतर है?
ज़रुरी नहीं। "प्रतीक नहीं मिल सकता है" और "प्रतीक को हल नहीं कर सकता" का अर्थ समान है। कुछ जावा कंपाइलर एक वाक्यांश का उपयोग करते हैं, और कुछ अन्य एक का उपयोग करते हैं।
1. "प्रतीक नहीं मिल सकता" त्रुटि का क्या मतलब है?
सबसे पहले, यह एक संकलन त्रुटि 1 है । इसका मतलब है कि या तो आपके जावा स्रोत कोड में कोई समस्या है , या जिस तरीके से आप इसे संकलित कर रहे हैं , उसमें कोई समस्या है।
आपके जावा स्रोत कोड में निम्नलिखित चीजें हैं:
- कीवर्ड: की तरह
true
, false
, class
, while
, और इतने पर।
- शाब्दिक: की तरह
42
और 'X'
और "Hi mum!"
।
- ऑपरेटरों और अन्य गैर-शब्दसंख्यात्क टोकन: की तरह
+
, =
, {
, और इतने पर।
- पहचानकर्ता: की तरह
Reader
, i
, toString
, processEquibalancedElephants
, और इतने पर।
- टिप्पणियाँ और व्हॉट्सएप।
एक "प्रतीक नहीं मिल सकता है" त्रुटि पहचानकर्ताओं के बारे में है। जब आपका कोड संकलित किया जाता है, तो संकलक को यह जानने की आवश्यकता होती है कि आपके कोड में प्रत्येक पहचानकर्ता का क्या अर्थ है।
"प्रतीक नहीं मिल सकता है" त्रुटि का अर्थ है कि संकलक ऐसा नहीं कर सकता है। आपका कोड ऐसी चीज़ का जिक्र करता है जो संकलक को समझ में नहीं आती है।
2. "प्रतीक नहीं मिल सकता" त्रुटि का कारण क्या हो सकता है?
पहले आदेश के रूप में, केवल एक कारण है। संकलक उन सभी स्थानों पर देखा गया जहाँ पहचानकर्ता को परिभाषित किया जाना चाहिए, और यह परिभाषा नहीं पा सका। यह कई चीजों के कारण हो सकता है। आम इस प्रकार हैं:
- सामान्य तौर पर पहचानकर्ताओं के लिए:
- शायद आपने नाम गलत लिखा; के
StringBiulder
बजाय यानी StringBuilder
। जावा खराब वर्तनी या टाइपिंग त्रुटियों की भरपाई करने का प्रयास नहीं कर सकता है।
- शायद आपको मामला गलत लगा; के
stringBuilder
बजाय यानी StringBuilder
। सभी जावा पहचानकर्ता केस संवेदी हैं।
- शायद आपने अनुचित रूप से अंडरस्कोर का इस्तेमाल किया; यानी
mystring
और my_string
अलग हैं। (यदि आप जावा शैली के नियमों से चिपके रहते हैं, तो आप इस गलती से काफी हद तक सुरक्षित रहेंगे ...)
- शायद आप किसी ऐसी चीज़ का उपयोग करने की कोशिश कर रहे हैं जिसे "कहीं और" घोषित किया गया था; एक अलग संदर्भ में यानी जहाँ आपने संकलक को देखने के लिए कहा है। (एक अलग वर्ग? एक अलग गुंजाइश? एक अलग पैकेज? एक अलग कोड-आधार?)
- चर के लिए संदर्भित करने वाले पहचानकर्ताओं के लिए:
- शायद आप चर घोषित करना भूल गए।
- शायद चर घोषणा उस दायरे से बाहर है जिस बिंदु पर आपने इसका उपयोग करने की कोशिश की थी। (नीचे उदाहरण देखें)
पहचानकर्ताओं के लिए जो विधि या क्षेत्र के नाम होने चाहिए:
ऐसे पहचानकर्ताओं के लिए जिन्हें कक्षा के नाम होने चाहिए:
उन मामलों के लिए जहां प्रकार या उदाहरण में वह सदस्य नहीं है, जिसकी आप अपेक्षा कर रहे थे:
- शायद आपने एक नेस्टेड क्लास या एक जेनेरिक पैरामीटर घोषित किया है जो उस प्रकार को छाया देता है जिसका आप उपयोग करने के लिए अर्थ थे।
- शायद आप एक स्थिर या उदाहरण चर को छाया कर रहे हैं।
- शायद आपने गलत प्रकार का आयात किया; जैसे IDE पूरा होने या ऑटो करेक्शन के कारण।
- शायद आप एक एपीआई के गलत संस्करण का उपयोग (के खिलाफ संकलन) कर रहे हैं।
- शायद आप अपनी वस्तु को एक उपयुक्त उपवर्ग में डालना भूल गए।
समस्या अक्सर उपरोक्त का एक संयोजन है। उदाहरण के लिए, शायद आपने "स्टार" आयात किया java.io.*
और फिर Files
वर्ग का उपयोग करने की कोशिश की ... जो कि java.nio
नहीं है java.io
। या हो सकता है आप लिखते हैं करने के लिए होती File
है ... जो है में एक वर्ग java.io
।
यहाँ एक उदाहरण दिया गया है कि कैसे गलत परिवर्तनशील स्कोपिंग "प्रतीक नहीं ढूँढ सकता" त्रुटि का कारण बन सकती है:
List<String> strings = ...
for (int i = 0; i < strings.size(); i++) {
if (strings.get(i).equalsIgnoreCase("fnord")) {
break;
}
}
if (i < strings.size()) {
...
}
यह कथन i
में "प्रतीक नहीं ढूंढ सकता" त्रुटि देगा if
। हालांकि हमने पहले घोषित किया था i
, कि घोषणा केवल बयान और उसके शरीर के लिए गुंजाइशfor
है। बयान i
में संदर्भ उस घोषणा को नहीं देख सकता है । यह दायरे से बाहर है ।if
i
(यहां एक उपयुक्त सुधार if
लूप के अंदर स्टेटमेंट को स्थानांतरित करने या लूप i
की शुरुआत से पहले घोषित करने के लिए हो सकता है।)
यहां एक उदाहरण है जो पहेली का कारण बनता है जहां एक टाइपो एक प्रतीत होता है कि अक्षम्य "प्रतीक नहीं मिल सकता है" त्रुटि:
for (int i = 0; i < 100; i++); {
System.out.println("i is " + i);
}
यह आपको println
कॉल में एक संकलन त्रुटि देगा, जो i
यह नहीं कह सकता है। लेकिन (मैं तुम्हें सुनता हूँ) मैंने इसे घोषित किया था!
समस्या से पहले डरपोक अर्धविराम ( ;
) है {
। जावा भाषा का सिंटैक्स उस संदर्भ में एक अर्धविराम को परिभाषित करता है जो एक रिक्त कथन है । खाली बयान तो for
पाश का शरीर बन जाता है । तो यह कोड वास्तव में इसका मतलब है:
for (int i = 0; i < 100; i++);
// The previous and following are separate statements!!
{
System.out.println("i is " + i);
}
{ ... }
ब्लॉक के शरीर नहीं है for
पाश, और इसलिए की पिछली घोषणा i
में for
बयान है क्षेत्र से बाहर ब्लॉक में।
यहाँ "एक प्रतीक मिल सकता है" त्रुटि का एक और उदाहरण है जो टाइपो के कारण होता है।
int tmp = ...
int res = tmp(a + b);
पिछले घोषणा के बावजूद, tmp
में tmp(...)
अभिव्यक्ति गलत है। कंपाइलर नामक एक विधि के लिए दिखेगा tmp
, और एक नहीं मिलेगा। पहले घोषित किया गया tmp
है वैरिएबल के नामस्थान में, विधियों के लिए नाम स्थान नहीं।
उदाहरण में मैं भर आया था, प्रोग्रामर वास्तव में एक ऑपरेटर छोड़ दिया था। वह लिखने का मतलब यह था:
int res = tmp * (a + b);
यदि आप कमांड लाइन से संकलन कर रहे हैं तो कंपाइलर को प्रतीक नहीं मिल सकता है, इसका एक और कारण है। आप बस कुछ अन्य वर्ग को संकलित या पुन: स्थापित करने के लिए भूल गए होंगे। उदाहरण के लिए, यदि आपके पास कक्षाएं हैं Foo
और Bar
जहां Foo
उपयोग होता है Bar
। यदि आपने कभी संकलित नहीं किया है Bar
और आप चलते हैं javac Foo.java
, तो आप यह पता लगाने के लिए उत्तरदायी हैं कि संकलक प्रतीक नहीं ढूँढ सकता है Bar
। सरल उत्तर संकलन Foo
और Bar
एक साथ करना है; जैसे javac Foo.java Bar.java
या javac *.java
। या बेहतर अभी भी जावा बिल्ड टूल का उपयोग करें; जैसे चींटी, मावेन, गादले इत्यादि।
कुछ और अस्पष्ट कारण भी हैं ... जिनका मैं नीचे से सामना करूंगा।
3. मैं इन त्रुटियों को कैसे ठीक करूं?
आम तौर पर बोलते हुए, आप यह पता लगाते हैं कि संकलन त्रुटि का कारण क्या है ।
- संकलन त्रुटि संदेश द्वारा बताई गई फ़ाइल की लाइन को देखें।
- पहचानें कि कौन सा प्रतीक त्रुटि संदेश के बारे में बात कर रहा है।
- यह पता लगाएं कि संकलक यह क्यों कह रहा है कि वह प्रतीक नहीं ढूंढ सकता है; ऊपर देखो!
फिर आप सोचते हैं कि आपका कोड क्या कहने वाला है। फिर अंत में आप वर्कआउट करते हैं कि आपको अपने सोर्स कोड में क्या सुधार करना है जो आप चाहते हैं।
ध्यान दें कि हर "सुधार" सही नहीं है। इस पर विचार करो:
for (int i = 1; i < 10; i++) {
for (j = 1; j < 10; j++) {
...
}
}
मान लीजिए कि संकलक कहता है "के लिए प्रतीक नहीं मिल सकता है" j
। ऐसे कई तरीके हैं जिनसे मैं "ठीक" कर सकता हूं:
- मैं भीतर
for
को बदल सकता था for (int j = 1; j < 10; j++)
- शायद सही।
- मैं आंतरिक लूप, या बाहरी लूप
j
से पहले के लिए एक घोषणा जोड़ सकता हूं - संभवतः सही।for
for
- मैं बदल सकता है
j
के लिए i
भीतरी में for
पाश - शायद गलत!
- और इसी तरह।
मुद्दा यह है कि आपको यह समझने की आवश्यकता है कि आपका कोड सही फ़िक्स को खोजने के लिए क्या करने की कोशिश कर रहा है।
4. अस्पष्ट कारण
यहां कुछ ऐसे मामले हैं जहां "प्रतीक नहीं मिल सकता है" प्रतीत होता है कि जब तक आप करीब नहीं दिखते हैं, तब तक यह अक्षम्य है।
गलत निर्भरताएँ : यदि आप एक IDE या बिल्ड टूल का उपयोग कर रहे हैं जो बिल्ड पथ और प्रोजेक्ट निर्भरता का प्रबंधन करता है, तो आपने निर्भरताओं के साथ एक गलती की हो सकती है; जैसे एक निर्भरता छोड़ दिया, या गलत संस्करण का चयन किया। यदि आप बिल्ड टूल (चींटी, मेवेन, ग्रैडल आदि) का उपयोग कर रहे हैं, तो प्रोजेक्ट की बिल्ड फ़ाइल की जाँच करें। यदि आप एक आईडीई का उपयोग कर रहे हैं, तो प्रोजेक्ट के बिल्ड पथ कॉन्फ़िगरेशन की जांच करें।
आप recompiling नहीं कर रहे हैं : यह कभी-कभी होता है कि नए जावा प्रोग्रामर समझ नहीं पाते हैं कि जावा टूल चेन कैसे काम करता है, या एक दोहराने योग्य "बिल्ड प्रक्रिया" को लागू नहीं किया है; जैसे IDE, Ant, Maven, Gradle इत्यादि का उपयोग करना। ऐसी स्थिति में, प्रोग्रामर अपनी पूंछ का पीछा करते हुए एक भ्रामक त्रुटि की तलाश कर सकता है, जो वास्तव में कोड को ठीक से नहीं हटाने के कारण होता है, और जैसे ...
पहले की बिल्ड समस्या : यह संभव है कि पहले का निर्माण इस तरह से विफल रहा हो जिसने लापता कक्षाओं के साथ एक जार फाइल दी हो। यदि आप बिल्ड टूल का उपयोग कर रहे थे तो ऐसी विफलता आमतौर पर देखी जाएगी। हालाँकि, अगर आपको किसी और से JAR फाइलें मिल रही हैं, तो आप उन पर ठीक से निर्माण कर रहे हैं , और त्रुटियों को नोटिस कर रहे हैं। यदि आपको इस पर संदेह है, tar -tvf
तो संदिग्ध JAR फ़ाइल की सामग्री को सूचीबद्ध करने के लिए उपयोग करें।
आईडीई मुद्दे : लोगों ने ऐसे मामलों की सूचना दी है जहां उनका आईडीई भ्रमित हो जाता है और आईडीई में कंपाइलर एक ऐसी कक्षा नहीं पा सकता है जो मौजूद है ... या रिवर्स स्थिति।
ऐसा हो सकता है यदि IDE को गलत JDK संस्करण के साथ कॉन्फ़िगर किया गया हो।
ऐसा हो सकता है अगर आईडीई के कैश फ़ाइल सिस्टम के साथ सिंक से बाहर निकलते हैं। इसे ठीक करने के लिए आईडीई विशिष्ट तरीके हैं।
यह एक IDE बग हो सकता है। उदाहरण के लिए @ जोएल कोस्टिग्लियोला एक ऐसे परिदृश्य का वर्णन करता है जहां एक्लिप्स एक मावेन "परीक्षण" पेड़ को सही ढंग से नहीं संभालता है: इस उत्तर को देखें ।
Android समस्याएँ : जब आप एंड्रॉइड के लिए प्रोग्रामिंग कर रहे हों, और आपके पास "प्रतीक नहीं पा सकते" से संबंधित त्रुटियां हों R
, तो ध्यान रखें कि R
प्रतीक context.xml
फ़ाइल द्वारा परिभाषित किए गए हैं। जांचें कि आपकी context.xml
फ़ाइल सही है और सही जगह पर है, और यह कि संबंधित R
वर्ग फ़ाइल जनरेट / संकलित हो गई है। ध्यान दें कि जावा प्रतीक संवेदनशील हैं, इसलिए संबंधित XML आईडी भी संवेदनशील हैं।
एंड्रॉइड पर अन्य प्रतीक त्रुटियां पहले उल्लिखित कारणों के कारण होने की संभावना है; उदाहरण के लिए गुम या गलत निर्भरताएँ, गलत पैकेज नाम, विधि या फ़ील्ड जो किसी विशेष API संस्करण में मौजूद नहीं हैं, वर्तनी / टाइपिंग त्रुटियां, और इसी तरह।
सिस्टम कक्षाओं को फिर से परिभाषित करना : मैंने ऐसे मामले देखे हैं जहां कंपाइलर शिकायत करता substring
है कि निम्नलिखित की तरह कुछ में एक अज्ञात प्रतीक है
String s = ...
String s1 = s.substring(1);
यह पता चला कि प्रोग्रामर ने अपना स्वयं का संस्करण बनाया था String
और कक्षा के उनके संस्करण ने substring
तरीकों को परिभाषित नहीं किया था ।
पाठ: अपनी खुद की कक्षाओं को समान पुस्तकालय कक्षाओं के समान नामों से परिभाषित न करें!
Homoglyphs: यदि आप अपनी स्रोत फ़ाइलों के लिए UTF-8 एन्कोडिंग का उपयोग करते हैं, तो ऐसे पहचानकर्ता होना संभव है जो समान दिखते हों , लेकिन वास्तव में भिन्न होते हैं क्योंकि उनमें समरूपताएँ होती हैं। देखें इस पेज में अधिक जानकारी के लिए।
आप स्रोत फ़ाइल एन्कोडिंग के रूप में ASCII या लैटिन -1 में खुद को सीमित करके, और \uxxxx
अन्य पात्रों के लिए जावा एस्केप का उपयोग करके इससे बच सकते हैं।
1 - यदि, गड़बड़ी, आप इसे एक रनटाइम अपवाद या त्रुटि संदेश में देखते हैं, तो या तो आपने संकलन त्रुटियों के साथ कोड को चलाने के लिए अपना आईडीई कॉन्फ़िगर किया है, या आपका एप्लिकेशन रनटाइम पर कोड बना रहा है और संकलन कर रहा है।
2 - सिविल इंजीनियरिंग के तीन बुनियादी सिद्धांत: पानी ऊपर की ओर नहीं बहता है, एक तख्ती इसके किनारे पर मजबूत होती है, और आप एक तार पर धक्का नहीं दे सकते ।