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中任何引用类型的数据用Object
    Object[] elements;
    //栈帧:定义栈顶指针
    //每增加一个元素,栈帧+1;
    //每减少一个元素,栈帧-1;
    int index;
    //初始化没有给容量大小的默认栈,定义容量大小为5
    public 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@4554617c
            testStack.push(new Object());//入栈成功,入栈元素:java.lang.Object@74a14482
            testStack.push(new Object()); //入栈成功,入栈元素:java.lang.Object@1540e19d
            testStack.push(new Object()); //入栈成功,入栈元素:java.lang.Object@677327b6
            testStack.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@1540e19d
            testStack.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零基础教程视频

你可能感兴趣的:(咖啡ice的Java学习记录,java,开发语言)