java“找不到符号”或“无法解析符号”错误是什么意思?

jmo0nnb3  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(486)

请解释以下关于“找不到符号”、“无法解析符号”或“找不到符号”的错误(java):
它们是什么意思?
什么事情会导致它们?
程序员如何着手修复它们?
这个问题旨在引发关于java中这些常见编译错误的全面问答。

gcxthw6b

gcxthw6b1#

0.这两个错误之间有什么区别吗?

不完全是。”“找不到符号”、“无法解析符号”和“找不到符号”的含义相同。不同的java编译器使用不同的术语。

1.“找不到符号”错误是什么意思?

首先,这是一个编译错误1。这意味着要么java源代码中存在问题,要么编译它的方式存在问题。
java源代码由以下内容组成:
关键词:喜欢 true , false , class , while 等等
文字:like 42'X'"Hi mum!" .
运算符和其他非字母数字标记:如 + , = , { 等等
标识符:像 Reader , i , toString , processEquibalancedElephants 等等
注解和空白。
“找不到符号”错误与标识符有关。编译代码时,编译器需要计算出代码中每个标识符的含义。
“找不到符号”错误表示编译器无法执行此操作。您的代码似乎引用了编译器不理解的内容。

2.什么会导致“找不到符号”错误?

首先,原因只有一个。编译器查找了应该定义标识符的所有位置,但找不到定义。这可能是由许多因素造成的。常见的有:
对于一般标识符:
也许你拼错了名字;即 StringBiulder 而不是 StringBuilder . java不能也不会试图弥补拼写错误或键入错误。
也许你错了;即 stringBuilder 而不是 StringBuilder . 所有java标识符都区分大小写。
也许你不恰当地使用了下划线;即 mystringmy_string 它们是不同的(如果您坚持java风格的规则,您将在很大程度上避免这个错误……)
也许你正在尝试使用一些声明为“其他地方”的东西;i、 e.在不同的上下文中,隐式地告诉编译器查看(不同的班级?不同的范围?另一个包裹?不同的代码库?)
对于应引用变量的标识符:
也许您忘记声明变量了。
可能变量声明在您尝试使用它时超出了范围(参见下面的示例)
对于应为方法或字段名的标识符:
可能您正试图引用未在父/祖先类或接口中声明的继承方法或字段。
可能您试图引用的方法或字段在您使用的类型中不存在(即尚未声明);例如 "someString".push() 2.
也许您正试图将一个方法用作字段,反之亦然;例如 "someString".lengthsomeArray.length() .
可能您错误地操作了数组而不是数组元素;例如

String strings[] = ...
    if (strings.charAt(3)) { ... }
    // maybe that should be 'strings[0].charAt(3)'

对于应为类名的标识符:
也许你忘了导入这个类。
也许您使用了“星型”导入,但是在您导入的任何包中都没有定义该类。
也许你忘了一个 new 例如:

String s = String();  // should be 'new String()'

对于类型或示例似乎没有您期望的成员的情况:
可能您已经声明了一个嵌套类或泛型参数,该类或泛型参数隐藏了您想要使用的类型。
也许您正在隐藏一个静态或示例变量。
也许您输入了错误的类型;e、 g.由于ide完成或自动更正。
也许您正在使用(针对)错误版本的api。
也许您忘了将对象强制转换为适当的子类。
问题往往是上述因素的组合。例如,也许你是“明星”进口的 java.io.* 然后尝试使用 Files 类。。。哪个在 java.niojava.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()) {
    ...
}

这将导致“找不到符号”错误 iif 陈述虽然我们之前声明 i ,该声明仅适用于 for 声明及其正文。提及 iif 语句无法看到该声明 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 循环,因此前面的声明 ifor 语句超出了块中的范围。
这里是另一个由打字错误导致的“找不到符号”错误示例。

int tmp = ...
int res = tmp(a + b);

尽管有先前的声明,但是 tmptmp(...) 表达是错误的。编译器将查找一个名为 tmp ,但找不到。先前宣布的 tmp 位于变量的命名空间中,而不是方法的命名空间中。
在我遇到的例子中,程序员实际上遗漏了一个操作符。他想写的是:

int res = tmp * (a + b);

如果从命令行编译,编译器可能找不到符号还有另一个原因。您可能只是忘记编译或重新编译其他类。例如,如果您有类 FooBar 哪里 Foo 使用 Bar . 如果您从未编译过 Bar 你跑了吗 javac Foo.java ,您可能会发现编译器找不到符号 Bar . 简单的答案是编译 FooBar 在一起例如 javac Foo.java Bar.javajavac *.java . 或者最好还是使用java构建工具;e、 蚂蚁、Maven、grad尔等等。
还有其他一些更模糊的原因。。。我将在下面讨论。

3.如何修复这些错误?

一般来说,首先要找出编译错误的原因。
查看编译错误消息指示的文件中的行。
识别错误消息所指的符号。
找出编译器为什么说找不到符号;看上面!
然后考虑代码应该说什么。最后,您需要对源代码进行什么样的修改才能实现您想要的功能。
请注意,并非每个“更正”都是正确的。考虑一下:

for (int i = 1; i < 10; i++) {
    for (j = 1; j < 10; j++) {
        ...
    }
}

假设编译器说“找不到符号” j . 我有很多方法可以“修复”这些问题:
我可以改变内心世界 forfor (int j = 1; j < 10; j++) -可能是对的。
我可以添加一个声明 j 在内心之前 for 环,还是外环 for 循环-可能是正确的。
我可以改变 ji 内心 for 循环-可能是错误的!
等等
关键是,为了找到正确的修复方法,您需要了解代码试图做什么。

4.不明原因

这里有几个例子,其中“找不到符号”似乎令人费解。。。直到你仔细看。
不正确的依赖项:如果您使用的是管理生成路径和项目依赖项的ide或生成工具,那么您可能在依赖项方面犯了错误;e、 g.遗漏了依赖项,或选择了错误的版本。如果您正在使用构建工具(ant、maven、gradle等),请检查项目的构建文件。如果您使用的是ide,请检查项目的生成路径配置。
找不到符号“var”:您可能正在尝试编译使用局部变量类型推断的源代码(即 var 声明)使用旧的编译器或旧的 --source 水平。这个 var 是在Java10中引入的。请检查您的jdk版本和构建文件,以及(如果在ide中出现这种情况)ide设置。
您没有重新编译:新的java程序员有时不了解java工具链的工作原理,或者没有实现可重复的“构建过程”;e、 使用ide、ant、maven、gradle等。在这种情况下,程序员可能会追尾寻找一个虚幻的错误,这实际上是由于没有正确地重新编译代码造成的,诸如此类。。。
早期构建问题:早期构建可能会失败,导致jar文件缺少类。如果使用构建工具,通常会注意到这种故障。但是,如果您是从其他人那里获取jar文件,那么您需要依赖于这些文件的正确构建,并注意到错误。如果您怀疑这一点,请使用 tar -tvf 列出可疑jar文件的内容。
ide问题:人们报告过这样的情况:他们的ide变得混乱,ide中的编译器找不到存在的类。。。或者相反的情况。
如果ide配置了错误的jdk版本,则可能会发生这种情况。
如果ide的缓存与文件系统不同步,则可能发生这种情况。有一些特定于ide的方法可以解决这个问题。
这可能是一个ide错误。例如@joelCostigliola描述了一个eclipse不处理maven“测试”树的场景

相关问题