当前位置: 首页 > 知识库问答 >
问题:

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

顾俊誉
2023-03-14

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

  • 这是什么意思

这个问题旨在产生一个全面的问题

共有3个答案

方飞翼
2023-03-14

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

正如我已经见过几次这样的问题,也许再举一个例子来说明什么是非法的,即使它可能感觉不错。

考虑这个代码:

if(somethingIsTrue()) {
  String message = "Everything is fine";
} else {
  String message = "We have an error";
}
System.out.println(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);
鲜于浩淼
2023-03-14

如果您忘记了一个新的,也会出现此错误:

String s = String();

String s = new String();

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

钱劲
2023-03-14

不是真的。“找不到符号”、“无法解析符号”和“找不到符号”都是同一个意思。不同的Java编译器使用不同的措辞。

首先,这是一个编译错误1。这意味着要么你的Java源代码有问题,要么你编译它的方式有问题。

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

  • 关键词:如while,等等

“找不到符号”错误是关于标识符的。编译代码时,编译器需要弄清楚代码中的每个标识符意味着什么。

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

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

>

  • 也许您拼写错误,即StringBiulder而不是StringBuilder。Java不能也不会尝试补偿错误的拼写或打字错误。
  • 也许您弄错了大小写,即stringBuilder而不是StringBuilder。所有Java标识符都区分大小写。
  • 也许您不恰当地使用了下划线;即mystringmy_string是不同的。(如果您坚持Java样式规则,您将在很大程度上避免这个错误...)
  • 也许您正在尝试使用在其他地方声明的东西;即在与您隐式告诉编译器查看的上下文不同的上下文中。(不同的类?不同的范围?不同的包?不同的代码库?)

对于应引用变量的标识符:

  • 也许你忘了声明变量

对于应该是方法或字段名的标识符:

