黑马程序员-java异常
2013-04-20 00:25
134 查看
-------
android培训、java培训、期待与您交流! ----------
java异常处理机制java根据异常的不同,将异常分为错误和异常两种
1.错误:错误是指程序在执行过程中所遇到的硬件或操作系统的错误,如内存溢出还有虚拟机错误之类的,程序本身不能处理错误,得靠外界干预,否则无法正常运行
2.异常:是指java可以处理的错误,如数组下标越界啊,除数为0啊,java提供了强大的异常处理机制,使程序能够自动的捕获异常,并调整程序运行的方向,使程序可以继续运行
在java的异常处理机制中,有两个最常用的类,分别是Exception和Error,它们位于java.lang包中,是Throwable的子类,关系如下图
Error:指的是jvm的错误,一般在程序中无法处理
Exception:指的是程序中出现的问题,一般在代码块中加入try..catch语句进行处理,或者将它抛出交给调用者处理(抛出异常不代表程序停止 RuntimeException 及其子类除外)
RuntimeException :此异常与此异常的子类的对象在程序中被抛出后,无需对他进行捕捉,直接交给jvm处理,届时程序将停止工作。
异常这一章的几个关键字
throw:此关键字可以将一个异常对象抛出。
throws:这个关键字用在方法声明的后面,标示此方法可能会抛出异常,告诉调用者,调用者就会对这个对象进行捕捉或者继续向上抛出。
finally:此关键字用在try......catch语句之后,不管前面有没有捕捉到异常,finally后面的代码块一定会被执行,一般用在关闭数据库的各项连接上。
看下面几段代码
1.try...catch语句的使用
实例1
public class TestException { public static void main(String[] args) { String str1 = "8"; String str2 = "2"; TestException.getResult(str1, str2); //调用静态方法 System.out.println("ok"); } //定义一个静态方法,用于取得两数之商 public static int getResult(String a, String b) { int value = 0; /* int num1 = Integer.parseInt(a); int num2 = Integer.parseInt(b); value = num1/num2;*/ try { //将字符串转为int值 int num1 = Integer.parseInt(a); int num2 = Integer.parseInt(b); value = num1/num2; System.out.println("运算结果是" + value); } catch (ArithmeticException e) { System.out.println(e.getMessage()); } catch (NumberFormatException e) { //打印出错信息 System.out.println(e.getMessage()); //打印出错的类型和信息 System.out.println(e.toString()); //打印出错的栈堆信息,就是方法的层次调用 e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("我一定会出现的"); } return value; } }
运行总结
由这段代码可看出,因为被除数的数值是不确定的,有可能是0,也有可能说起他的数,如若在getResult方法中没有对可能出现的ArithmeticException异常进行捕捉,程序会立刻中断并报错,最后的ok将不会被打印,但如果在方法中用try...catch 语句进行捕捉,异常捕捉后打印相关的信息,最后ok还是会被打印出来的,在finally后面代码块中的语句一定会被执行,“我一定会出现这句话” 不管有没有捕捉到异常都会出现。一个方法中抛出异常并且被本方法中的 catch 语句捉住的话,处理相关完错误信息,之后程序将无法回到错误产生的下一行代码执行,只能跳到
try..catch 语句外执行,直到方法结束,然后从调用这个方法的下一行继续执行,直到程序结束,还有,在 finally 语句中如果抛出异常,这个异常无法被上面的 catch 捕捉住,只有在方法的后面用 throws 关键字声明该方法可能会抛出某个异常才行
在此需要注意以下几点
1.
try...catch语句中最后的finally代码块可写可不写,如若不写,编译不会报错,如果写了,就一定会被执行。
2.
在 catch 语句中,如果有 Exception 子类的情况下,一定要把子类异常写在上面,如若不然,所有异常都会被Exception捉住,后面的catch语句就相当于废话了。
3.
如果在getResult方法中没有对异常进行捕捉,而是对他进行抛出,交给调用者处理,这样也是可以的,后面的代码将对此进行体现。
在Throwable类中封装了几个常用的方法,常用的有toString(),将打印错误的类型和信息,toMessage()打印的是出错的信息,而printStackTrace()将会打印出错的栈堆信息(方法的层次调用)。
2.自定义异常类
在java中,一切皆是对象,所谓的异常也就是一个用异常类创建出来的对象,java提供了非常多的异常对象,同时java也允许程序员创建属于自己的异常类,如果想自己定义一个异常的类,
一般是使这个类继承Exception(当然继承RuntimeException也是可行的)
看下面一段代码
实例2
public class TestMyException { public static void main(String[] args) { try { TestMyException.getResult(8, -2); } catch (MyException e) { System.out.println(e.toString()); } } public static int getResult(int a, int b) throws MyException { if(a <= 0 || b <= 0) { throw new MyException("输入的数据不符合规则"); } else { return a*b; } //return a*b; } } class MyException extends Exception { public String toString() { return super.toString(); } //String message = "信息错误"; MyException(String message) { //调用父类构造方法 super(message); } }
这段代码自定义异常是继承Exception类的,继承了 Exception 的异常在某一方法中被抛出后,方法后必须更上throws 自定义异常类名,否则编译无法通过,与此相对的如果继承 RuntimeException就不需要进行throws声明,在调用者中也不需要用try...catch语句进行捕捉,直接交给jvm进行处理即可,jvm调用e.printStackTrace()后程序将停止.并不是说一旦抛出 RuntimeException 及其子类的异常对象程序就会停止,你如果像 Exception 一样捕捉他们的话,程序还是会继续运行的.
3.关于标示异常方法的重写
实例3
/* 该程序用于测试如何重写抛出异常的方法 */ public class TestMyException { public static void main(String[] args) { try { System.out.println(new Rectangle(5,-8).getArea()); } catch (MyException2 e) { System.out.println(e.toString()); } } } //自定义一个异常 class MyException extends Exception { MyException(String message) { super(message); } } //自定义另一个异常,继承上一个异常 class MyException2 extends MyException { String message; MyException2(String message) { //调用父类构造方法 super(message); this.message = message; } public String toString() { return message; } } //定义一个几何图形抽象类, abstract class Shape { //声明一个计算面积的抽象方法 public abstract int getArea() throws MyException2; } //定义一个矩形类 class Rectangle extends Shape { private int len, width; public Rectangle(int len,int width) { this.len = len; this.width = width; } //重写父类的抽象方法 //注意:覆写父类的方法时只能抛出父类的异常以及父类异常的子类,不能抛出比父类异常还大的异常,如果父类方法没有抛出异常,子类也不能抛,只能用try catch语句捉住 public int getA 4000 rea() throws MyException2 { if(len <= 0 | width <= 0) { throw new MyException2("输入的数据错误"); } else { return len*width; } } }
4.使用 finally 关键字应该注意的地方,众说周知,finally 中的语句总是能得到执行,这时候应该注意一个问题,就是try语句的嵌套,很可能会套出问题来,致使你的异常对象被吞了
实例4
import java.io.FileNotFoundException; import java.io.IOException; public class TestFinally { public static void main(String[] args) { TestFinally.runTest(); } public static void runTest() throws RuntimeException { try { try { throw new RuntimeException("asdasd"); } finally { throw new NullPointerException("sdfsadfasdfasdf"); } } catch(RuntimeException e) { System.out.println(e.toString()); } } }
这个后面的异常对象明显将前面的覆盖了,前面的异常对象被吞了
多线程与 RuntimeException
抛出 RuntimeException ,不捕获的话,主线程将停止,当前程序将关闭,这是单线程,如果是多线程的话,有一条线程抛出了 RuntimeException 异常,是整个程序停止,还是那个线程停止
让我们来试试
实例4
public class TestThreadException { public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { public void run() { while(true) { try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()); } } }, "线程1"); Thread t2 = new Thread(new Runnable() { int i = 1; public void run() { while(true) { try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } if(i == 150) { //try { throw new RuntimeException(); /* } catch(RuntimeException e) { }*/ } System.out.println(Thread.currentThread().getName() + "----" + i); i++; } } }, "线程2"); t1.start(); t2.start(); } }
这个程序很有意思,线程2如果执行到到第150次循环会抛出一个 RuntimeException 异常,该线程停止,但是程序还没有停止,线程1还在循环执行,说明一个程序如果抛出 RuntimeException异常,程序不一定会停止,只是抛出异常的线程会停止,这个一定要注意.
相关文章推荐
- 黑马程序员 JAVA IO 异常日志 系统信息
- 黑马程序员-java基础(三)-异常体系
- 黑马程序员——Java基础__异常
- 黑马程序员——Java语言基础——03.面向对象(3)异常
- 黑马程序员——-——java基础之异常
- 黑马程序员_JAVA的异常处理
- 黑马程序员——Java基础 异常机制 (复习)
- 黑马程序员_JAVA的异常处理_2_总结
- 黑马程序员--java基础--多态,内部类,异常等
- 黑马程序员 JAVA学习笔记 ——— 异常
- 黑马程序员——JAVA基础——多态-异常
- 【黑马程序员】异常,File类,IO流——Java复习笔记
- 黑马程序员——Java---异常
- 黑马程序员——Java异常类笔记
- (每日一转)黑马程序员----跟着老毕学Java之异常机制
- 黑马程序员——Java异常
- 黑马程序员-----------java异常处理
- 黑马程序员——Java基础--多态、内部类、异常
- 黑马程序员java学习—异常
- 黑马程序员-----关于java的异常处理