“找不到符号”或“无法解析符号”错误是什么意思?0. 这些错误之间有什么区别吗?1. “找不到符号”错误是什么意思?2. 什么会导致“找不到符号”错误?3. 如何修复这些错误?4. 原因不明
请解释以下有关“找不到符号”、“无法解析符号”或“找不到符号”错误(在 Java 中)::
- 它们是什么意思?
- 什么事情会导致它们?
- 程序员如何修复它们?
这个问题旨在就Java中这些常见的编译错误进行全面的问答。
请解释以下有关“找不到符号”、“无法解析符号”或“找不到符号”错误(在 Java 中)::
这个问题旨在就Java中这些常见的编译错误进行全面的问答。
没有。“找不到符号”,“无法解析符号”和“找不到符号”都意味着同样的事情。(不同的Java编译器是由不同的人编写的,不同的人使用不同的短语来表达同样的事情。
首先,它是编译错误1。这意味着您的Java源代码中存在问题,或者您的编译方式存在问题。
您的 Java 源代码包含以下内容:
class
while
true
false
42
'X'
"Hi mum!"
+
=
{
Reader
i
toString
processEquibalancedElephants
“找不到符号”错误与标识符有关。编译代码时,编译器需要计算出代码中的每个标识符的含义。
“找不到符号”错误意味着编译器无法执行此操作。您的代码似乎引用了编译器不理解的内容。
作为第一顺序,只有一个原因。编译器查找了应定义标识符的所有位置,但找不到定义。这可能是由许多事情引起的。常见的有以下几种:
对于一般的标识符:
StringBiulder
StringBuilder
stringBuilder
StringBuilder
mystring
my_string
对于应引用变量的标识符:
对于应为方法或字段名称的标识符:
也许您正在尝试引用未在父/祖先类或接口中声明的继承方法或字段。
也许您正在尝试引用您正在使用的类型中不存在(即尚未声明)的方法或字段;例如 2."rope".push()
也许您正在尝试使用方法作为字段,反之亦然;例如: 或。"rope".length
someArray.length()
也许你错误地操作了数组而不是数组元素;例如:
String strings[] = ...
if (strings.charAt(3)) { ... }
// maybe that should be 'strings[0].charAt(3)'
对于应为类名的标识符:
也许您忘记导入该类。
也许您使用了“star”导入,但该类未在您导入的任何包中定义。
也许你忘了一个,如:new
String s = String(); // should be 'new String()'
对于类型或实例似乎没有您期望的成员(例如方法或字段)的情况:
java.awt.List
java.util.List
问题通常是上述因素的组合。例如,也许您“星形”导入,然后尝试使用该类...这不是 .或者也许你打算写...这是 中的一个类。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);
如果从命令行进行编译,则编译器可能无法找到符号还有另一个原因。您可能只是忘记编译或重新编译其他类。例如,如果您有类,并且其中使用 .如果你从来没有编译过,你运行过,你很容易发现编译器找不到符号。简单的答案是编译和组合;例如: 或。或者最好还是使用Java构建工具;例如蚂蚁,Maven,Gradle等。Foo
Bar
Foo
Bar
Bar
javac Foo.java
Bar
Foo
Bar
javac Foo.java Bar.java
javac *.java
还有其他一些更模糊的原因...我将在下面处理。
一般来说,您首先要找出导致编译错误的原因。
然后你想想你的代码应该说什么。最后,你弄清楚你需要对源代码进行哪些更正才能做你想做的事情。
请注意,并非每个“更正”都是正确的。请考虑以下情况:
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
关键是您需要了解代码尝试执行的操作才能找到正确的修复程序。
以下是“找不到符号”似乎莫名其妙的几个情况......直到你仔细观察。
不正确的依赖项:如果您使用的是管理构建路径和项目依赖项的IDE或构建工具,则可能是依赖项出错了。例如,省略了依赖项,或选择了错误的版本。如果您使用的是构建工具(Ant,Maven,Gradle等),请检查项目的构建文件。如果使用的是 IDE,请检查项目的生成路径配置。
找不到符号“var”:您可能正在尝试使用较旧的编译器或较旧的级别编译使用局部变量类型推断(即声明)的源代码。是在 Java 10 中引入的。检查 JDK 版本和生成文件,以及 IDE 设置(如果 IDE 中发生这种情况)。var
--source
var
你没有编译/重新编译:有时会发生新的Java程序员不了解Java工具链是如何工作的,或者没有实现可重复的“构建过程”;例如,使用IDE,Ant,Maven,Gradle等。在这种情况下,程序员最终可能会追逐他的尾巴,寻找一个虚幻的错误,这个错误实际上是由于没有正确重新编译代码等引起的。
另一个例子是当你使用(Java 9 +)编译和运行一个类时。如果该类依赖于您尚未编译(或重新编译)的另一个类,则可能会收到引用第二类的“无法解析符号”错误。其他源文件不会自动编译。该命令的新“编译并运行”模式不是为运行具有多个源代码文件的程序而设计的。java SomeClass.java
java
早期构建问题:早期构建可能以缺少类的 JAR 文件的方式失败。如果您使用的是构建工具,通常会注意到此类故障。但是,如果您从其他人那里获得JAR文件,则依赖于它们正确构建并注意到错误。如果您怀疑这一点,请使用 列出可疑 JAR 文件的内容。tar -tvf
IDE问题:人们报告了他们的IDE混乱并且IDE中的编译器找不到存在的类的情况...或相反的情况。
如果 IDE 配置了错误的 JDK 版本,则可能会发生这种情况。
如果 IDE 的缓存与文件系统不同步,则可能会发生这种情况。有一些IDE特定的方法来解决这个问题。
这可能是一个 IDE 错误。例如,@Joel Costigliola描述了一个Eclipse没有正确处理Maven“测试”树的场景:请参阅此答案。(显然,这个特定的错误很久以前就已经修复了。
Android 问题:当您为 Android 编程时,如果出现与 相关的“找不到符号”错误,请注意,符号是由文件定义的。检查您的文件是否正确且位于正确的位置,以及是否已生成/编译相应的类文件。请注意,Java 符号区分大小写,因此相应的 XML ID 也区分大小写。R
R
context.xml
context.xml
R
Android上的其他符号错误可能是由于前面提到的原因;例如,缺少或不正确的依赖项,不正确的包名称,方法或特定API版本中不存在的字段,拼写/键入错误等。
隐藏系统类:我见过编译器抱怨这是一个未知符号的情况,如下所示substring
String s = ...
String s1 = s.substring(1);
事实证明,程序员已经创建了自己的版本,并且他的类版本没有定义方法。我见过人们在 和其他类中这样做。String
substring
System
Scanner
课:不要使用与公共库类相同的名称定义自己的类!
该问题也可以通过使用完全限定的名称来解决。例如,在上面的示例中,程序员可以编写:
java.lang.String s = ...
java.lang.String s1 = s.substring(1);
同形异体:如果对源文件使用 UTF-8 编码,则标识符可能看起来相同,但实际上不同,因为它们包含同形异形。有关详细信息,请参阅此页面。
您可以通过将自己限制为 ASCII 或 Latin-1 作为源文件编码,并对其他字符使用 Java 转义来避免这种情况。\uxxxx
1 - 如果确实在运行时异常或错误消息中看到此情况,则表示您已将 IDE 配置为运行包含编译错误的代码,或者应用程序正在生成和编译代码。在运行时。
2 - 土木工程的三个基本原则:水不会上坡,木板的侧面更坚固,你不能推绳子。
如果您忘记了:new
String s = String();
对
String s = new String();
因为没有关键字的调用将尝试查找不带参数的(本地)方法 - 并且该方法签名可能未定义。new
String