Yanıtlar:
Genellikle, asla.
Ancak, bazen belirli hataları yakalamanız gerekir.
Framework-ish kod yazıyorsanız (3. taraf sınıfları yüklüyorsanız), yakalamak akıllıca olabilir LinkageError(sınıf bulunamadı, tatmin edici olmayan bağlantı, uyumsuz sınıf değişikliği).
Ayrıca alt sınıfları atan bazı aptal üçüncü taraf kodlar da gördüm Error, bu yüzden bunları da halletmeniz gerekecek.
Bu arada, iyileşmenin mümkün olmadığından emin değilim OutOfMemoryError.
Asla. Uygulamanın sonraki kod satırını çalıştırabileceğinden asla emin olamazsınız. Eğer bir alırsanız OutOfMemoryError, her şeyi güvenilir bir şekilde yapabileceğinizi garanti edemezsiniz . RuntimeException'ı yakalayın ve İstisnaları işaretleyin, ancak Hatalar'ı asla kontrol etmedi.
boolean assertionsEnabled = false; assert assertionsEnabled = true;
Genellikle, her zaman yakalayıp java.lang.Errorbir günlüğe yazmalı veya kullanıcıya göstermelisiniz. Destek olarak çalışıyorum ve her gün programcıların bir programda ne olduğunu söyleyemediklerini görüyorum.
Bir daemon iş parçacığınız varsa, sonlandırılmasını önlemelisiniz. Diğer durumlarda uygulamanız düzgün çalışacaktır.
Sadece java.lang.Erroren yüksek seviyede yakalamalısın .
Hataların listesine bakarsanız, çoğunun ele alınabileceğini göreceksiniz. Örneğin ZipError, bozuk zip dosyalarını okurken bir meydana gelir.
En yaygın hatalar OutOfMemoryErrorve NoClassDefFoundErrorçoğu durumda her ikisi de çalışma zamanı sorunlarıdır.
Örneğin:
int length = Integer.parseInt(xyz);
byte[] buffer = new byte[length];
bir üretebilir, OutOfMemoryErrorancak bu bir çalışma zamanı problemidir ve programınızı sonlandırmanız için bir neden yoktur.
NoClassDefFoundErrorçoğunlukla bir kitaplık yoksa veya başka bir Java sürümüyle çalışıyorsanız oluşur. Programınızın isteğe bağlı bir parçasıysa, programınızı sonlandırmamalısınız.
ThrowableEn üst seviyede yakalamanın ve yardımcı bir hata mesajı üretmenin neden iyi bir fikir olduğuna dair daha birçok örnek verebilirim .
OutOfMemoryErrorbir çalışma zamanı hatası değildir, uygulamanın bundan kurtulabileceğinin garantisi yoktur. Şanslıysanız, OOM alabilirsiniz, new byte[largeNumber]ancak bu tahsis OOM'ye neden olmak için yeterli değilse, sonraki satırda veya sonraki iş parçacığında tetiklenebilir. Bu çalışma zamanı sorunudur, çünkü lengthgüvenilir olmayan bir girdi ise , çağrı yapmadan önce doğrulanması gerekir new byte[].
NoClassDefFoundErroroluşabilir yerde derlenmiş java kodu bir sınıf bulamadıkları zaman o çağrılır olarak. JDK'nız yanlış yapılandırılmışsa, java.util.*sınıfı kullanmaya çalışmaktan tetiklenebilir ve ona karşı programlamak pratik olarak imkansızdır. İsteğe bağlı olarak bir bağımlılık ekliyorsanız, ClassLoadervar olup olmadığını kontrol etmek için kullanmalısınız , bu da fırlatır ClassNotFoundException.
ZipErrorsınıfları içeren jar dosyasının bozuk bir zip dosyası olduğunu belirtir. Bu oldukça ciddi bir sorundur ve bu noktada çalıştırılan herhangi bir koda güvenemezsiniz ve ondan "kurtarmaya" çalışmak sorumsuzca bir şey olur.
java.lang.Errorveya java.lang.Throwableen üst düzeyde yapmak ve onunla bir şeyler yapmaya çalışmak faydalı olabilir - diyelim ki bir hata mesajı kaydedin. Ancak bu noktada bunun yerine getirileceğine dair bir garanti yok. JVM'niz StringOOM yapıyorsa, günlüğe kaydetmeye çalışmak başka bir OOM'yi tetikleyen daha fazla s tahsis edebilir .
Çok iş parçacıklı bir ortamda, çoğu zaman onu yakalamak istersiniz! Yakaladığınızda, günlüğe kaydedin ve tüm uygulamayı sonlandırın! Bunu yapmazsanız, önemli bir kısmını yapan bazı iş parçacıkları ölür ve uygulamanın geri kalanı her şeyin normal olduğunu düşünür. Bunun dışında birçok istenmeyen durum ortaya çıkabilir. En küçük sorunlardan biri, bir iş parçacığının çalışmaması nedeniyle diğer iş parçacıkları bazı istisnalar atmaya başlarsa, sorunun kökenini kolayca bulamayacağınızdır.
Örneğin, genellikle döngü şöyle olmalıdır:
try {
while (shouldRun()) {
doSomething();
}
}
catch (Throwable t) {
log(t);
stop();
System.exit(1);
}
Bazı durumlarda bile, farklı Hataları farklı şekilde ele almak isteyebilirsiniz, örneğin, OutOfMemoryError'da uygulamayı düzenli olarak kapatabilirsiniz (hatta bir miktar hafızayı boşaltabilir ve devam edebilirsiniz), bazılarında ise yapabileceğiniz pek bir şey yoktur.
OutOfMemoryError ve devam etmek akıllıca değildir , çünkü programınız o zaman tanımlanmamış bir durumdadır .
Bir Errorgenellikle yakalanmış olmamalı o kadar, hiçbir zaman ortaya anormal bir duruma işaret eder .
ErrorSınıf için Java API Spesifikasyonundan :
An
Error,Throwablemakul bir uygulamanın yakalamaya çalışmaması gereken ciddi sorunları gösteren bir alt sınıfıdır . Bu tür hataların çoğu anormal durumlardır. [...]Bir yöntemin, yöntemin yürütülmesi sırasında atılan ancak yakalanmayan herhangi bir Error alt sınıfını kendi throws cümlesinde bildirmesi gerekmez, çünkü bu hatalar asla oluşmaması gereken anormal koşullardır.
Spesifikasyonda belirtildiği gibi, bir Erroryalnızca Şansların olduğu durumlarda atılır, bir Errormeydana geldiğinde uygulamanın yapabileceği çok az şey vardır ve bazı durumlarda Java Sanal Makinesi kararsız bir durumda olabilir (örneğin VirtualMachineError)
ErrorBir alt sınıfı olmasına rağmen , bir cümle Throwabletarafından yakalanabileceği anlamına gelir try-catch, ancak ErrorJVM tarafından bir atıldığında uygulama anormal bir durumda olacağından muhtemelen gerçekten gerekli değildir .
Bölümde bu konuda kısa bir bölüm de var 11.5 İstisna Hiyerarşi içinde Java Dili Şartname, 2. Baskı .
Ve bir Hata alırsanız , onu yeniden atmanız gereken birkaç durum daha vardır . Örneğin, ThreadDeath asla yakalanmamalıdır, büyük bir soruna neden olabilir, eğer onu kapalı bir ortamda yakalarsanız (örneğin bir uygulama sunucusu):
Bir uygulama, bu sınıfın örneklerini ancak zaman uyumsuz olarak sonlandırıldıktan sonra temizlemesi gerekiyorsa yakalamalıdır. ThreadDeath bir yöntem tarafından yakalanırsa, iş parçacığının gerçekten ölmesi için yeniden atılması önemlidir.
Errors.
Çok çok nadiren.
Bunu sadece çok özel bilinen bir vaka için yaptım. Örneğin, iki bağımsız ClassLoader aynı DLL dosyasını yüklüyse java.lang.UnsatisfiedLinkError atılabilir . (JAR'ı paylaşılan bir sınıf yükleyiciye taşımam gerektiğini kabul ediyorum)
Ancak en yaygın durum, kullanıcı şikayet etmeye geldiğinde ne olduğunu öğrenmek için oturum açmanız gerektiğidir. Sessizce ölmek yerine kullanıcıya bir mesaj veya açılır pencere istiyorsun.
C / C ++ programcıları bile, bir hatayı ortaya çıkarırlar ve çıkmadan önce insanların anlamadıkları bir şeyi söylerler (örneğin, hafıza hatası).
Bir Android uygulamasında bir java.lang.VerifyError yakalıyorum . Kullandığım bir kitaplık, işletim sisteminin eski sürümüne sahip cihazlarda çalışmaz ve kitaplık kodu böyle bir hata verir. İşletim zamanında işletim sistemi sürümünü kontrol ederek hatayı elbette önleyebilirim, ancak:
İdeal olarak hataları işlememeli / yakalamamalıyız. Ancak çerçevenin veya uygulamanın gerekliliğine bağlı olarak yapmamız gereken durumlar olabilir. Daha fazla Bellek tüketen DOM Ayrıştırıcıyı uygulayan bir XML Ayrıştırıcı arka plan programım olduğunu varsayalım . Ayrıştırıcı iş parçacığı gibi bir gereksinim varsa OutOfMemoryError aldığında ölmemeli , bunun yerine onu ele almalı ve uygulama / çerçeve yöneticisine bir mesaj / posta göndermelidir.
JVM artık beklendiği gibi çalışmadığında veya eşiğinde olduğunda bir Hata var. Bir hata yakalarsanız, catch bloğunun çalışacağının ve sonuna kadar çalışacağının garantisi yoktur.
Aynı zamanda çalışan bilgisayara, mevcut bellek durumuna da bağlı olacaktır, bu nedenle test etmenin, denemenin ve elinizden gelenin en iyisini yapmanın bir yolu yoktur. Sadece kötü bir sonuca sahip olacaksınız.
Ayrıca kodunuzun okunabilirliğini de düşüreceksiniz.