답변:
실제로는 아닙니다. "기호를 찾을 수 없습니다"와 "기호를 확인할 수 없습니다"는 같은 의미입니다. 일부 Java 컴파일러는 하나의 문구를 사용하고 일부는 다른 문구를 사용합니다.
먼저 컴파일 오류 1 입니다. 그것은 것을 의미 중 하나를 자바 소스 코드에 문제가, 또는 당신이 그것을 컴파일하는 방식에 문제가있다.
Java 소스 코드는 다음으로 구성됩니다.
true
, false
, class
, while
, 등.42
and 'X'
and "Hi mum!"
.+
,, =
등 {
)Reader
, i
, toString
,processEquibalancedElephants
, 등."심볼을 찾을 수 없음"오류는 식별자에 관한 것입니다. 코드가 컴파일되면 컴파일러는 코드의 각 식별자가 의미하는 바를 해결해야합니다.
"기호를 찾을 수 없음"오류는 컴파일러가이를 수행 할 수 없음을 의미합니다. 코드가 컴파일러가 이해하지 못하는 것을 나타내는 것으로 보입니다.
첫 번째 주문은 원인이 하나뿐입니다. 컴파일러는 식별자 를 정의 해야하는 모든 위치를 조사했지만 정의를 찾을 수 없습니다. 여러 가지가 원인 일 수 있습니다. 일반적인 것은 다음과 같습니다.
StringBiulder
대신StringBuilder
. Java는 잘못된 철자 나 타이핑 오류를 보상하려고 시도하지 않습니다.stringBuilder
대신 StringBuilder
. 모든 Java 식별자는 대소 문자를 구분합니다.mystring
와는 my_string
다르다. (자바 스타일 규칙을 고수하면이 실수로부터 크게 보호됩니다 ...)메소드 또는 필드 이름이어야하는 식별자의 경우 :
"someString".push()
2 ."someString".length
또는 someArray.length()
.아마도 배열 요소가 아닌 배열에서 실수로 작동하고있을 것입니다. 예 :
String strings[] = ...
if (strings.charAt(3)) { ... }
// maybe that should be 'strings[0].charAt(3)'
클래스 이름이어야하는 식별자의 경우 :
아마도 당신은 다음 new
과 같이 a를 잊어 버렸습니다 .
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()) {
...
}
명령문 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
where가 Foo
사용 되는 경우 Bar
. 컴파일 한 적이없고 Bar
실행 javac Foo.java
한 경우 컴파일러가 심볼을 찾을 수 없다는 것을 알게 Bar
됩니다. 간단한 대답은 컴파일 Foo
하고 Bar
함께하는 것입니다. 예를 들어 javac Foo.java Bar.java
또는 javac *.java
. 또는 여전히 Java 빌드 도구를 사용하는 것이 좋습니다. 예를 들어 Ant, Maven, Gradle 등.
다른 더 모호한 원인도 있습니다 ... 아래에서 다루겠습니다.
일반적으로 컴파일 오류의 원인 을 파악하여 시작합니다 .
그럼 당신은 생각 코드를 말하는 것으로 예상되는 것에 대해. 그런 다음 마지막으로 원하는 것을 수행하기 위해 소스 코드를 수정해야하는 문제를 해결합니다.
모든 "수정"이 올바른 것은 아닙니다. 이걸 고려하세요:
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
루프 - 잘못된 아마!요점은 당신이 있다는 것입니다 필요한 코드가 올바른 수정을 찾기 위해 어떻게 노력하고 이해하는.
다음은 "심볼을 찾을 수 없음"이 더 이상 보이지 않을 때까지 설명 할 수없는 몇 가지 경우입니다.
잘못된 종속성 : 빌드 경로 및 프로젝트 종속성을 관리하는 IDE 또는 빌드 도구를 사용하는 경우 종속성에 실수가있을 수 있습니다. 예를 들어 종속성을 제거하거나 잘못된 버전을 선택했습니다. 빌드 도구 (Ant, Maven, Gradle 등)를 사용하는 경우 프로젝트의 빌드 파일을 확인하십시오. IDE를 사용하는 경우 프로젝트의 빌드 경로 구성을 확인하십시오.
재 컴파일 하지 않는 경우 : 새로운 Java 프로그래머가 Java 툴 체인의 작동 방식을 이해하지 못하거나 반복 가능한 "빌드 프로세스"를 구현하지 않은 경우가 있습니다. 예를 들어 IDE, Ant, Maven, Gradle 등을 사용합니다. 이러한 상황에서 프로그래머가되는 환상 오류를 찾고 자신의 꼬리를 쫓는 끝낼 수 실제로 제대로 코드를 재 컴파일하지 않음으로써 발생하는 등 ...
초기 빌드 문제 : 클래스가 누락 된 JAR 파일을 제공하는 방식으로 이전 빌드가 실패했을 수 있습니다. 빌드 도구를 사용하는 경우 일반적으로 이러한 실패가 나타납니다. 그러나 다른 사람으로부터 JAR 파일을 얻는 경우 파일을 올바르게 빌드하고 오류를 확인 하는 데 의존 합니다. 의심되는 경우 tar -tvf
의심스러운 JAR 파일의 내용을 나열하는 데 사용 하십시오.
IDE 문제 : 사람들은 IDE가 혼란스러워 IDE의 컴파일러가 존재하는 클래스를 찾을 수없는 경우 또는 반대 상황을보고했습니다.
IDE가 잘못된 JDK 버전으로 구성된 경우 발생할 수 있습니다.
IDE의 캐시가 파일 시스템과 동기화되지 않으면 이런 일이 발생할 수 있습니다. 이를 해결하는 IDE 특정 방법이 있습니다.
이것은 IDE 버그 일 수 있습니다. 예를 들어 @Joel Costigliola는 Eclipse가 Maven "테스트"트리를 올바르게 처리하지 않는 시나리오를 설명합니다 ( 이 답변 참조) .
Android 문제 : Android 용 으로 프로그래밍 할 때와 관련된 "기호를 찾을 수 없습니다"오류가 발생 R
하면 R
기호가 context.xml
파일에 의해 정의 된다는 점에 유의 하십시오. 당신 있는지 확인 context.xml
파일이 정확하고 올바른 위치에 있고, 대응하는 R
클래스 파일이 생성 된 / 컴파일. Java 기호는 대소 문자를 구분하므로 해당 XML ID도 대소 문자를 구분합니다.
Android의 다른 기호 오류는 이전에 언급 한 이유 때문일 수 있습니다. 예 : 누락되거나 잘못된 종속성, 잘못된 패키지 이름, 특정 API 버전에 존재하지 않는 메소드 또는 필드, 철자 / 입력 오류 등
시스템 클래스 재정의 : 컴파일러 substring
가 다음과 같은 알 수없는 기호 라고 불평하는 경우를 보았습니다.
String s = ...
String s1 = s.substring(1);
프로그래머가 자신의 버전을 String
만들고 클래스 버전이 substring
메소드를 정의하지 않은 것으로 나타났습니다 .
레슨 : 공통 라이브러리 클래스와 이름이 같은 클래스를 직접 정의하지 마십시오!
호모 글리프 : 당신이 당신의 소스 파일을 UTF-8 인코딩을 사용하는 경우,이 식별자를 가질 수 있습니다 보면 같은, 그러나 호모 글리프 포함되어 있기 때문에 사실 다른에 있습니다. 자세한 내용은 이 페이지 를 참조하십시오.
소스 파일 인코딩으로 ASCII 또는 Latin-1로 제한 \uxxxx
하고 다른 문자에 Java 이스케이프를 사용하면이를 피할 수 있습니다 .
1 - 경우, 아마, 당신은 할 다음 중 하나를 사용하면 컴파일 오류와 실행 코드로 IDE를 구성하거나 응용 프로그램이 실행시에 .. 생성하고 코드를 컴파일, 런타임 예외 또는 오류 메시지에이를 참조하십시오.
2-토목 공학의 세 가지 기본 원칙 : 물이 오르막으로 흐르지 않고 널빤지가 더 강해져 끈을 밀 수 없습니다 .
다음을 잊어 버린 경우에도이 오류가 발생합니다 new
.
String s = String();
대
String s = new String();
new
키워드가 String
없는 호출 은 인수없이 호출 된 (로컬) 메소드를 찾으려고 시도 하므로 해당 메소드 서명이 정의되지 않았을 수 있습니다.
'가변이 범위를 벗어났습니다'의 또 다른 예
내가 몇 번이나 그런 종류의 질문을 보았 듯이, 그것이 기분 이 좋지 않더라도 불법적 인 것에 대한 또 다른 예일 것 입니다.
이 코드를 고려하십시오.
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-values를 외부 범위의 변수 이름에 미리 할당 한 다음 다음과 같은 경우에 다시 할당하는 것입니다.
String message = "We have an error";
if(somethingIsTrue()) {
message = "Everything is fine";
}
System.out.println(message);
final
변수 선언 을 사용하는 것 입니다.
이클립스 에서이 오류를 얻는 한 가지 방법 :
A
를 정의하십시오 src/test/java
.B
를 정의하십시오 .src/main/java
A
결과 : Eclipse는 코드를 컴파일하지만 maven은 "기호를 찾을 수 없음"을 표시합니다.
기본 원인 : Eclipse는 기본 트리와 테스트 트리에 대해 빌드 경로를 결합하여 사용합니다. 불행히도 Maven이 요구하는 Eclipse 프로젝트의 다른 부분에 대해 다른 빌드 경로 사용을 지원하지 않습니다.
해결책 :
"찾을 수 없음"은 적절한 변수, 메소드, 클래스 등을 찾을 수없는 컴파일러를 의미합니다. 오류 마사지를 받으면 먼저 오류 마사지를받는 코드 줄을 찾으십시오. 사용하기 전에 정의하지 않은 변수, 메소드 또는 클래스를 찾을 수 있습니다. 확인 후 해당 변수, 메소드 또는 클래스를 초기화 한 후 나중에 요구할 수 있습니다 ... 다음 예제를 고려하십시오.
데모 클래스를 만들고 이름을 인쇄하겠습니다.
class demo{
public static void main(String a[]){
System.out.print(name);
}
}
이제 결과를보십시오 ..
"변수 이름을 찾을 수 없습니다"라는 오류가 표시됩니다.
class demo{
public static void main(String a[]){
String name="smith";
System.out.print(name);
}
}
이제 새로운 출력을보십시오 ...
Ok는 성공적으로 그 에러를 해결했다.
나도이 오류가 발생했습니다. (내가 Google에 접속하여이 페이지로 연결됨)
문제점 : 다른 프로젝트 B에 정의 된 클래스에서 프로젝트 A의 클래스에 정의 된 정적 메소드를 호출했습니다. 다음 오류가 발생했습니다.
error: cannot find symbol
솔루션 : 먼저 메소드가 정의 된 프로젝트를 빌드 한 다음 메소드가 호출 된 프로젝트를 빌드하여이 문제를 해결했습니다.
일식 Java 빌드 경로가 7, 8에 매핑되고 Project pom.xml에서 Maven 속성 java.version이 7,8보다 높은 Java 버전 (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을 에서 작품에
또는
추가 (팝업 창이 열립니다)->
Name:
Java 11 지원
Location:
http://download.eclipse.org/eclipse/updates/4.9-P-builds
다음 과 같이 pom.xml 파일 의 Maven 속성에서 Java 버전을 업데이트 하십시오.
<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
마지막으로 프로젝트 디버그를 마우스 오른쪽 버튼으로 클릭하십시오-> Maven clean, Maven 빌드 단계
제 경우에는 아래 작업을 수행해야했습니다.
context.xml
에서 파일을 src/java/package
받는 resource
디렉토리 (인 IntelliJ IDE)target
디렉토리.