Pengendalian pengecualian Java


Pengecualian ialah beberapa ralat dalam atur cara, tetapi tidak semua ralat adalah pengecualian, dan ralat kadangkala boleh dielakkan.

Sebagai contoh, jika kod anda tiada koma bertitik, hasilnya akan menjadi ralat java.lang.Error jika anda menggunakan System.out.println(11/0), maka anda adalah kerana Jika anda menggunakan 0 sebagai pembahagi, java.lang.ArithmeticException akan dilemparkan.

Terdapat banyak sebab untuk pengecualian, yang biasanya termasuk kategori berikut:

  • Pengguna memasukkan data haram.

  • Fail yang hendak dibuka tidak wujud.

  • Sambungan terganggu semasa komunikasi rangkaian, atau memori JVM melimpah.

Sesetengah pengecualian ini disebabkan oleh ralat pengguna, sesetengahnya disebabkan oleh ralat program dan yang lain disebabkan oleh ralat fizikal. -

Untuk memahami cara pengendalian pengecualian Java berfungsi, anda perlu menguasai tiga jenis pengecualian berikut:

  • Pengecualian yang disemak: Pengecualian yang disemak paling mewakili adalah pengecualian yang disebabkan oleh ralat atau masalah pengguna, yang tidak dapat diramalkan oleh pengaturcara. Sebagai contoh, apabila cuba membuka fail yang tidak wujud, pengecualian berlaku Pengecualian ini tidak boleh diabaikan begitu sahaja pada masa penyusunan.

  • Pengecualian masa jalan: Pengecualian masa jalan ialah pengecualian yang mungkin dielakkan oleh pengaturcara. Berbeza dengan pengecualian yang diperiksa, pengecualian masa jalan boleh diabaikan pada masa penyusunan.

  • Ralat: Ralat bukan pengecualian, tetapi masalah di luar kawalan pengaturcara. Ralat sering diabaikan dalam kod. Sebagai contoh, apabila timbunan melimpah, ralat berlaku yang tidak boleh disemak semasa penyusunan.


Hierarki kelas pengecualian

Semua kelas pengecualian ialah subkelas yang diwarisi daripada kelas java.lang.Exception.

Kelas pengecualian ialah subkelas kelas Boleh Lempar. Sebagai tambahan kepada kelas Pengecualian, Throwable juga mempunyai Ralat subkelas.

Atur cara Java biasanya tidak menangkap ralat. Ralat biasanya berlaku apabila kegagalan serius berlaku, dan ia berada di luar skop pemprosesan oleh program Java.

Ralat digunakan untuk menunjukkan ralat yang berlaku dalam persekitaran masa jalan.

Sebagai contoh, limpahan memori JVM. Biasanya, program tidak pulih daripada ralat.

Kelas pengecualian mempunyai dua subkelas utama: kelas IOException dan kelas RuntimeException.

12-130Q1234I6223.jpg

Dalam kelas terbina dalam Java (diterangkan seterusnya), terdapat pengecualian bertanda dan tidak bertanda yang paling biasa digunakan.


Kelas pengecualian terbina dalam Java

Bahasa Java mentakrifkan beberapa kelas pengecualian dalam pakej standard java.lang.

Subkelas kelas pengecualian masa jalan standard ialah kelas pengecualian yang paling biasa. Memandangkan pakej java.lang dimuatkan ke dalam semua program Java secara lalai, kebanyakan pengecualian yang diwarisi daripada kelas pengecualian masa jalan boleh digunakan secara langsung.

Java juga mentakrifkan beberapa pengecualian lain berdasarkan setiap perpustakaan kelas Jadual berikut menyenaraikan pengecualian Java yang tidak ditanda.