>

  • 也许您正在尝试引用未在父/祖先类或接口中声明的继承方法或字段。

    可能您试图引用的方法或字段在您使用的类型中不存在(即尚未声明);e、 g.“绳索”。按下()2

    也许您正试图将方法用作字段,或者反之亦然;例如"绳". long一些rray.length()

    也许您错误地操作了一个数组,而不是数组元素。

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

    对于应为类名的标识符:

    >

  • 也许你忘了导入这个类。

    也许您使用了“星型”导入,但在您导入的任何包中都没有定义该类。

    也许你忘了一个new,如:

        String s = String();  // should be 'new String()'
    

    对于类型或实例似乎没有您期望的成员(例如方法或字段)的情况:

    • 也许您已经声明了一个嵌套类或泛型参数,该类或泛型参数隐藏了您想要使用的类型

    问题通常是上述问题的组合。例如,也许你“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);
    

    如果从命令行编译,编译器可能找不到符号还有另一个原因。您可能只是忘记编译或重新编译其他类。例如,如果您有类FooBar,其中Foo使用Bar。如果您从未编译过Bar,并且运行过javac Foo。java,您可能会发现编译器找不到符号。简单的答案是将FooBar一起编译;e、 g.javac-Foo。java吧。javajavac*。java。或者最好还是使用Java构建工具;e、 g.蚂蚁、马文、格拉德尔等等。

    还有一些其他更模糊的原因...我将在下面讨论。

    一般来说,您首先要弄清楚是什么导致了编译错误。

    • 查看编译错误消息指示的文件中的行

    然后思考代码应该说什么。最后,你需要对你的源代码进行什么样的修改,以达到你的目的。

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

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

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

    • 我可以将的内部更改为(int j=1;j)的

    关键是,为了找到正确的修复,您需要理解代码试图做什么。

    这里有几个例子,“找不到符号”似乎令人费解。。。直到你仔细看。

    >

  • 不正确的依赖关系:如果您使用的是管理生成路径和项目依赖关系的IDE或生成工具,那么您可能在依赖关系方面犯了错误;e、 g.遗漏了依赖项,或选择了错误的版本。如果您正在使用构建工具(Ant、Maven、Gradle等),请检查项目的构建文件。如果您使用的是IDE,请检查项目的生成路径配置。

    找不到符号“var”:您可能正试图用较旧的编译器或较旧的--source级别编译使用局部变量类型推断(即var声明)的源代码。var是在Java10中引入的。检查JDK版本和构建文件,以及(如果在IDE中发生这种情况)IDE设置。

    您不是在编译/重新编译:有时新的Java程序员不了解Java工具链是如何工作的,或者没有实现可重复的“构建过程”;e、 g.使用IDE、Ant、Maven、Gradle等。在这种情况下,程序员可能会追尾寻找一个虚幻的错误,这实际上是由于没有正确地重新编译代码造成的,诸如此类。

    另一个例子是使用(Java9)JavaSomeClass。java来编译和运行类。如果该类依赖于您尚未编译(或重新编译)的另一个类,那么您很可能会遇到与第二个类有关的“无法解析符号”错误。其他源文件不会自动编译。java命令的新“编译并运行”模式不是为运行包含多个源代码文件的程序而设计的。

    早期构建的一个问题:早期构建可能会失败,导致JAR文件缺少类。如果使用构建工具,通常会注意到这种故障。然而,如果你从其他人那里得到JAR文件,你需要依赖于它们的正确构建,并注意到错误。如果您怀疑这一点,请使用tar-tvf列出可疑JAR文件的内容。

    IDE问题:人们报告过这样的情况:他们的IDE变得混乱,IDE中的编译器找不到存在的类。。。或者相反的情况。

    >

  • 如果IDE配置了错误的JDK版本,就会发生这种情况。

    如果IDE的缓存与文件系统不同步,就会发生这种情况。有IDE特定的方法可以解决这个问题。

    这可能是一个IDE错误。例如@Joel Costigliola描述了一个Eclipse没有正确处理Maven“测试”树的场景:看到这个答案了吗。(显然,这个特定的错误很久以前就被修复了。)

    Android问题:当你为Android系统编程时,如果出现与R相关的“找不到符号”错误,请注意R符号是由上下文定义的。xml文件。检查你的上下文。xml文件正确且位置正确,并且相应的R类文件已生成/编译。请注意,Java符号区分大小写,因此相应的XML ID也区分大小写。

    Android上的其他符号错误可能是由于前面提到的原因;e、 g.缺少或不正确的依赖项、不正确的包名、特定API版本中不存在的方法或字段、拼写/键入错误等。

    隐藏系统类:我见过编译器抱怨subString是未知符号的情况,如下所示

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

    事实证明,程序员创建了自己版本的String,而他版本的类没有定义子字符串方法。我见过人们用系统扫描仪和其他课程来做这件事。

    教训:不要用与公共库类相同的名称定义自己的类!

    这个问题也可以通过使用完全限定的名称来解决。例如,在上面的例子中,程序员可以写:

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

    同形文字:如果您对源文件使用UTF-8编码,可能会有看起来相同但实际上不同的标识符,因为它们包含同形文字。有关详细信息,请参阅此页。

    您可以通过将自己限制为ASCII或拉丁语-1作为源文件编码,并对其他字符使用Java\uxxxx转义来避免这种情况。

    1-如果您可能在运行时异常或错误消息中看到这一点,那么您可能已经将IDE配置为运行带有编译错误的代码,或者您的应用程序正在生成和编译代码。。在运行时
    2-土木工程的三个基本原则:水不会向上流动,木板的侧面更坚固,你不能推绳子

  •  类似资料:
    • 我的Android Studio不断给出错误,无法解析符号R。它是Android目录中名为R.java的文件。我已将此文件安全地保存在目录中。但它仍然显示出错误。在互联网上搜索到这个错误后,人们建议我重新构建/清理/升级项目同步/重新启动Android Studio和其他方法。我什么都做了。但问题仍然存在!怎么办??

    • 我试图在我的Android项目中设置一个RecycerView,但是我不能引用我的列表,因为使用代码“RecycerView=view.findviewbyid(r.id.list)”给我的错误不能解析符号“list”。如果我尝试输入“R.ID”我找不到r.id.list,但我确定我给它的id是“list”。 我只是在代码中添加了依赖项和import语句。我试图重新同步和清理项目,但没有结果。 这

    • 这里是我的导入: 这里是错误的代码: 这里是xml文件中RecyclerView的声明:

    • 我的Android Studio一直在给出错误不能解析符号R。它是Android目录中的一个文件,名为r.java。我把这个文件安全地放在目录里。但是,它仍然显示出错误。在网上搜索到这个错误后,人们建议我做重建/清理/分级项目同步/重启Android Studio等方法。我什么都做了。但问题仍然存在!怎么办??

    • 这里有一个类似的答案:如何在Java中将函数作为参数传递? 但提供的正确答案不起作用。我有一门课: 在函数内部我试图将传递到,但我得到的错误是: 找不到符号 符号:类Callable 我不知道为什么。 另外,我尝试使用返回类型字符串作为xMethod,您能传递一个返回类型不同的函数吗?

    • 代码运行,但无法获得函数、类等的建议。 谢谢