Bir iddia ne zaman kullanılır ve bir istisna ne zaman kullanılır?


121

Çoğu zaman kodumdaki bir durumu kontrol etmek için bir istisna kullanacağım, bir iddia kullanmak için ne zaman uygun bir zaman olduğunu merak ediyorum.

Örneğin,

Group group=null;
try{
    group = service().getGroup("abc");
}catch(Exception e){
    //I dont log error because I know whenever error occur mean group not found
}

if(group !=null)
{
    //do something
}

Bir iddianın buraya nasıl oturduğunu belirtebilir misiniz? Bir iddia kullanmalı mıyım?

Görünüşe göre üretim kodunda asla iddialar kullanmıyorum ve sadece birim testlerinde iddiaları görüyorum. Çoğu durumda, yukarıdaki gibi kontrol yapmak için istisnayı kullanabileceğimi biliyorum, ancak bunu "profesyonelce" yapmanın uygun yolunu bilmek istiyorum.

Yanıtlar:


81

Asla olmaması gereken bir şeyi kontrol etmek için iddialar kullanılmalı, olabilecek bir şeyi kontrol etmek için bir istisna kullanılmalıdır.

Örneğin, bir işlev 0'a bölünebilir, bu nedenle bir istisna kullanılmalıdır, ancak sabit sürücünün aniden kaybolduğunu kontrol etmek için bir onay kullanılabilir.

Bir iddia, programın çalışmasını durdurur, ancak bir istisna programın çalışmaya devam etmesine izin verir.

Bunun if(group != null)bir iddia olmadığını, sadece koşullu olduğunu unutmayın.


3
"sabit sürücünün aniden kaybolduğunu kontrol etmek için bir iddia kullanılabilir" - bunun doğru olmadığını söyleyebilirim: neden bunun geliştirme sırasında ele alınmasını istersiniz ama üretimde değil (iddialar genellikle devre dışı bırakıldığında)?
herman

71
Sabit sürücü hakkındaki yorum yanlış. Onaylar, kod mantığınızdaki hataları kontrol etmek içindir. Asla, asla kontrol etmediğiniz bir şeyi kontrol etmek için kullanmayın. Unutmayın, bir iddia başarısız olursa bu kodunuzun yanlış olduğu anlamına gelir .
Ian Goldby

1
@Marius Koşulunuzun yerine aşağıdaki gibi bir iddia kullanılabilir: assert group! = Null
IgorGanapolsky

1
Olumsuz oy verildi çünkü sabit disk örneği kendi felsefenizle çelişiyor. Sabit disklerin "kaybolması" (kod açısından bakıldığında) gerçekte olabilir - ne kadar olanaksız olursa olsun. @ IanGoldby'nin dediği gibi, iddialar tamamen kodunuz tarafından kontrol edilen şeylere bağlı olmalıdır.
Vicky Chijwani

Gregory Pakosz tarafından gönderilmişse çok daha iyi bir cevap, lütfen bu yazıyı okuyun.
ormurin

169

Aklımın dışında (liste eksik olabilir ve bir yoruma sığmayacak kadar uzun), şunu söyleyebilirim:

  • genel veya korumalı yöntemlere ve yapıcılara iletilen parametreleri kontrol ederken istisnaları kullanın
  • Kullanıcıyla etkileşimde bulunurken veya istemci kodunun istisnai bir durumdan kurtulmasını beklediğinizde istisnalar kullanın
  • ortaya çıkabilecek sorunları ele almak için istisnalar kullanın
  • ön koşulları, son koşulları ve özel / dahili kod değişmezlerini kontrol ederken iddiaları kullanın
  • kendinize veya geliştirici ekibinize geri bildirim sağlamak için iddiaları kullanın
  • Gerçekleşme olasılığı çok düşük olan şeyleri kontrol ederken iddiaları kullanın, aksi takdirde başvurunuzda ciddi bir hata olduğu anlamına gelir
  • Doğru olduğunu bildiğiniz şeyleri (sözde) belirtmek için iddiaları kullanın

Başka bir deyişle, istisnalar uygulamanızın sağlamlığına, iddialar ise doğruluğuna yöneliktir.

