2015-04-07 46 views
5

böyle Java'da aynı türden farklı istisnalar işleniyor mu?

Exception, IOException, SocketException, etc. 

Ancak nasıl istisna üzerindeki asıl mesele ayrıntıları bulmaya devam do

gibi süper sınıf caugh olan hataları görmek çok yaygındır Java hataları, tutarken? Belirli bir istisna türünü diğerlerinden nasıl ayırırsınız. Örneğin, şu anda adlandırabileceğiniz her tür okuma/yazma hatası için bir IOException atan Netty.io kullanarak küçük bir proje üzerinde çalışıyorum. Bu mantıklı, çünkü sonuçta bu girdi/çıktı hatalarıdır, ancak bunları ayrı ayrı nasıl ele alırdım.

Örnek istisnalar:

java.io.IOException: An existing connection was forcibly closed by the remote host 
java.io.IOException: Connection reset by peer 
java.io.IOException: Stream closed 

liste sadece devam devam ediyor ama nasıl bu ayrı, etrafa bakarken buldum ve gerçekten kötü görünüyor ettik bir yaklaşım şudur taşıma konusunda gider. Bir correct yolu eğer olacak

try { 
    // ... 
} catch (IOException e) { 
    if(e.getMessage().contains("An existing connection was forcibly closed by the remote host")) { 
     // Handle error 
    } else //... 
} 

Bu, çok sıkıcı görünüyor ve bunu yapmak için daha iyi bir yol olarak kaçınılmazdır. Son birkaç saat zarfında yazım hatalarını inceledim ve hepsi sadece yaygın olarak kullanılan büyük çocuklar hakkında konuşuyorlar. IOException, Exception, SocketException, NullPointerException, and FileNotFoundException. SocketException ve FileNotFoundException'un doğrudan doğruya IOException ile ilgili olacağını düşündüğüm, muhtemelen bir alt sınıftan daha fazlası, yanılıyorsam düzeltin.

Her neyse, bu özel durumları ele almanın doğru yolu nedir ve ne tür bir istisnayı ele almanız gerektiğini tam olarak nasıl anlayabilirsiniz? Tek yapabildiğim, daha kesin bir şey gelene kadar IOException'u ele almaktır, ancak uygulamaları geliştirirken her hatayı benzersiz şekilde ele almak her zaman iyidir.

+0

: Bunu öğrendikten sonra , daha sonra, en genel IOException birden yakalama blokları, ilk alt sınıfları kullanabilirsiniz. Sonra, uzmanlıklarını tanımak için mesajlarıyla uğraşmanıza gerek yok. –

+0

Kullandığınız kitaplık yalnızca farklı iletilerle "IOException" atarsa, ayırma yapmanın tek yolu dize karşılaştırmasıdır. Farklı vakaları farklı şekilde ele alabileceğinden emin misin? Pratikte, bireysel istisnaları nadiren düzgün bir şekilde ele alabiliyordum, bu nedenle, sadece benzer istisnaların hepsinin aynı şekilde ele alınmasıyla bu sorunun önüne geçilmiş oluyor. – Richard

+0

@Richard Kütüphane, yalnızca 'IOException' yazmak için * bildirilmiş olabilir, ancak bu durum türetilmiş istisnalar atamadığı anlamına gelmez. Denemelisin. – EJP

cevap

2

Bu gibi durumlarda iletinin çoğu, kodunuzun bakış açısından önemsizdir. Sadece kullanıcıya gösterilecek veya giriş yapmış bir şey. Tek göze çarpan gerçek şu ki, bağlantı her ne sebeple olursa olsun kırılıyor ve hangi mesaja bağlı olarak kullanabileceğiniz farklı kod yolları yok.

Farklı olan yalnızca bir kodlama hatasını gösteren 'soket kapalı' dır. Aşağıda Yorumlarınızı İlişkin

DÜZENLEME: Bir soketi

  • SocketTimeoutException daha herhangi IOException diğer bağlantı için ölümcüldür.
  • geçersiz paketleri IOException neden olmaz: bu IOException: connection closed by remote host diye bir şey yoktur uygulama katmanı durumlar veya IOException: örneğin alt sınıfları atar bir uygulama katmanı sorun, java.io.StreamCorruptedException.
  • var. ya read() I alıcı önermek diğer herhangi bir X
