Bir işlevi çağırırken neden "istisna atar" gereklidir?


102
class throwseg1
{
    void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

    void show2() throws Exception  // Why throws is necessary here ?
    {
        show();
    }

    void show3() throws Exception  // Why throws is necessary here ?
    {
        show2();
    }

    public static void main(String s[]) throws Exception  // Why throws is necessary here ?
    {
        throwseg1 o1 = new throwseg1();
        o1.show3();
    }
}

Neden derleyici raporlar yöntemleri show2(), show3()ve main()var

rapor edilmeyen istisna Yakalanması veya atılacağı bildirilmesi gereken istisna

Ben kaldırdığınızda throws Exceptionbu yöntemlerden gelen?


2
@PaulTomblin main kesinlikle İstisna atacak şekilde ilan edilebilir. Varsa, JVM kapanacaktır. Bu, derleyicinin izin vereceği kadar onu görmezden gelmeye yakındır.
Taymon

Çağrılan yöntem ( Methdod1 ) atıldığındaException , çağırma yöntemini ( Yöntem2 ) throws Exception; çağıran yöntemde bu istisnayı vermiyorsak. Bunun amacı, Method2'nin çağrı yöntemine ( Method3 ), Method2 tarafından bir İstisnanın atılabileceğine ve burada işlemeniz gerektiğine dair uyarı vermektir , aksi takdirde programınızı kesintiye uğratabilir.
Rito

Benzer şekilde, Yöntem3 istisnayı gövdesindeki işlemiyorsa , throws Exceptionçağırma yönteminden vazgeçmek için yöntem tanımında tanımlaması gerekir. önceki yorumun uzantısı
Rito

Yanıtlar:


148

Java'da, bildiğiniz gibi, istisnalar ikiye ayrılabilir: Biri throwscümleciğe ihtiyaç duyar veya birini belirtmezseniz ele alınması gereken bir cümle. Şimdi aşağıdaki şekle bakın:

görüntü açıklamasını buraya girin

Java'da, Throwablesınıfı genişleten her şeyi atabilirsiniz . Ancak, throwstüm sınıflar için bir cümle belirtmenize gerek yoktur . Spesifik olarak, sınıfları, ya ki, bir Errorya da RuntimeExceptionya da bu ikisinin alt sınıflarından herhangi biri olabilir. Sizin durumunuzda Exceptionbir Errorveya RuntimeException. Bu nedenle, bu kontrol edilmiş bir istisnadır ve throwseğer bu istisnayı işlemezseniz, maddede belirtilmelidir . Bu yüzden throwsmaddeye ihtiyacın vardı .


Gönderen Java Eğitimi :

Bir istisna, bir programın yürütülmesi sırasında meydana gelen ve programın talimatlarının normal akışını bozan bir olaydır.

Şimdi, bildiğiniz gibi istisnalar ikiye ayrılır: işaretli ve işaretsiz. Neden bu sınıflandırma?

Kontrol Edilmiş İstisna: Programın yürütülmesi sırasında kurtarılabilecek sorunları temsil etmek için kullanılırlar. Genellikle programcının hatası değildir. Örneğin, kullanıcı tarafından belirtilen bir dosya okunabilir değil veya ağ bağlantısı yok, vb. Tüm bu durumlarda, programımızın çıkması gerekmez, bunun yerine kullanıcıyı uyarmak veya geri dönüşe girmek gibi eylemler gerçekleştirebilir. mekanizma (ağ mevcut olmadığında çevrimdışı çalışma gibi), vb.

Kontrol Edilmemiş İstisnalar: Yine ikiye ayrılabilirler: Hatalar ve Çalışma Zamanı İstisnaları. Kontrol edilmemelerinin bir nedeni, çok sayıda olmaları ve hepsinin üstesinden gelmek zorunda olmaları, programımızı karıştıracak ve netliğini azaltacaktır. Diğer sebep ise:

  • Çalışma Zamanı İstisnaları: Genellikle programcının bir hatası nedeniyle oluşurlar. Örneğin, ArithmeticExceptionsıfıra bölme meydana gelirse veya ArrayIndexOutOfBoundsExceptionmeydana gelirse, bunun nedeni kodlamamızda yeterince dikkatli olmamızdır. Genellikle program mantığımızdaki bazı hatalar nedeniyle olurlar. Bu nedenle, programımız üretim moduna girmeden önce temizlenmeleri gerekir. Programımız ortaya çıktığında başarısız olması gerektiği anlamında kontrolsüzdürler, böylece biz programcılar onu geliştirme ve test sırasında çözebiliriz.

  • Hatalar: Hatalar, genellikle programın kurtaramadığı durumlardır. Örneğin, bir StackOverflowErrormeydana gelirse, programımız, programın işlev çağıran yığının boyutunu artırmak gibi çok şey yapamaz. Veya bir OutOfMemoryErrormeydana gelirse, programımızın kullanabileceği RAM miktarını artırmak için fazla bir şey yapamayız. Bu gibi durumlarda programdan çıkmak daha iyidir. Bu yüzden kontrolsüz hale getiriliyorlar.

