Java进阶第六章——异常应用

1.try…catch中的finally

  • 在finally子句中的代码是最后执行的,并且一定会执行,即使try语句块中出现了异常。
  • finally子句必须和try一起出现,不能单独编写。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;public class ExceptionTest {public static void main(String[] args) {FileInputStream fis = null; //这里声明放到try外边,里边才能用。try{//创建输入流fis = new FileInputStream("D:\\text\\123.txt");//写一个会做空指针异常的语句String s = null;s.toString();//流使用完需要关闭//放在这里有可能关不了,如果上面出异常这里关闭不了//fis.close();}catch (FileNotFoundException e){e.printStackTrace();}catch (IOException e){e.printStackTrace();}catch (NullPointerException e){e.printStackTrace();}finally{System.out.println("流开始关闭"); //输出了:流开始关闭//流的关闭放在这里一定会在最后执行,即使try中出现异常也会执行if(fis != null){try {//close()方法有异常采用捕捉的方式。fis.close();} catch (IOException e) {e.printStackTrace();}}}}
}
  • 可以只写try和finally,没有catch是可以的。(try不能单独使用)
public class ExceptionTest {public static void main(String[] args) {//这里先执行try,再执行finally,再执行return//return只要执行方法就结束。try{System.out.println("try...");return;}finally {System.out.println("finally...");}//这里不能写语句,这里的代码无法执行到。因为上面有return}
}
  • 但是如果遇到退出JVM语句:System.exit(0);。那么finally就不可以
public class ExceptionTest {public static void main(String[] args) {try{//这里只输出了try...System.out.println("try...");//在这里退出了虚拟机,所以finally...输出不了System.exit(0);}finally {System.out.println("finally...");}}
}

2. final、fianlly、finalize

  • final是一个关键字,修饰表示最终的,不可修改的。
  • finally也是一个关键字,和try配合使用,使用在异常处理机制中。finally语句一定会执行。
  • finalize是Object类的一个方法,作为方法名出现。finalize是标识符。

3.自定义异常

  • 定义自定义异常:

    第一步:编写一个类继承Exception或者RuntimeException。

    第二步:提供两个构造方法,一个无参数的,一个有参数的。

//自定义一个异常类
public class MyException extends Exception{  //编译时异常public MyException(){}public MyException(String s){super(s);}
}/*
public class MyException extends RuntimeException{  //运行时异常public MyException(){}public MyException(String s){super(s);}
}
*///测试自定义的异常
public class ExceptionTest06 {public static void main(String[] args) {//创建异常对象,没有抛出MyException e = new MyException("用户名不能为空");//打印异常堆栈信息e.printStackTrace();  //控制台打印:exception.MyException: 用户名不能为空String msg = e.getMessage();System.out.println(msg);  //用户名不能为空}
}

4.用异常改良栈的练习

  • 自定义栈操作的异常
public class MyStackOperationException extends Exception{public MyStackOperationException(){}public MyStackOperationException(String s){super(s);}
}
  • 定义栈对象
public class MyStack {//提供一个数组来存储栈元素,可以存储java中任何引用类型的数据用ObjectObject[] elements;//栈帧:定义栈顶指针//每增加一个元素,栈帧+1;//每减少一个元素,栈帧-1;int index;//初始化没有给容量大小的默认栈,定义容量大小为5public MyStack() {this.elements = new Object[5];this.index = 0;}//初始化有给容量大小的默认栈public MyStack(int number) {this.elements = new Object[number];this.index = 0;}//压栈方法public void push(Object element) throws MyStackOperationException {if(this.index>=this.elements.length){MyStackOperationException e = new MyStackOperationException("压栈失败,栈已满!");throw e;}else if(this.index<this.elements.length){this.elements[index] = element;this.index++;System.out.println("入栈成功,入栈元素:" + element);}}//弹栈方法public void pop() throws MyStackOperationException {if(this.index<0){throw new MyStackOperationException("弹栈失败,栈已空");}else if(this.index>0){System.out.println(this.elements[index-1] + " ");this.index--;}}
}
  • 写一个测试类
//测试改良后的栈对象
public class Test {public static void main(String[] args) {MyStack testStack = new MyStack();System.out.println(testStack.elements.length);  //测试默认构造器构造的数组大小//测试压栈try {testStack.push(new Object());  //入栈成功,入栈元素:java.lang.Object@4554617ctestStack.push(new Object());//入栈成功,入栈元素:java.lang.Object@74a14482testStack.push(new Object()); //入栈成功,入栈元素:java.lang.Object@1540e19dtestStack.push(new Object()); //入栈成功,入栈元素:java.lang.Object@677327b6testStack.push(new Object()); //入栈成功,入栈元素:java.lang.Object@677327b6//定义的初始栈为5个容量,从第六个开始出现异常。testStack.push(new Object());//压栈失败,栈已满!testStack.push(new Object());testStack.push(new Object());} catch (MyStackOperationException e) {System.out.println(e.getMessage());}//测试弹栈try {testStack.pop();//java.lang.Object@14ae5a5 testStack.pop();//java.lang.Object@677327b6 testStack.pop();//java.lang.Object@1540e19dtestStack.pop();//java.lang.Object@74a14482 testStack.pop();//java.lang.Object@4554617c testStack.pop();//弹栈失败,栈已空} catch (MyStackOperationException e) {System.out.println(e.getMessage());}}
}

5.异常和方法覆盖

  • 重写方法不能比重写之前抛出更多异常,但可以更少
class Animal{public void doSome(){ }public void doOther() throws Exception{ }
}class Cat extends Animal{//由于父类方法没有抛出异常,所以这里不可以//这种写法不行:public void doSome() throws Exception{} public void doSome(){ }//doOther父类有抛出异常,这里可以不抛出也可以抛出,一下三种都可以写//public void doOther(){ }//public void doOther() throws Exception{ }public void doOther() throws NullPointerException{ }
}
  • 异常小总结:

    异常捕捉:try、catch、finally

    在方法位置声明,表示报异常信息给调用者:throws

    手动抛出异常:throw

——本章节为个人学习笔记。学习视频为动力节点Java零基础教程视频:动力节点—JAVA零基础教程视频