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

1tu0hz3e  于 2022-09-16  发布在  Java
关注(0)|答案(18)|浏览(405)

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

  • 他们是什么意思?
  • 什么因素会导致这些问题?
  • 程序员如何着手修复它们?
  • 这个问题旨在对Java中常见的编译错误进行全面的问答*
hrysbysz

hrysbysz1#

0。这些错误之间有什么区别吗?

不是真的。“找不到符号”、“无法解析符号”和“未找到符号”的含义相同。(不同的Java编译器是由不同的人编写的,不同的人使用不同的措辞来表达相同的意思。)

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

首先,这是一个编译错误1。这意味着或者Java源代码有问题,或者编译的方式有问题。
您的Java源代码包括以下内容:

  • 关键词:如classwhile等。
  • 文字:如truefalse、E1 D4D1E、'X'"Hi mum!"
  • 运算符和其他非字母数字标记:如+={等。
  • 标识符:如Readeri、E1 D12D1E、processEquibalancedElephants等。
  • 注解和空白。

“找不到符号”错误与标识符有关。编译代码时,编译器需要找出代码中每个标识符的含义。
“找不到符号”错误表示编译器无法执行此操作。您的代码似乎引用了编译器不理解的内容。

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

作为第一顺序,只有一个原因。编译器查找了所有应该定义标识符*的地方,但找不到定义。这可能是由许多因素造成的。常见的如下:

  • 对于一般标识符:
  • 也许你拼错了名字;i、 e.StringBiulder而不是StringBuilder。Java不能也不会尝试补偿拼写错误或打字错误。
  • 也许你错了;i、 e.stringBuilder而不是StringBuilder。所有Java标识符都区分大小写。
  • 也许你不恰当地使用了下划线;i、 e.mystringmy_string是不同的。(如果您坚持Java风格的规则,您将在很大程度上避免这个错误…)
  • 也许你正在尝试使用被声明为“其他地方”的东西;i、 e.在不同的上下文中,您隐式地告诉编译器要查看。(不同的类?不同的作用域?不同的包?不同的代码库?)
  • 对于应引用变量的标识符:
  • 也许您忘记声明变量了。
  • 也许变量声明在您尝试使用时超出了范围。(见以下示例)
  • 对于应为方法或字段名的标识符:
  • 可能您试图引用的继承方法或字段未在父/祖先类或接口中声明。
  • 可能您试图引用的方法或字段在您使用的类型中不存在(即尚未声明);e、 g."rope".push()2。
  • 也许您正在尝试将方法用作字段,反之亦然;e、 例如"rope".lengthsomeArray.length()
  • 可能您错误地操作了数组而不是数组元素;例如
String strings[] = ...
    if (strings.charAt(3)) { ... }
    // maybe that should be 'strings[0].charAt(3)'
  • 对于应为类名的标识符:
  • 也许您忘记导入类。
  • 也许您使用了“星”导入,但在导入的任何包中都没有定义类。
  • 可能您忘记了new,如:
String s = String();  // should be 'new String()'
  • 对于类型或示例似乎没有您期望的成员(例如方法或字段)的情况:
  • 也许您已经声明了一个嵌套类或泛型参数,它*隐藏了您想要使用的类型。
  • 也许您正在隐藏静态或示例变量。
  • 也许您输入了错误的类型;e、 g.由于IDE完成或自动校正,可能建议使用java.awt.List而不是java.util.List
  • 也许您正在使用(针对)错误版本的API。
  • 也许您忘记将对象强制转换为适当的子类。
  • 也许您已经将变量的类型声明为具有所需成员的变量的超类型。

问题通常是上述问题的组合。例如,您可能“star”导入了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()) {
    ...
}

这将导致if语句中的i出现“找不到符号”错误。尽管我们之前声明了i,但该声明仅适用于for语句及其主体。if声明中对i的引用*无法看到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循环的主体,因此for语句中i的先前声明在块中超出范围
下面是由打字错误导致的“找不到符号”错误的另一个示例。

int tmp = ...
int res = tmp(a + b);

尽管有先前的声明,tmp(...)表达式中的tmp是错误的。编译器将查找一个名为tmp的方法,但找不到。先前声明的tmp位于变量的命名空间中,而不是方法的命名空间中。
在我遇到的例子中,程序员实际上遗漏了一个操作符。他想写的是:

int res = tmp * (a + b);

如果从命令行编译,编译器可能找不到符号还有另一个原因。你可能只是忘记了

gr8qqesn

gr8qqesn2#

如果您忘记new,也会出现此错误:

String s = String();

String s = new String();

因为没有E1D1E关键字的调用将尝试查找一个没有参数的(本地)方法String,并且该方法签名可能没有定义。

cwxwcias

cwxwcias3#

“变量超出范围”的另一个示例

我已经见过这种问题好几次了,也许再举一个例子来说明什么是非法的,即使它可能感觉很好。
考虑以下代码:

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值预先分配给作用域外部的变量名,然后在以下情况下重新分配:

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

q3qa4bjr4#

解决

使用IntelliJ
选择构建->重建项目将解决此问题

qc6wkl3g

qc6wkl3g5#