Ayrıntılı bilgi için bakınız:


Cevabınızdan aldığım şey, Error sınıfı ve alt sınıflarının ve RuntimeException sınıfının ve alt sınıflarının denetlenmemiş istisnaya girdikleri (System.out.println (5/0) gibi; runtime istisnası ancak yine de try catch uygulayabiliriz) ve Exception sınıfı kontrol edilir, bu yüzden bu metotta ve onu çağıran her metotta throws cümlesi bildirmemiz gerekir
nr5

Bir soru daha: istisnalar kontrol edilmemiş ve kontrol edilmiş olarak sınıflandırılırsa, derleme sırasında daha fazla sayıda hatayı önlemek için özellikle kontrol edilmeyenler (çalışma zamanı hataları)?
nr5

@Jomoos - Bir yöntemin içindeki kodun IOException attığını söyleyin. O halde, yöntemin bildirimine "throws Exception" koymak uygun mudur?
MasterJoe

oh. Şimdi anladım. İstisna hiyerarşisinin kurallarında bir istisna vardır. Yapar. Mükemmel. Sense. Teşekkürler Java.
JJS

25

Java, tüm istisnaları işlemenizi veya bildirmenizi gerektirir. Bir dene / yakala bloğu kullanarak bir İstisna işlemiyorsanız, yöntemin imzasında bildirilmesi gerekir.

Örneğin:

class throwseg1 {
    void show() throws Exception {
        throw new Exception();
    }
}

Şu şekilde yazılmalıdır:

class throwseg1 {
    void show() {
        try {
            throw new Exception();
        } catch(Exception e) {
            // code to handle the exception
        }
    }
}

Bu şekilde, yöntem bildirimindeki "throws Exception" bildiriminden kurtulabilirsiniz.


7
RuntimeExceptionYani alt sınıfları olmayan tüm istisnalar .
yshavit

Exception gibi kontrol edilen başka bir sınıf varsa?
nr5

1
Ne demek istiyorsun? Tüm istisna nesnelerinin temel sınıfları olarak "Exception" olduğundan, bir "Exception" nesnesi yakalarsanız (benim örneğimdeki gibi), atılan tüm istisnaları yakalar. Daha spesifik olmak gerekirse (farklı istisnalar muhtemelen işleri halletmenin farklı yollarını gerektireceğinden) birden fazla yakalama bloğuna sahip olmalısınız.
jebar8

kontrol edilen istisnaların derleme zamanında ele alınması ve çalışma zamanında yakalanması gerektiğini söylersem. Haklı mıyım eğer evet ise o zaman Kontrolsüz istisna için aynı cümleyi ifade etmek?
nr5

@ jebar8 - Java'yı .NET ile karıştırıyorsunuz - Java'da, fırlatılabilir öğeler miras almalıdır Throwable(devralma Exceptionda çalışır, çünkü genişler Throwable, ancak gerekli değildir).
BrainSlugs83

5

throws ExceptionDeklarasyon beklenen fakat kaçınılmaz nedenlerle bir özel durum yöntemlerin tam tutmanın otomatik yoludur. Bildirim, tipik olarak throws IOExceptionveya gibi atılabilecek istisnaların türü veya türleri hakkında spesifiktir throws IOException, MyException.

Hepimiz, sıfıra bölme veya sınırların dışında indeks gibi, programı çalıştırmadan önce tahmin etmediğimiz bir şey nedeniyle beklenmedik şekilde duran ve bir istisna bildiren bir kod yazıyoruz veya yazacağız. Hatalar yöntem tarafından beklenmediğinden, bunlar "yakalanamadı" ve bir try catch cümlesiyle ele alınamadı. Yöntemin herhangi bir şüpheli kullanıcısı da bu olasılığı bilmez ve programları da durur.

Programcı belirli hata türlerinin ortaya çıkabileceğini bildiğinde, ancak bu istisnaları yöntemin dışında ele almak istediğinde, yöntem bunları işlemek yerine çağıran yönteme bir veya daha fazla istisna türü "atabilir". Programcı, yöntemin bir istisna atabileceğini (veya Java'nın bunu bildirme yeteneğine sahip olmadığını) beyan etmediyse (veya Java'nın bunu bildirme yeteneği yoksa), derleyici bunu bilemezdi ve bu, yöntemin gelecekteki kullanıcısına kalır, yöntemin ortaya çıkardığı istisnaları yakalar ve işler. Programlar, birçok farklı program tarafından yazılan birçok yöntem katmanına sahip olabileceğinden, hangi yöntemlerin istisna oluşturabileceğini izlemek zor (imkansız) hale gelir.

