Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
756 views
in Technique[技术] by (71.8m points)

java - “找不到符号”或“无法解析符号”错误是什么意思?(What does a “Cannot find symbol” or “Cannot resolve symbol” error mean?)

Please explain the following about "Cannot find symbol" and "Cannot resolve symbol" errors: (请解释以下有关“找不到符号”和“无法解析符号”错误的信息:)

  • What does they mean? (什么意思)
  • What things can cause them? (什么事会导致它们?)
  • How does the programmer go about fixing them? (程序员如何进行修复?)

This question is designed to seed a comprehensive Q&A about these common compilation errors in Java. (该问题旨在对Java中的这些常见编译错误进行全面的问答。)

  ask by Stephen C translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

0. Is there any difference between the two errors? (0.两种错误之间有区别吗?)

Not really. (并不是的。) "Cannot find symbol" and "Cannot resolve symbol" mean the same thing. (“找不到符号”和“无法解析符号”含义相同。) Some Java compilers use one phrase, and some the other one. (一些Java编译器使用一个短语,而另一些则使用。)

1. What does a "Cannot find symbol" error mean? (1.“找不到符号”错误是什么意思?)

Firstly, it is a compilation error 1 . (首先,它是编译错误 1 。) It means that either there is a problem in your Java source code, or there is a problem in the way that you are compiling it. (这意味着, 无论有在Java源代码中出现问题, 或者是你正在编译的方式有问题。)

Your Java source code consists of the following things: (您的Java源代码包含以下内容:)

  • Keywords: like true , false , class , while , and so on. (关键字:像truefalseclasswhile等等。)
  • Literals: like 42 and 'X' and "Hi mum!" (文字:例如42'X'以及"Hi mum!") . (。)
  • Operators and other non-alphanumeric tokens: like + , = , { , and so on. (运算符和其他非字母数字标记:像+={等等。)
  • Identifiers: like Reader , i , toString , processEquibalancedElephants , and so on. (标识符:如ReaderitoStringprocessEquibalancedElephants等。)
  • Comments and whitespace. (注释和空格。)

A "Cannot find symbol" error is about the identifiers. (“找不到符号”错误与标识符有关。) When your code is compiled, the compiler needs to work out what each and every identifier in your code means. (编译代码时,编译器需要确定代码中每个标识符的含义。)

A "Cannot find symbol" error means that the compiler cannot do this. (“找不到符号”错误表示编译器无法执行此操作。) Your code appears to be referring to something that the compiler doesn't understand. (您的代码似乎是指编译器无法理解的内容。)

2. What can cause a "Cannot find symbol" error? (2.什么会导致“找不到符号”错误?)

As a first order, there is only one cause. (首先,只有一个原因。) The compiler looked in all of the places where the identifier should be defined, and it couldn't find the definition. (编译器查看了应该定义标识符的所有位置,但找不到该定义。) This could be caused by a number of things. (这可能是由多种原因引起的。) The common ones are as follows: (常见的如下:)

  • For identifiers in general: (对于一般的标识符:)
    • Perhaps you spelled the name incorrectly; (也许您拼错了名字;) ie StringBiulder instead of StringBuilder . (即StringBiulder而不是StringBuilder 。) Java cannot and will not attempt to compensate for bad spelling or typing errors. (Java无法也不会尝试弥补拼写错误或输入错误。)
    • Perhaps you got the case wrong; (也许你错了。) ie stringBuilder instead of StringBuilder . (即stringBuilder而不是StringBuilder 。) All Java identifiers are case sensitive. (所有Java标识符均区分大小写。)
    • Perhaps you used underscores inappropriately; (也许您不恰当地使用了下划线;) ie mystring and my_string are different. (即mystringmy_string不同。) (If you stick to the Java style rules, you will be largely protected from this mistake ...) ((如果您坚持使用Java样式规则,则将在很大程度上避免出现此错误...))
    • Perhaps you are trying to use something that was declared "somewhere else"; (也许您正在尝试使用被声明为“其他地方”的东西;) ie 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?) ((不同的类?不同的作用域?不同的包?不同的代码库?))
  • For identifiers that should refer to variables: (对于应引用变量的标识符:)
    • 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) ((请参见下面的示例))
  • For identifiers that should be method or field names: (对于应为方法或字段名称的标识符:)

    • Perhaps you are trying to refer to an inherited method or field that wasn't declared in the parent / ancestor classes or interfaces. (也许您正在尝试引用在父/祖先类或接口中未声明的继承方法或字段。)
    • Perhaps you are trying to refer to a method or field that does not exist (ie has not been declared) in the type you are using; (也许您正在尝试引用所使用的类型中不存在(即尚未声明)的方法或字段;) eg "someString".push() 2 . (例如"someString".push() 2 。)
    • Perhaps you are trying to use a method as a field, or vice versa; (也许您正在尝试将方法用作字段,反之亦然;) eg "someString".length or someArray.length() . (例如"someString".lengthsomeArray.length() 。)
    • Perhaps you are mistakenly operating on an array rather than array element; (也许您是错误地对数组而不是数组元素进行操作。) eg (例如)

       String strings[] = ... if (strings.charAt(3)) { ... } // maybe that should be 'strings[0].charAt(3)' 
  • For identifiers that should be class names: (对于应为类名的标识符:)

    • Perhaps you forgot to import the class. (也许您忘记了导入课程。)
    • Perhaps you used "star" imports, but the class isn't defined in any of the packages that you imported. (也许您使用了“星号”导入,但是在您导入的任何软件包中均未定义该类。)
    • Perhaps you forgot a new as in: (也许您忘记了以下new :)

       String s = String(); // should be 'new String()' 
  • For cases where type or instance doesn't appear to have the member you were expecting it to have: (对于类型或实例似乎没有成员的情况,您希望它具有:)

    • 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; (也许您输入了错误的类型;) eg due to IDE completion or auto-correction. (例如由于IDE完成或自动更正。)
    • Perhaps you are using (compiling against) the wrong version of an API. (也许您正在使用(针对)错误版本的API。)
    • Perhaps you forgot to cast your object to an appropriate subclass. (也许您忘记了将对象转换为适当的子类。)

