请解释以下有关“无法找到符号”、“无法解析符号”或“未找到符号”错误(在 Java 中):它们是什么意思?什么原因会导致它们……
请解释以下有关“无法找到符号”、“无法解析符号”或“未找到符号”错误(在 Java 中):
这个问题旨在对 Java 中这些常见的编译错误进行全面的问答。
并非如此。\'无法找到符号\'、\'无法解析符号\' 和 \'未找到符号\' 都表示相同的意思。(不同的 Java 编译器由不同的人编写,不同的人使用不同的措辞来表达相同的意思。)
首先,这是一个 编译错误 1。这意味着 存在 问题, 或者 您的编译方式存在问题。
您的 Java 源代码由以下内容组成:
class
, while
,等等。
true
, false
, 42
, 'X'
和 "Hi mum!"
.
+
, =
, {
, 等等。
Reader
, i
, toString
, processEquibalancedElephants
,等等。
“无法找到符号”错误与标识符有关。编译代码时,编译器需要找出代码中每个标识符的含义。
“无法找到符号”错误意味着编译器无法执行此操作。您的代码似乎引用了编译器无法理解的内容。
首先,只有一个原因。编译器查找了所有 应该 定义标识符的位置,但找不到定义。这可能是由多种原因造成的。常见的原因如下:
p6
StringBiulder
instead of StringBuilder
. Java cannot and will not attempt to compensate for bad spelling or typing errors. stringBuilder
instead of StringBuilder
. All Java identifiers are case sensitive. mystring
and my_string
are different. (If you stick to the Java style rules, you will be largely protected from this mistake...) p7
p8
【【p9】】
【【p10】】
【【p11】】
【【p12】】
String strings[] = ... if (strings.charAt(3)) { ... } // Maybe that should be 'strings[0].charAt(3)'
p13
【【p14】】
【【p15】】
【【p16】】
String s = String(); // Should be 'new String()'
【【p17】】
【【p18】】
第19页
java.awt.List
rather than java.util.List
.
问题通常是上述情况的组合。例如,也许你导入了 \'star\' 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 等。
还有一些其他更不为人知的原因……我将在下面讨论。
一般来说,您首先要弄清楚 导致 编译错误的原因。
然后你 思考 你的代码应该表达什么。最后你弄清楚需要对源代码做哪些修正才能达到你想要的效果。
请注意,并非每个“更正”都是正确的。考虑一下:
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
——可能是错的!
关键在于您 需要 了解您的代码正在做什么,以便找到正确的修复方法。
以下几种情况中,“无法找到符号”似乎令人费解……直到你仔细观察。
p39
p40
p41
p42
p43
p44
【【p45】】
【【p46】】
【【p47】】
p48
p49
p50
String s = ...String s1 = s.substring(1);
p51
p52
p53
java.lang.String s = ...java.lang.String s1 = s.substring(1);
p54
p55
1 - If, perchance, you do see this in a runtime exception or error message, then either you have configured your IDE to run code with compilation errors, or your application is generating and compiling code .. at runtime.
2 - The three basic principles of 土木工程 : water doesn't flow uphill, a plank is stronger on its side, and you can't push on a rope .