Ste*_*n C 364 java compiler-errors cannot-find-symbol
请解释以下关于"无法找到符号"的错误:
这个问题旨在成为一个关于Java中"无法找到符号"编译错误的综合问题.
Ste*_*n C 381
首先,它是编译错误1.这意味着,无论有在Java源代码中的问题,或有在你编译它的方式有问题.
您的Java源代码包含以下内容:
true,false,class,while,等.42和'X'和"Hi mum!".+,=,{,等等.Reader,i,toString,processEquibalancedElephants,等."无法找到符号"错误与标识符有关.编译代码时,编译器需要确定代码中每个标识符的含义.
"无法找到符号"错误意味着编译器无法执行此操作.您的代码似乎是指编译器无法理解的内容.
作为第一个订单,只有一个原因.编译器查找了应该定义标识符的所有位置,并且找不到定义.这可能是由许多事情引起的.常见的如下:
StringBiulder代替StringBuilder.Java不能也不会尝试补偿错误的拼写或输入错误.stringBuilder代替StringBuilder.所有Java标识符都区分大小写.mystring和my_string不同.(如果您坚持使用Java样式规则,那么您将在很大程度上受到这种错误的保护......)"someString".push()2."someString".length或someArray.length().对于应该是类名的标识符:
也许你忘记了new:
String strings[] = ...
if (strings.charAt(3)) { ... }
// maybe that should be 'strings[0].charAt(3)'
Run Code Online (Sandbox Code Playgroud)对于类型或实例似乎没有您期望的成员的情况:
问题通常是上述的组合.例如,也许你"明星"导入java.io.*,然后尝试使用Files该类...这java.nio不是java.io.或许你打算写File...这是一个班级java.io.
以下是不正确的变量范围如何导致"无法找到符号"错误的示例:
String s = String(); // should be 'new String()'
Run Code Online (Sandbox Code Playgroud)
这将i在if语句中给出"无法找到符号"错误.虽然我们之前已经声明i,但该声明仅适用于for声明及其正文.以参考i在if声明中无法看到的那个声明i.它超出了范围.
(这里适当的修正可能是if在循环中移动语句,或者i在循环开始之前声明.)
这是一个导致困惑的例子,其中拼写错误导致看似莫名其妙的"无法找到符号"错误:
List<String> strings = ...
for (int i = 0; i < strings.size(); i++) {
if (strings.get(i).equalsIgnoreCase("fnord")) {
break;
}
}
if (i < strings.size()) {
...
}
Run Code Online (Sandbox Code Playgroud)
这将在println调用中显示i无法找到的编译错误.但是(我听你说)我确实宣布了!
问题是之前的鬼鬼祟祟的分号(;){.Java语言语法将该上下文中的分号定义为空语句.然后空语句成为for循环体.所以代码实际上意味着:
for (int i = 0; i < 100; i++); {
System.out.println("i is " + i);
}
Run Code Online (Sandbox Code Playgroud)
该{ ... }块不是身体for循环,并因此与先前的声明i中的for说法是超出范围的块.
这是由拼写错误引起的"无法找到符号"错误的另一个示例.
for (int i = 0; i < 100; i++);
// The previous and following are separate statements!!
{
System.out.println("i is " + i);
}
Run Code Online (Sandbox Code Playgroud)
尽管与先前的声明中,tmp在tmp(...)表达是错误的.编译器将查找一个名为的方法tmp,但不会找到一个方法.先前声明的tmp是变量的名称空间,而不是方法的名称空间.
在我遇到的例子中,程序员实际上已经遗漏了一个操作员.他打算写的是:
int tmp = ...
int res = tmp(a + b);
Run Code Online (Sandbox Code Playgroud)
如果从命令行编译,编译器可能找不到符号还有另一个原因.您可能只是忘记编译或重新编译其他类.举例来说,如果你有类Foo和Bar地方Foo使用Bar.如果您从未编译过Bar并且运行过javac Foo.java,则可能会发现编译器无法找到该符号Bar.简单的答案是编译Foo和Bar在一起; 例如javac Foo.java Bar.java或javac *.java.或者更好的是仍然使用Java构建工具; 例如Ant,Maven,Gradle等.
还有其他一些比较模糊的原因......我将在下面讨论.
一般来说,您首先要弄清楚导致编译错误的原因.
然后你想想你的代码应该说些什么.最后,您需要确定需要对源代码进行哪些更正才能执行您想要的操作.
请注意,并非每个"校正"都是正确的.考虑一下:
int res = tmp * (a + b);
Run Code Online (Sandbox Code Playgroud)
假设编译器说"找不到符号" j.有很多方法可以"修复":
for到for (int j = 1; j < 10; j++)-可能是正确的.j 之前添加一个声明- 可能是正确的.forforj,以i在内部for循环-可能是错的!关键是您需要了解代码尝试执行的操作才能找到正确的修复方法.
这里有几个案例,"无法找到符号"看起来似乎莫名其妙......直到你仔细观察.
不正确的依赖项:如果您使用的是IDE或构建工具来管理构建路径和项目依赖项,那么您可能在依赖项方面犯了错误; 例如,遗漏了依赖关系,或选择了错误的版本.如果您使用的是构建工具(Ant,Maven,Gradle等),请检查项目的构建文件.如果您使用的是IDE,请检查项目的构建路径配置.
您没有重新编译:有时会发生新的Java程序员不了解Java工具链的工作原理,或者没有实现可重复的"构建过程"; 例如使用IDE,Ant,Maven,Gradle等.在这种情况下,程序员最终可能会追逐他的尾巴寻找一个虚幻的错误,这个错误实际上是由于没有正确地重新编译代码而导致的......等等......
较早的构建问题:早期构建可能以一种给JAR文件缺少类的方式失败.如果您使用构建工具,通常会注意到这种失败.但是,如果您从其他人那里获取JAR文件,则依赖于它们正确构建并注意错误.如果您怀疑这一点,请使用tar -tvf列出可疑JAR文件的内容.
IDE问题:人们已经报告了他们的IDE混淆的情况,并且IDE中的编译器找不到存在的类......或者相反的情况.
如果IDE的缓存与文件系统不同步,则会发生这种情况.有IDE特定的方法来解决这个问题.
这可能是一个IDE错误.例如,@ Joel Costigliola描述了Eclipse无法正确处理Maven"测试"树的场景:请参阅此答案.
重新定义系统类:我已经看到了编译器抱怨这R是一个未知符号的情况,如下所示
for (int i = 1; i < 10; i++) {
for (j = 1; j < 10; j++) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
事实证明,程序员已经创建了自己的版本,R并且他的类版本没有定义context.xml方法.
课程:不要使用与公共库类相同的名称来定义自己的类!
Homoglyphs: 如果对源文件使用UTF-8编码,则可能具有看起来相同但实际上不同的标识符,因为它们包含同形字符.有关更多信息,请参阅此页面.
您可以通过将自己限制为ASCII或Latin-1作为源文件编码,并将Java context.xml转义符用于其他字符来避免这种情况.
1 -如果,或许,你也看到这个运行时异常或错误信息,那么无论你已经配置了IDE运行具有编译错误的代码,或者您的应用程序生成和编译代码..在运行时.
2 - 土木工程的三个基本原则:水不会上坡,木板侧面更强,你不能用绳子推.
thi*_*rry 22
如果您忘记了new以下情况,您也会收到此错误:
String s = String();
Run Code Online (Sandbox Code Playgroud)
与
String s = new String();
Run Code Online (Sandbox Code Playgroud)
Jan*_*Jan 14
"变量超出范围"的另一个例子
正如我已经看过几次这样的问题,也许还有一个例子,即使它可能感觉不错也是非法的.
考虑以下代码:
if(somethingIsTrue()) {
String message = "Everything is fine";
} else {
String message = "We have an error";
}
System.out.println(message);
Run Code Online (Sandbox Code Playgroud)
这是无效的代码.因为命名的变量都不在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);
}
Run Code Online (Sandbox Code Playgroud)
"哦,有重复的代码,让我们拉出那条普通的线路" - >然后就可以了.
处理这种范围问题的最常见方法是将else-values预先分配给外部作用域中的变量名称,然后在以下情况下重新分配:
String message = "We have an error";
if(somethingIsTrue()) {
message = "Everything is fine";
}
System.out.println(message);
Run Code Online (Sandbox Code Playgroud)
在Eclipse中获取此错误的一种方法:
A在src/test/java.B在src/main/java该使用类中定义另一个类A.结果:Eclipse将编译代码,但maven将给出"找不到符号".
基本原因:Eclipse正在使用主树和测试树的组合构建路径.不幸的是,它不支持为Eclipse项目的不同部分使用不同的构建路径,这是Maven所需要的.
方案:
如果您在其他地方的构建中遇到此错误,而您的 IDE 表示一切正常,那么请检查您在两个地方是否使用相同的 Java 版本。
例如,Java 7 和 Java 8 有不同的 API,因此在较旧的 Java 版本中调用不存在的 API 会导致此错误。
“找不到”表示编译器找不到合适的变量,方法,类等...如果您得到了错误提示,首先您要查找得到错误提示的代码行。然后,您将找到能够在使用之前找到尚未定义的变量,方法或类。确认初始化后,该变量,方法或类可用于以后的需求...请考虑以下示例。
我将创建一个演示类并打印名称...
class demo{
public static void main(String a[]){
System.out.print(name);
}
}
Run Code Online (Sandbox Code Playgroud)
现在看一下结果。
该错误表示“找不到变量名”。可以消除“ name”变量的定义和初始化值。实际上,
class demo{
public static void main(String a[]){
String name="smith";
System.out.print(name);
}
}
Run Code Online (Sandbox Code Playgroud)
现在看看新的输出...
好,成功解决了该错误。同时,如果您得到“找不到方法”或“找不到类”的东西,请首先定义一个类或方法,然后再使用它。
正如人们在之前的答案中提到的那样,可能存在各种情况。以下是帮助我解决此问题的几件事。
\n如果您使用的是IntelliJ IDEA
\n菜单文件\xe2\x86\x92使缓存无效/重新启动
\n或者
\n被引用的类位于另一个项目中,并且该依赖项未添加到我的项目的 Gradle 构建文件中。所以我使用添加了依赖项
\ncompile project(\':anotherProject\')
它奏效了。
\n| 归档时间: |
|
| 查看次数: |
856350 次 |
| 最近记录: |