PengecualianPenerangan
ArithmeticException                 Pengecualian ini dilemparkan apabila keadaan operasi tidak normal berlaku. Sebagai contoh, apabila integer "dibahagikan dengan sifar", contoh kelas ini dilemparkan.
ArrayIndexOutOfBoundsException                 Pengecualian dilemparkan apabila mengakses tatasusunan dengan indeks haram. Indeks ialah indeks haram jika ia negatif atau lebih besar daripada atau sama dengan saiz tatasusunan.
ArrayStoreException                 Pengecualian dilemparkan apabila cuba menyimpan objek daripada jenis yang salah ke dalam tatasusunan objek.
ClassCastException                   Pengecualian ini dilemparkan apabila percubaan dibuat untuk menghantar objek ke subkelas yang bukan contoh.
IllegalArgumentException Pengecualian yang dilemparkan menunjukkan bahawa parameter yang menyalahi undang-undang atau salah telah dihantar kepada kaedah tersebut.
IllegalMonitorStateException Pengecualian yang dilemparkan menunjukkan bahawa utas telah cuba menunggu pada monitor objek, atau telah cuba untuk memberitahu utas lain yang sedang menunggu pada monitor objek tanpa sendiri menentukan monitor.
IllegalStateException                   Isyarat yang dihasilkan apabila kaedah dipanggil pada masa yang tidak sah atau tidak sesuai. Dalam erti kata lain, persekitaran Java atau aplikasi Java tidak berada dalam keadaan yang sesuai untuk operasi yang diminta.
IllegalThreadStateException Pengecualian dilemparkan apabila benang tidak berada dalam keadaan yang sesuai yang diperlukan oleh operasi yang diminta.
IndexOutOfBoundsException Dilemparkan apabila menunjukkan bahawa indeks isihan (seperti isihan pada tatasusunan, rentetan atau vektor) berada di luar julat.
NegativeArraySizeException               Pengecualian ini dibuang jika aplikasi cuba mencipta tatasusunan dengan saiz negatif.
NullPointerException                 Pengecualian ini dilemparkan apabila aplikasi cuba menggunakan null di mana objek dijangka
NumberFormatException                 Pengecualian ini dilemparkan apabila aplikasi cuba menukar rentetan kepada jenis angka, tetapi rentetan itu tidak boleh ditukar kepada format yang sesuai.
SecurityException                 Pengecualian yang dilemparkan oleh pengurus keselamatan untuk menunjukkan pelanggaran keselamatan.
StringIndexOutOfBoundsException                 Pengecualian ini dilemparkan dengan kaedah String dan menunjukkan bahawa indeks sama ada negatif atau melebihi saiz rentetan.
UnsupportedOperationException                 Pengecualian ini dilemparkan apabila operasi yang diminta tidak disokong.

Jadual berikut menyenaraikan kelas pengecualian yang disemak Java yang ditakrifkan dalam pakej java.lang.

异常描述
                    ClassNotFoundException                    应用程序试图加载类时,找不到相应的类,抛出该异常。
                    CloneNotSupportedException                    当调用 Object 类中的 clone 方法克隆对象,但该对象的类无法实现 Cloneable 接口时,抛出该异常。
                    IllegalAccessException                    拒绝访问一个类的时候,抛出该异常。
                    InstantiationException                    当试图使用 Class 类中的 newInstance 方法创建一个类的实例,而指定的类对象因为是一个接口或是一个抽象类而无法实例化时,抛出该异常。
                    InterruptedException                    一个线程被另一个线程中断,抛出该异常。
                    NoSuchFieldException                    请求的变量不存在
                    NoSuchMethodException                    请求的方法不存在

Kaedah pengecualian

Senarai berikut ialah kaedah utama kelas Boleh Lempar:

序号方法及说明
                    1public String getMessage()
返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。
                    2public Throwable getCause()
返回一个Throwable 对象代表异常原因。
                    3public String toString()
使用getMessage()的结果返回类的串级名字。
                    4public void printStackTrace()
打印toString()结果和栈层次到System.err,即错误输出流。
                    5public StackTraceElement [] getStackTrace()
返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。
                    6public Throwable fillInStackTrace()
用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。

Pengecualian tangkap

Gunakan kata kunci cuba dan tangkap untuk menangkap pengecualian. Blok kod cuba/tangkap diletakkan di tempat pengecualian mungkin berlaku.

Kod dalam blok kod try/catch dipanggil kod pengawal Sintaks untuk menggunakan try/catch adalah seperti berikut:

try
{
   // 程序代码
}catch(ExceptionName e1)
{
   //Catch 块
}

Pernyataan Catch mengandungi pengisytiharan jenis pengecualian. ditangkap. Apabila pengecualian berlaku dalam blok kod yang dilindungi, blok tangkapan selepas percubaan akan diperiksa.

Jika pengecualian yang berlaku terkandung dalam blok tangkapan, pengecualian akan dihantar ke blok tangkapan, yang sama seperti menghantar parameter kepada kaedah.

