Mengapa "throws Exception" diperlukan saat memanggil suatu fungsi?

98
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();
    }
}

Mengapa laporan compiler bahwa metode show2(), show3()dan main()memiliki

pengecualian yang tidak dilaporkan Pengecualian yang harus ditangkap atau dinyatakan akan dibuang

kapan saya menghapus throws Exceptiondari metode ini?

nr5
sumber
2
@PaulTomblin main pasti bisa dideklarasikan untuk melempar Exception. Jika ya, JVM akan ditutup. Ini hampir mengabaikannya karena kompilator akan mengizinkan.
Taymon
Ketika metode yang dipanggil ( Methdod1 ) melempar Exception, kita harus mendefinisikan metode pemanggilan ( Method2 ) dengan throws Exception; jika kita tidak memberikan pengecualian itu dalam metode pemanggilan. Tujuan dari ini adalah untuk memberikan kepala ke metode pemanggilan ( Method3 ) dari Metode2 yang Exception mungkin dilemparkan oleh Method2 dan Anda harus menanganinya di sini, jika tidak maka dapat mengganggu program Anda.
Rito
Demikian pula, jika Method3 tidak menangani pengecualian dalam tubuhnya, itu harus mendefinisikan throws Exceptiondalam definisi metodenya untuk memberikan kepala metode pemanggilannya. perpanjangan dari komentar sebelumnya
Rito

Jawaban:

144

Di Java, seperti yang Anda ketahui, pengecualian dapat dikategorikan menjadi dua: Satu yang memerlukan throwsklausa atau harus ditangani jika Anda tidak menentukan satu dan satu lagi tidak. Sekarang, lihat gambar berikut:

masukkan deskripsi gambar di sini

Di Java, Anda bisa melempar apa pun yang memperluas Throwablekelas. Namun, Anda tidak perlu menentukan throwsklausa untuk semua kelas. Secara khusus, kelas yang baik sebagai Erroratau RuntimeExceptionatau salah satu subclass dari kedua. Dalam kasus Anda, Exceptionini bukan merupakan subclass dari Erroratau RuntimeException. Jadi, ini adalah pengecualian yang dicentang dan harus ditentukan dalam throwsklausa, jika Anda tidak menangani pengecualian tersebut. Itulah mengapa Anda membutuhkan throwsklausul tersebut.


Dari Tutorial Java :

Pengecualian adalah peristiwa, yang terjadi selama eksekusi program, yang mengganggu aliran normal instruksi program.

Sekarang, seperti yang Anda ketahui, pengecualian diklasifikasikan menjadi dua: dicentang dan tidak dicentang. Mengapa klasifikasi ini?

Pengecualian yang Dicentang: Mereka digunakan untuk mewakili masalah yang dapat dipulihkan selama pelaksanaan program. Mereka biasanya bukan kesalahan programmer. Misalnya, file yang ditentukan oleh pengguna tidak dapat dibaca, atau tidak ada koneksi jaringan yang tersedia, dll., Dalam semua kasus ini, program kami tidak perlu keluar, melainkan dapat mengambil tindakan seperti memberi tahu pengguna, atau beralih ke fallback mekanisme (seperti offline bekerja ketika jaringan tidak tersedia), dll.

Pengecualian yang Tidak Dicentang: Mereka sekali lagi dapat dibagi menjadi dua: Kesalahan dan RuntimeExceptions. Salah satu alasan mereka tidak dicentang adalah jumlahnya banyak, dan diminta untuk menangani semuanya akan mengacaukan program kami dan mengurangi kejelasannya. Alasan lainnya adalah:

  • Pengecualian Waktu Proses: Biasanya terjadi karena kesalahan programmer. Misalnya, jika terjadi ArithmeticExceptionpembagian dengan nol atau ArrayIndexOutOfBoundsExceptionterjadi, itu karena kami kurang berhati-hati dalam pengkodean kami. Mereka biasanya terjadi karena beberapa kesalahan dalam logika program kami. Jadi, mereka harus dibersihkan sebelum program kita memasuki mode produksi. Mereka tidak dicentang dalam arti bahwa, program kita harus gagal ketika itu terjadi, sehingga kita para pemrogram dapat menyelesaikannya pada saat pengembangan dan pengujian itu sendiri.

  • Kesalahan: Kesalahan adalah situasi yang biasanya program tidak dapat dipulihkan. Misalnya, jika StackOverflowErrorterjadi, program kami tidak dapat berbuat banyak, seperti meningkatkan ukuran stack pemanggil fungsi program. Atau jika OutOfMemoryErrorterjadi, kami tidak dapat berbuat banyak untuk meningkatkan jumlah RAM yang tersedia untuk program kami. Dalam kasus seperti itu, lebih baik keluar dari program. Itulah mengapa mereka dibuat tidak dicentang.

