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条答案
按热度按时间7vux5j2d1#
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()
.可能是错误地操作数组而不是数组元素;例如
对于应为类名的标识符:
也许你忘了导入类。
也许您使用了“star”导入,但是您导入的任何包中都没有定义该类。
也许你忘了
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、 遗漏了依赖项,或者选择了错误的版本。如果您正在使用构建工具(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的场景