“找不到符号”编译错误是什么意思?
请解释以下关于“无法找到符号”错误:
这个问题被设计成一个关于Java中“无法找到符号”编译错误的综合性问题。
1.“无法找到符号”错误是什么意思?
首先,这是一个编译错误1。 这意味着您的Java源代码中存在问题,或者您编译的方式存在问题。
您的Java源代码包含以下内容:
true
, false
, class
, while
等等。 42
和'X'
和"Hi mum!"
。 +
, =
, {
等等。 Reader
, i
, toString
, processEquibalancedElephants
等。 “无法找到符号”错误是关于标识符。 编译代码时,编译器需要确定代码中每个标识符的含义。
“无法找到符号”错误意味着编译器无法执行此操作。 你的代码似乎是指编译器不理解的东西。
2.什么会导致“无法找到符号”错误?
作为第一个订单,只有一个原因。 编译器查看了应该定义标识符的所有地方,并且找不到定义。 这可能是由许多因素造成的。 常见的如下:
StringBiulder
而不是StringBuilder
。 Java不能也不会试图补偿拼写错误或输入错误。 stringBuilder
而不是StringBuilder
。 所有Java标识符都区分大小写。 mystring
和my_string
是不同的。 (如果你坚持Java风格的规则,你将会在很大程度上免受这个错误的影响......) "someString".length
或someArray.length()
。 对于应该是类名称的标识符:
也许你忘了一个new
的:
String s = String(); // should be 'new String()'
对于类型或实例似乎没有您期望的成员的情况:
问题通常是上述的组合。 比如,也许你的“明星”进口java.io.*
,然后试图用Files
类...这是java.nio
不java.io
。 或者也许你打算写File
...这是java.io
一个类。
下面是一个不正确的变量范围如何导致“无法找到符号”错误的例子:
for (int i = 0; i < strings.size(); i++) {
if (strings.get(i).equalsIgnoreCase("fnoord")) {
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 (int i = 0; i < 100; i++);
{
System.out.println("i is " + i);
}
{ ... }
块不是for
循环的主体,所以i
的声明不在该块的范围内。
这是另一个由错字造成的“无法找到符号”错误的例子。
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++)
- 可能是正确的。 for
循环之前为j
添加一个声明,或者在outer for
循环之前添加一个声明 - 可能是正确的。 j
到i
在内for
循环-可能是错的! 重点是你需要了解你的代码试图做什么,以找到正确的修复。
4.不明原因
以下是几个“无法找到符号”的情况,看起来似乎无法解释......直到你仔细观察。
您正在查看错误的源代码 :经常发生的情况是,新的Java程序员不明白Java工具链如何工作,或者没有实现可重复的“构建过程”; 例如使用IDE,Ant,Maven,Gradle等。 在这种情况下,程序员最终可能会追逐他的尾巴寻找一个虚幻的错误,这实际上是由于没有正确地重新编译代码而造成的,等等......
IDE问题 :人们报告了他们的IDE感到困惑,并且IDE中的编译器无法找到存在的类或相反的情况。
如果IDE的缓存与文件系统不同步,就会发生这种情况。 有IDE特定的方法来解决这个问题。
这可能是一个IDE错误。 例如@Joel Costigliola描述了一个Eclipse不能正确处理Maven“测试”树的场景: 查看这个答案 。
重新定义系统类 :我见过编译器抱怨substring
是一个未知符号的情况,如下所示
String s = ...
String s1 = s.substring(1);
事实证明,程序员已经创建了他们自己的String
版本,并且他的版本没有定义substring
方法。
课程:不要使用与通用库类相同的名称定义自己的类!
同态语言:如果您对源文件使用UTF-8编码,可能会使标识符看起来相同,但事实上不同,因为它们包含同类映射。 请参阅此页面了解更多信息。
您可以通过将自己限制为ASCII或Latin-1作为源文件编码,并将Java uxxxx
转义用于其他字符来避免这种情况。
1 - 如果偶然发现运行时异常或错误消息中出现这种情况,那么要么您将IDE配置为运行带有编译错误的代码,要么您的应用程序正在运行时生成并编译代码。
如果你忘记了一个new
话,你也会得到这个错误:
String s = String();
与
String s = new String();
“变量超出范围”的另一个例子是
正如我已经多次看到过这样的问题,或许可以再举一个例子来证明什么是非法的,即使它可能感觉没问题。
考虑这个代码:
if(somethingIsTrue()) {
String message = "Everything is fine";
} else {
String message = "We have an error";
}
System.out.println(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);
}
“哦,这里有重复的代码,让我们把这条公共线路拉出来 - ”然后就是它了。
处理这种范围问题的最常见方法是预先将其他值分配给外部范围中的变量名称,然后在以下情况下重新分配:
String message = "We have an error";
if(somethingIsTrue()) {
message = "Everything is fine";
}
System.out.println(message);
链接地址: http://www.djcxy.com/p/9373.html
上一篇: What does a "Cannot find symbol" compilation error mean?