- Konu sahibi
- #1
Java konusunda bir sorunu çözmenin en güvenilir yolu, hatayı tahmin ederek kodu rastgele değiştirmek yerine önce hatayı yeniden üretmek, mesajın kaynağını ayırmak, en küçük örnekte doğrulamak ve her değişiklikten sonra sonucu yeniden kontrol etmektir. Önce derleme mi, çalışma zamanı mı, mantık mı yoksa ortam mı kaynaklı olduğunu belirleyin; ardından hatanın oluştuğu satırı ve o satıra gelen veriyi inceleyin. Sorun düzelmiyorsa çalışan ve çalışmayan durum arasındaki farkı küçülterek izole edin.
İlk adım, karşılaştığınız belirtinin hangi tür soruna ait olduğunu belirlemektir. Çünkü derleyicinin bildirdiği bir yazım hatasıyla, programın yanlış sonuç üretmesi aynı yöntemle çözülmez.
Bu ayrım yalnızca düzen sağlamak için değildir. Örneğin
Derleme hatasında Java derleyicisinin gösterdiği dosya ve satır numarasını açın. Önce o satırın söz dizimini, değişken türlerini ve kullanılan sınıf ya da metodun gerçekten erişilebilir olup olmadığını kontrol edin. Hata bazen bir önceki satırdaki eksik parantez veya noktalı virgül nedeniyle sonraki satırda görünür; bu nedenle yalnızca işaretlenen kelimeye bakmayın.
Çalışma zamanı hatasında stack trace'in tamamını okuyun. Genellikle en üstte istisna türü ve açıklaması, devamında çağrı zinciri bulunur. Kendi paketinizdeki ilk anlamlı satır, çoğu durumda incelemeye başlanacak yerdir. Kütüphane içindeki satır doğrudan kök neden olmayabilir; o kütüphaneye hangi veriyi gönderdiğinizi de kontrol edin.
Örneğin aşağıdaki kodda sorun,
Bu örnekte beklenen sonuç kullanıcı adının yazdırılması, gerçek sonuç ise
Ancak bu kontrol, kullanıcının neden bulunamadığını kanıtlamaz.
Sorun büyük bir uygulamada ortaya çıkıyorsa önce onu en küçük tekrar üretilebilir örneğe indirin. Bunun için gereksiz sınıfları, ağ çağrılarını, veritabanı işlemlerini ve ilgisiz iş kurallarını geçici olarak ayırın. Aynı girdiyi her çalıştırmada kullanarak hatanın gerçekten tekrar oluştuğunu doğrulayın.
İzlenecek sıra şöyledir:
Kod çalışıyor fakat yanlış sonuç veriyorsa önce sonucu değil, ilk yanlış ara değeri bulun. Örneğin toplamın yanlış olduğunu görüyorsanız bütün hesaplamayı baştan incelemek yerine listedeki elemanların, döngü koşulunun ve toplam değişkeninin her adımda hangi değeri aldığını kontrol edin.
Aşağıdaki örnekte amaç 1'den 5'e kadar olan sayıları toplamaktır:
Çıktı
Java'da birçok hata, verinin beklenenden farklı türde veya sınırda olmasından kaynaklanır. Özellikle şu durumları ayrı ayrı deneyin:
Buradaki dönüşüm yalnızca bölme sonucunun türünü düzeltir; yanlış birim, yanlış veri veya hatalı iş kuralı varsa bunları kendiliğinden çözmez.
Bir seferde birçok satırı değiştirmek sorunun hangi değişiklikle düzeldiğini veya yeni hatanın nereden geldiğini belirsiz hâle getirir. Önce hipotezinizi yazın: “Bu hata, listenin boş olması nedeniyle oluşuyor.” Ardından yalnızca bu hipotezi sınayan küçük bir değişiklik yapın ve aynı test girdisiyle yeniden çalıştırın.
Sonuç değişmediyse hipotez desteklenmemiştir; eski değişikliği geri alıp başka bir olasılığı inceleyin. Sonuç değiştiyse değişiklik sorunun görünen belirtisini etkilediği anlamına gelir, fakat kök nedenin tamamen çözüldüğü anlamına gelmez. Aynı işlemi normal veri, boş veri ve sınır değerle tekrar çalıştırın.
Başka birinden yardım isterken yalnızca “Java hata veriyor” demek çözümü hızlandırmaz. Şu bilgileri birlikte verin:
Sorunu sınıflandırarak başlayın
İlk adım, karşılaştığınız belirtinin hangi tür soruna ait olduğunu belirlemektir. Çünkü derleyicinin bildirdiği bir yazım hatasıyla, programın yanlış sonuç üretmesi aynı yöntemle çözülmez.
| Sorun türü | Belirti | İlk kontrol |
|---|---|---|
| Derleme hatası | Program başlamadan hata mesajı verir | Hata satırı, türler, parantezler ve import bildirimleri |
| Çalışma zamanı hatası | Program çalışırken istisna oluşur | Stack trace içindeki ilk anlamlı uygulama satırı ve kullanılan değerler |
| Mantık hatası | Program çalışır fakat sonuç yanlıştır | Beklenen ve gerçek sonuç arasındaki ilk fark |
| Ortam veya yapılandırma hatası | Kod doğru görünmesine rağmen bağımlılık, sürüm veya çalıştırma sorunu oluşur | Java sürümü, sınıf yolu, derleme ayarları ve bağımlılıklar |
NullPointerException bir çalışma zamanı istisnasıdır; ancak asıl neden, beklenmeyen null değerinin daha önce üretilmiş olması olabilir. Hata mesajını susturmak yerine bu değerin neden oluştuğunu bulmanız gerekir.Hata mesajını doğru satırdan okuyun
Derleme hatasında Java derleyicisinin gösterdiği dosya ve satır numarasını açın. Önce o satırın söz dizimini, değişken türlerini ve kullanılan sınıf ya da metodun gerçekten erişilebilir olup olmadığını kontrol edin. Hata bazen bir önceki satırdaki eksik parantez veya noktalı virgül nedeniyle sonraki satırda görünür; bu nedenle yalnızca işaretlenen kelimeye bakmayın.
Çalışma zamanı hatasında stack trace'in tamamını okuyun. Genellikle en üstte istisna türü ve açıklaması, devamında çağrı zinciri bulunur. Kendi paketinizdeki ilk anlamlı satır, çoğu durumda incelemeye başlanacak yerdir. Kütüphane içindeki satır doğrudan kök neden olmayabilir; o kütüphaneye hangi veriyi gönderdiğinizi de kontrol edin.
Örneğin aşağıdaki kodda sorun,
getName() metodunun kendisi değil, user değişkeninin null olabilmesidir:
Java:
public class Main {
public static void main(String[] args) {
User user = findUser();
System.out.println(user.getName());
}
static User findUser() {
return null;
}
static class User {
String getName() {
return "Ali";
}
}
}
Bu örnekte beklenen sonuç kullanıcı adının yazdırılması, gerçek sonuç ise
NullPointerException oluşmasıdır. Geçici olarak null kontrolü eklemek hatayı önleyebilir:
Java:
if (user == null) {
System.out.println("Kullanıcı bulunamadı");
return;
}
System.out.println(user.getName());
Ancak bu kontrol, kullanıcının neden bulunamadığını kanıtlamaz.
findUser() metodunun yanlış veri döndürmesi, aramanın başarısız olması veya çağıran kodun eksik bilgi göndermesi ayrıca incelenmelidir.Sorunu küçük ve tekrar edilebilir hâle getirin
Sorun büyük bir uygulamada ortaya çıkıyorsa önce onu en küçük tekrar üretilebilir örneğe indirin. Bunun için gereksiz sınıfları, ağ çağrılarını, veritabanı işlemlerini ve ilgisiz iş kurallarını geçici olarak ayırın. Aynı girdiyi her çalıştırmada kullanarak hatanın gerçekten tekrar oluştuğunu doğrulayın.
İzlenecek sıra şöyledir:
- Hatanın oluştuğu işlemi ve kullanılan girdiyi kaydedin.
- Hatanın her çalıştırmada aynı noktada oluşup oluşmadığını kontrol edin.
- İşlemi küçük metotlara ayırarak hangi adımda beklenen değerin bozulduğunu bulun.
- Ara sonuçları geçici olarak yazdırın veya hata ayıklayıcıda inceleyin.
- Sorunu oluşturan en küçük kod parçasını ayırın.
- Tek bir değişiklik yapıp aynı girdiyi yeniden çalıştırın.
Beklenen ve gerçek sonucu karşılaştırın
Kod çalışıyor fakat yanlış sonuç veriyorsa önce sonucu değil, ilk yanlış ara değeri bulun. Örneğin toplamın yanlış olduğunu görüyorsanız bütün hesaplamayı baştan incelemek yerine listedeki elemanların, döngü koşulunun ve toplam değişkeninin her adımda hangi değeri aldığını kontrol edin.
Aşağıdaki örnekte amaç 1'den 5'e kadar olan sayıları toplamaktır:
Java:
int total = 0;
for (int i = 1; i < 5; i++) {
total += i;
}
System.out.println(total);
Çıktı
10 olur; çünkü döngü 5 değerine girmeden biter. Beklenen sonuç 15 ise sorun toplama işleminde değil, döngü koşulundadır. Koşul i <= 5 yapılırsa 5 de hesaba katılır. Bu düzeltme yalnızca aralığın gerçekten 1 ile 5 arasında kapalı olduğunu biliyorsanız doğrudur; bazı problemlerde üst sınırın hariç tutulması özellikle istenebilir.Türleri, sınır değerleri ve boş durumları kontrol edin
Java'da birçok hata, verinin beklenenden farklı türde veya sınırda olmasından kaynaklanır. Özellikle şu durumları ayrı ayrı deneyin:
- Boş metin ve
nulldeğer. - Listenin boş olması veya tek eleman içermesi.
- Sıfır, negatif değer ve izin verilen en büyük değer.
- Ondalıklı sayılarda yuvarlama ve tam sayı bölmesi.
- Beklenen biçime uymayan kullanıcı veya dosya girdisi.
- Ağ ya da veritabanı sonucunun hiç dönmemesi.
5 / 2 ifadesi iki int değerle kullanılırsa sonuç 2 olur. Ondalıklı sonuç gerekiyorsa en az bir değerin kayan noktalı türde olması gerekir:
Java:
int a = 5;
int b = 2;
double result = (double) a / b;
System.out.println(result); // 2.5
Buradaki dönüşüm yalnızca bölme sonucunun türünü düzeltir; yanlış birim, yanlış veri veya hatalı iş kuralı varsa bunları kendiliğinden çözmez.
Değişiklikleri tek tek doğrulayın
Bir seferde birçok satırı değiştirmek sorunun hangi değişiklikle düzeldiğini veya yeni hatanın nereden geldiğini belirsiz hâle getirir. Önce hipotezinizi yazın: “Bu hata, listenin boş olması nedeniyle oluşuyor.” Ardından yalnızca bu hipotezi sınayan küçük bir değişiklik yapın ve aynı test girdisiyle yeniden çalıştırın.
Sonuç değişmediyse hipotez desteklenmemiştir; eski değişikliği geri alıp başka bir olasılığı inceleyin. Sonuç değiştiyse değişiklik sorunun görünen belirtisini etkilediği anlamına gelir, fakat kök nedenin tamamen çözüldüğü anlamına gelmez. Aynı işlemi normal veri, boş veri ve sınır değerle tekrar çalıştırın.
Sorun düzelmiyorsa paylaşılacak bilgiyi hazırlayın
Başka birinden yardım isterken yalnızca “Java hata veriyor” demek çözümü hızlandırmaz. Şu bilgileri birlikte verin:
- Kullandığınız Java sürümü ve programı nasıl çalıştırdığınız.
- Hatanın tam metni ve mümkünse stack trace.
- Sorunu üreten en küçük kod parçası.
- Kullanılan örnek girdi.
- Beklediğiniz sonuç ve gerçekte aldığınız sonuç.
- Son değişiklikten önce çalışıp çalışmadığı.