İddialar yazmak için ucuz olacak şekilde tasarlandı, onları hemen hemen her yerde kullanabilirsiniz ve ben bu temel kuralı kullanıyorum: bir iddia ifadesi ne kadar aptal görünüyorsa, o kadar değerli ve daha fazla bilgi katıyor. Doğru şekilde davranmayan bir programın hatalarını ayıklarken, deneyiminize bağlı olarak daha bariz hata olasılıklarını mutlaka kontrol edeceksiniz. O zaman gerçekleşemeyecek sorunları kontrol edeceksiniz: bu tam olarak iddiaların çok yardımcı olduğu ve zaman kazandırdığı zamandır.


53
Bunu ifade etme şeklinizi beğendim: İstisnalar, uygulamanızın sağlamlığına hitap ederken iddialar doğruluğunu ele alır .
M. Dudley


Ve bir C ++ özel iddia kitaplığı ararsanız
Gregory Pakosz'u

26

Unutmayın iddialar çalışma zamanında parametreler kullanılarak devre dışı bırakılabilir ve varsayılan olarak devre dışı bırakılır , bu nedenle hata ayıklama amaçları dışında bunlara güvenmeyin.

Ayrıca, nerede kullanılacağını veya kullanılmayacağını iddia eden daha fazla durum görmek için assert hakkındaki Oracle makalesini de okumalısınız .


Hue hue hue Kodumun Eclipse'de neden başarısız olduğunu ancak komut satırında sorunsuz çalıştığını merak ediyordum.
Steve

15

Genel bir kural olarak:

  • Birisinin onları kapatmasının hiç önemli olmadığı iç tutarlılık kontrolleri için iddiaları kullanın. ( javaKomutun varsayılan olarak tüm iddiaları kapattığını unutmayın.)
  • Kapatılmaması gereken her türlü kontrol için düzenli testler kullanın. Bu , hataların neden olduğu olası hasarlara karşı koruma sağlayan savunma kontrollerini ve her türlü doğrulama verilerini / isteklerini / kullanıcılar veya harici hizmetler tarafından sağlananları içerir.

Sorunuzdaki aşağıdaki kod kötü stil ve potansiyel olarak hatalı

try {
    group = service().getGroup("abc");
} catch (Exception e) {
    //i dont log error because i know whenever error occur mean group not found
}

Sorun şu ki, bir istisnanın grubun bulunamadığı anlamına geldiğini Bilmiyorsunuz. O da mümkündür service()çağrısı istisna attı, yoksa döndüğünü nullsonra neden olan NullPointerException.

"Beklenen" bir istisnayı yakaladığınızda, yalnızca beklediğiniz istisnayı yakalamalısınız . Yakalayarak java.lang.Exception(ve özellikle günlüğe kaydetmeyerek), sorunu teşhis etmeyi / hata ayıklamayı zorlaştırıyor ve potansiyel olarak uygulamanın daha fazla zarar vermesine izin veriyorsunuz.


4

Microsoft'a dönersek, öneri, herkese açık hale getirdiğiniz tüm API'lerde İstisnalar atmak ve dahili olan kod hakkında yaptığınız her türlü varsayımda Onayları kullanmaktı. Biraz gevşek bir tanım ama sanırım çizgiyi çizmek her geliştiriciye kalmış.

İstisnaların kullanımıyla ilgili olarak, adından da anlaşılacağı gibi, kullanımları istisnai olmalıdır, bu nedenle yukarıda sunduğunuz kod için, hizmet yoksa getGroupçağrı geri dönmelidir null. İstisna, yalnızca bir ağ bağlantısı kesildiğinde veya buna benzer bir şey olduğunda ortaya çıkmalıdır.

Sanırım sonuç, her uygulama için iddia ve istisnaların sınırlarını tanımlamak için biraz geliştirme ekibine bırakılmış olmasıdır.


IMHO, bu tür bir öneriyle ilgili sorun, bir API'nin genel ve özel bölümleri arasındaki sınır oldukça sabit olduğu sürece sorun olmamasıdır. Yeni bir kod geliştiriyorsanız, o zaman bu sınır genellikle oldukça akıcıdır ...
Len Holgate