Contoh

Contoh berikut mengisytiharkan tatasusunan dengan dua elemen Apabila kod cuba mengakses elemen ketiga tatasusunan, pengecualian akan dilemparkan.

// 文件名 : ExcepTest.java
import java.io.*;
public class ExcepTest{

   public static void main(String args[]){
      try{
         int a[] = new int[2];
         System.out.println("Access element three :" + a[3]);
      }catch(ArrayIndexOutOfBoundsException e){
         System.out.println("Exception thrown  :" + e);
      }
      System.out.println("Out of the block");
   }
}

Keluaran menyusun dan menjalankan kod di atas adalah seperti berikut:

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block

Berbilang blok tangkapan

Sebuah blok kod cuba diikuti oleh berbilang blok kod tangkapan ialah dipanggil tangkapan blok tangkapan berbilang.

Sintaks berbilang blok tangkapan adalah seperti berikut:

 try{
    // 程序代码
 }catch(异常类型1 异常的变量名1){
    // 程序代码
 }catch(异常类型2 异常的变量名2){
    // 程序代码
 }catch(异常类型2 异常的变量名2){
    // 程序代码
 }

Coretan kod di atas mengandungi 3 blok tangkapan.

Anda boleh menambah sebarang bilangan blok tangkapan selepas pernyataan cubaan.

Jika pengecualian berlaku dalam kod yang dilindungi, pengecualian itu dibuang ke blok tangkapan pertama.

Jika jenis data pengecualian yang dilemparkan sepadan dengan ExceptionType1, ia akan ditangkap di sini.

Jika tiada perlawanan, ia akan dihantar ke blok tangkapan kedua.

Ini dilakukan sehingga pengecualian ditangkap atau melepasi semua blok tangkapan.

Contoh

Contoh ini menunjukkan cara menggunakan berbilang cubaan/tangkap.

try
{
   file = new FileInputStream(fileName);
   x = (byte) file.read();
}catch(IOException i)
{
   i.printStackTrace();
   return -1;
}catch(FileNotFoundException f) //Not valid!
{
   f.printStackTrace();
   return -1;
}

kata kunci throws/throw:

Jika kaedah tidak menangkap pengecualian yang diperiksa, maka kaedah mesti diisytiharkan menggunakan kata kunci throws. Kata kunci lontaran diletakkan di hujung tandatangan kaedah.

Anda juga boleh menggunakan kata kunci lontaran untuk melontar pengecualian, sama ada ia baru dibuat atau baru ditangkap.

Pengisytiharan kaedah berikut membuang RemoteException:

import java.io.*;
public class className
{
   public void deposit(double amount) throws RemoteException
   {
      // Method implementation
      throw new RemoteException();
   }
   //Remainder of class definition
}

Kaedah boleh mengisytiharkan berbilang pengecualian, dipisahkan dengan koma.

Sebagai contoh, pengisytiharan kaedah berikut membuang RemoteException dan InsufficientFundsException:

import java.io.*;
public class className
{
   public void withdraw(double amount) throws RemoteException,
                              InsufficientFundsException
   {
       // Method implementation
   }
   //Remainder of class definition
}

akhirnya kata kunci

akhirnya kata kunci digunakan untuk mencipta blok kod cuba yang dilaksanakan selepas kod blok.

Tidak kira sama ada pengecualian berlaku atau tidak, kod dalam blok kod akhirnya akan sentiasa dilaksanakan.

Dalam blok kod akhirnya, anda boleh menjalankan pernyataan pembersihan dan pernyataan pembersihan lain.

Blok kod akhirnya muncul di penghujung blok kod tangkapan, dan sintaksnya adalah seperti berikut:

 try{
    // 程序代码
 }catch(异常类型1 异常的变量名1){
    // 程序代码
 }catch(异常类型2 异常的变量名2){
    // 程序代码
 }finally{
    // 程序代码
 }

Contoh

 public class ExcepTest{

   public static void main(String args[]){
      int a[] = new int[2];
      try{
         System.out.println("Access element three :" + a[3]);
      }catch(ArrayIndexOutOfBoundsException e){
         System.out.println("Exception thrown  :" + e);
      }
      finally{
         a[0] = 6;
         System.out.println("First element value: " +a[0]);
         System.out.println("The finally statement is executed");
      }
   }
}