Untuk informasi rinci, lihat:

Jomoos
sumber
apa yang saya dapatkan dari jawaban Anda adalah bahwa kelas Error dan sublaclass dan kelas RuntimeException dan sub kelasnya, mereka berada di bawah pengecualian yang tidak dicentang (seperti System.out.println (5/0); tidak perlu membuang karena ini adalah runtime exception tetapi kita masih bisa menerapkan try catch) dan kelas Exception diperiksa sehingga kita perlu mendeklarasikan klausa throws dalam metode itu dan setiap metode yang memanggilnya
nr5
Satu pertanyaan lagi: jika pengecualian dikategorikan menjadi tidak dicentang dan dicentang, khususnya yang tidak dicentang (kesalahan waktu proses) untuk menghindari lebih banyak kesalahan selama waktu kompilasi?
nr5
@Jomoos - Katakanlah bahwa kode di dalam metode menampilkan IOException. Lalu, apakah boleh meletakkan "throws Exception" di deklarasi metode?
MasterJoe
oh. Aku mengerti sekarang. ada pengecualian untuk aturan hierarki Exception. Membuat. Sempurna. Merasakan. Terima kasih Java.
JJS
25

Java mengharuskan Anda menangani atau mendeklarasikan semua pengecualian. Jika Anda tidak menangani Exception menggunakan blok coba / tangkap maka itu harus dideklarasikan dalam tanda tangan metode.

Sebagai contoh:

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

Harus ditulis sebagai:

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

Dengan cara ini Anda bisa menyingkirkan deklarasi "throws Exception" dalam deklarasi metode.

jebar8
sumber
7
Semua pengecualian yang bukan merupakan subkelas dari RuntimeException.
yshavit
apakah ada kelas lain seperti Exception yang dicentang?
nr5
1
Maksud kamu apa? Karena semua objek pengecualian memiliki "Exception" sebagai kelas dasarnya, jika Anda menangkap objek "Exception" (seperti dalam contoh saya), objek tersebut akan menangkap pengecualian apa pun yang dilemparkan. Untuk lebih spesifik (karena pengecualian yang berbeda mungkin akan membutuhkan cara penanganan yang berbeda) Anda harus memiliki beberapa blok tangkapan.
jebar8
jika saya harus mengatakan bahwa pengecualian yang dicentang perlu ditangani @ waktu kompilasi dan ditangkap saat runtime. Apakah saya benar ? jika ya maka kalimat yang sama untuk pengecualian Tidak Dicentang akan menjadi?
nr5
@ jebar8 - Anda mengacaukan Java dengan .NET - di Java, throwable harus mewarisi Throwable(mewarisi Exceptionjuga berfungsi, karena meluas Throwable, tetapi tidak wajib).
BrainSlugs83
5

The throws Exceptiondeklarasi adalah cara otomatis melacak metode yang mungkin melemparkan pengecualian untuk alasan diantisipasi tetapi tidak dapat dihindari. Deklarasi biasanya spesifik tentang tipe atau tipe pengecualian yang mungkin dilemparkan seperti throws IOExceptionatau throws IOException, MyException.

Kita semua memiliki atau pada akhirnya akan menulis kode yang berhenti tiba-tiba dan melaporkan pengecualian karena sesuatu yang tidak kita antisipasi sebelum menjalankan program, seperti pembagian dengan nol atau indeks di luar batas. Karena kesalahan tidak diharapkan oleh metode, mereka tidak dapat "ditangkap" dan ditangani dengan klausa coba tangkap. Pengguna metode yang tidak curiga juga tidak akan mengetahui kemungkinan ini dan program mereka juga akan berhenti.

Ketika pemrogram mengetahui jenis kesalahan tertentu yang mungkin terjadi tetapi ingin menangani pengecualian ini di luar metode, metode dapat "melempar" satu atau lebih jenis pengecualian ke metode pemanggil alih-alih menanganinya. Jika pemrogram tidak mendeklarasikan bahwa metode (mungkin) memunculkan pengecualian (atau jika Java tidak memiliki kemampuan untuk mendeklarasikannya), kompilator tidak dapat mengetahuinya dan akan tergantung pada pengguna metode yang akan datang untuk mengetahuinya, menangkap dan menangani pengecualian apa pun yang mungkin dilontarkan metode. Karena program dapat memiliki banyak lapisan metode yang ditulis oleh banyak program berbeda, menjadi sulit (tidak mungkin) untuk melacak metode mana yang mungkin mengeluarkan pengecualian.

