day14
一、异常
在Java程序执行过程中,发生的问题叫做异常。
1.1 编译时异常和运行时异常
运行时异常: RuntimeException的子类。运行时异常可以处理,也可以不处理。这类问题只要细心一点就可以了。 比如:除数不能为0
编译时异常: 除了RuntimeException之外的所有Exception的子类。 编译时异常一定要处理,如果不处理程序就无法通过编译,也就无法运行。
1.2 异常的呈现方式
Java是将异常包装成了一个类,这个类中有关于异常的解释,如果遇到此类异常了,Java会通过一个特殊的关键字将这个异常对象抛给Java程序开发者。开发者看到程序抛出来的异常对象之后,就知道程序出了什么错误,就可以根据这个错误解决问题。
1.3 异常处理方案
方案一:jvm虚拟机自动处理
方案二:手动处理
1.4 自动处理
Java程序在执行过程中,遇到异常的话,如果程序员不处理,那么最终会由jvm虚拟机自动处理。
自动处理的方式为:
异常所在的类,及具体的错误信息,包括出现异常的位置都打印在控制台上。同时停止jvm虚拟机。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RTIeTO1M-1620344740110)(img/image-20210423103712481.png)]
1.5 手动处理
手动处理的两种解决方案:
try...catch
throws
try…catch
格式一:
try {
可能出现异常的代码;
}catch(异常类名 异常对象名){
}
注意:
1. try是尝试的意思,里面放的是可能出现问题的代码。这个代码要尽可能的少。
2. catch是捕获的意思,catch会将try发现的异常捕获到,并在其大括号中进行处理。
格式二:
try {
可能出现问题的代码;
}catch(异常类名1 异常对象名1){
}catch(异常类名2 异常对象名2){
}
注意:
1. catch后面的异常一定要是从小到大的(也就是最大的异常一定要放在最后)
格式三:
try {
可能出现问题的代码;
}catch(异常类名1 | 异常类名2 | 异常类名3 | ... e) {
}
注意:
1. 这种处理方案是jdk7之后才出来的
2. catch后面跟的异常必须是同级的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sIO9XTgF-1620344740112)(img/image-20210423115127874.png)]
throws
有些异常,我们解决不了,或者可以解决,但是没有权限去解决。像这种我们就可以通过throws关键字将异常声明给方法的调用者,然后让调用者去解决。
throws用在方法声明的最后面。throws后面可以跟多个异常类名
格式为:
修饰符 返回值类型 方法名(参数列表) throws 异常类名1, 异常类名2, ...{
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-llXwG4Of-1620344740114)(img/image-20210423114921336.png)]
总结:
以后遇到运行时异常不用通过try...catch或者throws解决。
遇到编译时异常,一定要通过try...catch或者throws解决。并且这个不用自己写,只需要将鼠标放到出现问题的方法上,根据提示选择就好了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lRuauSjm-1620344740116)(img/image-20210423114546515.png)]
1.6 Throwable的常见方法
String getMessage() 返回此 throwable 的详细消息字符串(也就是错误的原因)
String toString() 返回此 throwable 的简短描述。(也就是 异常类名加上错误的原因)
void printStackTrace() 将此 throwable 及其追踪输出至标准错误流
public class Demo5 {
public static void main(String[] args) {
int a = 3;
try {
System.out.println(a / 0);
}catch(ArithmeticException e){
// System.out.println("除数不能为0");
// String message = e.getMessage();
// System.out.println(message); // / by zero
// String s = e.toString();
// System.out.println(s); //java.lang.ArithmeticException: / by zero
e.printStackTrace();
}
System.out.println("end");
}
}
1.7 throw关键字
throw关键字用来抛出一个异常。throw后面只能跟一个异常对象。
public class Demo6 {
public static void main(String[] args) {
int a = 5;
/*
下方代码只是为了测试throw关键字,并没有什么特殊含义。
如果a=3 就正常输出
如果a不等于3,那么就使用throw抛出一个异常
*/
if(a == 3){
System.out.println("a等于3");
}else{
throw new ArrayIndexOutOfBoundsException();
}
}
}
1.8 throw和throws的区别
作用:
throws: 用来解决异常。(就是给方法的调用者提示哪里出现了问题)
throw: 用来抛出一个异常。
声明位置:
throws: 方法声明的后面
throw:用在方法内部
后面跟的内容不同:
throws: 后面跟异常类名,并且可以跟多个
throw: 后面跟异常对象,并且只能跟一个
异常的出现情况不同:
throws: 异常有可能发生,也有可能不发生
throw: 一定会发生
1.9 finally关键字
finally中的内容一定会被执行。
try {
}catch() {
}finally {
}
注意:
finally中一般放必须执行的内容,必须关闭流、关闭数据库对象。
public class Demo7 {
public static void main(String[] args) {
int a = 3;
try {
System.out.println(a / 0);
// System.out.println("我很重要,执行我呗!!!");
}catch (ArithmeticException e){
System.out.println("除数不能为0");
}finally {
System.out.println("我很重要,执行我呗!!!");
}
System.out.println("end");
}
}
二、自定义异常
我们目前遇到的异常都是一些常见的异常,这些官方都已经定义好了,我们直接使用就可以了。但是还有一些异常,比如家里小孩成绩考了160分,这个肯定也是异常。这种异常官方没有,所以我们只能自己定义了。
要想自定义异常,一定要将自己定义的类通过继承和异常体系产生关系。
编译时异常:继承Exception
运行时异常:继承RuntimeException
/*
自定义的成绩异常
编译时异常
*/
public class MyException extends Exception {
public MyException(){
}
public MyException(String s){
// System.out.println(s);
super(s);
}
}
/*
学生类
*/
public class Student {
String name;
int score;
public Student(){
}
public Student(String name, int score) {
this.name = name;
this.score = score;
}
/*
检查成绩的方法:
如果成绩合法就输出
如果成绩不合法就抛异常
*/
public void checkScore() throws MyException {
if(score >= 0 && score <= 100){
System.out.println("成绩为:" + score);
}else{
throw new MyException("成绩非法!!!");
}
}
}
/*
测试类
*/
public class Demo {
public static void main(String[] args) throws MyException {
Student s = new Student("马云", 160);
s.checkScore();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IpreB7yR-1620344740118)(img/image-20210423143037395.png)]
三、自动装箱、拆箱(JDK5新特性)
装箱:就是将基本数据类型包装成引用数据类型
拆箱:就是将引用数据类型变为基本数据类型
自动装箱: 就是系统通过自发的调用方法来将基本数据类型变成引用数据类型
自动拆箱: 就是系统通过自发的调用方法来将引用数据类型变成基本数据类型
public class Demo {
public static void main(String[] args) {
/*
以下过程中:是否发生了自动装箱和拆箱,具体是哪一步
*/
//自动装箱 【valueOf】
Integer i = 10;
/*
先自动拆箱 【intValue】(拆箱成基本数据类型之后才可以直接相加)
后自动装箱【valueOf】(运行的结果30又赋值给了Integer)
*/
i += 20;
System.out.println(i);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YzUrLu92-1620344740119)(img/image-20210423150057137.png)]
程中:是否发生了自动装箱和拆箱,具体是哪一步
*/
//自动装箱 【valueOf】
Integer i = 10;
/*
先自动拆箱 【intValue】(拆箱成基本数据类型之后才可以直接相加)
后自动装箱【valueOf】(运行的结果30又赋值给了Integer)
*/
i += 20;
System.out.println(i);
}
}
[外链图片转存中...(img-YzUrLu92-1620344740119)]