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

pqwbnv8z  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(375)

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

nr7wwzry

nr7wwzry1#

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

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

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

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

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

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

对于类型或示例似乎没有预期的成员的情况:
可能您已经声明了一个嵌套类或泛型参数,该类或泛型参数隐藏了您要使用的类型。
也许您正在跟踪一个静态变量或示例变量。
也许你输入了错误的类型;e、 g.由于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()) {
    ...
}

这将导致“找不到符号”错误 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);

如果您是从命令行编译,编译器可能找不到符号还有另一个原因。您可能只是忘记编译或重新编译其他类。例如,如果你有课 Foo 以及 Bar 哪里 Foo 使用 Bar . 如果你从未编译过 Bar 你跑了 javac Foo.java ,您可能会发现编译器找不到符号 Bar . 简单的答案是编译 Foo 以及 Bar 一起;例如 javac Foo.java Bar.java 或者 javac *.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、 遗漏了依赖项,或者选择了错误的版本。如果您正在使用构建工具(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错误。例如@joelcostigliola描述了一个eclipse不处理maven“test”树cor的场景

相关问题