8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

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

DarthGizka 2月前

129 0

请解释以下有关“无法找到符号”、“无法解析符号”或“未找到符号”错误(在 Java 中):它们是什么意思?什么原因会导致它们……

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

  • 它们是什么意思?
  • 什么因素可能导致这些情况?
  • 程序员如何修复这些问题?

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

帖子版权声明 1、本帖标题:“无法找到符号”或“无法解析符号”错误是什么意思?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由DarthGizka在本站《java》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 0. 这些错误有什么区别吗?

    并非如此。\'无法找到符号\'、\'无法解析符号\' 和 \'未找到符号\' 都表示相同的意思。(不同的 Java 编译器由不同的人编写,不同的人使用不同的措辞来表达相同的意思。)

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

    首先,这是一个 编译错误 1​​。这意味着 存在 问题, 或者 您的编译方式存在问题。

    您的 Java 源代码由以下内容组成:

    • 关键字:如 class , while ,等等。
    • 文字:像 true , false , 42 , 'X' "Hi mum!" .
    • 运算符和其他非字母数字标记:如 + , = , { , 等等。
    • 标识符:如 Reader , i , toString , processEquibalancedElephants ,等等。
    • 评论和空格。

    “无法找到符号”错误与标识符有关。编译代码时,编译器需要找出代码中每个标识符的含义。

    “无法找到符号”错误意味着编译器无法执行此操作。您的代码似乎引用了编译器无法理解的内容。

    2. 什么原因会导致“无法找到符号”错误?

    首先,只有一个原因。编译器查找了所有 应该 定义标识符的位置,但找不到定义。这可能是由多种原因造成的。常见的原因如下:

    • p6

      • Perhaps you spelled the name incorrectly; i.e., StringBiulder instead of StringBuilder . Java cannot and will not attempt to compensate for bad spelling or typing errors.
      • Perhaps you got the case wrong; i.e. stringBuilder instead of StringBuilder . All Java identifiers are case sensitive.
      • Perhaps you used underscores inappropriately; i.e., mystring and my_string are different. (If you stick to the Java style rules, you will be largely protected from this mistake...)
      • Perhaps you are trying to use something that was declared "somewhere else"; i.e. in a different context to where you have implicitly told the compiler to look. (A different class? A different scope? A different package? A different code-base?)
    • p7

      • Perhaps you forgot to declare the variable.
      • Perhaps the variable declaration is out of scope at the point you tried to use it. (See example below)
    • p8

      • 【【p9】】

      • 【【p10】】

      • 【【p11】】

      • 【【p12】】

            String strings[] = ...    if (strings.charAt(3)) { ... }    // Maybe that should be 'strings[0].charAt(3)'
    • p13

      • 【【p14】】

      • 【【p15】】

      • 【【p16】】

            String s = String();  // Should be 'new String()'
      • 【【p17】】

        【【p18】】

    • 第19页

      • Perhaps you have declared a nested class or a generic parameter that shadows the type you were meaning to use.
      • Perhaps you are shadowing a static or instance variable.
      • Perhaps you imported the wrong type; e.g., due to IDE completion or auto-correction may have suggested java.awt.List rather than java.util.List .
      • Perhaps you are using (compiling against) the wrong version of an API.
      • Perhaps you forgot to cast your object to an appropriate subclass.
      • Perhaps you have declared the variable's type to be a supertype of the one with the member you are looking for.

    问题通常是上述情况的组合。例如,也许你导入了 \'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()) {
        ...
    }
    

    中的 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 超出了 块的范围。


    这是由于拼写错误导致的“无法找到符号”错误的另一个示例。

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

    尽管先前声明过,但 tmp tmp(...) 是错误的。编译器将查找名为 的方法 tmp ,但找不到。先前声明的 tmp 位于变量命名空间中,而不是方法命名空间中。

    在我遇到的例子中,程序员实际上漏掉了一个运算符。他原本想写的是:

    int res = tmp * (a + b);
    

    如果您从命令行进行编译,编译器可能找不到符号的另一个原因是。您可能只是忘记编译或重新编译其他类。例如,如果您有类 Foo 和使用 Bar Foo 如果 Bar 您从未编译过 Bar 并且运行 javac Foo.java ,则很可能会发现编译器找不到符号 Bar 。简单的答案是将 Foo Bar 一起编译;例如, javac Foo.java Bar.java javac *.java 。或者更好的是使用 Java 构建工具;例如, Ant , Maven , Gradle 等。

    还有一些其他更不为人知的原因……我将在下面讨论。

    3. 我该如何修复这些错误?

    一般来说,您首先要弄清楚 导致 编译错误的原因。

    • 查看文件中编译错误消息所指示的行。
    • 确定错误消息中提到的符号。
    • 弄清楚 为什么 编译器说它找不到该符号;参见上文!

    然后你 思考 你的代码应该表达什么。最后你弄清楚需要对源代码做哪些修正才能达到你想要的效果。

    请注意,并非每个“更正”都是正确的。考虑一下:

    for (int i = 1; i < 10; i++) {
        for (j = 1; j < 10; j++) {
            ...
        }
    }
    

    假设编译器提示“找不到符号” j 。我可以用很多方法来“修复”这个问题:

    • 我可以将内部改变 for for (int j = 1; j < 10; j++) - 可能正确。
    • 在内 j 循环或外 之前 for 添加一个声明 for ——可能是正确的。
    • 我可以 j 在内循环中 i 改变 for ——可能是错的!
    • 等等。

    关键在于您 需要 了解您的代码正在做什么,以便找到正确的修复方法。

    4. 原因不明

    以下几种情况中,“无法找到符号”似乎令人费解……直到你仔细观察。

    1. p39

    2. p40

    3. p41

      p42

    4. p43

    5. p44

      • 【【p45】】

      • 【【p46】】

      • 【【p47】】

    6. p48

      p49

    7. p50

      String s = ...String s1 = s.substring(1);

      p51

      p52

      p53

      java.lang.String s = ...java.lang.String s1 = s.substring(1);
    8. p54

      p55


    1 - If, perchance, you do see this in a runtime exception or error message, then either you have configured your IDE to run code with compilation errors, or your application is generating and compiling code .. at runtime.
    2 - The three basic principles of 土木工程 : water doesn't flow uphill, a plank is stronger on its side, and you can't push on a rope .

  • jpa 2月前 0 只看Ta
    引用 3

    我遇到过另一种情况,即在 eclipse 没有发现问题的情况下发生了此编译错误:两个类具有分别在另一个类中定义的依赖项。在我的例子中,我有一个枚举,实现了一个接口,该枚举定义在一个类中,而我愚蠢地已经使用了该枚举。

  • 与上面的评论有些相似,当我从 Eclipse 编译并运行我的程序时,它运行正常。从控制台编译它会引发一堆“无法找到符号”错误,这些错误通常与导入中的最后一个元素有关。我不知道是什么原因造成的,因为代码中实际上没有任何问题。

  • 另一个问题是 IDE 可能会将其他错误“解释”到此类别中。例如,如果将 System.out.println 中的 println 放在标准编译器下的类级别,则会出现预期(演示)但在 IntelliJ 中我们将看到无法解析符号“println”(演示)。

  • (看起来 Intellij 采取了一些语法无效的东西(需要声明的语句),然后试图解析符号。但是编译器已经混乱不堪,无法解析应该解析的符号……如果语句在正确的上下文中,它将解析。这导致了误导性的编译错误消息。)

  • 如果您忘记了以下内容,您也会收到此错误 new

    String s = String();
    

    相对

    String s = new String();
    

    因为没有关键字的调用 new 将尝试寻找 String 没有参数的(本地)方法 - 并且该方法签名可能未定义。

  • 已解决

    使用 IntelliJ

    选择 Build -> Rebuild Project 即可解决

  • 这对我来说很管用。我无法弄清楚,因为包/目录都是正确的。似乎需要重建才能纳入更改。

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

    由于我已经多次见过此类问题,即使 感觉 没问题,也许还需要一个例子来说明什么是非法的。

    考虑以下代码:

    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);
    
  • \'Java 没有 free() 或 delete 运算符,因此它必须依靠跟踪变量范围来找出变量何时不再使用(以及对这些变量的引用)。\' - 虽然这是真的,但这无关紧要。C 和 C++ 分别有 free / delete 运算符,但与您的示例等效的 C / C++ 代码将是非法的。C 和 C++ 块限制变量的范围,就像在 Java 中一样。事实上,对于大多数“块结构”语言来说都是如此。

  • 中出现此错误的一种方法 Eclipse :

    1. 在中 A 定义一个类 src/test/java .
    2. 定义另一个 B 使用类的 src/main/java A .

    结果:Eclipse 可以编译代码,但是 Maven 会给出“无法找到符号”的错误提示。

    根本原因:Eclipse 正在为主树和测试树使用组合构建路径。遗憾的是,它不支持为 Eclipse 项目的不同部分使用不同的构建路径,而这正是 Maven 所要求的。

    解决方案:

    1. 不要以那种方式定义你的依赖关系;即不要犯这个错误。
    2. 定期使用 Maven 构建代码库,以便尽早发现此错误。一种方法是使用 CI 服务器。
  • 引用 13

    您在 src/main/java 中使用的任何内容都需要在 src/main/java 或任何编译/运行时依赖项(不是测试依赖项)中进行定义。

  • 引用 14

    “找不到”的意思是编译器找不到合适的变量、方法、类等等。如果您收到了该错误消息,首先,您要找到收到错误消息的代码行。

    然后,你将能够在使用之前找到哪些变量、方法或类尚未定义。确认后,初始化该变量、方法或类,以便稍后使用请考虑以下示例。

    我将创建一个演示类并打印一个名称......

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

    现在看看结果..

    Enter image description here

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

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

    现在看看新的输出...

    Enter image description here

    好的,我们成功解决了该错误。同时,如果您遇到“找不到方法”或“找不到类”之类的错误,请首先定义一个类或方法,然后使用它。

  • 请查看为什么提问时不上传代码/错误图片?(例如,“图片只能用于说明无法通过其他方式说明的问题,例如提供用户界面的屏幕截图。”)并做正确的事情(它也涵盖了答案)。提前致谢。

  • rxon 2月前 0 只看Ta
    引用 16

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

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

  • 正如人们在之前的回答中提到的那样,可能会有各种情况。以下是一些帮助我解决这个问题的方法。

    1. 点1

      点2

    或者

    1. p4

      compile project(':anotherProject')

      p5

  • 如果 Eclipse Java 构建路径映射到 7、8,并且项目 pom.xml Maven 属性 java.version 中提到的 Java 版本高于 7,8(9、10、11 等),则需要在 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

    或者

    添加(弹出窗口将打开)->

    Name: Java 11 支持 Location: http://download.eclipse.org/eclipse/updates/4.9-P-builds

    的 Maven 属性中更新 Java 版本 pom.xml ,如下所示:

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

    最后,在项目上单击鼠标右键,选择“Debug as -> Maven clean”,进入“Maven build”步骤。

  • Atif 2月前 0 只看Ta
    引用 19

    我也遇到了这个错误(我用 Google 搜索并被引导到这个页面)。

    问题: 我从另一个项目 B 中定义的类调用项目 A 的类中定义的静态方法。

    我收到以下错误:

    error: cannot find symbol
    

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

  • 是的,如果您决定将一些可重复使用的函数从当前包移动到公共实用程序包,但是在从当前包调用该函数之前忘记编译公共包,就会发生这种情况。

返回
作者最近主题: