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 语句超出了块中的范围。 这里是另一个由打字错误导致的“找不到符号”错误示例。
1条答案
按热度按时间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标识符都区分大小写。也许你不恰当地使用了下划线;即
mystring
及my_string
它们是不同的(如果您坚持java风格的规则,您将在很大程度上避免这个错误……)也许你正在尝试使用一些声明为“其他地方”的东西;i、 e.在不同的上下文中,隐式地告诉编译器查看(不同的班级?不同的范围?另一个包裹?不同的代码库?)
对于应引用变量的标识符:
也许您忘记声明变量了。
可能变量声明在您尝试使用它时超出了范围(参见下面的示例)
对于应为方法或字段名的标识符:
可能您正试图引用未在父/祖先类或接口中声明的继承方法或字段。
可能您试图引用的方法或字段在您使用的类型中不存在(即尚未声明);例如
"someString".push()
2.也许您正试图将一个方法用作字段,反之亦然;例如
"someString".length
或someArray.length()
.可能您错误地操作了数组而不是数组元素;例如
对于应为类名的标识符:
也许你忘了导入这个类。
也许您使用了“星型”导入,但是在您导入的任何包中都没有定义该类。
也许你忘了一个
new
例如:对于类型或示例似乎没有您期望的成员的情况:
可能您已经声明了一个嵌套类或泛型参数,该类或泛型参数隐藏了您想要使用的类型。
也许您正在隐藏一个静态或示例变量。
也许您输入了错误的类型;e、 g.由于ide完成或自动更正。
也许您正在使用(针对)错误版本的api。
也许您忘了将对象强制转换为适当的子类。
问题往往是上述因素的组合。例如,也许你是“明星”进口的
java.io.*
然后尝试使用Files
类。。。哪个在java.nio
不java.io
. 也许你是想写File
... 哪一个班在班上java.io
.下面是一个不正确的变量作用域如何导致“找不到符号”错误的示例:
这将导致“找不到符号”错误
i
在if
陈述虽然我们之前声明i
,该声明仅适用于for
声明及其正文。提及i
在if
语句无法看到该声明i
. 这超出了范围。(此处的适当更正可能是移动
if
循环内的语句,或要声明的i
在循环开始之前。)以下是一个导致困惑的示例,其中打字错误导致看似无法解释的“找不到符号”错误:
这将在中给您一个编译错误
println
打电话说i
找不到。但是(我听到你说)我确实申报了!问题是这个狡猾的分号(
;
)在{
. java语言语法将该上下文中的分号定义为空语句。然后,空语句将成为for
环所以这个代码实际上意味着:这个
{ ... }
块不是对象的主体for
循环,因此前面的声明i
在for
语句超出了块中的范围。这里是另一个由打字错误导致的“找不到符号”错误示例。
尽管有先前的声明,但是
tmp
在tmp(...)
表达是错误的。编译器将查找一个名为tmp
,但找不到。先前宣布的tmp
位于变量的命名空间中,而不是方法的命名空间中。在我遇到的例子中,程序员实际上遗漏了一个操作符。他想写的是:
如果从命令行编译,编译器可能找不到符号还有另一个原因。您可能只是忘记编译或重新编译其他类。例如,如果您有类
Foo
及Bar
哪里Foo
使用Bar
. 如果您从未编译过Bar
你跑了吗javac Foo.java
,您可能会发现编译器找不到符号Bar
. 简单的答案是编译Foo
及Bar
在一起例如javac Foo.java Bar.java
或javac *.java
. 或者最好还是使用java构建工具;e、 蚂蚁、Maven、grad尔等等。还有其他一些更模糊的原因。。。我将在下面讨论。
3.如何修复这些错误?
一般来说,首先要找出编译错误的原因。
查看编译错误消息指示的文件中的行。
识别错误消息所指的符号。
找出编译器为什么说找不到符号;看上面!
然后考虑代码应该说什么。最后,您需要对源代码进行什么样的修改才能实现您想要的功能。
请注意,并非每个“更正”都是正确的。考虑一下:
假设编译器说“找不到符号”
j
. 我有很多方法可以“修复”这些问题:我可以改变内心世界
for
到for (int j = 1; j < 10; j++)
-可能是对的。我可以添加一个声明
j
在内心之前for
环,还是外环for
循环-可能是正确的。我可以改变
j
到i
内心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“测试”树的场景