更新時(shí)間:2022-11-17 12:02:57 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1423次
Java是一種面向?qū)ο蟮木幊陶Z(yǔ)言。它提供對(duì)異常處理等各種機(jī)制的支持。Java 的這一特性使開發(fā)人員能夠管理由異常引起的運(yùn)行時(shí)錯(cuò)誤。
在本文中,您將了解Java中的異常。您還將了解Java 中不同類型的異常。
Java異常是限制程序正常執(zhí)行的不需要的錯(cuò)誤或錯(cuò)誤或事件。每次發(fā)生異常時(shí),程序執(zhí)行都會(huì)中斷。屏幕上顯示一條錯(cuò)誤消息。
異常的發(fā)生背后有幾個(gè)原因。這些是發(fā)生異常的一些情況:
每當(dāng)用戶提供無(wú)效數(shù)據(jù)時(shí)。
請(qǐng)求訪問(wèn)的文件在系統(tǒng)中不存在。
當(dāng)Java 虛擬機(jī)(JVM) 內(nèi)存不足時(shí)。
網(wǎng)絡(luò)在通信過(guò)程中掉線。
現(xiàn)在讓我們探索 Java 中不同類型的異常。
所有異常類的父類都是java.lang.Exception類。圖 1 說(shuō)明了不同類型的 Java 異常。
如果我們談?wù)揈xception類,它是內(nèi)置Throwable類的子類。還有另一個(gè)從 Throwable 類派生的子類,即Error,如圖 1 所示。錯(cuò)誤可以定義為一種異常情況,表明程序的執(zhí)行出現(xiàn)了問(wèn)題。這些不是由 Java 程序處理的。
Throwable類中有一些重要的方法可用,如下所示:
public String getMessage() – 提供有關(guān)通過(guò)消息發(fā)生的異常的信息,該消息在Throwable 構(gòu)造函數(shù)中初始化。
public Throwable getCause() – 提供由Throwable 對(duì)象表示的異常的根本原因。
public void printStackTrace() – 用于顯示toString()的輸出以及到System.err(錯(cuò)誤輸出流)的堆棧跟蹤。
public StackTraceElement [] getStackTrace() – 返回一個(gè)數(shù)組,其中包含堆棧跟蹤中存在的每個(gè)元素。索引 0 元素將象征調(diào)用堆棧的頂部,數(shù)組的最后一個(gè)元素將標(biāo)識(shí)調(diào)用堆棧的底部。
Java中主要有以下兩種類型的異常:
檢查異常
未經(jīng)檢查的異常
檢查異常也稱為編譯時(shí)異常,因?yàn)檫@些異常在編譯過(guò)程中由編譯器檢查,以確認(rèn)程序員是否處理了異常。如果不是,則系統(tǒng)顯示編譯錯(cuò)誤。例如,SQLException、IOException、InvocationTargetException和ClassNotFoundException。
為了說(shuō)明檢查異常的概念,讓我們考慮以下代碼片段:
import java.io.*;
class demo1 {
public static void main(String args[]) {
FileInputStream input1 = null;
/* FileInputStream(File filename) is a constructor that will throw
* FileNotFoundException (a checked exception)
*/
input1 = new FileInputStream("D:/file.txt");
int m;
// The read() of FileInputStream will also throw a checked exception
while(( m = input1.read() ) != -1) {
System.out.print((char)m);
}
// The close() will close the file input stream, and it will also throw a exception
input1.close();
}
}
輸出
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
Unhandled exception type FileNotFoundException
Unhandled exception type IOException
Unhandled exception type IOException
輸出中清楚地顯示程序在編譯過(guò)程中拋出異常。有兩種方法可以解決此類問(wèn)題。您可以在throw關(guān)鍵字的幫助下聲明異常。
import java.io.*;
class demo1 {
public static void main(String args[]) throws IOException {
FileInputStream input1 = null;
input1 = new FileInputStream("D:/file.txt");
int m;
while ((m = input1.read()) != -1) {
System.out.print((char)m);
}
input1.close();
}
}
輸出:文件將顯示在屏幕上。
除了上述方法外,還有一種解決異常的方法。您可以在try-catch 塊的幫助下管理它們。
import java.io.*;
class demo1 {
public static void main(String args[]) {
FileInputStream input1 = null;
try {
input1 = new FileInputStream("D:/file.txt");
} catch(FileNotFoundException input2) {
system.out.println("The file does not " + "exist at the location");
}
int m;
try {
while((m = input1.read()) != -1) {
System.out.print((char)m);
}
input1.close();
} catch(IOException input3) {
system.out.println("I/O error occurred: "+ input3);
}
}
}
輸出:代碼將順利運(yùn)行并顯示文件。
現(xiàn)在,讓我們了解其他檢查異常。他們之中有一些是:
此類異常發(fā)生在對(duì)與 SQL 語(yǔ)法相關(guān)的數(shù)據(jù)庫(kù)執(zhí)行查詢時(shí)。例如,考慮以下代碼片段:
public void setClientInfo ( String sname , String svalue ) throws SQLClientInfoException { try {
checkClosed (); ((java.sql.Connection)這個(gè).mc)。_ _ _ setClientInfo (名稱,值); } catch ( SQLException sqlEx ) { try {
checkAndFireConnectionError ( sqlEx );
} catch ( SQLException sqlEx2 ) { SQLClientInfoException client_Ex = new SQLClientInfoException ();
client_Ex 。初始化原因(sqlEx2 );拋出client_Ex ;} } }
輸出:此代碼將生成 SQLException。
這種類型的異常發(fā)生在使用文件 I/O 流操作時(shí)。例如,考慮以下代碼片段:
import java.io.*;
public class sample_IOException {
private static String filepath = "D:\User\guest\Desktop\File2.txt";
public static void main(String[] args) {
BufferedReader br1 = null;
String curline;
try {
br1 = new BufferedReader(new FileReader(filepath));
while ((curline = br1.readLine()) != null) {
System.out.println(curline);
}
} catch (IOException e) {
System.err.println("IOException found :" + e.getMessage());
} finally {
try {
if (br1 != null)
br1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
輸出:此代碼將生成 IOException。
當(dāng) JVM 無(wú)法找到所需的類時(shí),將拋出此類異常。這可能是由于命令行錯(cuò)誤、類路徑問(wèn)題或缺少 .class 文件造成的。例如,考慮以下代碼片段:
public class sample_ClassNotFoundException {
private static final String CLASS_TO_LOAD = "main.java.Utils";
public static void main(String[] args) {
try {
Class loadedClass = Class.forName(CLASS_TO_LOAD);
System.out.println("Class " + loadedClass + " found!");
} catch (ClassNotFoundException ex) {
System.err.println("ClassNotFoundException was found: " + ex.getMessage());
ex.printStackTrace();
}
}
}
輸出:此代碼將生成 ClassNotFoundException。
這種類型的異常包裝由調(diào)用的方法或構(gòu)造函數(shù)拋出的異常??梢越柚鷊etTargetException方法訪問(wèn)拋出的異常。例如,考慮以下代碼片段:
package main.samplejava;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Example {
@SuppressWarnings("unused")
private int test_sample(String s1) {
if (s1.length() == 0)
throw new IllegalArgumentException("The string should have at least one character!");
System.out.println("Inside test_sample: argument's value equals to: "" + s1 + """);
return 0;
}
public static void main(String... args) {
try {
Class<?> c1 = Class.forName("main.samplejava. Example");
Object t1 = c1.newInstance();
Method[] declared_Methods = c1.getDeclaredMethods();
for (Method method : declared_Methods) {
String methodName = method.getName();
if (methodName.contains("main"))
continue;
System.out.format("Invoking %s()%n", methodName);
try {
method.setAccessible(true);
Object returnValue = method.invoke(t1, "");
System.out.format("%s() returned: %d%n", methodName, returnValue);
} catch (InvocationTargetException ex) {
System.err.println("An InvocationTargetException was caught!");
Throwable cause = ex.getCause();
System.out.format("Invocation of %s failed because of: %s%n",
methodName, cause.getMessage());
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) {
System.err.println("The following exception was thrown:");
ex.printStackTrace();
}
}
}
輸出
Invoking testMethod()
An InvocationTargetException was caught!
Invocation of testMethod failed because of: The string must contain at least one character!
輸出:此代碼將生成 InstantiationException。
未經(jīng)檢查的異常是在程序執(zhí)行期間發(fā)生的那些異常。因此它們也被稱為運(yùn)行時(shí)異常。這些異常在編譯過(guò)程中一般會(huì)被忽略。編譯程序時(shí)不檢查它們。例如,邏輯錯(cuò)誤和使用不正確的 API 等編程錯(cuò)誤。
為了說(shuō)明未經(jīng)檢查的異常的概念,讓我們考慮以下代碼片段:
import java.util.Scanner;
public class Sample_RunTimeException {
public static void main(String[] args) {
// Reading user input
Scanner input_dev = new Scanner(System.in);
System.out.print("Enter your age in Numbers: ");
int age1 = input_dev.nextInt();
if (age1>20) {
System.out.println("You can view the page");
} else {
System.out.println("You cannot view the page");
}
}
}
輸出1
Enter your age in Numbers: 21
You can view the page
輸出2
Enter your age in Numbers: Twelve
Exception in thread “main” java.util.InputMismatchException
at java.util.Scanner.throwFor (Unknown Source)
at java.util.Scanner.next (Unknown Source)
at java.util.Scanner.nextInt (Unknown Source)
at java.util.Scanner.nextInt (Unknown Source)
at exceptiondemo.sample_runtimedemo.main(Sample_RunTimeExceptionDemo.java:11)
現(xiàn)在,讓我們了解其他未檢查的異常。他們之中有一些是:
當(dāng)您嘗試借助當(dāng)前值為 null 或空的引用變量訪問(wèn)對(duì)象時(shí),會(huì)發(fā)生此類異常。例如,考慮以下代碼片段:
// Program to demonstrate the NullPointerException
class SampleNullPointer {
public static void main(String args[]) {
try {
String a1 = null; // null value
System.out.println(a1.charAt(0));
} catch(NullPointerException e) {
System.out.println("NullPointerException is found in the program.");
}
}
}
輸出:在程序中發(fā)現(xiàn) NullPointerException。
當(dāng)您嘗試訪問(wèn)具有無(wú)效索引值的數(shù)組時(shí),會(huì)發(fā)生此類異常。您提供的值是負(fù)數(shù)或超出數(shù)組的長(zhǎng)度。
例如,考慮以下代碼片段:
// Program to demonstrate the ArrayIndexOutOfBoundException
class sample_ArrayIndexOutOfBound {
public static void main(String args[]) {
try {
int b[] = new int[6];
b[8] = 2; // we are trying to access 9th element in an array of size 7
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println ("The array index is out of bound");
}
}
}
輸出:數(shù)組索引越界
每當(dāng)將不適當(dāng)或不正確的參數(shù)傳遞給方法時(shí),就會(huì)發(fā)生這種類型的異常。例如,如果一個(gè)方法是用非空字符串作為參數(shù)定義的。但是您提供的是空輸入字符串。然后,拋出 IllegalArgumentException以指示用戶您不能將空輸入字符串傳遞給該方法。
請(qǐng)考慮以下代碼片段來(lái)演示此類異常:
import java.io.File;
public class Sample_IllegalArgumentException {
public static String createRelativePath(String par, String f_name) {
if (par == null)
throw new IllegalArgumentException("You cannot provide null parent path!");
if (f_name == null)
throw new IllegalArgumentException("Please enter the complete filename!");
return par + File.separator + f_name;
}
public static void main(String[] args) {
// This command will be successfully executed.
system.out.println(IllegalArgumentExceptionExample.createRelativePath("dir1", "file1"));
system.out.println();
// This command will throw an IllegalArgumentException.
System.out.println(IllegalArgumentExceptionExample.createRelativePath(null, "file1"));
}
}
Output: This code will generate an IllegalArgumentException.
當(dāng)環(huán)境狀態(tài)與正在執(zhí)行的操作不匹配時(shí),就會(huì)發(fā)生這種類型的異常。例如,考慮下面的代碼片段,它演示了這種類型的異常:
/**
* This code will publish the current book.
* If the book is already published, it will throw an IllegalStateException.
**/
public void pub() throws IllegalStateException {
Date pub_at = getPub_at();
if (pub_at == null) {
setPub_at(new Date());
Logging.log(String.format("Published '%s' by %s.", getTitle(), getAuthor()));
} else {
throw new IllegalStateException(
String.format("Cannot publish '%s' by %s (already published on %s).",
getTitle(), getAuthor(), pub_at));
}
}
輸出:此代碼將生成 IllegalStateException。
如果系統(tǒng)中已經(jīng)存在出版日期,那么它將產(chǎn)生一個(gè) IllegalStateException 指示該書不能再次出版。
當(dāng)您將字符串傳遞給無(wú)法轉(zhuǎn)換為數(shù)字的方法時(shí),會(huì)發(fā)生此類異常。例如,考慮以下代碼片段:
// Program to demonstrate the NumberFormatException
class Sample_NumberFormat {
public static void main(String args[]) {
try {
// "Test" is not a number
int n = Integer.parseInt ("Test") ;
System.out.println(n);
} catch(NumberFormatException e) {
System.out.println("Number format exception");
}
}
}
輸出:此代碼將生成 NumberFormatException。
當(dāng)您執(zhí)行不正確的算術(shù)運(yùn)算時(shí),會(huì)發(fā)生這種類型的異常。比如任意一個(gè)數(shù)除以零,就會(huì)顯示這樣的異常。讓我們考慮以下代碼片段:
// Program to demonstrate the ArithmeticException
class Sample_ArithmeticException {
public static void main(String args[]) {
try {
int p = 30, q = 0;
int r = p/q; // It cannot be divided by zero
System.out.println ("Result = " + r);
} catch(ArithmeticException e) {
System.out.println ("Number cannot be divided by 0");
}
}
}
輸出:此代碼將生成一個(gè) ArithmeticException。
以上就是關(guān)于“Java異常類型匯總”的介紹,大家如果想了解更多相關(guān)知識(shí),不妨來(lái)關(guān)注一下本站的Java基礎(chǔ)教程,里面的課程內(nèi)容細(xì)致全面,很適合沒(méi)有基礎(chǔ)的小伙伴學(xué)習(xí),希望對(duì)大家能夠有所幫助哦。
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)