Evet haklısın. Bu bir kılavuzdur, ancak günün sonunda programcıların duyarlılığına bırakılmıştır. Bunlar için nihai bir tanımlama çizgisi olduğunu düşünmüyorum, bu yüzden sanırım bir sürü farklı kod okumaktan doğru olduğunu düşündüğünüz şeyi kullanıyorsunuz.
rui

3

Bu belgeye göre http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html#design-faq-general , "Assert ifadesi kamuya açık olmayan önkoşul, sonkoşul ve sınıf değişmezi için uygundur Genel ön koşul denetimi, IllegalArgumentException ve IllegalStateException gibi özellikle belgelenmiş istisnalarla sonuçlanan yöntemlerin içindeki denetimlerle gerçekleştirilmelidir. "

Ön koşul, son koşul ve sınıf değişmezliği hakkında daha fazla bilgi edinmek istiyorsanız, şu belgeye bakın: http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html#usage-conditions . Aynı zamanda iddia kullanım örneklerini de içerir.


1

Boş değer testi, yalnızca sorunlara neden olan boş değerleri yakalarken, sahip olduğunuz bir dene / yakala herhangi bir hatayı yakalayacaktır .

Genel olarak, dene / yakala daha güvenlidir, ancak biraz daha yavaştır ve meydana gelebilecek her türlü hatayı yakalamanıza dikkat etmelisiniz. Bu yüzden dene / yakala kullan derim - bir gün getGroup kodu değişebilir ve daha büyük bir ağa ihtiyacınız olabilir.


1

Kullanımları sırasında bu basit farkı göz önünde bulundurarak kullanabilirsiniz. İstisnalar, kontrol edilen ve kontrol edilmeyen hata olarak adlandırılan beklenen ve beklenmeyen hataları kontrol etmek için kullanılırken, iddia, varsayımların doğrulanıp doğrulanmadığını görmek için çalışma zamanında hata ayıklama amacıyla kullanılır.


1

İtiraf ediyorum, sorunuz biraz kafam karıştı. Bir onaylama koşulu karşılanmadığında, bir istisna atılır. Kafa karıştırıcı bir şekilde buna AssertionError denir . Çok benzer durumlarda (örneğin) IllegalArgumentException gibi denetlenmediğini unutmayın .

Yani Java'da iddiaları kullanmak

  1. bir koşul yazmak / blok atmak için daha kısa bir yoldur
  2. JVM parametreleri aracılığıyla bu kontrolleri açıp kapatmanıza izin verir. Normalde, çalışma zamanı performansını etkilemedikleri veya benzer bir cezaya sahip olmadıkları sürece bu kontrolleri her zaman bırakırdım.

AssertionError, Error not RuntimeException'ın bir alt sınıfıdır.
Stephen C

Ah. Elbette. İşaretli / işaretsiz düşünüyordum. Şimdi düzeltildi
Brian Agnew

İddiaların ne olduğunu (tartışmalı bir bakış açısından) açıklar, ancak onları tam olarak ne zaman kullanacağını açıklamaz.
Karl Richter

1

Aşağıdaki bağlantıdan Sun'ın dokümantasyonundaki 6.1.2 (İddialara karşı diğer hata kodu) bölümüne bakın.

http://www.oracle.com/technetwork/articles/javase/javapch06.pdf

Bu belge, iddiaların ne zaman kullanılacağına dair gördüğüm en iyi tavsiyeyi veriyor. Belgeden alıntı yapmak:

"İyi bir genel kural, unutmak isteyeceğiniz istisnai durumlar için bir iddia kullanmanız gerektiğidir. Bir iddia, yapmak zorunda kalmayı beklemediğiniz bir durum veya durumu çözmenin ve unutmanın en hızlı yoludur. uğraşmak."


0

Maalesef iddialar devre dışı bırakılabilir. Üretim sırasında öngörülemeyen bir şeyin izini sürerken alabileceğiniz tüm yardıma ihtiyacınız var, bu yüzden kendilerini diskalifiye edin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.