【JAVA学习笔记】异常
2021-04-23 本文已影响0人
Geekero
学习自华为开发者学院陈璇老师的JAVA系列课程
一、try--catch--finally
- System.err.println()
- System.exit(状态码) #非零代表异常
-
input.hasNextInt()
try{
//尝试执行,但可能出现异常的代码
}catch(Exception e){
//捕获异常,对异常做处理
System.err.println(....);
System.exit(1);
}finally{
//是否异常,异常是否捕获到都会执行
}
finally无论是否异常,异常是否正确捕获到都会执行,但是唯一不执行的就是catch完异常后System.exit(1) 中断程序,退出Java虚拟机
先执行finally, 然后再return结束方法
输出异常的堆栈信息:
e.printStackTrace()
返回异常信息描述字符串,是printStackTrace()输出信息的一部分 :
e.printStackTrace()
常见异常:
注意:
try--catch--finally结构中try语句块是必须的,catch、finally语句均可选,但两种必须至少有一个出现一次
多重catch块
引发多种类型的异常
- 排列catch语句的顺序:先子类后父类
- 发生异常时按顺序逐个匹配
- 只执行第一个与异常类型匹配的catch语句
import java.util.Scanner;
public class PrintSubName {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入课程代号(1~3之间的数字):");
try {
int num = input.nextInt();
switch (num) {
case 1:
System.out.println("Java 基础语法");
break;
case 2:
System.out.println("Java OOP");
break;
case 3:
System.out.println("Java 高级特性");
break;
}
}catch (Exception e) {
System.out.println("输入格式不正确,课程代码必须是1~3之间的数字!");
e.printStackTrace();
}finally {
System.out.println("欢迎提出建议!");
}
}
}
二、使用throws声明异常
throws 声明某个方法可能抛出的各种异常,多种异常用逗号隔开
方式1:调用者处理异常
方式2:调用者继续声明异常
- main()方法声明的异常由Java虚拟机处理
import java.net.Socket;
import java.util.InputMismatchException;
import java.util.Scanner;
//使用throws声明异常
public class CalcTest {
//两个数的除法运算
//通过throws声明方法可能抛出的各种异常,多个异常之间用逗号隔开
public void divide() throws InputMismatchException, ArithmeticException{
Scanner in = new Scanner(System.in);
System.out.print("请输入被除数:");
int num1 = in.nextInt();
System.out.print("请输入输出:");
int num2 = in.nextInt();
System.out.println(num1 + "/" + num2+"=" + num1/num2);
}
// public static void main(String[] args) {
//
// CalcTest calc = new CalcTest();
// //方式一:调用者直接处理掉异常
// try {
// calc.divide();
//// int num1 = in.nextInt();
//// System.out.print("请输入输出:");
//// int num2 = in.nextInt();
//// System.out.println(num1 + "/" + num2+"=" + num1/num2);
// }catch(InputMismatchException e) {
// //捕获异常,对异常进行处理
// System.err.println("出现错误:被除数和输出必须为整数!");
// }catch (ArithmeticException e) {
// //捕获异常,对异常进行处理
// System.err.println("出现错误:除数不能为零!");
// }catch (Exception e){
// //捕获异常,对异常进行处理
// System.err.println("出现错误, 非法操作!");
// }finally {
// System.out.println("感谢使用本程序!");
// }
// }
public static void main(String[] args) throws InputMismatchException, ArithmeticException {
CalcTest calc = new CalcTest();
//方式二:调用者不处理掉异常,继续声明。最终main()声明的异常由JVM处理
calc.divide();
}
}
三、使用throw抛出异常
//人类
public class Person {
private String name;
private int age;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) throws Exception {
if (age<=100 && age>=1){
this.age = age;
}else {
throw new Exception("年龄必须在1~100之间!");
}
}
public String getSex() {
return sex;
}
//性别只能是“男”或“女”,其他性别字符串报异常
//使用throw抛出异常
public void setSex(String sex) throws Exception {
if (sex.equals("男")||sex.equals("女")) {
this.sex = sex;
}else {
//写法1:
// Exception e = new Exception("性别只能为男女!");
// throw e;
//写法2:
//当使用throw显式抛出异常,必须对异常处理,或throws声明异常
throw new Exception("性别只能为男女!");
}
}
//个人信息介绍
public void print() {
System.out.println(this.getName()+"-"+this.getSex()+"-"+this.getAge());
}
public static void main(String[] args) {
Person p = new Person();
//当调用的方法有throws抛出异常,必须对异常处理,或throws声明异常
try {
p.setSex("男");
p.setAge(0);
p.print();
} catch (Exception e) {
e.printStackTrace();
}
}
}
四、异常体系结构
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* 不处理Checked异常,编译无法通过。1. throws 2.try--catch捕获异常和处理异常
*/
public class TestIO {
public static void main(String[] args) {
FileInputStream fis = null;
// 创建指定文件的流
try {
fis = new FileInputStream(new File("accp.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
五、自定义异常
继承Throwable、Exception RuntimeException类
AgeException.java
public class AgeException extends Exception {
public AgeException(){}
public AgeException(String message){
super(message);
}
}
SexException.java
//自定义异常类(Person类性别赋值异常)
public class SexException extends Exception {
public SexException(){}
//由特定异常信息构建异常对象
public SexException(String message){
super(message);
}
}
Person.java
//人类
public class Person {
private String name;
private int age;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) throws AgeException {
if (age<=100 && age>=1){
this.age = age;
}else {
throw new AgeException("年龄必须在1~100之间!");
}
}
public String getSex() {
return sex;
}
//性别只能是“男”或“女”,其他性别字符串报异常
//使用throw抛出异常(SexException--性别赋值异常)
public void setSex(String sex) throws SexException {
if (sex.equals("男")||sex.equals("女")) {
this.sex = sex;
}else {
//写法1:
// Exception e = new Exception("性别只能为男女!");
// throw e;
//写法2:
//当使用throw显式抛出异常,必须对异常处理,或throws声明异常
// throw new Exception("性别只能为男女!");
throw new SexException("性别只能为男女!");
}
}
//个人信息介绍
public void print() {
System.out.println(this.getName()+"-"+this.getSex()+"-"+this.getAge());
}
public static void main(String[] args) {
Person p = new Person();
//当调用的方法有throws抛出异常,必须对异常处理,或throws声明异常
try {
p.setSex("boy");
} catch (SexException e) {
e.printStackTrace();
}
try {
p.setAge(0);
} catch (AgeException e) {
e.printStackTrace();
}
p.print();
}
}
六、异常链 和 异常处理原则
6.1 异常链
异常链:创建了新的异常,但却保留了原有异常的信息(jdk1.4以后的特性)
6.2 异常处理原则
- 异常处理与性能(在没有异常时,异常处理对性能影响不大)
- 整个代码段会被压在一个方法栈的地方(一块内存区域),JVM在读取方法时,如果发现有try catch触发异常,就会在方法的方法栈里面去找catch来进行执行
- 但是通过throws声明和throw异常的话,JVM会顺着方法的调用,一直逐层去方法调用,到最后定位到相应的方法栈里的方法体找catch,对性能产生影响。 - 异常只能用于非正常情况
- 需要对捕获的异常做处理(如果有能力处理就进行处理,尽量不要往外抛出异常)
- 不要将过于庞大的代码块放在try中
- 在catch中指定具体的异常类型