The problem is often a combination of the above. (问题通常是上述情况的组合。) For example, maybe you "star" imported java.io.* and then tried to use the Files class ... which is in java.nio not java.io . (例如,也许您“星标”了导入的java.io.* ,然后尝试使用Files类...,它在java.nio而不是java.io 。) Or maybe you meant to write File ... which is a class in java.io . (也许您打算写File ...这 java.io一个类。)


Here is an example of how incorrect variable scoping can lead to a "Cannot find symbol" error: (这是一个示例,说明变量作用域范围不正确会如何导致“找不到符号”错误:)

List<String> strings = ...

for (int i = 0; i < strings.size(); i++) {
    if (strings.get(i).equalsIgnoreCase("fnord")) {
        break;
    }
}
if (i < strings.size()) {
    ...
}

This will give a "Cannot find symbol" error for i in the if statement. (这将使“无法找到符号”错误iif声明。) Though we previously declared i , that declaration is only in scope for the for statement and its body. (尽管我们之前曾声明过i ,但该声明仅 for语句及其主体的范围内 。) The reference to i in the if statement cannot see that declaration of i . (在if语句中对i的引用看不到 i声明。) It is out of scope . (它超出范围 。)

(An appropriate correction here might be to move the if statement inside the loop, or to declare i before the start of the loop.) ((这里的适当修正可能是将if语句移入循环,或在循环开始之前声明i 。))


Here is an example that causes puzzlement where a typo leads to a seemingly inexplicable "Cannot find symbol" error: (这是一个引起困惑的示例,其中的错别字导致看似莫名的“找不到符号”错误:)

for (int i = 0; i < 100; i++); {
    System.out.println("i is " + i);
}

This will give you a compilation error in the println call saying that i cannot be found. (这会给你一个编译错误的println电话,说i无法找到。) But (I hear you say) I did declare it! (但是(我听到你说)我确实宣布了!)

The problem is the sneaky semicolon ( ; ) before the { . (问题是{之前的冒号( ; )。) The Java language syntax defines a semicolon in that context to be an empty statement . (Java语言语法在该上下文中将分号定义为空语句 。) The empty statement then becomes the body of the for loop. (然后,空语句将成为for循环的主体。) So that code actually means this: (因此该代码实际上意味着:)

for (int i = 0; i < 100; i++); 

// The previous and following are separate statements!!

{
    System.out.println("i is " + i);
}

The { ... } block is NOT the body of the for loop, and therefore the previous declaration of i in the for statement is out of scope in the block. ({ ... }块不是for循环的主体,因此for语句中i的先前声明超出了该块的范围 。)


Here is another example of "Cannot find symbol" error that is caused by a typo. (这是由错字引起的“找不到符号”错误的另一个示例。)

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

Despite the previous declaration, the tmp in the tmp(...) expression is erroneous. (尽管与先前的声明中, tmptmp(...)的表达是错误的。) The compiler will look for a method called tmp , and won't find one. (编译器将寻找一种名为tmp的方法,但找不到。) The previously declared tmp is in the namespace for variables, not the namespace for methods. (先前声明的tmp在变量的名称空间中,而不在方法的名称空间中。)

In the example I came across, the programmer had actually left out an operator. (在我遇到的示例中,程序员实际上省略了一个运算符。) What he meant to write was this: (他的意思是这样写的:)

int res = tmp * (a + b);

There is another reason why the compiler might not find a symbol if you are compiling from the command line. (如果从命令行进行编译,则编译器可能找不到符号还有另一个原因。) You might simply have forgotten to compile or recompile some other clas


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...