+1

Yani, istisna tarafından atılan mesaj, kodun ele alması gereken mantıkla tamamen ilgisiz mi? Sunucu uygulamaları yazarken katılmamalıyım. Örneğin, IOException bir kullanıcının bağlantısının kesilmesine karşı geçersiz paket uzunluklarından şikayetçi olsaydı. Belki de, belirli bir olay nedeniyle kullanıcının bağlantısı kesildiğinde, belleğinde veriyi önbelleğe almak isteyebilirsiniz, böylece tüm kullanıcı verilerini tekrar veritabanından yüklemeden hızlı ve verimli bir şekilde tekrar çevrimiçi olarak kaydolabilirler. Yanlış olabilir, hala daha iyi bir anlayışa kavuşmaya çalışıyorum. – Hobbyist

+0

Kullanıcı sadece bir ağ başarısızlığı nedeniyle bağlantıyı keserse, sadece oturumun kapatılmasından ziyade ("Bağlantıyı uzaktaki ana bilgisayar tarafından kapatılır" iletisini) atarsanız başka bir işlemi takip etmek isteyebilirsiniz. – Hobbyist

+3

@ Christian.tucker Aşırı karmaşık olduğunuza benziyor. Çok nadirdir (imkansız değil, sadece nadir), mesajın kodunuzda herhangi bir istisna için ne olduğunu bilmeniz gerekir. Bu, istisna yazmanın bütün noktasıdır. Listelediğiniz tüm köşe durumları için, tek bir eylem dizisini öneriyorum (örneğin: HER durumda her durumda bağlantı kesildiğinde kullanıcı durumunu kaydetme). – MadConan

1

için EOFException atma -1, readLine() dönen boş dönen veya readXXX() akran kendini gösteren bir sonu akımı durumu neden bağlantısı, kapatır İstisnalar, en özelden en az - sırayla, aradığınız istisna durumlarına ulaşıldığında devre kesici bir patern göreceksiniz.catch (IOException|SocketException|

+0

Bahşiş için teşekkürler, ama sorunun genel noktası, özel durum türünü bulmaktı, örneğin, 'IOException Özel Durum' ve 'FileNotFoundException, IOException' – Hobbyist

+2

@ Christian.tucker 'i genişletiyor. yorum Yap. Sorunuzda (miserad olmadıkça) 'IOExcepption' 'FileNotFoundException' gibi belirli bir alt sınıf değil, mesaj içeriğine göre bunları işlemek zorunda olduğunuz durumla karşılaştığınızı iddia ediyorsunuz. Ancak, yorumlarınızda "sorunun amacı özel durum türünü bulmaktı. Örneğin, IOException Özel Durumunu genişletiyor ve FileNotFoundException IOException özelliğini genişletiyor". Yani, hassas tip (FileNotFoundException) veya değil mi (IOException)? – Pshemo

+1

@ Christian.tucker veya metodun yalnızca IOException'ı attığı bildirilen durumdan bahsediyoruz, bu yüzden derleyici bunu ele almanızı sağlıyor, ancak gerçekte yöntem FileNotFoundException'ı atabilir mi? Bu durumda '' IOException' ele alma işleminden önce 'FileNotFoundException' için bir durumun oluşturulması sorununuzu çözmelidir. – Pshemo

1

belgeleri (http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html) uzun bir listesini içerir: Ayrıca | komutunu kullanarak farklı türde birden istisnalar yakalamak unutmayın

try { 
    /// Something that can result in IOException or a SocketException 
catch (IOException e){ 
    //Do something specific 
}catch (SocketExcpetion e){ 

}catch (Exception e) { //or some superclass of the above exceptions 
/// 
} 

: Bu ben ile gelebilir en iyisi doğrudan alt sınıfların Onlara bakmak ve farklı olarak hangi tedaviyi yapmak istediğinizi kontrol etmek isteyebilirsiniz. uygulamaları geliştirirken, farklı türde istisna olarak farklı ele hak istisnaları kapsülleyen

catch(SSLException se) { 
    // do something 
} 
catch(HttpRetryException he) { 
    // do something else 
} 
catch(IOException ioe) { 
    // nop 
}