Meskipun Java memiliki kemampuan untuk mendeklarasikan pengecualian, Anda masih dapat menulis metode baru dengan pengecualian yang tidak tertangani dan tidak dideklarasikan, dan Java akan mengkompilasinya dan Anda dapat menjalankannya dan berharap yang terbaik. Apa yang tidak boleh dilakukan oleh Java adalah mengompilasi metode baru Anda jika ia menggunakan metode yang telah dideklarasikan sebagai pelemparan pengecualian, kecuali Anda menangani pengecualian yang dideklarasikan dalam metode Anda atau mendeklarasikan metode Anda sebagai melempar yang sama pengecualian atau jika ada beberapa pengecualian, Anda dapat menangani beberapa dan membuang sisanya.

Ketika seorang programmer menyatakan bahwa metode tersebut melempar tipe pengecualian tertentu, itu hanyalah cara otomatis untuk memperingatkan programmer lain menggunakan metode bahwa pengecualian dimungkinkan. Programmer kemudian dapat memutuskan untuk menangani pengecualian atau meneruskan peringatan dengan mendeklarasikan metode pemanggilan sebagai juga melempar pengecualian yang sama. Karena kompilator telah diperingatkan, pengecualian dimungkinkan dalam metode baru ini, ia dapat secara otomatis memeriksa apakah pemanggil metode baru di masa mendatang menangani pengecualian atau mendeklarasikannya dan memaksakan satu atau yang lain terjadi.

Hal yang menyenangkan tentang jenis solusi ini adalah ketika kompilator melaporkannya Error: Unhandled exception type java.io.IOExceptionmemberikan file dan nomor baris dari metode yang dideklarasikan untuk membuang pengecualian. Anda kemudian dapat memilih untuk meneruskan tanggung jawab dan mendeklarasikan metode Anda juga "melempar IOException". Ini bisa dilakukan sampai ke metode utama yang kemudian akan menyebabkan program berhenti dan melaporkan pengecualian kepada pengguna. Namun, lebih baik menangkap pengecualian dan menanganinya dengan cara yang baik seperti menjelaskan kepada pengguna apa yang telah terjadi dan bagaimana memperbaikinya. Ketika sebuah metode menangkap dan menangani pengecualian, metode tersebut tidak lagi harus mendeklarasikan pengecualian. Uang berhenti di situ untuk berbicara.

dansalmo
sumber
4

Exceptionadalah kelas pengecualian yang dicentang. Oleh karena itu, kode apa pun yang memanggil metode yang menyatakan bahwa ia throws Exceptionharus menangani atau mendeklarasikannya.

Taymon
sumber
Setiap metode dalam rantai dideklarasikan untuk membuang Exception, termasuk main. Jadi dimana masalahnya?
Paul Tomblin
@PaulTomblin im menanyakan mengapa perlu menulis pengecualian lemparan dalam fungsi pemanggil, memanggil fungsi yang melempar pengecualian
nr5
Oke, saya tidak mengerti mengapa Anda bertanya tentang kesalahan kompiler yang sebenarnya tidak Anda dapatkan dari kode yang Anda posting. Itu cara bertanya yang aneh.
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());
   }
}

Hanya perubahan kecil dalam program Anda. Apa yang tampaknya disalahpahami oleh banyak orang tentang masalah utama, adalah setiap kali Anda mengeluarkan pengecualian, Anda perlu menanganinya, tidak perlu di tempat yang sama (mis. Metode show1,2,3 dalam program Anda) tetapi Anda harus pada metode pemanggil pertama di dalam 'utama'. dalam satu kata, ada 'lemparan', harus ada 'tangkap / coba', bahkan jika bukan metode yang sama di mana pengecualian terjadi.

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

Karena ada pengecualian yang diperiksa dalam metode show (), yang tidak ditangani dalam metode itu, jadi kami menggunakan kata kunci lemparan untuk menyebarkan Exception.

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

Karena Anda menggunakan metode show () dalam metode show2 () dan Anda telah menyebarkan pengecualian setidaknya yang harus Anda tangani di sini. Jika Anda tidak menangani Exception di sini, maka Anda menggunakan kata kunci throws. Jadi itulah alasan untuk menggunakan kata kunci lemparan pada tanda tangan metode.

Aditya
sumber
0

Jika Anda menyebarkan pengecualian dengan mendeklarasikan direktif throws dalam tanda tangan metode saat ini, maka di suatu tempat di atas garis atau memanggil tumpukan, konstruksi coba / tangkap harus digunakan untuk menangani pengecualian.

Beaumont Muni
sumber
Komentar ini harus ditambahkan ke bagian komentar karena tidak memberikan jawaban atau contoh yang dapat diverifikasi. - stackoverflow.com/help/how-to-answer
Paul Dawson
-1

Pada dasarnya, jika Anda tidak menangani pengecualian di tempat yang sama saat Anda melemparkannya, maka Anda dapat menggunakan "throws exception" pada definisi fungsi tersebut.

Shahzeb Sheikh
sumber