0. İki hata arasında fark var mı?
Pek sayılmaz. "Sembol bulunamıyor" ve "Sembol çözülemiyor" aynı anlama geliyor. Bazı Java derleyicileri bir kelime öbeği, diğer kelime öbekleri kullanır.
1. "Sembol bulunamıyor" hatası ne anlama geliyor?
İlk olarak, bir derleme hatası 1'dir . 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şmez: gibi
42ve 'X've "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.
"Sembol bulunamıyor" hatası tanımlayıcılarla ilgilidir. Kodunuz derlendiğinde, derleyicinin kodunuzdaki her 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 atıfta bulunuyor gibi görünüyor.
2. "Sembol bulunamadı" hatasına ne sebep olabilir?
İlk sipariş olarak, sadece bir sebep var. Derleyici, tanımlayıcının tanımlanması gereken tüm yerlere baktı ve tanımı bulamadı. Bu birkaç şeyden kaynaklanabilir. Ortak olanlar aşağıdaki gibidir:
- Genel olarak tanımlayıcılar için:
- Belki de ismi yanlış hecelediniz; yani
StringBiulderyerine StringBuilder. Java, kötü yazım veya yazım hatalarını telafi edemez ve denemez.
- 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 kullandınız; yani
mystringve my_stringfarklı. (Java stili 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; yani derleyiciye bakmasını örtük olarak anlattığınız yerden farklı bir bağlamda. (Farklı bir sınıf? Farklı bir kapsam? Farklı bir paket? Farklı bir kod tabanı?)
- Değişkenlere başvurması gereken tanımlayıcılar için:
- Belki de değişkeni beyan etmeyi unuttun.
- Değişken bildirimi, kullanmaya çalıştığınız noktada kapsam dışı olabilir. (Aşağıdaki örneğe bakın)
Yöntem veya alan adları olması gereken tanımlayıcılar için:
Sınıf adları olması gereken tanımlayıcılar için:
Tür veya örneğin, üyeye sahip olmasını beklediğiniz üyeye sahip olmadığı durumlarda:
- Belki de iç içe bir sınıf veya kullanmak istediğiniz türün gölgesini veren genel bir parametre bildirmişsinizdir .
- Belki statik veya örnek bir değişkeni gölgeliyorsunuzdur.
- Belki de yanlış türü içe aktardınız; örneğin IDE tamamlanması veya otomatik düzeltme nedeniyle.
- Belki de bir API'nin yanlış sürümünü kullanıyorsunuz (buna karşı derliyorsunuz).
- Belki de objenizi uygun bir alt sınıfa dökmeyi unutmuşsunuzdur.
Sorun genellikle yukarıdakilerin bir kombinasyonudur. Örneğin, belki "yıldız" ithal java.io.*ve sonra Filessınıf kullanmaya çalıştı ... ki java.niodeğil java.io. Ya da belki de yazmak istedin File... ki bu bir sınıf java.io.
Yanlış değişken kapsamlandırmanın nasıl "Sembol bulunamıyor" hatasına yol açabileceğine ilişkin 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 bir "sembol bulamıyor" hatası verecektir iiçinde ifdeyimi. Daha önce ilan rağmen i, bu beyanı sadece kapsamda için forifade ile onun vücudunda. Yapılan atıf iiçinde ifdeyimi göremiyorum bu beyanı i. Öyle kapsam dışında .
(Burada uygun bir düzeltme, ififadeyi döngü içinde taşımak veya döngü ibaşlamadan önce bildirmek olabilir .)
Yazım hatası, açıklanamayan bir "Sembol bulunamıyor" hatasına yol açan şaşkınlığa neden olan bir örnek:
for (int i = 0; i < 100; i++); {
System.out.println("i is " + i);
}
Bu, printlnaramada ibulunamadığını söyleyen bir derleme hatası verecektir . Ama (duyduğunu duyuyorum) beyan ettim!
Sorun sinsi noktalı virgül ( ;) {. Java dili sözdizimi, bu bağlamdaki noktalı virgülün boş bir ifade olduğunu tanımlar . Boş ifade daha sonra forhalkanın gövdesi olur . Yani bu kod aslında şu anlama gelir:
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.
Aşağıda, yazım hatası nedeniyle oluşan "Sembol bulunamıyor" hatasının başka bir örneği verilmiştir.
int tmp = ...
int res = tmp(a + b);
Bir önceki bildiriminde rağmen tmpiçinde tmp(...)ifade yanlıştır. Derleyici adlı bir yöntemi arayacak tmpve bulamayacaktır. Daha önce bildirilenler tmp, yöntemlerin ad alanında değil, değişkenlerin ad alanındadır.
Karşılaştığım örnekte, programcı aslında bir operatör bırakmıştı. Yazmak istediği şey şuydu:
int res = tmp * (a + b);
Komut satırından derliyorsanız, derleyicinin bir sembol bulamamasının başka bir nedeni daha vardır. Başka bir sınıfı derlemeyi veya yeniden derlemeyi unutmuş olabilirsiniz. Örneğin, sınıflarınız Foove Barnerede Fookullandığınız varsa Bar. Daha önce hiç derlemediyseniz Barve çalıştırıyorsanız javac Foo.java, derleyicinin sembolü bulamadığını görebilirsiniz Bar. Basit cevap derlemek Foove Barbirlikte yapmaktır ; örneğin javac Foo.java Bar.javaveya javac *.java. Ya da daha iyisi bir Java derleme aracı kullanın; örneğin Ant, Maven, Gradle vb.
Aşağıda ele alacağım daha belirsiz bazı başka nedenler de var.
3. Bu hataları nasıl düzeltirim?
Genel olarak, derleme hatasına neyin sebep olduğunu bularak işe başlarsınız .
- Dosyada derleme hata mesajı ile gösterilen 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üyorsunuz . Son olarak, istediğinizi yapmak için kaynak kodunuzda hangi düzeltmeyi yapmanız gerektiğini hesaplarsınız.
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 "sembolü bulunamıyor" yazdığını varsayalım j. Bunu "düzeltmenin" 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 açıklama ekleyebilirim - muhtemelen doğru.forfor
- Ben değişebilir
jiçin iiç içinde fordöngü - yanlış muhtemelen!
- ve bunun gibi.
Mesele şu ki , doğru düzeltmeyi bulmak için kodunuzun ne yapmaya çalıştığını anlamanız gerekiyor .
4. Belirsiz nedenler
Yakında görünene kadar "Sembol bulunamıyor" un görünüşte açıklanamayacağı birkaç durum var.
Yanlış bağımlılıklar : Derleme yolunu ve proje bağımlılıklarını yöneten bir IDE veya oluşturma aracı kullanıyorsanız, bağımlılıklarla ilgili bir hata yapmış olabilirsiniz; örneğin bir bağımlılığı göz ardı etmek veya yanlış sürümü seçmek. Bir oluşturma aracı (Ant, Maven, Gradle, vb.) Kullanıyorsanız, projenin derleme dosyasını kontrol edin. Bir IDE kullanıyorsanız, projenin derleme yolu yapılandırmasını kontrol edin.
Yeniden derlemiyorsunuz : Bazen yeni Java programcıları Java araç zincirinin nasıl çalıştığını anlamıyor veya tekrarlanabilir bir "oluşturma işlemi" uygulamıyor olabilir; örneğin bir IDE, Ant, Maven, Gradle vb. Böyle bir durumda, programcı olan hayali bir hata arayan kuyruğunu kovalayan sona erebilir aslında düzgün kodu yeniden derlenerek değil kaynaklanır ve benzeri ...
Önceki bir derleme sorunu : Önceki bir derlemenin eksik sınıflara sahip bir JAR dosyası verecek şekilde başarısız olması mümkündür. Böyle bir hata genellikle bir oluşturma aracı kullanıyorsanız fark edilir. Ancak, JAR dosyalarını başka birinden alıyorsanız, bunların düzgün bir şekilde oluşturulmasına ve hataları fark etmenize bağlıdır . Bundan şüpheleniyorsanız tar -tvf, şüpheli JAR dosyasının içeriğini listelemek için kullanın .
IDE sorunları : İnsanlar IDE'lerinin kafasının karıştığı ve IDE'deki derleyicinin var olan bir sınıfı veya tersi durumu bulamadığı durumlar bildirmiştir.
Bu, IDE yanlış JDK sürümüyle yapılandırılmışsa olabilir.
Bu, IDE'nin önbellekleri dosya sistemiyle senkronize olmazsa olabilir. Bunu düzeltmek için IDE'ye özgü yollar vardır.
Bu bir IDE hatası olabilir. Örneğin, @Joel Costigliola, Eclipse'in Maven "test" ağacını doğru işlemediği bir senaryoyu tanımlar: bu cevaba bakınız .
Android sorunları : Android için programlama yaparken ve ilgili "Sembol bulunamadı" hatalarınız Rolduğunda, 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, dolayısıyla karşılık gelen XML kimliklerinin de büyük / küçük harfe duyarlı olduğunu unutmayın.
Android'deki diğer sembol hatalarının daha önce bahsedilen nedenlerden kaynaklanması muhtemeldir; ö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 / yazma hataları vb.
Sistem sınıflarını yeniden tanımlama : Derleyicinin şikayet ettiği substringve aşağıdaki gibi bir şeyde bilinmeyen bir sembol olduğunu gördüm
String s = ...
String s1 = s.substring(1);
Programcının kendi versiyonunu yarattığı Stringve sınıf versiyonunun bir substringyöntem tanımlamadığı ortaya çıktı .
Ders: Ortak kütüphane sınıflarıyla aynı adlara sahip kendi sınıflarınızı tanımlamayın!
Homoglifler: Kaynak dosyalarınız için UTF-8 kodlaması kullanırsanız , aynı görünen ancak aslında farklı olan tanımlayıcılara sahip olmanız mümkündür çünkü bunlar homoglifler içerir. Daha fazla bilgi için bu sayfaya bakın .
Kendinizi kaynak dosya kodlaması olarak ASCII veya Latin-1 ile sınırlayarak ve \uxxxxdiğer karakterler için Java çıkışlarını 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, bir tahta kendi tarafında daha güçlüdür ve bir ipte itemezsiniz .