ข้อผิดพลาด“ ไม่พบสัญลักษณ์” หรือ“ ไม่สามารถแก้ไขสัญลักษณ์” หมายความว่าอย่างไร
โปรดอธิบายต่อไปนี้เกี่ยวกับข้อผิดพลาด "ไม่พบสัญลักษณ์", "ไม่สามารถแก้ไขสัญลักษณ์" หรือ "ไม่พบสัญลักษณ์":
- พวกเขาหมายถึงอะไร?
- สิ่งใดที่สามารถทำให้เกิดพวกเขา?
- โปรแกรมเมอร์จะแก้ไขอย่างไร
คำถามนี้ออกแบบมาเพื่อสร้างคำถามและคำตอบที่ครอบคลุมเกี่ยวกับข้อผิดพลาดในการคอมไพล์ทั่วไปใน Java
คำตอบ
0. ข้อผิดพลาดทั้งสองมีความแตกต่างกันหรือไม่?
ไม่จริง. "ไม่พบสัญลักษณ์", "ไม่สามารถแก้ไขสัญลักษณ์" และ "ไม่พบสัญลักษณ์" ทั้งหมดหมายถึงสิ่งเดียวกัน คอมไพเลอร์ Java ที่แตกต่างกันใช้วลีที่แตกต่างกัน
1. ข้อผิดพลาด "ไม่พบสัญลักษณ์" หมายถึงอะไร?
ประการแรกก็คือการรวบรวมข้อผิดพลาด 1 ก็หมายความว่าทั้งสองมีปัญหาในโค้ด Java ของคุณหรือมีปัญหาในทางที่คุณกำลังรวบรวมมัน
ซอร์สโค้ด Java ของคุณประกอบด้วยสิ่งต่อไปนี้:
- คำสำคัญ: เช่น
true
,false
,class
,while
และอื่น ๆ - ตัวอักษร: like
42
and'X'
and"Hi mum!"
. - ผู้ประกอบการและราชสกุลไม่ใช่ตัวเลขอื่น ๆ เช่น
+
,=
,{
และอื่น ๆ - ตัวบ่งชี้: เช่น
Reader
,i
,toString
,processEquibalancedElephants
และอื่น ๆ - ความคิดเห็นและช่องว่าง
ข้อผิดพลาด "ไม่พบสัญลักษณ์" เป็นเรื่องเกี่ยวกับตัวระบุ เมื่อคอมไพล์โค้ดของคุณคอมไพลเลอร์จะต้องค้นหาว่าตัวระบุแต่ละตัวในโค้ดของคุณหมายถึงอะไร
ข้อผิดพลาด "ไม่พบสัญลักษณ์" หมายความว่าคอมไพเลอร์ไม่สามารถดำเนินการนี้ได้ ดูเหมือนโค้ดของคุณจะอ้างถึงสิ่งที่คอมไพเลอร์ไม่เข้าใจ
2. อะไรทำให้เกิดข้อผิดพลาด "ไม่พบสัญลักษณ์"
เป็นลำดับแรกมีเพียงสาเหตุเดียว คอมไพเลอร์ตรวจสอบในทุกตำแหน่งที่ควรกำหนดตัวระบุและไม่พบคำจำกัดความ ซึ่งอาจเกิดจากหลายสิ่ง คนทั่วไปมีดังนี้:
สำหรับตัวระบุโดยทั่วไป:
- บางทีคุณอาจสะกดชื่อไม่ถูกต้อง คือ
StringBiulder
แทนStringBuilder
. Java ไม่สามารถและจะไม่พยายามชดเชยการสะกดผิดหรือการพิมพ์ผิดพลาด - บางทีคุณอาจเข้าใจผิด คือ
stringBuilder
แทนStringBuilder
. ตัวระบุ Java ทั้งหมดคำนึงถึงขนาดตัวพิมพ์ - บางทีคุณอาจใช้เครื่องหมายขีดล่างอย่างไม่เหมาะสม กล่าวคือ
mystring
และmy_string
แตกต่างกัน (หากคุณยึดติดกับกฎสไตล์ Java คุณจะได้รับการปกป้องอย่างมากจากความผิดพลาดนี้ ... ) - บางทีคุณอาจพยายามใช้สิ่งที่ประกาศว่า "ที่อื่น" กล่าวคือในบริบทที่แตกต่างกับที่คุณบอกโดยปริยายให้คอมไพเลอร์ดู (คลาสที่แตกต่างกันขอบเขตที่แตกต่างกันแพ็คเกจที่แตกต่างกันรหัสฐานที่แตกต่างกัน)
- บางทีคุณอาจสะกดชื่อไม่ถูกต้อง คือ
สำหรับตัวระบุที่ควรอ้างถึงตัวแปร:
- บางทีคุณอาจลืมประกาศตัวแปร
- บางทีการประกาศตัวแปรจะอยู่นอกขอบเขต ณ จุดที่คุณพยายามใช้ (ดูตัวอย่างด้านล่าง)
สำหรับตัวระบุที่ควรเป็นเมธอดหรือชื่อฟิลด์:
บางทีคุณอาจกำลังพยายามอ้างถึงวิธีการหรือฟิลด์ที่สืบทอดมาซึ่งไม่ได้ประกาศไว้ในคลาสหรืออินเทอร์เฟซของพาเรนต์ / บรรพบุรุษ
บางทีคุณอาจพยายามอ้างถึงวิธีการหรือเขตข้อมูลที่ไม่มีอยู่ (เช่นยังไม่ได้รับการประกาศ) ในประเภทที่คุณใช้ เช่น
"someString".push()
2 .บางทีคุณอาจพยายามใช้วิธีการเป็นเขตข้อมูลหรือในทางกลับกัน เช่น
"someString".length
หรือsomeArray.length()
.บางทีคุณอาจทำงานผิดพลาดในอาร์เรย์มากกว่าองค์ประกอบอาร์เรย์ เช่น
String strings[] = ... if (strings.charAt(3)) { ... } // maybe that should be 'strings[0].charAt(3)'
สำหรับตัวระบุที่ควรเป็นชื่อคลาส:
บางทีคุณอาจลืมนำเข้าชั้นเรียน
บางทีคุณอาจใช้การนำเข้า "ติดดาว" แต่คลาสไม่ได้กำหนดไว้ในแพ็กเกจใด ๆ ที่คุณนำเข้า
บางทีคุณอาจลืม
new
ใน:String s = String(); // should be 'new String()'
สำหรับกรณีที่ประเภทหรืออินสแตนซ์ไม่ปรากฏว่ามีสมาชิกที่คุณคาดหวังให้มี:
- บางทีคุณอาจจะมีการประกาศให้เป็นชั้นซ้อนกันหรือพารามิเตอร์ทั่วไปที่เงาชนิดที่คุณหมายถึงการใช้
- บางทีคุณอาจกำลังเงาตัวแปรแบบคงที่หรืออินสแตนซ์
- บางทีคุณอาจนำเข้าผิดประเภท เช่นเนื่องจาก IDE เสร็จสมบูรณ์หรือแก้ไขอัตโนมัติ
- บางทีคุณอาจใช้ (คอมไพล์เทียบกับ) เวอร์ชันที่ไม่ถูกต้องของ API
- บางทีคุณอาจลืมโยนวัตถุของคุณไปยังคลาสย่อยที่เหมาะสม
ปัญหามักเกิดจากการผสมผสานข้างต้น ยกตัวอย่างเช่นบางทีคุณ "ดาว" ที่นำเข้ามา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
ไม่พบ แต่ (ฉันได้ยินคุณพูด) ฉันประกาศแล้ว!
ปัญหาคือเครื่องหมายอัฒภาค ( ;
) ลับๆก่อนหน้าไฟล์{
. ไวยากรณ์ภาษา Java กำหนดอัฒภาคในบริบทที่จะเป็นคำสั่งที่ว่างเปล่า คำสั่งว่างจะกลายเป็นเนื้อความของ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
. หรือดีกว่ายังคงใช้เครื่องมือสร้าง Java เช่น Ant, Maven, Gradle เป็นต้น
มีสาเหตุที่คลุมเครืออื่น ๆ เช่นกัน ... ซึ่งฉันจะจัดการกับด้านล่าง
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 หรือเครื่องมือสร้างที่จัดการเส้นทางการสร้างและการอ้างอิงโครงการคุณอาจทำผิดพลาดกับการอ้างอิง เช่นละทิ้งการพึ่งพาหรือเลือกเวอร์ชันผิด หากคุณใช้เครื่องมือสร้าง (Ant, Maven, Gradle ฯลฯ ) ให้ตรวจสอบไฟล์สร้างของโครงการ หากคุณใช้ IDE ให้ตรวจสอบคอนฟิกูเรชันบิลด์พา ธ ของโปรเจ็กต์
คุณไม่ได้ทำการคอมไพล์ใหม่ : บางครั้งอาจเกิดขึ้นที่โปรแกรมเมอร์ Java ใหม่ไม่เข้าใจวิธีการทำงานของห่วงโซ่เครื่องมือ Java หรือไม่ได้ใช้ "กระบวนการสร้าง" ที่ทำซ้ำได้ เช่นการใช้ IDE, Ant, Maven, Gradle เป็นต้น ในสถานการณ์เช่นโปรแกรมเมอร์ที่สามารถจบลงไล่หางของเขามองหาข้อผิดพลาดที่ไม่จริงที่เป็นจริงที่เกิดจากการไม่ recompiling รหัสได้อย่างถูกต้องและไม่ชอบ ...
ปัญหาการสร้างก่อนหน้านี้ : เป็นไปได้ว่าการสร้างก่อนหน้านี้ล้มเหลวในลักษณะที่ให้ไฟล์ JAR ที่ไม่มีคลาส โดยทั่วไปความล้มเหลวดังกล่าวจะสังเกตเห็นได้หากคุณใช้เครื่องมือสร้าง อย่างไรก็ตามหากคุณได้รับไฟล์ JAR จากคนอื่นคุณจะต้องพึ่งพาไฟล์เหล่านั้นในการสร้างอย่างถูกต้องและสังเกตเห็นข้อผิดพลาด หากคุณสงสัยสิ่งนี้ให้ใช้
tar -tvf
เพื่อแสดงรายการเนื้อหาของไฟล์ JAR ที่ต้องสงสัยปัญหา IDE : ผู้คนรายงานกรณีที่ IDE ของพวกเขาสับสนและคอมไพเลอร์ใน IDE ไม่พบคลาสที่มีอยู่ ... หรือสถานการณ์ย้อนกลับ
กรณีนี้อาจเกิดขึ้นได้หากกำหนดค่า IDE ด้วยเวอร์ชัน JDK ที่ไม่ถูกต้อง
สิ่งนี้อาจเกิดขึ้นได้หากแคชของ IDE ไม่ซิงค์กับระบบไฟล์ มีวิธีเฉพาะของ IDE ในการแก้ไขปัญหานั้น
นี่อาจเป็นข้อบกพร่องของ IDE ตัวอย่างเช่น @Joel Costigliola อธิบายสถานการณ์ที่ Eclipse ไม่จัดการกับ Maven "test" tree อย่างถูกต้อง: ดูคำตอบนี้
ประเด็น Android : เมื่อคุณเขียนโปรแกรมสำหรับ Android และคุณมี "ไม่สามารถหาสัญลักษณ์" ข้อผิดพลาดที่เกี่ยวข้องกับการ
R
จะทราบว่าR
สัญลักษณ์ถูกกำหนดโดยcontext.xml
ไฟล์ ตรวจสอบว่าcontext.xml
ไฟล์ของคุณถูกต้องและอยู่ในตำแหน่งที่ถูกต้องและR
มีการสร้าง / รวบรวมไฟล์คลาสที่เกี่ยวข้อง โปรดทราบว่าสัญลักษณ์ Java นั้นคำนึงถึงตัวพิมพ์เล็กและใหญ่ดังนั้นรหัส XML ที่เกี่ยวข้องจึงต้องคำนึงถึงขนาดตัวพิมพ์ด้วยข้อผิดพลาดของสัญลักษณ์อื่น ๆ บน Android น่าจะมาจากสาเหตุที่กล่าวไว้ก่อนหน้านี้ เช่นการอ้างอิงที่ขาดหายไปหรือไม่ถูกต้องชื่อแพ็กเกจที่ไม่ถูกต้องวิธีการหรือฟิลด์ที่ไม่มีอยู่ในเวอร์ชัน API เฉพาะข้อผิดพลาดในการสะกด / การพิมพ์เป็นต้น
การกำหนดคลาสระบบใหม่ : ฉันเคยเห็นกรณีที่คอมไพเลอร์บ่นว่า
substring
เป็นสัญลักษณ์ที่ไม่รู้จักในสิ่งต่อไปนี้String s = ... String s1 = s.substring(1);
ปรากฎว่าโปรแกรมเมอร์ได้สร้างเวอร์ชันของตัวเอง
String
และเวอร์ชันของคลาสของเขาไม่ได้กำหนดsubstring
วิธีการบทเรียน: อย่ากำหนดชั้นเรียนของคุณเองด้วยชื่อเดียวกับคลาสห้องสมุดทั่วไป!
Homoglyphs: หากคุณใช้การเข้ารหัส UTF-8 สำหรับไฟล์ต้นฉบับของคุณเป็นไปได้ที่จะมีตัวระบุที่มีลักษณะเหมือนกัน แต่ในความเป็นจริงแล้วแตกต่างกันเนื่องจากมี homoglyphs ดูหน้านี้สำหรับข้อมูลเพิ่มเติม
คุณสามารถหลีกเลี่ยงสิ่งนี้ได้โดย จำกัด ตัวเองเป็น ASCII หรือ Latin-1 เป็นการเข้ารหัสไฟล์ต้นฉบับและใช้ Java
\uxxxx
Escape สำหรับอักขระอื่น ๆ
1 - ถ้าบางทีคุณไม่เห็นนี้ในข้อยกเว้นรันไทม์หรือข้อผิดพลาดแล้วทั้งคุณได้กำหนดค่า IDE ของคุณเพื่อเรียกใช้รหัสมีข้อผิดพลาดการรวบรวมหรือใบสมัครของคุณคือการสร้างและรวบรวมรหัส .. ที่รันไทม์
2 - หลักการพื้นฐานสามประการของวิศวกรรมโยธา: น้ำไม่ไหลขึ้นเนินไม้กระดานจะแข็งแรงกว่าที่ด้านข้างและคุณไม่สามารถดันเชือกได้
คุณจะได้รับข้อผิดพลาดนี้หากคุณลืมnew
:
String s = String();
เทียบกับ
String s = new String();
เนื่องจากการเรียกที่ไม่มีnew
คีย์เวิร์ดจะพยายามและมองหาเมธอด (ในระบบ) ที่เรียกString
โดยไม่มีอาร์กิวเมนต์ - และลายเซ็นของเมธอดนั้นไม่ได้กำหนดไว้
อีกหนึ่งตัวอย่างของ 'ตัวแปรอยู่นอกขอบเขต'
อย่างที่ฉันเคยเห็นคำถามแบบนั้นมาสองสามครั้งแล้วอาจจะเป็นอีกตัวอย่างหนึ่งของสิ่งที่ผิดกฎหมายแม้ว่ามันจะรู้สึกโอเคก็ตาม
พิจารณารหัสนี้:
if(somethingIsTrue()) {
String message = "Everything is fine";
} else {
String message = "We have an error";
}
System.out.println(message);
รหัสไม่ถูกต้อง เนื่องจากตัวแปรที่ตั้งชื่อmessage
ไม่สามารถมองเห็นได้นอกขอบเขตตามลำดับซึ่งจะเป็นวงเล็บโดยรอบ{}
ในกรณีนี้
คุณอาจพูดว่า: "แต่มีการกำหนดตัวแปรชื่อข้อความไม่ว่าจะด้วยวิธีใดก็ตามดังนั้นข้อความจึงถูกกำหนดไว้หลังif
"
แต่คุณคิดผิด
Java ไม่มีfree()
หรือdelete
ตัวดำเนินการดังนั้นจึงต้องพึ่งพาขอบเขตตัวแปรการติดตามเพื่อค้นหาว่าเมื่อใดที่ไม่ได้ใช้ตัวแปรอีกต่อไป (พร้อมกับการอ้างอิงถึงตัวแปรสาเหตุเหล่านี้)
โดยเฉพาะอย่างยิ่งถ้าคุณคิดว่าคุณได้ทำสิ่งที่ดี ฉันเห็นข้อผิดพลาดประเภทนี้หลังจากโค้ด "เพิ่มประสิทธิภาพ" ดังนี้:
if(somethingIsTrue()) {
String message = "Everything is fine";
System.out.println(message);
} else {
String message = "We have an error";
System.out.println(message);
}
"โอ้มีรหัสที่ซ้ำกันลองดึงบรรทัดร่วมนั้นออกมา" -> และตรงนั้น
วิธีที่ใช้บ่อยที่สุดในการจัดการกับปัญหาขอบเขตประเภทนี้คือการกำหนดค่าอื่นล่วงหน้าให้กับชื่อตัวแปรในขอบเขตภายนอกจากนั้นกำหนดใหม่ใน if:
String message = "We have an error";
if(somethingIsTrue()) {
message = "Everything is fine";
}
System.out.println(message);
วิธีหนึ่งในการรับข้อผิดพลาดนี้ใน Eclipse:
- กำหนดคลาส
A
ในsrc/test/java
. - กำหนดอีกชั้น
B
ในที่ใช้ในชั้นเรียนsrc/main/java
A
ผลลัพธ์: Eclipse จะคอมไพล์โค้ด แต่ maven จะให้ "ไม่พบสัญลักษณ์"
สาเหตุที่สำคัญ: Eclipse ใช้พา ธ การสร้างแบบรวมสำหรับต้นไม้หลักและทดสอบ น่าเสียดายที่ไม่สนับสนุนการใช้เส้นทางการสร้างที่แตกต่างกันสำหรับส่วนต่างๆของโครงการ Eclipse ซึ่งเป็นสิ่งที่ Maven ต้องการ
วิธีการแก้ :
- อย่ากำหนดการอ้างอิงของคุณด้วยวิธีนั้น คืออย่าทำผิดพลาดนี้
- สร้าง codebase ของคุณโดยใช้ Maven เป็นประจำเพื่อที่คุณจะได้รับข้อผิดพลาดนี้ แต่เนิ่นๆ วิธีหนึ่งที่ทำได้คือใช้เซิร์ฟเวอร์ CI
"ไม่พบ" หมายความว่าคอมไพเลอร์ที่ไม่พบตัวแปรที่เหมาะสมวิธีการคลาส ฯลฯ ... หากคุณได้รับการนวดผิดพลาดก่อนอื่นคุณต้องค้นหาโค้ดไลน์ที่ได้รับการนวดผิดพลาด .. แล้วคุณจะ สามารถค้นหาตัวแปรวิธีการหรือคลาสที่ยังไม่ได้กำหนดก่อนที่จะใช้หลังจากการยืนยันเริ่มต้นตัวแปรแล้ววิธีการหรือคลาสสามารถใช้เพื่อต้องการในภายหลัง ... พิจารณาตัวอย่างต่อไปนี้
ฉันจะสร้างคลาสสาธิตและพิมพ์ชื่อ ...
class demo{
public static void main(String a[]){
System.out.print(name);
}
}
ตอนนี้ดูผล ..
ข้อผิดพลาดนั้นระบุว่า "ไม่พบชื่อตัวแปร" .. การกำหนดและกำหนดค่าเริ่มต้นสำหรับตัวแปร "ชื่อ" สามารถยกเลิกข้อผิดพลาดนั้นได้ .. ที่จริงเป็นเช่นนี้
class demo{
public static void main(String a[]){
String name="smith";
System.out.print(name);
}
}
ตอนนี้ดูผลลัพธ์ใหม่ ...
ตกลงแก้ไขข้อผิดพลาดนั้นสำเร็จแล้ว .. ในขณะเดียวกันหากคุณได้รับ "ไม่พบวิธีการ" หรือ "ไม่พบคลาส" บางสิ่งในตอนแรกให้กำหนดคลาสหรือวิธีการและหลังจากใช้งานแล้ว ..
หากคุณได้รับข้อผิดพลาดนี้ในบิลด์ที่อื่นในขณะที่ IDE ของคุณบอกว่าทุกอย่างเรียบร้อยดีให้ตรวจสอบว่าคุณใช้ Java เวอร์ชันเดียวกันในทั้งสองที่
ตัวอย่างเช่น Java 7 และ Java 8 มี API ที่แตกต่างกันดังนั้นการเรียก API ที่ไม่มีอยู่จริงใน Java เวอร์ชันเก่าจะทำให้เกิดข้อผิดพลาดนี้
แก้ไขแล้ว
ใช้ IntelliJ
เลือกสร้าง -> สร้างโครงการใหม่จะแก้ปัญหาได้
ฉันก็ได้รับข้อผิดพลาดนี้เช่นกัน (ซึ่งฉัน googled และถูกนำไปที่หน้านี้)
ปัญหา:ฉันกำลังเรียกใช้วิธีการแบบคงที่ที่กำหนดในคลาสของโครงการ A จากคลาสที่กำหนดไว้ในโครงการอื่น B ฉันได้รับข้อผิดพลาดต่อไปนี้:
error: cannot find symbol
วิธีแก้ไข:ฉันแก้ไขสิ่งนี้โดยการสร้างโปรเจ็กต์ก่อนโดยที่เมธอดถูกกำหนดจากนั้นโปรเจ็กต์ที่เมธอดถูกเรียกใช้
หาก eclipse Java build path ถูกแมปกับ 7, 8 และใน Project pom.xml Maven properties java.version ถูกกล่าวถึงเวอร์ชัน Java ที่สูงกว่า (9,10,11 ฯลฯ .. ,) มากกว่า 7,8 คุณต้องอัพเดตใน pom xml ไฟล์
ใน Eclipse หากแมป Java กับ Java เวอร์ชัน 11 และใน pom.xml จะแมปกับ Java เวอร์ชัน 8 อัปเดตการสนับสนุน Eclipse เป็น Java 11 โดยทำตามขั้นตอนด้านล่างใน eclipse IDE Help -> ติดตั้งซอฟต์แวร์ใหม่ ->
วางลิงค์ต่อไปนี้http://download.eclipse.org/eclipse/updates/4.9-P-builds at Work With
หรือ
เพิ่ม (หน้าต่างป๊อปอัปจะเปิดขึ้น) ->
Name:
รองรับ Java 11
Location:
http://download.eclipse.org/eclipse/updates/4.9-P-builds
จากนั้นอัปเดตเวอร์ชัน Java ในคุณสมบัติ Maven ของไฟล์pom.xmlดังต่อไปนี้
<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
สุดท้ายให้คลิกขวาที่ Project Debug as -> Maven clean, Maven build steps
อาจมีสถานการณ์ต่างๆตามที่ผู้คนได้กล่าวไว้ข้างต้น สองสิ่งที่ช่วยฉันแก้ไขปัญหานี้ได้
หากคุณใช้ IntelliJ
File -> 'Invalidate Caches/Restart'
หรือ
คลาสที่อ้างถึงอยู่ในโปรเจ็กต์อื่นและการอ้างอิงนั้นไม่ได้ถูกเพิ่มลงในไฟล์บิวด์ Gradle ของโปรเจ็กต์ของฉัน ดังนั้นฉันจึงเพิ่มการพึ่งพาโดยใช้
compile project(':anotherProject')
และมันได้ผล เฮ้!
คุณคอมไพล์โค้ดของคุณโดยใช้ maven compile แล้วใช้ maven test เพื่อเรียกใช้งานได้ดี ตอนนี้ถ้าคุณเปลี่ยนบางอย่างในโค้ดของคุณแล้วโดยไม่คอมไพล์คุณกำลังเรียกใช้งานคุณจะได้รับข้อผิดพลาดนี้
วิธีแก้ไข: รวบรวมอีกครั้งจากนั้นเรียกใช้การทดสอบ สำหรับฉันมันทำงานในลักษณะนี้
ในกรณีของฉัน - ฉันต้องดำเนินการด้านล่าง:
- ย้าย
context.xml
ไฟล์จากsrc/java/package
ไปยังresource
ไดเร็กทอรี (IntelliJ IDE) - ล้าง
target
ไดเรกทอรี
สำหรับคำแนะนำให้ดูที่ชื่อคลาสที่แสดงข้อผิดพลาดและหมายเลขบรรทัดตัวอย่างเช่นคอมไพล์ล้มเหลว [ERROR] \ applications \ xxxxx.java: [44,30] error: ไม่พบสัญลักษณ์
อีกสาเหตุหนึ่งคือวิธีที่ไม่รองรับสำหรับเวอร์ชัน java พูดว่า jdk7 vs 8 ตรวจสอบ% JAVA_HOME% ของคุณ
เราพบข้อผิดพลาดในโปรเจ็กต์ Java ที่ตั้งค่าเป็น Gradle multi-project build มันกลับกลายเป็นว่าหนึ่งในโครงการย่อยได้ที่ขาดหายไปปลั๊กอิน Gradle Java ห้องสมุด ซึ่งป้องกันไม่ให้ไฟล์คลาสของโปรเจ็กต์ย่อยมองเห็นโปรเจ็กต์อื่นในบิลด์
หลังจากเพิ่มปลั๊กอินไลบรารี Java ไปยังโปรเจ็กต์ย่อยbuild.gradle
ด้วยวิธีต่อไปนี้ข้อผิดพลาดก็หายไป:
plugins {
...
id 'java-library'
}
ฉันแก้ไขข้อผิดพลาดแบบนี้ ... ความบ้าคลั่งของ android ฉันมีชื่อแพ็คเกจเป็นอะแดปเตอร์และฉันเปลี่ยนชื่อเป็นอะแดปเตอร์ด้วย "a" แทน "A" และแก้ไขข้อผิดพลาด