Hasil penyusunan dan larian di atas contohnya adalah seperti berikut:

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
First element value: 6
The finally statement is executed

Perhatikan Perkara berikut:

  • tangkapan tidak boleh wujud secara bebas daripada cubaan.

  • Ia tidak wajib untuk menambah blok akhirnya selepas cuba/tangkap.

  • Tidak boleh ada blok tangkapan mahupun blok akhirnya selepas kod cuba.

  • Tiada kod boleh ditambah antara cuba, tangkap, dan akhirnya menyekat.


Isytiharkan pengecualian tersuai

Dalam Java, anda boleh mentakrifkan pengecualian tersuai. Terdapat beberapa perkara yang perlu diingat semasa menulis kelas pengecualian anda sendiri.

  • Semua pengecualian mestilah subkelas Throwable.

  • Jika anda ingin menulis kelas pengecualian bertanda, anda perlu mewarisi kelas Pengecualian.

  • Jika anda ingin menulis kelas pengecualian runtime, anda perlu mewarisi kelas RuntimeException.

Anda boleh mentakrifkan kelas pengecualian anda sendiri seperti berikut:

class MyException extends Exception{
}

Kelas pengecualian yang dibuat dengan mewarisi hanya kelas Pengecualian ialah kelas pengecualian yang disemak.

Kelas InsufficientFundsException berikut ialah kelas pengecualian yang ditakrifkan pengguna yang mewarisi daripada Exception.

Kelas pengecualian, seperti mana-mana kelas lain, mengandungi pembolehubah dan kaedah.

Contoh

// 文件名InsufficientFundsException.java
import java.io.*;

public class InsufficientFundsException extends Exception
{
   private double amount;
   public InsufficientFundsException(double amount)
   {
      this.amount = amount;
   } 
   public double getAmount()
   {
      return amount;
   }
}

Untuk menunjukkan cara menggunakan kelas pengecualian tersuai kami,

termasuk kaedah withdraw() dalam kelas CheckingAccount di bawah untuk membuang pengecualian InsufficientFundsException.

// 文件名称 CheckingAccount.java
import java.io.*;

public class CheckingAccount
{
   private double balance;
   private int number;
   public CheckingAccount(int number)
   {
      this.number = number;
   }
   public void deposit(double amount)
   {
      balance += amount;
   }
   public void withdraw(double amount) throws
                              InsufficientFundsException
   {
      if(amount <= balance)
      {
         balance -= amount;
      }
      else
      {
         double needs = amount - balance;
         throw new InsufficientFundsException(needs);
      }
   }
   public double getBalance()
   {
      return balance;
   }
   public int getNumber()
   {
      return number;
   }
}

Program BankDemo berikut menunjukkan cara memanggil kaedah deposit() dan pengeluaran() kelas CheckingAccount.

//文件名称 BankDemo.java
public class BankDemo
{
   public static void main(String [] args)
   {
      CheckingAccount c = new CheckingAccount(101);
      System.out.println("Depositing 0...");
      c.deposit(500.00);
      try
      {
         System.out.println("\nWithdrawing 0...");
         c.withdraw(100.00);
         System.out.println("\nWithdrawing 0...");
         c.withdraw(600.00);
      }catch(InsufficientFundsException e)
      {
         System.out.println("Sorry, but you are short $"
                                  + e.getAmount());
         e.printStackTrace();
      }
    }
}

Kompilasikan tiga fail di atas dan jalankan program BankDemo Hasilnya adalah seperti berikut:

Depositing 0...

Withdrawing 0...

Withdrawing 0...
Sorry, but you are short 0.0
InsufficientFundsException
        at CheckingAccount.withdraw(CheckingAccount.java:25)
        at BankDemo.main(BankDemo.java:13)

Pengecualian Umum

Terdapat dua jenis yang ditakrifkan dalam pengecualian Java. dan kesilapan.

  • JVM (JavaMesin Maya)Pengecualian: Pengecualian yang dilemparkan oleh JVM atau ralat . Contohnya: kelas NullPointerException, kelas ArrayIndexOutOfBoundsException, kelas ClassCastException.

  • Pengecualian peringkat program: Pengecualian yang dilemparkan oleh program atau program API. Contohnya, kelas IllegalArgumentException, kelas IllegalStateException.