Java拾遗-异常
2015-09-03 13:53
477 查看
一、为什么需要异常
二、什么是异常
异常(Exception)是程序运行过程中发生的事件,该事件可以中断程序指令的正常执行流程。
三、异常的处理机制
1. 当Java程序运行时出现问题时,系统会自动检测到该错误,并立即生成一个与该错误对应的异常现象。
2. 然后把该异常对象交给Java虚拟机。
3. Java虚拟机会自动寻找相应的代码处理这个异常,如果没有找到,则程序终止。
4. 程序员可以自己编写代码来捕捉可能出现的异常,并编写代码来处理相应的异常。
四、常见的一些异常
1. 空指针异常
2.下标越界异常
3.算术异常
五. 异常的分类
![](http://img.blog.csdn.net/20150902225008670)
![](http://img.blog.csdn.net/20150902225127445)
六. 异常的处理步骤
![](http://img.blog.csdn.net/20150902225608457)
七. finally的作用
1. 无论try所指定的程序块中是否跑出异常,也无论catch语句的异常类型是否与所抛出的异常类型一致,finally中的代码一定会执行。
2. finally语句为异常处理提供一个统一的出口,使得在控制流程转到程序的其他部分之前,能够对程序的状态统一的管理。
3. 通常在finally语句中可以 进行资源的清除工作,如关闭打开的文件,删除临时文件等。
八. throw
1. throw用来抛出异常
2. 格式:
throw new 异常名(参数);
3. 假设f方法抛出了A异常,则f方法有两种方式来处理A异常
1. throws A
谁调用f方法,谁处理A异常,f方法本书不处理A异常
2. try{…} catch() {……}
f方法本身自己来处理A异常
4. 要抛出的异常,必须是Throwable的子类
![](http://img.blog.csdn.net/20150903123140287)
九. throws
1. void f() throws A
{
……
}
2. throws A表示调用f方法时f方法可能会抛出A类异常,建议您调用f方法时最好对f方法可能抛出的A类异常进行捕捉。
3. throws A不表示f方法一定会抛出异常。
throws A, f方法也可以不抛出异常
4. throws A 不表示调用f方法时,必须对A异常进行捕捉
假设A是RuntimeException子类异常
由于RuntimeException的子类异常可以处理也可以不处理,所以编译器允许你调用f方法时,对f方法抛出的RuntimeException之类异常不进行处理。
5. 建议:
对throws出的所有异常进行处理
如果一个方法内部已经对A异常进行了处理,则不要再throws A
![](http://img.blog.csdn.net/20150903125634946)
十. 注意问题
1. 所有的catch只能有一个执行
2. 所有的catch可能都没有执行
3. 先catch子类异常再catch父类异常
如果先catch父类异常,再catch子类异常,编译时报错
4. catch与catch之间不能有其他代码
5. 重写方法抛出异常的范围 不能大于重写方法抛出的异常范围
6. 编译器认为放在try里边的代码都有执行失败的可能。
十一. _printStackTrace方法
十二. 异常的优点
1. 没有错误处理的程序:
{
openTheFile;
determine its size;
allocate that much memory;
read-file;
closeTheFile;
}
![](http://img.blog.csdn.net/20150903135130839)
/* 示例1 */ import java.util.*; public class TestInput { public static void main(String[] args) { Scanner sc = null; try { sc = new Scanner(System.in); int i = sc.nextInt(); System.out.printf("%d\n", i); } catch (InputMismatchException e) { System.out.println("读取错误,程序终止"); } } } /* 示例2 */ class A { int divide(int a, int b) { return a / b; } int add(int a, int b) { return a + b; } } class Excep_1 { public static void main(String[] args) { A aa = new A(); try { int i = aa.divide(3, 0); System.out.println(i); } catch (ArithmeticException e) { System.out.println("除数不能为零!"); } int j = aa.add(2, 4); System.out.println("j = " + j); } }
二、什么是异常
异常(Exception)是程序运行过程中发生的事件,该事件可以中断程序指令的正常执行流程。
三、异常的处理机制
1. 当Java程序运行时出现问题时,系统会自动检测到该错误,并立即生成一个与该错误对应的异常现象。
2. 然后把该异常对象交给Java虚拟机。
3. Java虚拟机会自动寻找相应的代码处理这个异常,如果没有找到,则程序终止。
4. 程序员可以自己编写代码来捕捉可能出现的异常,并编写代码来处理相应的异常。
四、常见的一些异常
1. 空指针异常
class Person{ public int age; } public class TestNullPointerException{ public static void main(String[] args) { Person p = null; System.out.println(p.age); } } /* 输出结果 */ Exception in thread "main" java.lang.NullPointerException at TestNullPointerException.main(TestNullPointerException.java:7)
2.下标越界异常
public class TestIndexOutOf{ public static void main(String[] args) { String friends[]={"Lisa","Bily","Kessy"}; for(int i=0;i<5;i++) { System.out.println(friends[i]); } System.out.println("\nthis is the end"); } } /* 输出结果 */ Lisa Bily Kessy Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3 at TestIndexOutOf.main(TestIndexOutOf.java:5)
3.算术异常
五. 异常的分类
六. 异常的处理步骤
try { // 可能出现异常的代码块 } catch (ExceptionName1 e) { // 当产生ExceptionName1异常时的处理措施 } catch (ExceptionName2 e) { // 当产生ExceptionName2异常时的处理措施 } .... finally { // 无论是否捕捉到异常都必须处理的代码 }
七. finally的作用
1. 无论try所指定的程序块中是否跑出异常,也无论catch语句的异常类型是否与所抛出的异常类型一致,finally中的代码一定会执行。
2. finally语句为异常处理提供一个统一的出口,使得在控制流程转到程序的其他部分之前,能够对程序的状态统一的管理。
3. 通常在finally语句中可以 进行资源的清除工作,如关闭打开的文件,删除临时文件等。
import java.awt.*; import java.awt.event.*; import java.net.*; import java.io.*; public class ChatServer { public static void main(String[] args) { boolean started = false; // 判断服务器是否启动了,先假定没有启动 ServerSocket ss = null; DataInputStream dis = null; try { ss = new ServerSocket(8888); // 服务器已经启动了,设置started为true while (started) { //当服务器端启动时。。。。 boolean bConnect = false; //判断服务器和客户端的连接是否已经建立, 没有为false,连接成功返回true Socket s = ss.accept(); //accept()与readUTF()方法一样,都是一个阻塞式方法,如果没有收到连接请求,则一直等待。。。。。 bConnect = true; //连接成功,设置bConnect为true System.out.println("一个连接已经建立!"); // -------------------------- dis = new DataInputStream(s.getInputStream()); while (bConnect) { String str = null; str = dis.readUTF(); //如果客户端突然断开连接,该语句就会抛出异常EOFException,所以我们必须得对dis.readUTF();进行异常处理 //readUTF()是阻塞式方法,如果得不到数据,则继续等待,直到读取到数据为止 System.out.println("从客户端接受的数据是:" + str); } } } catch (BindException e) { System.out.println("端口已被占用,其使用其他端口"); System.out.println("请关闭相关程序,重新运行!"); System.exit(-1); } catch (EOFException e) { System.out.println("客户端已经断开连接!"); } catch (IOException e) { //e.printStackTrace(); System.out.println("服务器端读写错误!"); } finally { try { if (null != ss) //如果监听程序打开了,则关闭网络监听程序 { ss.close(); ss = null; } if (null != dis) //如果输入流打开了,则关闭输入流 { dis.close(); dis = null; } } catch (Exception e) { } } } }
八. throw
1. throw用来抛出异常
2. 格式:
throw new 异常名(参数);
3. 假设f方法抛出了A异常,则f方法有两种方式来处理A异常
1. throws A
谁调用f方法,谁处理A异常,f方法本书不处理A异常
2. try{…} catch() {……}
f方法本身自己来处理A异常
4. 要抛出的异常,必须是Throwable的子类
九. throws
1. void f() throws A
{
……
}
2. throws A表示调用f方法时f方法可能会抛出A类异常,建议您调用f方法时最好对f方法可能抛出的A类异常进行捕捉。
3. throws A不表示f方法一定会抛出异常。
throws A, f方法也可以不抛出异常
4. throws A 不表示调用f方法时,必须对A异常进行捕捉
假设A是RuntimeException子类异常
由于RuntimeException的子类异常可以处理也可以不处理,所以编译器允许你调用f方法时,对f方法抛出的RuntimeException之类异常不进行处理。
5. 建议:
对throws出的所有异常进行处理
如果一个方法内部已经对A异常进行了处理,则不要再throws A
十. 注意问题
1. 所有的catch只能有一个执行
2. 所有的catch可能都没有执行
3. 先catch子类异常再catch父类异常
如果先catch父类异常,再catch子类异常,编译时报错
4. catch与catch之间不能有其他代码
5. 重写方法抛出异常的范围 不能大于重写方法抛出的异常范围
6. 编译器认为放在try里边的代码都有执行失败的可能。
/* 子类覆盖了基类方法时, 子类方法抛出异常的范围不能大于基类方法抛出的异常范围 子类方法可以不抛出异常,也可以只抛出基类方法的部分异常 但不可以抛出基类方法以外的异常 */ //自定义异常A class A extends Exception { } //自定义异常B class B extends Exception { } //自定义异常C class C extends Exception { } class M { void f() throws A, B { } } class N extends M { void f() throws A,B //可以throws A或B,也可以throws A,B 也可以不throws, //但不可以throws C 即"子类覆盖了基类方法时,子类方法抛出异常的范围不能大于基类方法抛出的异常范围" { } } class Test { public static void main(String[] args) { M m = new M(); N n = new N(); System.out.println("1111"); } } /* 在JDK 1.6中的运行结果是: -------------------------- 1111 -------------------------- */
/* 先catch子类异常再catch父类异常 如果先catch父类异常再catch子类异常,则编译时会报错 */ class A extends Exception { } class B extends A { } class C extends B { } class M { public void compare(int i, int j) throws A,B { if (i > j) throw new A(); else throw new B(); } } public class TestTryCatch { public static void main(String[] args) { M mm = new M(); try { mm.compare(-4, 1); } catch (B bb) { System.out.println("左边不能小于右边"); } catch (A aa) { System.out.println("左边不能大于右边"); } } }
class A{ public void static main(String[] args) { int m ; try{ m = 2; } catch { } System.out.printf("m = %d", m); } } /* 编译报错,编译器认为m未初始化。 因为编译器认为try中的代码有执行失败的可能。 */
十一. _printStackTrace方法
public A{ int divide(int a, int b) { return a / b; } public void f() { g(); } public void g(){ divide(6, 0); } } public class Test { public static void main(String[] args) { try{ new A.f(); } catch (Exception e){ e.printStackTrace(); } } }
/* Exception类中有一个private的Message属性,通过构造函数 public Exception(String message) 可以完成对该属性的初始化 */ class E extends Exception { public E() { super("哈哈"); //这实际是调用父类Exception的构造函数: public Exception(String message) //this.Message = "哈哈"; //error } } class M { public static void f() throws E //也可以改为 throws Exception { throw new E(); } public static void main(String[] args) { try { f(); } catch (Exception e) { String strExcep = e.getMessage(); System.out.println("strExcep = " + strExcep); } System.out.println("程序正常终止了!"); } } /* 在JDK 1.6中的运行结果是: -------------------------------- strExcep = 生命在于静止! 程序正常终止了! -------------------------------- 总结: getMessage() 返回的是异常的具体信息,是个String类型 public Exception(String message) 用message字符串来表示异常的具体信息 */
/* 自定义异常 */ class DivisorIsMinusException extends Exception { public DivisorIsMinusException(String message) { super(message); //实际是调用Exception 的构造函数 public Exception(String message) } } class HH { public void f(int a, int b) throws DivisorIsMinusException { if (b < 0) throw new DivisorIsMinusException("除数不能为负数!"); } } class Excep_3 { public static void main(String[] args) { HH h = new HH(); try { h.f(3, -2); } catch (DivisorIsMinusException e) { System.out.println(e.getMessage()); } System.out.println("程序正常终止了!"); } } /* 在JDK 1.6中的运行结果是: -------------------------- 除数不能为负数! 程序正常终止了! -------------------------- */
十二. 异常的优点
1. 没有错误处理的程序:
{
openTheFile;
determine its size;
allocate that much memory;
read-file;
closeTheFile;
}
/* 以常规方法处理错误 */ openFiles; if (theFileOpen) { determine the length of the file; if (gotTheFileLength) { allocate that much memory; if (gotEnoughMemory) { read the file into memory; if (readFileFailed) errorCode = -1; else errorCode = -2; } else errCode = -3; } else errorCode = -4; } else errorCode = -5;
相关文章推荐
- [Java Core]Java字符串的代码点和代码单元
- eclipse ide for java ee developers与eclipse ide for java developers有什么区别
- [置顶] JAVAEE struts2的简单文件上传与下载
- Java编译原理
- 【软件使用】GitHub使用教程for Eclipse
- 深入Java单例模式
- Java枚举类
- java中的线程同步问题 模拟出售火车票
- Eclipse Debug的一些用法
- Java并发编程:volatile关键字解析
- java中的线程同步问题解决方案
- MyEclipse 代码自动提示功能失效, 提示no default proposals
- 我的Eclipse设置
- Spring笔记――13.Spring的AOP
- 设置你的开发环境(Eclipse中,IntelliJ IDEA的,NetBeans的)
- Java就业指导
- 技海拾贝 - Java
- 在Mac OS X上面指定Eclipse启动时用指定的某一版本JDK
- Struts2核心工作原理解析
- Java 基础笔记之二 变量和常量有什么区别