Java, istisnaları bildirme yeteneğine sahip olsa da, işlenmemiş ve bildirilmemiş istisnalarla yeni bir yöntem yazabilirsiniz ve Java onu derler ve çalıştırıp en iyisini umabilirsiniz. Java'nın yapmanıza izin vermeyeceği şey, yönteminizde bildirilen istisnaları işlemediğiniz veya yönteminizin aynı şeyi fırlattığını bildirmediğiniz sürece, istisna (ler) olarak bildirilmiş bir yöntemi kullanıyorsa yeni yönteminizi derlemektir istisna (lar) veya birden fazla istisna varsa, bazılarını halledebilir ve gerisini atabilirsiniz.

Bir programcı, yöntemin belirli bir istisna türü attığını bildirdiğinde, bu, diğer programcıları yöntemi kullanarak bir istisnanın mümkün olduğu konusunda uyarmanın otomatik bir yoludur. Programcı daha sonra istisnayı işlemeye karar verebilir veya çağıran yöntemi aynı istisnayı atmış gibi bildirerek uyarıyı iletebilir. Derleyici uyarıldığından, bu yeni yöntemde istisna olasıdır, yeni yöntemin gelecekteki çağırıcılarının istisnayı işleyip işlemediğini veya bildirip birinin veya diğerinin gerçekleşmesini zorunlu kılıp kılmadığını otomatik olarak kontrol edebilir.

Bu tür bir çözümle ilgili güzel olan şey, derleyici rapor Error: Unhandled exception type java.io.IOExceptionettiğinde, istisnayı atmak için bildirilen yöntemin dosya ve satır numarasını vermesidir. Daha sonra basitçe parayı geçmeyi seçebilir ve yönteminizi "IOException oluşturur" olarak da bildirebilirsiniz. Bu, programın durmasına ve istisnayı kullanıcıya bildirmesine neden olacağı ana yönteme kadar yapılabilir. Ancak, istisnayı yakalamak ve kullanıcıya ne olduğunu ve nasıl düzeltileceğini açıklamak gibi güzel bir yolla başa çıkmak daha iyidir. Bir yöntem istisnayı yakalayıp işlediğinde, artık istisnayı bildirmesi gerekmez. Kova tabiri caizse orada durur.


4

Exceptionkontrol edilmiş bir istisna sınıfıdır. Bu nedenle, throws Exceptionişlemesi veya bildirmesi gerektiğini bildiren bir yöntemi çağıran herhangi bir kod .


Zincirdeki her yöntem, main dahil olmak üzere İstisna atacak şekilde bildirilir. Peki sorun nerede?
Paul Tomblin

@PaulTomblin, çağıran işlevlerde istisna atar yazmanın neden gerekli olduğunu soruyorum, istisna atan bir işlevi çağırıyor
nr5

Tamam, neden gönderdiğiniz koddan almadığınız bir derleyici hatası hakkında soru sorduğunuzu anlamadım. Bu garip bir sorma şekli.
Paul Tomblin

0
package javaexception;


public class JavaException {
   void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

void show2() throws Exception  // Why throws is necessary here ?
{
    show();
}

void show3() throws Exception  // Why throws is necessary here ?
{
    show2();
}
public static void main(String[] args) {

   JavaException a = new JavaException();

   try{
   a.show3();
   }catch(Exception e){
       System.out.println(e.getMessage());
   }
}

Programınızda yalnızca küçük değişiklikler. Ana konu ile ilgili olarak birçok kişi tarafından yanlış anlaşılmış gibi görünen şey, istisnayı ne zaman atarsanız, aynı yerde gerekli değildir (örn. Programınızda show1,2,3 yöntemi), ancak ilk önce arayan yöntemi 'ana' içinde. tek kelimeyle, 'fırlat' vardır, istisnanın meydana geldiği yöntemle aynı yöntem olmasa bile 'yakala / dene' olmalıdır.


0
void show() throws Exception
{
    throw new Exception("my.own.Exception");
}

Show () yönteminde denetlenen istisna olduğu için, bu yöntemde işlenmez, bu nedenle Exception'ı yaymak için throws anahtar sözcüğünü kullanırız.

void show2() throws Exception //Why throws is necessary here ?
{
show();
}

Show2 () yönteminde show () yöntemini kullandığınızdan ve istisnayı en azından yaydığınız için burada işlem yapmanız gerekir. İstisnayı burada işlemiyorsanız, throws anahtar kelimesini kullanıyorsunuz demektir. Yöntem imzasında throws anahtar sözcüğünü kullanmanın nedeni budur.


0

Mevcut yöntemin imzasında throws direktifini bildirerek istisnayı yayarsanız, istisnayı işlemek için satırın veya çağrı yığınının yukarısında bir dene / yakala yapısı kullanılmalıdır.


Doğrulanabilir bir cevap veya bir örnek sağlamadığı için bu yorum yorumlar bölümüne eklenmelidir. - stackoverflow.com/help/how-to-answer
Paul Dawson

-1

Temel olarak, istisnayı fırlattığınız yerde işlemiyorsanız, fonksiyonun tanımında "istisna atar" seçeneğini kullanabilirsiniz.

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.