java学习初探七之异常处理

1.异常的基本概念
(1)异常是什么?
第一,异常模拟的是现实世界中“不正常“的事件。
第二,java中采用“类”去模拟异常。
第三,类是可以创建对象的。
NullpointerException e=0x1234;
e是引用类型,e中保存的内存地址指向堆中的“对象”,这个对象一定是NullpointerException 类型。这个对象就表示真实存在的异常事件。NullpointerException 是一类异常。
(2)异常机制的作用是什么?
java语言为我们提供了一种完善的异常处理机制。
作用是:程序发生异常事件之后,为我们输出详细的错误信息。程序员通过这个信息,可以对程序进行一些处理,使程序更加健壮。
2.异常类继承层次结构
Error:java程序中如果出现了错误,错误是不能处理的,只能退出JVM。例如:StackOverflowError。可抛出,不可处理。
Exception:可抛出,也可处理。如果没有处理异常,则程序直接退出JVM。
异常继承结构图如下所示:
异常继承结构图
3.两种处理异常方式
处理异常有两种方式:
(1)声明抛出 throws
下面是第一种方式 声明抛出
第一个例子

import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class Testhrows {
    public static void main(String[] args) throws FileNotFoundException {
        //创建文件输入流,读取文件
        //java编辑器不是那么智能,因为FileInputStream这个构造方法在声明的位置上使用了throws FileNotFoundException
        FileInputStream file=new FileInputStream("c:/ab.txt");
    }
}

下面是第二个例子:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class TestThrows02 {
    public static void main(String[] args) throws FileNotFoundException {
        m1();
        //使用throws处理异常不是真正处理异常而是推卸责任
        //谁调用的就会抛给谁
        //上面的m1方法如果出现了异常,因为采用的是上抛,给了JVM,JVM遇到这个异常就会推出JVM,下面的代码不会执行
        //System.out.println();

        //真正处理
        try{
            m1();
        }
        catch(FileNotFoundException e){}
        System.out.println();
    }
    public static void m1() throws FileNotFoundException{
        m2();
    }
    public static void m2() throws FileNotFoundException{
        m3();
    }
    public static void m3() throws FileNotFoundException{
        new FileInputStream("c:/cd.txt");//FileInputStream构造方法声明位置上使用throws(向上抛)
    }
}

(2)捕捉 try…catch…
语法:
try{
可能出现异常的代码;
}catch{
处理异常的代码;
}catch{
处理异常的代码;
}…….
第一,catch语句块可以写多个。
第二,但是从上到下catch,必须从小类型异常到大类型异常进行捕捉。
第三,try catch中最多执行一个catch语句块,执行结束后,try catch结束。

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TestTryCatch {
    /*
     * 下面编译无法通过,catch可以写多个,但是必须从上到下,从小到大捕捉。
     */
    /*public static void main(String[] args)  {
        try {
            FileInputStream file=new FileInputStream("c:/cd.txt");
            file.read();
        }catch (IOException e) {

        }catch (FileNotFoundException e) {

        }
    }*/

    //通过
    /*public static void main(String[] args) throws FileNotFoundException,IOException {
        FileInputStream file=new FileInputStream("abc");
        file.read();
    }*/

    public static void main(String[] args)  {
        try {
        //程序执行到此处发生了FileNotFoundException类型的异常。
        //JVM会自动创建一个FileNotFoundException类型的对象,将该对象的内存地址赋值给catch语句块中的e变量。
        FileInputStream file=new FileInputStream("abc");
        //上面的代码出了异常try语句块中的代码不再执行,直接进入catch语句块中执行。
        System.out.println("111111111111");
        file.read();
        System.out.println("222222222222");
        }catch (FileNotFoundException e) {//e内存地址指向堆中的那个对象是“FileNotFoundException”类型的事件。
            System.out.println("读取文件不存在");//java.io.FileNotFoundException: abc (系统找不到指定的文件。)
            System.out.println(e);
        } 
        catch (IOException e) {
            System.out.println("其他异常");
        }
        System.out.println("hello world");  
    }   
}

输出结果:
读取文件不存在
java.io.FileNotFoundException: abc (系统找不到指定的文件。)
hello world

4.getMessage和printstackTrace方法的应用

