java i o流异常问题_第四章 Java的I/O流和异常处理
Java.io包幾乎包含了所有操作輸入、輸出需要的類。所有這些流類代表了輸入源和輸出目標(biāo)。? Java.io包中的流支持很多種格式,比如:基本類型、對(duì)象、本地化字符集等等。? 一個(gè)流可以理解為一個(gè)數(shù)據(jù)的序列。輸入流表示從一個(gè)源讀取數(shù)據(jù),輸出流表示向一個(gè)目標(biāo)寫數(shù)據(jù)。? Java為I/O提供了強(qiáng)大的而靈活的支持,使其更廣泛地應(yīng)用到文件傳輸和網(wǎng)絡(luò)編程中。
讀取控制臺(tái)輸入
Java的控制臺(tái)輸入由System.in完成。? 為了獲得一個(gè)綁定到控制臺(tái)的字符流,可以把System.in包裝在一個(gè)BufferedReader 對(duì)象中來(lái)創(chuàng)建一個(gè)字符流。? 下面是創(chuàng)建BufferedReader的基本語(yǔ)法:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedReader對(duì)象創(chuàng)建后,我們便可以使用read()方法從控制臺(tái)讀取一個(gè)字符,或者用readLine()方法讀取一個(gè)字符串
從控制臺(tái)讀取多字符輸入
從BufferedReader對(duì)象讀取一個(gè)字符要使用read()方法,它的語(yǔ)法如下:
int read( ) throws IOException
每次調(diào)用read()方法,它從輸入流讀取一個(gè)字符并把該字符作為整數(shù)值返回。 當(dāng)流結(jié)束的時(shí)候返回-1。該方法拋出IOException。? 下面的程序示范了用read()方法從控制臺(tái)不斷讀取字符直到用戶輸入”q”
// 使用 BufferedReader 在控制臺(tái)讀取字符
import java.io.*;
public class BRRead {
public static void main(String args[]) throws IOException
{
char c;
// 使用 System.in 創(chuàng)建 BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter characters, 'q' to quit.");
// 讀取字符
do {
c = (char) br.read();
System.out.println(c);
} while(c != 'q');
}
}
以上運(yùn)行結(jié)果如下:
Enter characters, ‘q’ to quit.? 123abcq? 1? 2? 3? a? b? c? q
從控制臺(tái)讀取字符串
從標(biāo)準(zhǔn)輸入讀取一個(gè)字符串需要使用BufferedReader的readLine()方法。? 它的一般格式是:
String readLine( ) throws IOException
下面的程序讀取和顯示字符行直到你輸入了單詞”end”:
// 使用 BufferedReader 在控制臺(tái)讀取字符
import java.io.*;
public class BRReadLines {
public static void main(String args[]) throws IOException
{
// 使用 System.in 創(chuàng)建 BufferedReader
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
String str;
System.out.println("Enter lines of text.");
System.out.println("Enter 'end' to quit.");
do {
str = br.readLine();
System.out.println(str);
} while(!str.equals("end"));
}
}
以上運(yùn)行結(jié)果如下:
Enter lines of text.? Enter ‘end’ to quit.? This is line one? This is line one? This is line two? This is line two? end? end
JDK 5 后的版本我們也可以使用 Java Scanner 類來(lái)獲取控制臺(tái)的輸入
控制臺(tái)輸出
控制臺(tái)的輸出由 print( ) 和println( )完成。這些方法都由類PrintStream 定義,System.out是該類對(duì)象的一個(gè)引用。? PrintStream 繼承了OutputStream類,并且實(shí)現(xiàn)了方法write()。這樣,write()也可以用來(lái)往控制臺(tái)寫操作。
PrintStream 定義write()的最簡(jiǎn)單格式如下所示:
void write(int byteval)
該方法將byteval的低八位字節(jié)寫到流中。
實(shí)例? 下面的例子用write()把字符”A”和緊跟著的換行符輸出到屏幕:
import java.io.*;
// 演示 System.out.write().
public class WriteDemo {
public static void main(String args[]) {
int b;
b = 'A';
System.out.write(b);
System.out.write('\n');
}
}
運(yùn)行以上實(shí)例在輸出窗口輸出”A”字符:
A
注意:write()方法不經(jīng)常使用,因?yàn)閜rint()和println()方法用起來(lái)更為方便。
讀寫文件
如前所述,一個(gè)流被定義為一個(gè)數(shù)據(jù)序列。輸入流用于從源讀取數(shù)據(jù),輸出流用于向目標(biāo)寫數(shù)據(jù)。? 下圖是一個(gè)描述輸入流和輸出流的類層次圖:
下面將要討論的兩個(gè)重要的流是FileInputStream 和FileOutputStream:
FileInputStream
該流用于從文件讀取數(shù)據(jù),它的對(duì)象可以用關(guān)鍵字new來(lái)創(chuàng)建。? 有多種構(gòu)造方法可用來(lái)創(chuàng)建對(duì)象。? 可以使用字符串類型的文件名來(lái)創(chuàng)建一個(gè)輸入流對(duì)象來(lái)讀取文件:
InputStream f = new FileInputStream(“C:/java/hello”);
也可以使用一個(gè)文件對(duì)象來(lái)創(chuàng)建一個(gè)輸入流對(duì)象來(lái)讀取文件。我們首先得使用File()方法來(lái)創(chuàng)建一個(gè)文件對(duì)象:
File f = new File(“C:/java/hello”);? InputStream f = new FileInputStream(f);
創(chuàng)建了InputStream對(duì)象,就可以使用下面的方法來(lái)讀取流或者進(jìn)行其他的流操作:
public void close() throws IOException{}
關(guān)閉此文件輸入流并釋放與此流有關(guān)的所有系統(tǒng)資源。拋出IOException異常。
protected void finalize()throws IOException {}
這個(gè)方法清除與該文件的連接。確保在不再引用文件輸入流時(shí)調(diào)用其 close 方法。拋出IOException異常。
public int read(int r)throws IOException{}
這個(gè)方法從InputStream對(duì)象讀取指定字節(jié)的數(shù)據(jù)。返回為整數(shù)值。返回下一字節(jié)數(shù)據(jù),如果已經(jīng)到結(jié)尾則返回-1。
public int read(byte[] r) throws IOException{}
這個(gè)方法從輸入流讀取r.length長(zhǎng)度的字節(jié)。返回讀取的字節(jié)數(shù)。如果是文件結(jié)尾則返回-1。
public int available() throws IOException{}
返回下一次對(duì)此輸入流調(diào)用的方法可以不受阻塞地從此輸入流讀取的字節(jié)數(shù)。返回一個(gè)整數(shù)值。
FileOutputStream
該類用來(lái)創(chuàng)建一個(gè)文件并向文件中寫數(shù)據(jù)。? 如果該流在打開文件進(jìn)行輸出前,目標(biāo)文件不存在,那么該流會(huì)創(chuàng)建該文件。? 有兩個(gè)構(gòu)造方法可以用來(lái)創(chuàng)建FileOutputStream 對(duì)象。
使用字符串類型的文件名來(lái)創(chuàng)建一個(gè)輸出流對(duì)象:
OutputStream f = new FileOutputStream(“C:/java/hello”)
也可以使用一個(gè)文件對(duì)象來(lái)創(chuàng)建一個(gè)輸出流來(lái)寫文件。我們首先得使用File()方法來(lái)創(chuàng)建一個(gè)文件對(duì)象:
File f = new File(“C:/java/hello”);? OutputStream f = new FileOutputStream(f);
創(chuàng)建OutputStream 對(duì)象完成后,就可以使用下面的方法來(lái)寫入流或者進(jìn)行其他的流操作:
public void close() throws IOException{}
關(guān)閉此文件輸入流并釋放與此流有關(guān)的所有系統(tǒng)資源。拋出IOException異常。
protected void finalize()throws IOException {}
這個(gè)方法清除與該文件的連接。確保在不再引用文件輸入流時(shí)調(diào)用其 close 方法。拋出IOException異常。
public void write(int w)throws IOException{}
這個(gè)方法把指定的字節(jié)寫到輸出流中。
public void write(byte[] w)
把指定數(shù)組中w.length長(zhǎng)度的字節(jié)寫到OutputStream中。
實(shí)例? 下面是一個(gè)演示InputStream和OutputStream用法的例子:
import java.io.*;
public class fileStreamTest{
public static void main(String args[]){
try{
byte bWrite [] = {11,21,3,40,5};
OutputStream os = new FileOutputStream("test.txt");
for(int x=0; x < bWrite.length ; x++){
os.write( bWrite[x] ); // writes the bytes
}
os.close();
InputStream is = new FileInputStream("test.txt");
int size = is.available();
for(int i=0; i< size; i++){
System.out.print((char)is.read() + "? ");
}
is.close();
}catch(IOException e){
System.out.print("Exception");
}
}
}
上面的程序首先創(chuàng)建文件test.txt,并把給定的數(shù)字以二進(jìn)制形式寫進(jìn)該文件,同時(shí)輸出到控制臺(tái)上。? 以上代碼由于是二進(jìn)制寫入,可能存在亂碼,可以使用以下代碼實(shí)例來(lái)解決亂碼問(wèn)題:
//文件名 :fileStreamTest2.java
import java.io.*;
public class fileStreamTest2{
public static void main(String[] args) throws IOException {
File f = new File("a.txt");
FileOutputStream fop = new FileOutputStream(f);
// 構(gòu)建FileOutputStream對(duì)象,文件不存在會(huì)自動(dòng)新建
OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8");
// 構(gòu)建OutputStreamWriter對(duì)象,參數(shù)可以指定編碼,默認(rèn)為操作系統(tǒng)默認(rèn)編碼,windows上是gbk
writer.append("中文輸入");
// 寫入到緩沖區(qū)
writer.append("\r\n");
//換行
writer.append("English");
// 刷新緩存沖,寫入到文件,如果下面已經(jīng)沒(méi)有寫入的內(nèi)容了,直接close也會(huì)寫入
writer.close();
//關(guān)閉寫入流,同時(shí)會(huì)把緩沖區(qū)內(nèi)容寫入文件,所以上面的注釋掉
fop.close();
// 關(guān)閉輸出流,釋放系統(tǒng)資源
FileInputStream fip = new FileInputStream(f);
// 構(gòu)建FileInputStream對(duì)象
InputStreamReader reader = new InputStreamReader(fip, "UTF-8");
// 構(gòu)建InputStreamReader對(duì)象,編碼與寫入相同
StringBuffer sb = new StringBuffer();
while (reader.ready()) {
sb.append((char) reader.read());
// 轉(zhuǎn)成char加到StringBuffer對(duì)象中
}
System.out.println(sb.toString());
reader.close();
// 關(guān)閉讀取流
fip.close();
// 關(guān)閉輸入流,釋放系統(tǒng)資源
}
}
Java序列化
Java? 提供了一種對(duì)象序列化的機(jī)制,該機(jī)制中,一個(gè)對(duì)象可以被表示為一個(gè)字節(jié)序列,該字節(jié)序列包括該對(duì)象的數(shù)據(jù)、有關(guān)對(duì)象的類型的信息和存儲(chǔ)在對(duì)象中數(shù)據(jù)的類型。將序列化對(duì)象寫入文件之后,可以從文件中讀取出來(lái),并且對(duì)它進(jìn)行反序列化,也就是說(shuō),對(duì)象的類型信息、對(duì)象的數(shù)據(jù),還有對(duì)象中的數(shù)據(jù)類型可以用來(lái)在內(nèi)存中新建對(duì)象。整個(gè)過(guò)程都是Java虛擬機(jī)(JVM)獨(dú)立的,也就是說(shuō),在一個(gè)平臺(tái)上序列化的對(duì)象可以在另一個(gè)完全不同的平臺(tái)上反序列化該對(duì)象。類ObjectInputStream 和ObjectOutputStream是高層次的數(shù)據(jù)流,它們包含序列化和反序列化對(duì)象的方法。
ObjectOutputStream 類包含很多寫方法來(lái)寫各種數(shù)據(jù)類型,但是一個(gè)特別的方法例外:
public final void writeObject(Object x) throws IOException
上面的方法序列化一個(gè)對(duì)象,并將它發(fā)送到輸出流。相似的ObjectInputStream 類包含如下反序列化一個(gè)對(duì)象的方法:
public final Object readObject() throws IOException,ClassNotFoundException
該方法從流中取出下一個(gè)對(duì)象,并將對(duì)象反序列化。它的返回值為Object,因此,需要將它轉(zhuǎn)換成合適的數(shù)據(jù)類型。? 為了演示序列化在Java中是怎樣工作的,假設(shè)我們定義了如下的Employee類,該類實(shí)現(xiàn)了Serializable 接口:
public class Employee implements java.io.Serializable
{
public String name;
public String address;
public transient int SSN;
public int number;
public void mailCheck()
{
System.out.println("Mailing a check to " + name
+ " " + address);
}
}
請(qǐng)注意,一個(gè)類的對(duì)象要想序列化成功,必須滿足兩個(gè)條件:
該類必須實(shí)現(xiàn) java.io.Serializable 對(duì)象。該類的所有屬性必須是可序列化的。如果有一個(gè)屬性不是可序列化的,則該屬性必須注明是短暫的。
檢驗(yàn)一個(gè)類的實(shí)例是否能序列化十分簡(jiǎn)單, 只需要查看該類有沒(méi)有實(shí)現(xiàn)java.io.Serializable接口。
序列化對(duì)象
ObjectOutputStream 類用來(lái)序列化一個(gè)對(duì)象,如下的SerializeDemo例子實(shí)例化了一個(gè)Employee對(duì)象,并將該對(duì)象序列化到一個(gè)文件中。? 該程序執(zhí)行后,就創(chuàng)建了一個(gè)名為employee.ser文件。該程序沒(méi)有任何輸出,但是可以通過(guò)代碼研讀來(lái)理解程序的作用。? 注意: 當(dāng)序列化一個(gè)對(duì)象到文件時(shí), 按照J(rèn)ava的標(biāo)準(zhǔn)約定是給文件一個(gè).ser擴(kuò)展名。
import java.io.*;
public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = new Employee();
e.name = "Reyan Ali";
e.address = "Phokka Kuan, Ambehta Peer";
e.SSN = 11122333;
e.number = 101;
try
{
FileOutputStream fileOut =
new FileOutputStream("/tmp/employee.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in /tmp/employee.ser");
}catch(IOException i)
{
i.printStackTrace();
}
}
}
反序列化對(duì)象
下面的DeserializeDemo程序?qū)嵗朔葱蛄谢?#xff0c;/tmp/employee.ser存儲(chǔ)了Employee對(duì)象:
import java.io.*;
public class DeserializeDemo
{
public static void main(String [] args)
{
Employee e = null;
try
{
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
}catch(IOException i)
{
i.printStackTrace();
return;
}catch(ClassNotFoundException c)
{
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}
以上運(yùn)行結(jié)果如下:
Deserialized Employee…? Name: Reyan Ali? Address:Phokka Kuan, Ambehta Peer? SSN: 0? Number:101
這里要注意以下要點(diǎn):
readObject() 方法中的try/catch代碼塊嘗試捕獲 ClassNotFoundException異常。對(duì)于JVM可以反序列化對(duì)象,它必須是能夠找到字節(jié)碼的類。如果JVM在反序列化對(duì)象的過(guò)程中找不到該類,則拋出一個(gè) ClassNotFoundException異常。? 注意,readObject()方法的返回值被轉(zhuǎn)化成Employee引用。? 當(dāng)對(duì)象被序列化時(shí),屬性SSN的值為111222333,但是因?yàn)樵搶傩允嵌虝旱?#xff0c;該值沒(méi)有被發(fā)送到輸出流。所以反序列化后Employee對(duì)象的SSN屬性為0
Java異常處理
異常是程序中的一些錯(cuò)誤,但并不是所有的錯(cuò)誤都是異常,并且錯(cuò)誤有時(shí)候是可以避免的。? 比如說(shuō),你的代碼少了一個(gè)分號(hào),那么運(yùn)行出來(lái)結(jié)果是提示是錯(cuò)誤java.lang.Error;如果你用System.out.println(11/0),那么你是因?yàn)槟阌?做了除數(shù),會(huì)拋出java.lang.ArithmeticException的異常。? 異常發(fā)生的原因有很多,通常包含以下幾大類:
用戶輸入了非法數(shù)據(jù)要打開的文件不存在網(wǎng)絡(luò)通信時(shí)連接中斷,或者JVM內(nèi)存溢出
這些異常有的是因?yàn)橛脩翦e(cuò)誤引起,有的是程序錯(cuò)誤引起的,還有其它一些是因?yàn)槲锢礤e(cuò)誤引起的。-? 要理解Java異常處理是如何工作的,你需要掌握以下三種類型的異常:
檢查性異常:最具代表的檢查性異常是用戶錯(cuò)誤或問(wèn)題引起的異常,這是程序員無(wú)法預(yù)見(jiàn)的。例如要打開一個(gè)不存在文件時(shí),一個(gè)異常就發(fā)生了,這些異常在編譯時(shí)不能被簡(jiǎn)單地忽略運(yùn)行時(shí)異常: 運(yùn)行時(shí)異常是可能被程序員避免的異常。與檢查性異常相反,運(yùn)行時(shí)異常可以在編譯時(shí)被忽略錯(cuò)誤: 錯(cuò)誤不是異常,而是脫離程序員控制的問(wèn)題。錯(cuò)誤在代碼中通常被忽略。例如,當(dāng)棧溢出時(shí),一個(gè)錯(cuò)誤就發(fā)生了,它們?cè)诰幾g也檢查不到的
Exception類的層次
所有的異常類是從java.lang.Exception類繼承的子類。? Exception類是Throwable類的子類。除了Exception類外,Throwable還有一個(gè)子類Error 。? Java程序通常不捕獲錯(cuò)誤。錯(cuò)誤一般發(fā)生在嚴(yán)重故障時(shí),它們?cè)贘ava程序處理的范疇之外。? Error用來(lái)指示運(yùn)行時(shí)環(huán)境發(fā)生的錯(cuò)誤。
例如,JVM內(nèi)存溢出。一般地,程序不會(huì)從錯(cuò)誤中恢復(fù)。? 異常類有兩個(gè)主要的子類:IOException類和RuntimeException類。
捕獲異常
使用try和catch關(guān)鍵字可以捕獲異常。try/catch代碼塊放在異常可能發(fā)生的地方。? try/catch代碼塊中的代碼稱為保護(hù)代碼,使用 try/catch的語(yǔ)法如下:
try
{
// 程序代碼
}catch(ExceptionName e1)
{
//Catch 塊
}
Catch語(yǔ)句包含要捕獲異常類型的聲明。當(dāng)保護(hù)代碼塊中發(fā)生一個(gè)異常時(shí),try后面的catch塊就會(huì)被檢查。? 如果發(fā)生的異常包含在catch塊中,異常會(huì)被傳遞到該catch塊,這和傳遞一個(gè)參數(shù)到方法是一樣。
實(shí)例? 下面的例子中聲明有兩個(gè)元素的一個(gè)數(shù)組,當(dāng)代碼試圖訪問(wèn)數(shù)組的第三個(gè)元素的時(shí)候就會(huì)拋出一個(gè)異常:
// 文件名 : 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");
}
}
以上運(yùn)行結(jié)果如下:
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3? Out of the block
多重捕獲塊
一個(gè)try代碼塊后面跟隨多個(gè)catch代碼塊的情況就叫多重捕獲。? 多重捕獲塊的語(yǔ)法如下所示:
try{
// 程序代碼
}catch(異常類型1 異常的變量名1){
// 程序代碼
}catch(異常類型2 異常的變量名2){
// 程序代碼
}catch(異常類型2 異常的變量名2){
// 程序代碼
}
上面的代碼段包含了3個(gè)catch塊。? 可以在try語(yǔ)句后面添加任意數(shù)量的catch塊。? 如果保護(hù)代碼中發(fā)生異常,異常被拋給第一個(gè)catch塊。? 如果拋出異常的數(shù)據(jù)類型與ExceptionType1匹配,它在這里就會(huì)被捕獲。? 如果不匹配,它會(huì)被傳遞給第二個(gè)catch塊。? 如此,直到異常被捕獲或者通過(guò)所有的catch塊。(與C++一樣)
實(shí)例? 該實(shí)例展示了怎么使用多重try/catch:
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;
}
throws/throw關(guān)鍵字:
如果一個(gè)方法沒(méi)有捕獲一個(gè)檢查性異常,那么該方法必須使用throws 關(guān)鍵字來(lái)聲明。throws關(guān)鍵字放在方法簽名的尾部。? 也可以使用throw關(guān)鍵字拋出一個(gè)異常,無(wú)論它是新實(shí)例化的還是剛捕獲到的。? 下面方法的聲明拋出一個(gè)RemoteException異常:
import java.io.*;
public class className
{
public void deposit(double amount) throws RemoteException
{
// Method implementation
throw new RemoteException();
}
//Remainder of class definition
}
一個(gè)方法可以聲明拋出多個(gè)異常,多個(gè)異常之間用逗號(hào)隔開。? 例如,下面的方法聲明拋出RemoteException和InsufficientFundsException:
import java.io.*;
public class className
{
public void withdraw(double amount) throws RemoteException,
InsufficientFundsException
{
// Method implementation
}
//Remainder of class definition
}
finally關(guān)鍵字
finally關(guān)鍵字用來(lái)創(chuàng)建在try代碼塊后面執(zhí)行的代碼塊。? 無(wú)論是否發(fā)生異常,finally代碼塊中的代碼總會(huì)被執(zhí)行。? 在finally代碼塊中,可以運(yùn)行清理類型等收尾善后性質(zhì)的語(yǔ)句。
finally代碼塊出現(xiàn)在catch代碼塊最后,語(yǔ)法如下:
try{
// 程序代碼
}catch(異常類型1 異常的變量名1){
// 程序代碼
}catch(異常類型2 異常的變量名2){
// 程序代碼
}finally{
// 程序代碼
}
實(shí)例:
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");
}
}
}
以上運(yùn)行結(jié)果如下:
Exception thrown :java.lang.ArrayIndexOutOfBoundsException:? 3 First element value: 6? The finally statement is executed
注意下面事項(xiàng):
catch不能獨(dú)立于try存在。在try/catch后面添加finally塊并非強(qiáng)制性要求的。try代碼后不能既沒(méi)catch塊也沒(méi)finally塊。try, catch, finally塊之間不能添加任何代碼。
聲明自定義異常
在Java中可以自定義異常。編寫自己的異常類時(shí)需要記住下面的幾點(diǎn)。
所有異常都必須是Throwable的子類。如果希望寫一個(gè)檢查性異常類,則需要繼承Exception類。如果想寫一個(gè)運(yùn)行時(shí)異常類,那么需要繼承RuntimeException 類。
可以像下面這樣定義自己的異常類:
class MyException extends Exception{ }
只繼承Exception 類來(lái)創(chuàng)建的異常類是檢查性異常類。? 下面的InsufficientFundsException類是用戶定義的異常類,它繼承自Exception。? 一個(gè)異常類和其它任何類一樣,包含有變量和方法。? 實(shí)例:
// 文件名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;
}
}
為了展示如何使用我們自定義的異常類,? 在下面的CheckingAccount 類中包含一個(gè)withdraw()方法拋出一個(gè)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;
}
}
下面的BankDemo程序示范了如何調(diào)用CheckingAccount類的deposit() 和withdraw()方法:
//文件名稱 BankDemo.java
public class BankDemo
{
public static void main(String [] args)
{
CheckingAccount c = new CheckingAccount(101);
System.out.println("Depositing $500...");
c.deposit(500.00);
try
{
System.out.println("\nWithdrawing $100...");
c.withdraw(100.00);
System.out.println("\nWithdrawing $600...");
c.withdraw(600.00);
}catch(InsufficientFundsException e)
{
System.out.println("Sorry, but you are short $"
+ e.getAmount());
e.printStackTrace();
}
}
}
編譯上面三個(gè)文件,并運(yùn)行程序BankDemo,得到結(jié)果如下所示:
Depositing $500…
Withdrawing $100…
Withdrawing
600...Sorry,butyouareshort
600... Sorry, but you are short 200.0? InsufficientFundsException? at CheckingAccount.withdraw(CheckingAccount.java:25)? at BankDemo.main(BankDemo.java:13)
總結(jié)
以上是生活随笔為你收集整理的java i o流异常问题_第四章 Java的I/O流和异常处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java 计算小费_java-以某些形状
- 下一篇: jsonp java后台_jsonp与J