"Sembol bulunamıyor" veya "Sembol çözülemiyor" hatası ne anlama geliyor?

Sep 07 2014

Lütfen "Sembol bulunamıyor", "Sembol çözülemiyor" veya "Sembol bulunamadı" hataları hakkında aşağıdakileri açıklayın:

  • Ne demek istiyorlar?
  • Onlara ne sebep olabilir?
  • Programcı bunları düzeltmeye nasıl gidiyor?

Bu soru, Java'daki bu yaygın derleme hataları hakkında kapsamlı bir Soru-Cevap başlatmak için tasarlanmıştır.

Yanıtlar

441 StephenC Sep 07 2014 at 08:12

0. İki hata arasında herhangi bir fark var mı?

Pek sayılmaz. "Sembol bulunamıyor", "Sembol çözülemiyor" ve "Sembol bulunamadı" hepsi aynı anlama gelir. Farklı Java derleyicileri farklı ifadeler kullanır.

1. "Sembol bulunamıyor" hatası ne anlama geliyor?

İlk olarak, bu bir derleme hatasıdır 1 . Bu demektir ya da Java kaynak kodunda bir sorun vardır, ya bunu derleme bu şekilde bir sorun vardır.

Java kaynak kodunuz aşağıdakilerden oluşur:

  • Anahtar Kelimeler: gibi true, false, class, while, vb.
  • Değişmezler: 42ve 'X've gibi "Hi mum!".
  • Operatörler ve alfanümerik olmayan diğer belirteçleri: gibi +, =, {, vb.
  • Tanımlayıcıları: gibi Reader, i, toString, processEquibalancedElephants, vb.
  • Yorumlar ve boşluk.

Tanımlayıcılarla ilgili bir "Sembol bulunamıyor" hatası. Kodunuz derlendiğinde, derleyicinin kodunuzdaki her bir tanımlayıcının ne anlama geldiğini hesaplaması gerekir.

"Sembol bulunamıyor" hatası, derleyicinin bunu yapamayacağı anlamına gelir. Kodunuz, derleyicinin anlamadığı bir şeye gönderme yapıyor gibi görünüyor.

2. "Sembol bulunamıyor" hatasına ne sebep olabilir?

İlk sırada, tek bir neden var. Derleyici, tanımlayıcının tanımlanması gereken tüm yerlere baktı ve tanımı bulamadı. Bunun birkaç nedeni olabilir. Yaygın olanlar aşağıdaki gibidir:

  • Genel olarak tanımlayıcılar için:

    • Belki adı yanlış yazmışsınızdır; yani StringBiulderyerine StringBuilder. Java, kötü yazım veya yazım hatalarını telafi edemez ve etmeyecektir.
    • Belki de davayı yanlış anladınız; yani stringBuilderyerine StringBuilder. Tüm Java tanımlayıcıları büyük / küçük harfe duyarlıdır.
    • Belki de alt çizgileri uygunsuz bir şekilde kullandınız; yani mystringve my_stringfarklı. (Java stil kurallarına bağlı kalırsanız, bu hatadan büyük ölçüde korunacaksınız ...)
    • Belki de "başka bir yerde" ilan edilen bir şeyi kullanmaya çalışıyorsunuz; örtük olarak derleyiciye bakmasını söylediğinizden farklı bir bağlamda. (Farklı bir sınıf mı? Farklı bir kapsam mı? Farklı bir paket mi? Farklı bir kod tabanı mı?)
  • Değişkenlere başvurması gereken tanımlayıcılar için:

    • Belki de değişkeni açıklamayı unuttunuz.
    • Belki de değişken bildirimi, onu kullanmaya çalıştığınız noktada kapsam dışındadır. (Aşağıdaki örneğe bakın)
  • Yöntem veya alan adları olması gereken tanımlayıcılar için:

    • Belki de üst / üst sınıflarda veya arabirimlerde bildirilmemiş, miras alınan bir yönteme veya alana başvurmaya çalışıyorsunuz.

    • Belki de kullandığınız türde olmayan (yani bildirilmemiş) bir yönteme veya alana başvurmaya çalışıyorsunuz; örneğin "someString".push()2 .

    • Belki de bir yöntemi alan olarak kullanmaya çalışıyorsunuz ya da tam tersi; örneğin "someString".lengthveya someArray.length().

    • Belki de yanlışlıkla dizi elemanı yerine bir dizi üzerinde çalışıyorsunuzdur; Örneğin

          String strings[] = ...
          if (strings.charAt(3)) { ... }
          // maybe that should be 'strings[0].charAt(3)'
      
  • Sınıf adları olması gereken tanımlayıcılar için:

    • Belki de dersi almayı unuttunuz.

    • Belki "yıldız" içe aktarımları kullandınız, ancak sınıf, içe aktardığınız paketlerin hiçbirinde tanımlanmadı.

    • Belki de şu şekilde unuttunuz new:

          String s = String();  // should be 'new String()'
      
  • Tür veya örneğin, sahip olmasını beklediğiniz üyeye sahip olmadığı durumlar için:

    • Belki de kullanmak istediğiniz türü gölgeleyen yuvalanmış bir sınıf veya genel bir parametre bildirmişsinizdir .
    • Belki de bir statik veya örnek değişkeni gölgeliyorsunuzdur.
    • Belki de yanlış türü içe aktarmışsınızdır; örneğin IDE tamamlama veya otomatik düzeltme nedeniyle.
    • Belki de bir API'nin yanlış sürümünü kullanıyorsunuz (karşı derliyor).
    • Belki de nesnenizi uygun bir alt sınıfa atmayı unuttunuz.

Sorun genellikle yukarıdakilerin bir kombinasyonudur. Örneğin, belki "yıldız" içe aktardınız java.io.*ve sonra Filesiçinde java.nioolmayan ... sınıfı kullanmaya çalıştınız java.io. Veya belki de yazmak istediniz File... ki bu bir sınıftır java.io.


Yanlış değişken kapsamının nasıl bir "Sembol bulunamıyor" hatasına neden olabileceğine dair bir örnek:

List<String> strings = ...

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

Bu i, ififadede "Sembol bulunamıyor" hatası verir . Daha önce beyan etmiş olsak da i, bu beyan sadece ifade ve içeriği için kapsam dahilindedir for. Yapılan atıf iiçinde ifdeyimi göremiyorum bu beyanı i. Öyle kapsam dışında .

(Burada uygun bir düzeltme, ifdeyimi döngünün içine taşımak veya döngünün ibaşlamasından önce bildirmek olabilir .)


Aşağıda, bir yazım hatasının görünüşte açıklanamaz bir "Sembol bulunamıyor" hatasına yol açtığı şaşkınlığa neden olan bir örnek verilmiştir:

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

Bu size printlnarama isırasında bulunamadığını söyleyen bir derleme hatası verecektir . Ama (dediğini duydum) Ben ilan ettim!

Sorun sinsi noktalı virgül (olduğu ;öncesi) {. Java dili sözdizimi, bu bağlamda bir noktalı virgülü boş bir ifade olarak tanımlar . Boş ifade daha sonra fordöngünün gövdesi haline gelir . Yani bu kod aslında şu anlama geliyor:

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

// The previous and following are separate statements!!

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

{ ... }Blok gövdesi DEĞİLDİR fordöngü ve dolayısıyla önceki beyanı iiçinde forifadesi kapsam dışında bloğunda.


Burada, bir yazım hatasından kaynaklanan "Sembol bulunamıyor" hatasının başka bir örneği var.

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

Bir önceki bildiriminde rağmen tmpiçinde tmp(...)ifade yanlıştır. Derleyici adında bir yöntem arayacak tmpve bulamayacaktır. Önceden bildirilen tmp, yöntemler için ad alanı değil, değişkenler için ad alanı içindedir.

Karşılaştığım örnekte, programcı aslında bir operatörü atlamıştı. Yazmak istediği şuydu:

int res = tmp * (a + b);

Komut satırından derliyorsanız, derleyicinin bir sembol bulamamasının başka bir nedeni vardır. Başka bir sınıfı derlemeyi veya yeniden derlemeyi unutmuş olabilirsiniz. Örneğin, eğer sınıfları Foove Barnerede Fookullanır Bar. Hiç derlemediyseniz Barve çalıştırırsanız javac Foo.java, derleyicinin sembolü bulamadığını bulmakla yükümlüsünüz Bar. Basit cevap derlemek Foove Barbirlikte yapmaktır ; örneğin javac Foo.java Bar.javaveya javac *.java. Ya da daha iyisi bir Java oluşturma aracı kullanın; örneğin Ant, Maven, Gradle vb.

Aşağıda ele alacağım daha belirsiz başka nedenler de var.

3. Bu hataları nasıl düzeltirim?

Genel olarak, derleme hatasına neyin neden olduğunu bulmakla işe başlarsınız .

  • Derleme hata mesajıyla belirtilen dosyadaki satıra bakın.
  • Hata mesajının hangi sembolden bahsettiğini belirleyin.
  • Anlamaya neden derleyici o sembolü bulamadığını söylüyor; yukarıyı görmek!

Sonra kodunuzun ne söylemesi gerektiğini düşünürsünüz . Sonunda, istediğinizi yapmak için kaynak kodunuzda hangi düzeltmeyi yapmanız gerektiğini çözersiniz.

Her "düzeltmenin" doğru olmadığını unutmayın. Bunu düşün:

for (int i = 1; i < 10; i++) {
    for (j = 1; j < 10; j++) {
        ...
    }
}

Derleyicinin için "Sembol bulunamıyor" dediğini varsayalım j. Bunu "düzeltebilmemin" birçok yolu vardır:

  • Ben iç değişebilir forYapılır for (int j = 1; j < 10; j++)- Doğru muhtemelen.
  • İç döngüden veya dış döngüden j önce bir bildirim ekleyebilirim - muhtemelen doğru.forfor
  • Ben değişebilir jiçin iiç içinde fordöngü - yanlış muhtemelen!
  • ve bunun gibi.

Nokta olduğunu gerek kodunuzu doğru çözüm yolunu bulmak için yapmaya çalışıyor anlamak için.

4. Belirsiz nedenler

Burada "Sembol bulunamıyor" ifadesinin açıklanamaz olduğu birkaç durum var ... ta ki siz daha yakından bakana kadar.

  1. Yanlış bağımlılıklar : Derleme yolunu ve proje bağımlılıklarını yöneten bir IDE veya derleme aracı kullanıyorsanız, bağımlılıklarla ilgili bir hata yapmış olabilirsiniz; örneğin bir bağımlılığı atlamak veya yanlış sürümü seçmek. Bir derleme aracı kullanıyorsanız (Ant, Maven, Gradle, vb.), Projenin derleme dosyasını kontrol edin. Bir IDE kullanıyorsanız, projenin derleme yolu yapılandırmasını kontrol edin.

  2. Yeniden derlemiyorsunuz : Bazen, yeni Java programcıları Java araç zincirinin nasıl çalıştığını anlamıyor veya tekrarlanabilir bir "oluşturma süreci" uygulamamış oluyor; örneğin bir IDE, Ant, Maven, Gradle vb. kullanarak. Böyle bir durumda, programcı kuyruğunu kovalayarak, aslında kodu düzgün şekilde yeniden derlememekten kaynaklanan yanıltıcı bir hata arayabilir ve benzeri ...

  3. Daha önceki bir yapı sorunu : Daha önceki bir yapının, eksik sınıfları olan bir JAR dosyası verecek şekilde başarısız olması mümkündür. Bir derleme aracı kullanıyorsanız, böyle bir başarısızlık genellikle fark edilir. Bununla birlikte, JAR dosyalarını başka birinden alıyorsanız, bunların düzgün bir şekilde oluşturulmasına ve hataları fark etmesine bağımlı olursunuz . Bundan şüpheleniyorsanız tar -tvf, şüpheli JAR dosyasının içeriğini listelemek için kullanın .

  4. IDE sorunları : İnsanlar, IDE'lerinin kafasının karıştığı ve IDE'deki derleyicinin var olan bir sınıfı bulamadığı veya tersi durumları bildirdiler.

  • Bu, IDE yanlış JDK sürümüyle yapılandırılmışsa olabilir.

  • Bu, IDE'nin önbellekleri dosya sistemiyle senkronize değilse olabilir. Bunu düzeltmenin IDE'ye özgü yolları var.

  • Bu bir IDE hatası olabilir. Örneğin @Joel Costigliola, Eclipse'in bir Maven "test" ağacını doğru şekilde işlemediği bir senaryoyu anlatıyor: bu yanıta bakın .

  1. Android sorunları : Android için programlama yaparken ve ilgili "Sembol bulunamıyor" hatalarınız Rvarsa, Rsembollerin context.xmldosya tarafından tanımlandığını unutmayın . Senin olmadığını kontrol context.xmldosyası doğru ve doğru yerde olduğunu ve karşılık gelen bu Rsınıf dosyası oluşturulduktan / derlenmiş. Java sembollerinin büyük / küçük harfe duyarlı olduğunu, bu nedenle karşılık gelen XML kimliklerinin de büyük / küçük harfe duyarlı olduğunu unutmayın.

    Android'deki diğer sembol hataları muhtemelen daha önce bahsedilen nedenlerden kaynaklanmaktadır; örneğin eksik veya yanlış bağımlılıklar, yanlış paket adları, belirli bir API sürümünde bulunmayan yöntem veya alanlar, yazım / yazım hataları vb.

  2. Sistem sınıflarını yeniden tanımlama : Derleyicinin substringaşağıdaki gibi bir şeyde bilinmeyen bir sembol olduğundan şikayet ettiği durumlar gördüm

    String s = ...
    String s1 = s.substring(1);
    

    Programcının kendi sürümünü oluşturduğu Stringve sınıf sürümünün bir substringyöntem tanımlamadığı ortaya çıktı .

    Ders: Kendi sınıflarınızı ortak kitaplık sınıflarıyla aynı adlarla tanımlamayın!

  3. Homoglifler: Kaynak dosyalarınız için UTF-8 kodlamasını kullanırsanız , aynı görünen , ancak homoglifler içerdikleri için aslında farklı olan tanımlayıcılara sahip olmak mümkündür . Daha fazla bilgi için bu sayfaya bakın .

    Kendinizi kaynak dosya kodlaması olarak ASCII veya Latin-1 ile sınırlandırarak ve \uxxxxdiğer karakterler için Java kaçışları kullanarak bunu önleyebilirsiniz .


1 - Eğer belki, sen mi o zaman ya sen derleme hataları ile çalışma koduna IDE yapılandırmış veya başvurunuz zamanında .. üretme ve kod derleme, bir çalışma zamanı istisnası ya da hata iletisinde görüyoruz.

2 - İnşaat Mühendisliğinin üç temel prensibi: su yokuş yukarı akmaz, tahta kenarı daha güçlüdür ve bir ipi itemezsiniz .

26 thinkterry Apr 17 2015 at 15:50

Ayrıca şunları unutursanız da bu hatayı alırsınız new:

String s = String();

karşı

String s = new String();

çünkü newanahtar sözcük içermeyen çağrı, Stringbağımsız değişkenler olmadan çağrılan (yerel) bir yöntemi deneyecek ve arayacaktır - ve bu yöntem imzası büyük olasılıkla tanımlanmamıştır.

14 Jan Dec 06 2015 at 16:19

'Değişken kapsam dışı' için bir örnek daha

Bu tür soruları daha önce birkaç kez gördüğüm gibi, iyi hissettirse bile neyin yasadışı olduğuna dair bir örnek daha olabilir .

Bu kodu düşünün:

if(somethingIsTrue()) {
  String message = "Everything is fine";
} else {
  String message = "We have an error";
}
System.out.println(message);

Bu geçersiz kod. Çünkü adı geçen değişkenlerin hiçbiri messagekendi kapsamlarının dışında görünmez - {}bu durumda bu parantezleri çevreleyen parantezler olacaktır .

Sen diyebilirsiniz: "Ama bu mesaj adında bir değişken her iki şekilde tanımlanır - mesaj böylece edilir sonra tanımlanmış if".

Ama yanılıyorsun.

Java'nın hiçbir free()veya deleteoperatörü yoktur , bu nedenle değişkenlerin artık ne zaman kullanılmadığını öğrenmek için değişken kapsamını izlemeye güvenmek zorundadır (bu neden değişkenlerine referanslarla birlikte).

İyi bir şey yaptığınızı düşünmeniz özellikle kötüdür. Kodu şöyle "optimize ettikten" sonra bu tür bir hatayla karşılaştım:

if(somethingIsTrue()) {
  String message = "Everything is fine";
  System.out.println(message);
} else {
  String message = "We have an error";
  System.out.println(message);
}

"Oh, yinelenen kod var, hadi şu ortak satırı çıkaralım" -> ve işte orada.

Bu tür kapsam sorunuyla başa çıkmanın en yaygın yolu, else değerlerini dış kapsamdaki değişken adlarına önceden atamak ve ardından aşağıdaki durumlarda yeniden atamaktır:

String message = "We have an error";
if(somethingIsTrue()) {
  message = "Everything is fine";
} 
System.out.println(message);
10 JoelCostigliola May 13 2016 at 17:09

Eclipse'de bu hatayı almanın bir yolu:

  1. Bir sınıf tanımlayın Aiçinde src/test/java.
  2. Başka bir sınıf tanımlayın Biçinde src/main/javathat use sınıfında A.

Sonuç: Eclipse kodu derleyecek, ancak maven "Sembol bulunamıyor" verecektir.

Temel neden: Eclipse, ana ve test ağaçları için birleşik bir oluşturma yolu kullanıyor. Ne yazık ki, bir Eclipse projesinin farklı bölümleri için farklı derleme yollarının kullanılmasını desteklemiyor, Maven bunu gerektiriyor.

Çözüm :

  1. Bağımlılıklarınızı bu şekilde tanımlamayın; yani bu hatayı yapmayın.
  2. Maven kullanarak kod tabanınızı düzenli olarak oluşturun, böylece bu hatayı erkenden fark edebilirsiniz. Bunu yapmanın bir yolu, bir CI sunucusu kullanmaktır.
5 GT_hash Jun 30 2018 at 18:09

"Bulunamıyor", uygun değişken, yöntem, sınıf vb. Bulamayan derleyici anlamına gelir ... eğer bu hata masajını aldıysanız, öncelikle hata masajı alacağınız kod satırını bulmak istiyorsunuz ... Ve sonra Kullanmadan önce hangi değişken, yöntem veya sınıfın tanımlamadığını bulabilir. Onaylandıktan sonra bu değişken, yöntem veya sınıf daha sonra kullanılabilir. Aşağıdaki örneği düşünün.

Bir demo sınıfı oluşturacağım ve bir isim yazdıracağım ...

class demo{ 
      public static void main(String a[]){
             System.out.print(name);
      }
}

Şimdi sonuca bakın ..

Bu hata, "değişken adı bulunamıyor" diyor .. "İsim" değişkeni için değer tanımlama ve başlatma bu hatayı ortadan kaldırabilir ... Aslında böyle,

class demo{ 
      public static void main(String a[]){

             String name="smith";

             System.out.print(name);
      }
}

Şimdi yeni çıktıya bakın ...

Tamam Bu hatayı başarıyla çözdüm ... Aynı zamanda "yöntem bulamıyorum" veya "sınıf bulamıyorum" gibi bir şey alabiliyorsanız, önce bir sınıf veya yöntem tanımlayın ve sonra onu kullanın ..

3 JonathanLin Mar 08 2016 at 12:58

Bu hatayı yapıda başka bir yerde alıyorsanız, IDE'niz her şeyin mükemmel olduğunu söylerken, o zaman her iki yerde de aynı Java sürümlerini kullandığınızı kontrol edin.

Örneğin, Java 7 ve Java 8'in farklı API'leri vardır, bu nedenle daha eski bir Java sürümünde var olmayan bir API'yi çağırmak bu hataya neden olur.

3 Ajay Oct 10 2019 at 19:07

ÇÖZÜLDÜ

IntelliJ kullanma

Seç Yapı -> Proje Yeniden çözecek

2 DivyaJose Sep 28 2016 at 21:59

Ben de bu hatayı alıyordum. (bunun için googledim ve bu sayfaya yönlendirildim)

Sorun: Başka bir B projesinde tanımlanan bir sınıftan A projesi sınıfında tanımlanan statik bir yöntemi çağırıyordum.Aşağıdaki hatayı alıyordum:

error: cannot find symbol

Çözüm: Bunu önce yöntemin tanımlandığı projeyi, ardından yöntemin çağrıldığı projeyi oluşturarak çözdüm.

2 UdayKiranPulipati Jan 24 2019 at 18:18

Eclipse Java derleme yolu 7, 8 ile eşlenmişse ve Project pom.xml Maven properties java.version'da 7,8'den daha yüksek Java sürümünden (9,10,11, vb.) Bahsediliyorsa, pom'da güncellemeniz gerekir. xml dosyası.

Eclipse'de Java, Java sürüm 11 ile eşlenirse ve pom.xml'de Java sürüm 8 ile eşlenir. Eclipse IDE Yardımı -> Yeni Yazılım Yükle -> bölümünde aşağıdaki adımları izleyerek Eclipse desteğini Java 11'e güncelleyin ->

Aşağıdaki bağlantıyı yapıştırın http://download.eclipse.org/eclipse/updates/4.9-P-builds at Work With

veya

Ekle (Popup penceresi açılacaktır) ->

Name:Java 11 desteği Location: http://download.eclipse.org/eclipse/updates/4.9-P-builds

ardından aşağıdaki gibi pom.xml dosyasının Maven özelliklerinde Java sürümünü güncelleyin

<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>

Son olarak Debug as projesine sağ tıklayın -> Maven clean, Maven build steps

1 avp Aug 18 2018 at 08:45

İnsanların yukarıda bahsettiği gibi çeşitli senaryolar olabilir. Bunu çözmeme yardımcı olan birkaç şey.

  1. IntelliJ kullanıyorsanız

    File -> 'Invalidate Caches/Restart'

VEYA

  1. Başvurulan sınıf başka bir projedeydi ve bu bağımlılık projemin Gradle derleme dosyasına eklenmedi. Bu yüzden bağımlılığı ekledim

    compile project(':anotherProject')

ve işe yaradı. HTH!

1 ANILKUMAR Aug 07 2019 at 11:59

Kodunuzu maven derlemesini kullanarak derlediniz ve daha sonra çalıştırmak için maven testini kullandınız. Şimdi kodunuzdaki bir şeyi değiştirdiyseniz ve sonra derlemeden çalıştırıyorsanız, bu hatayı alırsınız.

Çözüm: Tekrar derleyin ve ardından testi çalıştırın. Benim için bu şekilde çalıştı.

1 VIPINKUMAR Sep 08 2019 at 14:50

Benim durumumda - aşağıdaki işlemleri yapmak zorunda kaldım:

  1. Taşı context.xmldosyayı src/java/packageiçin resourcedizine (IntelliJ IDE)
  2. Temiz targetdizin.
Striker Sep 06 2017 at 19:47

İpuçları için, hata veren sınıf adına ve satır numarasına daha yakından bakın, örneğin: Derleme hatası [HATA] \ uygulamalar \ xxxxx.java: [44,30] hatası: sembol bulunamıyor

Diğer bir neden de desteklenmeyen bir yöntem olan java sürümü için jdk7 vs 8 diyelim.% JAVA_HOME%

sakra Jul 20 2020 at 19:31

Gradle çoklu proje derlemesi olarak ayarlanmış bir Java projesinde hatayı aldık. Alt projelerden birinde Gradle Java Library eklentisinin eksik olduğu ortaya çıktı . Bu, alt projenin sınıf dosyalarının yapıdaki diğer projelere görünür olmasını engelledi.

Java kitaplığı eklentisini build.gradleaşağıdaki şekilde alt projelere ekledikten sonra , hata ortadan kalktı:

plugins {
    ...
    id 'java-library'
}
FelipeFranco Nov 20 2020 at 04:03

Ben bu hatayı şöyle çözdüm ... Android'in çılgınlığı. Paket adını Adapter olarak aldım ve bağdaştırıcının adını "A" yerine "a" ile yeniden düzenledim ve hatayı çözdüm.