What does a “Cannot find symbol” compilation error mean?
请解释以下"找不到符号"错误:
- 这个错误是什么意思?
- 什么事情会导致这个错误?
- 程序员如何解决这个错误?
这个问题被设计成一个关于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风格的规则,你将在很大程度上避免这种错误……) - 也许您正试图使用声明为"其他地方"的内容;即,在另一个上下文中,您隐式地告诉编译器要查看的内容。(不同的班级?不同的范围?一个不同的包裹?不同的代码库?)
- 也许你把名字拼错了,即用
- 对于应引用变量的标识符:
- 也许你忘了声明变量。
- 在您试图使用变量声明时,它可能超出了范围。(见下例)
- 对于应该是方法名或字段名的标识符:
- 可能您正试图引用一个继承的方法或字段,而该方法或字段没有在父类/祖先类或接口中声明。
- 可能您试图引用的方法或字段在您使用的类型中不存在(即尚未声明);例如,
"someString".push() 2。 - 也许您试图将方法用作字段,或者相反;例如,
"someString".length 或someArray.length() 。
对于应为类名的标识符:好的。
- 也许你忘了导入类。
- 也许您使用了"star"导入,但是类没有在您导入的任何包中定义。
也许你忘记了一个
new ,比如:好的。
对于类型或实例似乎没有预期的成员的情况:好的。
- 也许您已经声明了一个嵌套类或一个通用参数,它隐藏了您要使用的类型。
- 可能您正在隐藏静态或实例变量。
- 可能您导入了错误的类型;例如,由于IDE完成或自动更正。
- 也许您使用(编译)了错误的API版本。
- 也许您忘记了将对象强制转换为适当的子类。
问题往往是上述两者的结合。例如,也许你"星"进口了
下面是一个示例,说明不正确的变量范围会导致"找不到符号"错误:好的。
1 2 3 4 5 6 7 8 | for (int i = 0; i < strings.size(); i++) { if (strings.get(i).equalsIgnoreCase("fnoord")) { break; } } if (i < strings.size()) { ... } |
这将给
(这里适当的修正可能是在循环内部移动
下面是一个导致困惑的例子,打字错误导致了一个看似无法解释的"找不到符号"错误:好的。
1 2 3 |
这会在
问题是,在
1 2 3 4 5 6 7 | for (int i = 0; i < 100; i++); // The previous and following are separate statements!! { System.out.println("i is" + i); } |
这里是另一个由打字错误引起的"找不到符号"错误的例子。好的。
1 2 | int tmp = ... int res = tmp(a + b); |
尽管之前有声明,但
在我遇到的例子中,程序员实际上漏掉了一个操作员。他想写的是:好的。
1 | int res = tmp * (a + b); |
如果从命令行编译,编译器可能找不到符号还有另一个原因。您可能只是忘记了编译或重新编译其他类。例如,如果您有
还有其他一些更为隐晦的原因…我将在下面处理。好的。三。如何修复这些错误?
一般来说,首先要弄清楚是什么导致了编译错误。好的。
- 查看编译错误消息指示的文件中的行。
- 确定错误消息所指的符号。
- 找出编译器为什么说找不到符号;请参见上面的内容!
然后你想想你的代码应该说什么。最后,您需要对源代码进行什么样的修正,才能完成您想要的工作。好的。
请注意,并非每个"更正"都是正确的。考虑一下:好的。
1 2 3 4 5 | for (int i = 1; i < 10; i++) { for (j = 1; j < 10; j++) { ... } } |
假设编译器对
- 我可以把里面的
for 改成for (int j = 1; j < 10; j++) ,也许是对的。 - 我可以在内部
for 循环或外部for 循环之前为j 添加声明-可能是正确的。 - 我可以把
j 改为i ,在内部的for 循环中-可能是错的! - 等等。
要点是,您需要了解代码试图做什么,以便找到正确的修复方法。好的。4。模糊原因
这里有两种情况,"找不到符号"似乎难以解释…直到你看得更近。好的。
不正确的依赖项:如果使用的是管理生成路径和项目依赖项的IDE或生成工具,则可能对依赖项犯了错误;例如,遗漏了依赖项或选择了错误的版本。如果您使用的是构建工具(Ant、Maven、Gradle等),请检查项目的构建文件。如果使用的是IDE,请检查项目的构建路径配置。好的。
您没有重新编译:有时新Java程序员不理解Java工具链是如何工作的,或者没有实现可重复的"构建过程";例如使用IDE、ANT、Maven、Gradle等。在这种情况下,程序员最终可能会追寻自己的尾巴,寻找一个实际上是由于没有正确地重新编译代码而导致的错误,等等……好的。
早期版本的问题:它是可能的,早期的失败是生成在一个JAR文件单给A一班。搜索设备失效会注意到如果你是使用一个版本的工具。但是如果你从别人得到的JAR文件,你在他们的建筑,没有依赖性,和noticing错误。如果你看看这个列表的内容,使用
IDE的问题:有人会在他们的案例被混淆的IDE和编译器在IDE无法找到一个一流的存在……或反向的情况。
这可以发生,如果IDE’s get走出同步缓存文件系统。有特异的方式来固定这是IDE。
这可能是在IDE的bug。例如:"在目前情况costigliola乔尔Eclipse不手柄a Maven的"测试"这个正确答案:湖树。
redefining系统类:我的湖泊。在编译
它使程序员创造出这样一个自己的版本的版本,他的
教训:不要使用你自己的类相同的名称作为一个类的公共图书馆。
homoglyphs:如果你使用UTF-8编码的源文件,它是可能的,有标识看起来一样,但实际上他们是不同的,因为homoglyphs包含。湖本页的更多信息。
你可以通过自己来避免这restricting ASCII或为Latin-1编码使用Java源文件,和其他
1如果你perchance湖,这一运行时异常或错误消息,那么你已经配置您的IDE运行代码和编译错误,或是生成和编译代码的应用程序。在运行时。
2土木工程的基本原则三:水不流完成,A板是在其侧更强,你不能推一弦。
好的。
如果您忘记了
对战
"变量超出范围"的另一个示例
正如我已经看到过几次这样的问题,也许还有一个例子可以说明什么是非法的,即使它可能感觉良好。
考虑此代码:
1 2 3 4 5 6 |
这是无效代码。因为两个名为
您可能会说:"但是名为message的变量是以任何方式定义的,因此message是在
但你错了。
Java没有EDCOX1,4或EDCOX1,5个操作符,因此必须依靠跟踪变量范围来发现变量何时不再被使用(连同这些变量的原因的引用)。
如果你认为你做了好事,那就更糟了。我在这样的"优化"代码之后看到了这种错误:
1 2 3 4 5 6 7 |
"哦,这里有重复的代码,让我们把这条公用线拉出来"->然后就到了。
处理此类范围问题的最常见方法是将else值预先分配给外部范围中的变量名,然后在if:
1 2 3 4 5 |
在Eclipse中获取此错误的一种方法:
结果:Eclipse将编译代码,但Maven将给出"找不到符号"。
根本原因:Eclipse使用的是主树和测试树的组合构建路径。不幸的是,它不支持为Eclipse项目的不同部分使用不同的构建路径,这正是Maven所要求的。
解决方案:
"找不到"是指编译器找不到合适的变量、方法、类等。如果你得到了错误消息,首先你要找到代码行,在那里得到错误消息。然后你就可以在使用之前找到没有定义的变量、方法或类。确认后,初始化该变量、方法或类。可用于以后的需求…请考虑以下示例。
我将创建一个演示类并打印一个名称…
现在看看结果……
该错误表示,"变量名找不到"…定义和初始化"名称"变量的值可以取消该错误..实际上是这样的,
1 2 3 4 5 6 7 8 |
现在看看新的输出…
OK成功地解决了这个错误..同时,如果你能得到"找不到方法"或"找不到类"的东西,首先定义一个类或方法,然后使用它..
如果你在其他地方构建了这个错误,而你的IDE说一切都很好,那么检查你在两个地方使用的是相同的Java版本。
例如,Java 7和Java 8具有不同的API,因此调用旧的Java版本中不存在的API会导致此错误。
如果Eclipse Java构建路径被映射到7, 8,并且在Projo POM.XML Maven属性java.版本中提到了更高的Java版本(9,10,11,等等),而不是7,8,则需要在POM.XML文件中进行更新。
在Eclipse中,如果Java映射到Java版本11和POM.XML,则映射到Java版本8。通过Eclipse IDE中的以下步骤更新Eclipse对Java 11的支持帮助->安装新软件->
粘贴以下链接http://download.eclipse.org/eclipse/updates/4.9-p-builds-at-work-with
或
添加(弹出窗口将打开)->
EDCOX1·2·Java 11支持
然后在POM.XML文件的Maven属性中更新Java版本,如下所示
1 2 3 | <java.version>11</java.version> <maven.compiler.source>${java.version}</maven.compiler.source> <maven.compiler.target>${java.version}</maven.compiler.target> |
最后右键单击项目调试as->maven clean,maven build steps
正如上面提到的,可能会有各种各样的场景。一些帮助我解决这个问题的事情。
如果您使用Intellij
或
被引用的类在另一个项目中,并且该依赖项没有添加到我的项目的Gradle构建文件中。所以我用
它奏效了。嗯!
有关提示,请仔细查看引发错误的类名和行号,例如:编译失败[错误] 应用程序xxxxx .java:[44,30]错误:找不到符号
另一个原因是不支持Java版本的方法,如JDK7 vs 8。检查您的%java_主页%
我也收到了这个错误。(我在谷歌上搜索了一下,然后就被转到了这一页)
问题:我正在从另一个项目B中定义的类调用项目A类中定义的静态方法。我收到以下错误:
1 | error: cannot find symbol |
解决方案:我通过首先在定义方法的项目中构建方法,然后从中调用方法的项目来解决这个问题。