在Eclipse中获取此错误的一种方法是:
1.在src/test/java中定义类别A
1.在src/main/java中定义使用类A的另一类B
结果:Eclipse将编译代码,但maven将给出“找不到符号”。
根本原因:Eclipse使用主树和测试树的组合构建路径。不幸的是,它不支持为Eclipse项目的不同部分使用不同的构建路径,这正是Maven所需要的。
解决方案:
1.不要这样定义依赖关系;i、 不要犯这个错误。
1.定期使用Maven构建代码库,以便及早发现错误。一种方法是使用CI服务器。

rslzwgfq

rslzwgfq6#

“找不到”意味着,编译器找不到合适的变量、方法、类等。如果你得到了错误消息,首先你想找到获取错误消息的代码行。然后你将能够找到在使用它之前没有定义的变量、方法或类。确认后,初始化变量、方法或类可用于以后的需求…考虑以下示例。
我将创建一个演示类并打印一个名称。。。

class demo{ 
      public static void main(String a[]){
             System.out.print(name);
      }
}

现在看看结果。。

该错误表示“找不到变量名”。定义和初始化“名称”变量的值可以消除该错误。实际上,这样,

class demo{ 
      public static void main(String a[]){

             String name="smith";

             System.out.print(name);
      }
}

现在看看新的输出。。。

Ok成功地解决了这个错误。同时,如果你能得到“找不到方法”或“找不着类”的东西,首先定义一个类或方法,然后使用它。。

5q4ezhmt

5q4ezhmt7#

如果您在其他地方的构建中出现此错误,而IDE说一切都很好,那么请检查您在这两个地方使用的Java版本是否相同。
例如,Java 7和Java 8具有不同的API,因此在较旧的Java版本中调用不存在的API将导致此错误。

8ftvxx2r

8ftvxx2r8#

正如人们在上面提到的,可以有各种各样的场景。有几件事帮助我解决了这个问题。
1.如果您正在使用IntelliJ
File -> 'Invalidate Caches/Restart'

1.被引用的类位于另一个项目中,并且该依赖项未添加到我的项目的Gradle构建文件中。因此,我使用添加了依赖项
compile project(':anotherProject')
它成功了。嗯!

flvtvl50

flvtvl509#

如果eclipse Java构建路径Map到7、8和项目pom中。xml是java的Maven属性。版本提到了比pom中需要更新的7.8更高的Java版本(9、10、11等)。xml文件。
在Eclipse中,如果JavaMap到Java版本11,则在pom中。xmlMap到Java版本8。通过在Eclipse IDE帮助->安装新软件->中执行以下步骤,将Eclipse支持更新到Java 11
将以下链接http://download.eclipse.org/eclipse/updates/4.9-P-builds粘贴到***处。使用***

添加(弹出窗口将打开)->
Name: Java 11支持E1d1d1ed1c1d
然后在pom的Maven属性中更新Java版本。xml文件,如下所示

<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>

最后右键单击projectdebug as->Maven clean,Maven构建步骤

mf98qq94

mf98qq9410#

我也犯了这个错误。(为此,我在谷歌上搜索,并被引导到该页面。)

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

error: cannot find symbol

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

ef1yzkbh

ef1yzkbh11#

您使用maven compile编译代码,然后使用maven test运行代码,效果良好。现在,如果您更改了代码中的某些内容,然后在不编译的情况下运行它,则会出现以下错误。
解决方案:再次编译它,然后运行测试。对我来说是这样的。

cgyqldqp

cgyqldqp12#

在我的情况下,我必须执行以下操作:
1.将context.xml文件从src/java/package移动到resource目录(IntelliJ IDE)
1.清理target目录。

fkvaft9z

fkvaft9z13#

有关提示,请仔细查看引发错误的类名和行号,例如:编译失败[错误]\applications\xxxxx。java:[44,30]错误:找不到符号
另一个原因是java版本不支持的方法,比如jdk7 vs 8。请检查您的%java_HOME%

xqnpmsa8

xqnpmsa814#

我们在一个设置为Gradle多项目构建的Java项目中得到了错误。事实证明,其中一个子项目缺少Gradle Java Library plugin。这防止子项目的类文件对生成中的其他项目可见。
通过以下方式将Java库插件添加到子项目的build.gradle后,错误消失了:

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

watbbzwu15#

回复:*4.4:Stephen C的优秀答案中的早期构建问题:
我在开发osgi应用程序时遇到了这种情况。
我有一个java项目A,它依赖于B。构建B时,出现以下错误:

Compilation failure: org.company.projectA.bar.xyz does not exist

但是在eclipse中,根本没有编译问题。

调查

当我查看A.jar时,org.company.projectA.foo.abc有类,但org.company.projectA.bar.xyz没有类。
缺少类的原因是,在A/pom.xml中,是用于导出相关包的条目。

<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    ...
    <configuration>
        <instructions>
            ....
            <Export-Package>org.company.projectA.foo.*</Export-Package>
        </instructions>
    </configuration>
</plugin>

解决方案

添加缺少的包,如下所示:

<Export-Package>org.company.projectA.foo.*,org.company.projectA.bar.*</Export-Package>

重建一切。
现在,A.jar包含了所有预期的类,一切都可以编译。

相关问题