JAVA异常

1.异常

 Error:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError(栈溢出)和OOM(内存溢出)。一般不编写针对性的代码进行处理。

  Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。

 错误:Error类以及它的子类的实例,代表了JVM本身的错误。错误不能被程序员通过代码处理,Error很少出现。因此,程序员应该关注Exception为父类的分支下的各种异常类。

异常:Exception以及它的子类,代表程序运行时发生的各种不期望发生的事件。可以被Java异常处理机制使用,是异常处理的核心。
Error是系统中的错误,程序员是不能改变的和处理的,一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序终止。因此我们编写程序时不需要关心这类错误。
Exception,也就是我们经常见到的一些异常情况,表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。

 2.JVM默认处理异常的方式

如果程序出现了问题,我们没有做任何处理,最终JVM 会做默认的处理,处理方式有如下两个步骤:

1.把异常的名称,错误原因及异常出现的位置等信息输出在了控制台

2.程序停止执行(哪里出现异常程序就在哪里停止,下面的代码就不执行)

3.处理异常方式——throws

throws是另一种处理异常的方式,它不同于try...catch...finally,throws仅仅是将函数中可能出现的异常向调用者声明,而自己则不具体处理。

 采取这种异常处理的原因可能是:方法本身不知道如何处理这样的异常,或者说让调用者处理更好,调用者需要为可能发生的异常负责。

定义格式:

public void 方法() throws 异常类名 {
    
}

 代码:

public class ExceptionDemo {
    public static void main(String[] args) {
        System.out.println("开始");
//        method();
        try {
            method2();
        }catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println("结束");
    }

    //编译时异常
    public static void method2() throws ParseException {
        String s = "2048-08-09";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date d = sdf.parse(s);
        System.out.println(d);
    }

    //运行时异常
    public static void method() throws ArrayIndexOutOfBoundsException {
        int[] arr = {1, 2, 3};
        System.out.println(arr[3]);
    }
}

注意:如果声明的异常是运行时异常,那么声明的代码可以省略

          如果声明的异常是编译时异常,那么声明的代码必须手动写出

4.手动抛出异常——throw

Java异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出,也可根据需要使用人工创建并抛出。 

throw 语句必须写在函数中,执行throw 语句的地方就是一个异常抛出点

定义格式:

throw new 异常();

 代码:

public class StudentTest {
    public static void main(String[] args) {
        try {
            Student s = new Student();
            s.regist(-1001);
            System.out.println(s);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
 
class Student {
    private int id;
 
    public void regist(int id) throws Exception {
        if (id > 0) {
            this.id = id;
        } else {
            // System.out.println("您输入的数据非法!");
 
            //手动抛出异常对象
            // throw new RuntimeException("您输入的数据非法!");
            throw new Exception("您输入的数据非法!");
 
            //错误的
            // throw new String("不能输入负数");
        }
 
    }
 
    @Override
    public String toString() {
        return "Student [id=" + id + "]";
    }
}

5.throws和throw的区别

在这里插入图片描述

 6.异常处理方式——try-catch

try块中的局部变量和catch块中的局部变量(包括异常变量),以及finally中的局部变量,他们之间不可共享使用。

每一个catch块用于处理一个异常。异常匹配是按照catch块的顺序从上往下寻找的,只有第一个匹配的catch会得到执行。匹配时,不仅运行精确匹配,也支持父类匹配,因此,如果同一个try块下的多个catch异常类型有父子关系,应该将子类异常放在前面,父类异常放在后面,这样保证每个catch块都有存在的意义。

定义格式:

try {
	可能出现异常的代码;
} catch(异常类名 变量名) {
	异常的处理代码;
}

代码:

public class ExceptionDemo01 {
    public static void main(String[] args) {
        System.out.println("开始");
        method();
        System.out.println("结束");
    }

    public static void method() {
        try {
            int[] arr = {1, 2, 3};
            System.out.println(arr[3]);
            System.out.println("这里能够访问到吗");
        } catch (ArrayIndexOutOfBoundsException e) {
//            System.out.println("你访问的数组索引不存在,请回去修改为正确的索引");
            e.printStackTrace();
        }
    }
}

7.Throwable成员方法

常用方法:

方法名说明
public String getMessage()返回此 throwable 的详细消息字符串
public String toString()返回此可抛出的简短描述
public void printStackTrace()把异常的错误信息输出在控制台

代码:

public class ExceptionDemo02 {
    public static void main(String[] args) {
        System.out.println("开始");
        method();
        System.out.println("结束");
    }

    public static void method() {
        try {
            int[] arr = {1, 2, 3};
            System.out.println(arr[3]); //new ArrayIndexOutOfBoundsException();
            System.out.println("这里能够访问到吗");
        } catch (ArrayIndexOutOfBoundsException e) { //new ArrayIndexOutOfBoundsException();
//            e.printStackTrace();

            //public String getMessage():返回此 throwable 的详细消息字符串
//            System.out.println(e.getMessage());
            //Index 3 out of bounds for length 3

            //public String toString():返回此可抛出的简短描述
//            System.out.println(e.toString());
            //java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3

            //public void printStackTrace():把异常的错误信息输出在控制台
            e.printStackTrace();
//            java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3

        }
    }
}

 8.编译时异常和运行时异常的区别

  • 编译时异常

    • 都是Exception类及其子类
    • 必须显示处理,否则程序就会发生错误,无法通过编译
  • 运行时异常

    • 都是RuntimeException类及其子类
    • 无需显示处理,也可以和编译时异常一样处理

 9.自定义异常

 如果要自定义异常类,则扩展Exception类即可,因此这样的自定义异常都属于检查异常(checked exception)。如果要自定义非检查异常,则扩展自RuntimeException。

        按照国际惯例,自定义的异常应该总是包含如下的构造函数:
                一个无参构造函数
                一个带有String参数的构造函数,并传递给父类的构造函数。
                一个带有String参数和Throwable参数,并都传递给父类构造函数。
                一个带有Throwable 参数的构造函数,并传递给父类的构造函数。
自定义异常的构建:

继承Exception

public class MyException extends Exception {
 
    public MyException() {
        super();
    }
 
    public MyException(String message) {
        super(message);
    }
 
    public MyException(String message, Throwable cause) {
        super(message, cause);
    }
 
 
    public MyException(Throwable cause) {
        super(cause);
    }
}

使用自定义异常

   如果自定义异常是为了提示,在使用的时候,一定要用try..catch,不要直接用throw往外抛。

public class Test {
    public static void main(String[] args) {
        A a = new A();
        try {
            a.show(-2);
        } catch (MyException e) {
            System.out.println(e.getMessage());
        }
    }
}
 
class A {
    public void show(int num) throws MyException {
        if (num < 0) {
            MyException me = new MyException("异常:" + num + "不是正数");
            throw me;//抛出异常,结束方法show()的执行
        }
        System.out.println(num);
    }
}

应用:

自定义异常类:

public class ScoreException extends Exception {

    public ScoreException() {}

    public ScoreException(String message) {
        super(message);
    }

}

老师类:

public class Teacher {
    public void checkScore(int score) throws ScoreException {
        if(score<0 || score>100) {
//            throw new ScoreException();
            throw new ScoreException("你给的分数有误,分数应该在0-100之间");
        } else {
            System.out.println("成绩正常");
        }
    }
}

测试类:

public class Demo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入分数:");

        int score = sc.nextInt();

        Teacher t = new Teacher();
        try {
            t.checkScore(score);
        } catch (ScoreException e) {
            e.printStackTrace();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值