请解释以下关于“无法找到符号”,“无法解析符号”或“符号未找到”的错误(在Java中):

它们是什么意思? 什么东西会引起它们? 程序员如何着手修复它们?

本问题旨在针对Java中常见的编译错误进行全面的问答。


当前回答

我也得到了这个错误。(我在谷歌上搜索了一下,然后转到了这个页面)

问题:我正在从另一个项目B中定义的类调用项目a的类中定义的静态方法。 我得到以下错误:

error: cannot find symbol

解决方案:我通过首先构建定义方法的项目,然后构建调用方法的项目来解决这个问题。

其他回答

我们在一个Java项目中得到了一个错误,该项目被设置为Gradle多项目构建。结果发现其中一个子项目缺少Gradle Java Library插件。 这阻止了子项目的类文件对构建中的其他项目可见。

在将Java库插件添加到子项目的构建之后。用下面的方法Gradle,错误就消失了:

plugins {
    ...
    id 'java-library'
}

如果您在其他地方的构建中遇到此错误,而您的IDE表示一切正常,那么请检查您在两个地方使用的Java版本是否相同。

例如,Java 7和Java 8有不同的API,因此在较旧的Java版本中调用不存在的API会导致此错误。

再举一个"变量超出范围"的例子

这类问题我已经见过几次了,也许是另一个例子,说明什么是非法的,即使它可能感觉不错。

考虑下面的代码:

if(somethingIsTrue()) {
  String message = "Everything is fine";
} else {
  String message = "We have an error";
}
System.out.println(message);

这是无效代码。因为命名为message的变量在它们各自的作用域之外都是不可见的——在本例中是周围的括号{}。

你可能会说:“但是一个名为message的变量是用两种方式定义的——所以message是在if之后定义的。”

但你错了。

Java没有free()或delete操作符,因此它必须依赖于跟踪变量作用域来发现变量何时不再使用(以及对这些原因变量的引用)。

如果你认为自己做了好事,那就更糟了。我在“优化”代码后就见过这样的错误:

if(somethingIsTrue()) {
  String message = "Everything is fine";
  System.out.println(message);
} else {
  String message = "We have an error";
  System.out.println(message);
}

“哦,这里有重复的代码,让我们把公共线拉出来”->,就是这样。

处理这种作用域问题最常见的方法是将else值预先分配给外部作用域的变量名,然后在if中重新分配:

String message = "We have an error";
if(somethingIsTrue()) {
  message = "Everything is fine";
} 
System.out.println(message);

Optional.isEmpty ()

我很高兴在我的IDE中使用!Optional.isEmpty(),它工作得很好,因为我正在用>= JDK11编译/运行我的项目。现在,当我在命令行上使用Gradle(在JDK8上运行)时,我在编译任务中得到了讨厌的错误。

Why?

从文档中(注意最后一行):

boolean java.util.Optional.isEmpty()

If a value is not present, returns true, otherwise false.
Returns:true if a value is not present, otherwise false
Since:11

我在误差以下

java: cannot find symbol
  symbol: class __

要解决这个问题

我尝试启用lambok,重新启动intellij等,但下面对我有用。

Intellij Preferences ->Compiler -> Shared Build process VM Options,设置为

  -Djps.track.ap.dependencies=false

比跑

mvn clean install