"심볼을 찾을 수 없음"컴파일 오류는 무엇을 의미합니까?
"기호를 찾을 수 없음"오류에 대해 다음을 설명하십시오.
- 이 오류는 무엇을 의미합니까?
- 이 오류의 원인은 무엇입니까?
- 프로그래머는이 오류를 어떻게 해결합니까?
이 질문은 Java에서 "심볼을 찾을 수 없음"컴파일 오류에 대한 포괄적 인 질문으로 설계되었습니다.
1. "기호를 찾을 수 없음"오류는 무엇을 의미합니까?
먼저 컴파일 오류 1 입니다. 그것은 것을 의미 중 하나를 자바 소스 코드에 문제가, 또는 당신이 그것을 컴파일하는 방식에 문제가있다.
Java 소스 코드는 다음으로 구성됩니다.
- 키워드 : 같은
true
,false
,class
,while
, 등. - 리터럴 : like
42
and'X'
and"Hi mum!"
. - 연산자 및 기타 영숫자가 아닌 토큰 (예 :
+
,,=
등{
) - 식별자 : 같은
Reader
,i
,toString
,processEquibalancedElephants
, 등. - 주석과 공백.
"심볼을 찾을 수 없습니다"오류는 식별자에 관한 것입니다. 코드가 컴파일되면 컴파일러는 코드의 각 식별자가 의미하는 바를 해결해야합니다.
"기호를 찾을 수 없음"오류는 컴파일러가이를 수행 할 수 없음을 의미합니다. 코드가 컴파일러가 이해하지 못하는 것을 나타내는 것으로 보입니다.
2. "기호를 찾을 수 없음"오류의 원인은 무엇입니까?
첫 번째 주문은 원인이 하나뿐입니다. 컴파일러는 식별자 를 정의 해야하는 모든 위치를 조사했으며 정의를 찾을 수 없습니다. 여러 가지가 원인 일 수 있습니다. 일반적인 것은 다음과 같습니다.
- 일반적으로 식별자의 경우 :
- 아마도 당신은 이름의 철자를 잘못 입력했을 것입니다; 즉
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()'
유형 또는 인스턴스에 예상 한 멤버가없는 것으로 보이는 경우 :
- 아마도 사용하려는 유형 을 가리는 중첩 클래스 또는 일반 매개 변수를 선언했을 것 입니다.
- 아마도 당신은 정적 변수 나 인스턴스 변수를 가리고있을 것입니다.
- 아마도 잘못된 유형을 가져 왔을 것입니다. 예를 들어 IDE 완성 또는 자동 수정으로 인해.
- 아마도 잘못된 버전의 API를 사용하고 있습니다 (컴파일).
- 아마도 객체를 적절한 서브 클래스로 캐스팅하는 것을 잊었을 것입니다.
문제는 종종 위의 조합입니다. 예를 들어, "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 등.
다른 더 모호한 원인도 있습니다 ... 아래에서 다루겠습니다.
3.이 오류를 어떻게 해결합니까?
일반적으로 컴파일 오류의 원인 을 파악하여 시작합니다 .
- 컴파일 오류 메시지로 표시된 파일의 행을보십시오.
- 오류 메시지가 말하는 기호를 식별하십시오.
- 그림 밖으로 이유는 컴파일러가 심볼을 찾을 수없는 것을 말하고, 위 참조!
그럼 당신은 생각 코드를 말하는 것으로 예상되는 것에 대해. 그런 다음 마지막으로 원하는 것을 수행하기 위해 소스 코드를 수정해야하는 문제를 해결합니다.
모든 "수정"이 올바른 것은 아닙니다. 이걸 고려하세요:
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
루프 - 잘못된 아마! - 등등.
요점은 당신이 있다는 것입니다 필요한 코드가 올바른 수정을 찾기 위해 어떻게 노력하고 이해하는.
4. 모호한 원인
다음은 "심볼을 찾을 수 없음"이 더 이상 보이지 않을 때까지 설명 할 수없는 몇 가지 경우입니다.
잘못된 종속성 : 빌드 경로 및 프로젝트 종속성을 관리하는 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();
'가변이 범위를 벗어남'의 또 다른 예
내가 몇 번이나 그런 종류의 질문을 보았 듯이, 그것이 괜찮다고 느낄 지라도 불법적 인 것에 대한 또 다른 예일 것 입니다.
이 코드를 고려하십시오.
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);
이클립스 에서이 오류를 얻는 한 가지 방법 :
- 에 클래스
A
를 정의하십시오src/test/java
. - class 를 사용하는 다른 클래스
B
를 정의하십시오 .src/main/java
A
결과 : Eclipse는 코드를 컴파일하지만 maven은 "기호를 찾을 수 없음"을 표시합니다.
기본 원인 : Eclipse는 기본 트리와 테스트 트리에 대해 빌드 경로를 결합하여 사용합니다. 불행히도 Maven이 요구하는 Eclipse 프로젝트의 다른 부분에 대해 다른 빌드 경로 사용을 지원하지 않습니다.
해결책 :
- 그런 식으로 의존성을 정의하지 마십시오. 즉,이 실수를하지 마십시오.
- Maven을 사용하여 정기적으로 코드베이스를 구축하여이 실수를 조기에 해결하십시오. 이를 수행하는 한 가지 방법은 CI 서버를 사용하는 것입니다.
"찾을 수 없음"은 적절한 변수, 메소드, 클래스 등을 찾을 수없는 컴파일러를 의미합니다. 오류 마사지를 받으면 먼저 오류 마사지를받는 코드 줄을 찾으십시오. 사용하기 전에 정의하지 않은 변수, 메소드 또는 클래스를 찾을 수 있습니다. 확인 후 해당 변수, 메소드 또는 클래스를 나중에 초기화하기 위해 사용할 수 있습니다 ... 다음 예제를 고려하십시오.
데모 클래스를 만들고 이름을 인쇄하겠습니다.
class demo{
public static void main(String a[]){
System.out.print(name);
}
}
이제 결과를보십시오 ..
'변수 이름을 찾을 수 없습니다'라는 오류가 표시됩니다. 'name'변수의 값을 정의하고 초기화하면 해당 오류가 사라질 수 있습니다.
class demo{
public static void main(String a[]){
String name="smith";
System.out.print(name);
}
}
이제 새로운 출력을보십시오 ...
Ok는 성공적으로 그 오류를 해결했습니다 .. 동시에, 당신이 "메소드를 찾을 수 없습니다"또는 "클래스를 찾을 수 없습니다"를 얻을 수 있다면, 처음에는 클래스 또는 메소드를 정의하고 사용 후에 ..
IDE에서 모든 것이 완벽하다고 말하면서 빌드 에서이 오류가 발생하면 두 곳에서 동일한 Java 버전을 사용하고 있는지 확인하십시오.
예를 들어, Java 7과 Java 8의 API는 서로 다르므로 이전 Java 버전에서 존재하지 않는 API를 호출하면이 오류가 발생합니다.
나도이 오류가 발생했습니다. (내가 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 빌드 단계
힌트를 보려면 오류가 발생하는 클래스 이름 이름과 행 번호를 자세히 살펴보십시오. 예 : 컴파일 실패 [ERROR] \ applications \ xxxxx.java : [44,30] 오류 : 기호를 찾을 수 없습니다
또 다른 원인은 jdk7 대 8 버전의 Java 버전에서 지원되지 않는 방법입니다. % JAVA_HOME % 확인
사람들이 위에서 언급 한 것처럼 다양한 시나리오가있을 수 있습니다. 이 문제를 해결하는 데 도움이 된 몇 가지 사항이 있습니다.
IntelliJ를 사용하는 경우
File -> 'Invalidate Caches/Restart'
또는
참조되는 클래스가 다른 프로젝트에 있었고 해당 종속성이 내 프로젝트의 Gradle 빌드 파일에 추가되지 않았습니다. 그래서 다음을 사용하여 종속성을 추가했습니다.
compile project(':anotherProject')
그리고 효과가있었습니다. HTH!
maven compile을 사용하여 코드를 컴파일 한 다음 maven 테스트를 사용하여 정상적으로 작동했습니다. 이제 코드에서 무언가를 변경하고 컴파일하지 않고 실행하면이 오류가 발생합니다.
솔루션 : 다시 컴파일 한 다음 테스트를 실행하십시오. 나에게 이런 식으로 일했다.
제 경우에는 아래 작업을 수행해야했습니다.
- 이동
context.xml
에서 파일을src/java/package
받는resource
디렉토리 (인 IntelliJ IDE) - 깨끗한
target
디렉토리.
참고 URL : https://stackoverflow.com/questions/25706216/what-does-a-cannot-find-symbol-compilation-error-mean
'development' 카테고리의 다른 글
레일스 라우팅 헬퍼 (예 : mymodel_path (model))를 모델에 사용할 수 있습니까? (0) | 2020.02.29 |
---|---|
버퍼와 같은 Vim의 탭 사용 (0) | 2020.02.29 |
Microsoft .NET 4.0 전체 프레임 워크와 클라이언트 프로파일의 차이점 (0) | 2020.02.29 |
EXE를 출력하기 위해 .NET Core 콘솔 응용 프로그램을 빌드 하시겠습니까? (0) | 2020.02.29 |
빈 Pandas DataFrame을 만든 다음 채우시겠습니까? (0) | 2020.02.29 |