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
42
ve '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
StringBiulder
yerine StringBuilder
. Java, kötü yazım veya yazım hatalarını telafi edemez ve denemez.
- Belki de davayı yanlış anladınız; yani
stringBuilder
yerine 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
mystring
ve my_string
farklı. (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 Files
sınıf kullanmaya çalıştı ... ki java.nio
değ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 i
içinde if
deyimi. Daha önce ilan rağmen i
, bu beyanı sadece kapsamda için for
ifade ile onun vücudunda. Yapılan atıf i
içinde if
deyimi göremiyorum bu beyanı i
. Öyle kapsam dışında .
(Burada uygun bir düzeltme, if
ifadeyi döngü içinde taşımak veya döngü i
baş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, println
aramada i
bulunamadığı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 for
halkanı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 for
döngü ve dolayısıyla önceki beyanı i
içinde for
ifadesi 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 tmp
içinde tmp(...)
ifade yanlıştır. Derleyici adlı bir yöntemi arayacak tmp
ve 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 Foo
ve Bar
nerede Foo
kullandığınız varsa Bar
. Daha önce hiç derlemediyseniz Bar
ve çalıştırıyorsanız javac Foo.java
, derleyicinin sembolü bulamadığını görebilirsiniz Bar
. Basit cevap derlemek Foo
ve Bar
birlikte yapmaktır ; örneğin javac Foo.java Bar.java
veya 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
for
Yapı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.for
for
- Ben değişebilir
j
için i
iç içinde for
dö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 R
olduğunda, R
sembollerin context.xml
dosya tarafından tanımlandığını unutmayın . Senin olmadığını kontrol context.xml
dosyası doğru ve doğru yerde olduğunu ve karşılık gelen bu R
sı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 substring
ve 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ığı String
ve sınıf versiyonunun bir substring
yö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 \uxxxx
diğ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 .