import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class TestTryCatch05 {
    public static void main(String[] args) {
    try {
        FileInputStream file=new FileInputStream("c:/kkjgd.txt");
        //JVM为我们执行了以下代码
        //FileNotFoundException e=new FileNotFoundException("c:/\\kkjgd.txt (系统找不到指定的文件。)");

    } catch (FileNotFoundException e) {
        //打印异常堆栈信息。一般情况下,都会使用该方式去调试程序。
        e.printStackTrace();
        /*java.io.FileNotFoundException: c:\kkjgd.txt (系统找不到指定的文件。)
        at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(FileInputStream.java:195)
        at java.io.FileInputStream.<init>(FileInputStream.java:138)
        at java.io.FileInputStream.<init>(FileInputStream.java:93)
        at TestTryCatch05.main(TestTryCatch05.java:8)*/

        System.out.println(e.getMessage());//c:\kkjgd.txt (系统找不到指定的文件。)
    }
    System.out.println("abcdef");
    }
}

5.finally语句
第一,finally语句块可直接和try语句块联用。try…finally
第二,try…catch…finally
第三,在finally语句块中的代码一定会执行的。所以通常为了保证某资源一定会释放,所以一般在finally语句块中释放资源。

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class TestFinally {
    public static void main(String[] args) throws Exception {
    try {
        //会执行
        System.out.println("try");
        return;
    } finally {
        //会执行
        System.out.println("finally");
    } 


    try {
        FileInputStream file=new FileInputStream("ddet.txt");
        //不会执行
        System.out.println("try");
    } finally {
        //会执行
        System.out.println("finally");
    } 

    try {
        //只要在执行finally语句块之前推出了JVM,则finally语句块不会执行
        System.exit(0);
    } finally {
        //不会执行
        System.out.println("finally");
    } 
    }

}

深入finally:

public class Testfinally02 {
public static void main(String[] args) {
    int i=m1();
    System.out.println("main的i是"+i);//10
}
public static int m1(){
    int i=10;
    try {
        //底层其实是这样操作的
        //int tmp=i;return tmp;
        return i;
    } finally {
        i++;
        System.out.println("m1的i是"+i);
    }

}
}
输出结果
m1的i是11
main的i是10

释放资源例子

import java.io.File;
import java.io.FileInputStream;

public class Testfinally04 {
public static void main(String[] args) {
    FileInputStream file=null;
    try {
         file=new FileInputStream("Test.java");
    } catch (Exception e) {
        e.printStackTrace();
    }finally {
        //为了保证资源一定会释放
        if(file!=null){
            try {
                System.out.println("finally try");
                file.close();

            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }
}
}

6.final finalize(方法名,垃圾回收器回收对象前调用) finally
7.如何手动抛出异常
(1)自定义异常
编译时异常:直接继承Exception
运行时异常:直接继承RuntimeException

public class MyException extends Exception{//编译时异常
//public class MyException extends RuntimeException{//运行时异常

    //定义异常一般提供两个构造方法
    public MyException(){}
    public MyException(String msg){
        super(msg);
    }

}
public class CustomService {
//对外提供一个注册的方法
    public void register(String name) throws MyException{
        if(name.length()<6){
            //异常
            //创建异常对象
            //MyException e=new MyException("用户名长度不能少于六位");
            //手动抛出异常
            //throw e;
            throw new MyException("用户名长度不能少于六位");
        }
        //如果代码能执行到此处,证明用户名是合法的
        System.out.println("注册成功");
    }
}
public class TestException {

    public static void main(String[] args) {
        //假如用户提供用户名如下
        String username="jack";
        CustomService cs=new CustomService();
        try {
            cs.register(username);
        } catch (MyException e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
        ;

    }

}

输出结果:
用户名长度不能少于六位
MyException: 用户名长度不能少于六位
at CustomService.register(CustomService.java:11)
at TestException.main(TestException.java:9)

8.方法的覆盖与异常
重写的方法不能比被重写的方法抛出更宽泛的异常。

//下例,不能通过编译。
import java.io.FileNotFoundException;
import java.io.IOException;
public class A {
    public void m1() throws FileNotFoundException {

    }
}
class B extends A{
    //子类永远无法抛出比父类更多的异常
    public void m1() throws IOException{}
}
//可以通过编译
import java.io.FileNotFoundException;
import java.io.IOException;
public class A {
    public void m1() throws IOException {       
    }
}
class B extends A{
    public void m1() throws FileNotFoundException{}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值