Throwable
Throwable 异常最顶端的类
Error 服务器崩溃 数据库崩溃
Exception 异常类
RuntimeException 运行时异常
出现异常如何解决
找任务的调用者(出现异常找上级去解决),比如main函数的调用者JVM去处理
JVM默认的处理方式:打印异常类的错误信息和错误发生的位置,直接停止程序
几种常见异常:
1.空指针异常
NullPointerException
访问了一块本不属于我的空间
2.角标越界异常
ArrayIndexOutOfBoundsException
3.算术异常
ArithmeticException
try…catch
try 指测试异常代码
catch 指捕获异常信息
try...catch 捕获异常的流程
1.函数中某句代码发生异常
2.发生异常就产生了对应异常对象
3.这个异常对象返回给调用者
情况一:没有对异常进行处理这时就会把异常交给JVM(交给上级)去处理,jvm使用了默认的处理方式
情况二:调用者进行了异常处理(try...catch),这时 返回的异常对象会跟catch进行匹配,匹配成功执行catch中的语句,程序继续运行
代码示例:
class TestException {
public int fun(int a, int b) {
return a / b;
}
}
public static void main(String[] args) {
TestException testException = new TestException();
try {
int num = testException.fun(10, 2);
System.out.println(num);
} catch (ArithmeticException e) {
System.out.println("你除数是0");
}
System.out.println("你猜我执行了吗");
}
多catch处理异常
处理空指针 角标越界 算术异常
int[] array = new int[4];
try {
System.out.println(array[5]);
array = null;
System.out.println(array[1]);
System.out.println(10 / 0);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("你越界了");
} catch (NullPointerException e) {
System.out.println("空指针");
} catch (ArithmeticException e) {
System.out.println("除0");
}
System.out.println("你猜我执行了吗");
注意:在匹配catch的时候有一个被匹配上,其他的catch 就不会被匹配;如果catch中要写Exception来捕获异常,要放到最下面并且catch中异常由小到大
finally
finally作用:一般用来关闭资源、关闭流、关闭数据库
注意:出现异常与否不会影响到finally的执行,也就是说 finally一定会执行
finally 实例1:
try {
System.out.println(10 / 0);
return;
} catch (Exception e) {
System.out.println("➗0");
} finally {
System.out.println("这是我的遗言");
}
System.out.println("你猜我执行了吗");
finally 实例2:
class TestFinally {
public int fun() {
int num = 10;
try {
num = 20;
System.out.println(10 / 0);
return num;
} catch (Exception e) {
num = 30;
return num;
} finally {
num = 40;
}
}
}
编译时异常
编译时异常就是为了这个可能的错误做的提前准备
编译时异常:系统强制你要处理 try 或者 抛出异常
例如:
FileInputStream inputStream = new FileInputStream("wl.txt");
读取该路径下的文件,相当于系统不知道这个路径有没有文件,需要提前询问如果没有这个路径下的文件你如何去处理。
处理方式一 添加try...catch(自己来处理)
try {
FileInputStream inputStream = new FileInputStream("wl.txt");
} catch (FileNotFoundException e) {
System.out.println("没有这个文件");
}
处理方式二 可以把问题抛给main函数,然后在main函数的函数声明上添加throws要抛出的异常类名
public static void main(String[] args) throws FileNotFoundException {
FileInputStream inputStream = new FileInputStream("wl.txt");
}
运行时异常
运行时异常(RuntimeException):
1.抛出运行时异常,方法的声明上可以不用throws来标识
2.可以不对运行时异常进行处理
1)处理程序可以继续执行
2)不处理程序就直接停止
当方法中抛出运行时异常说明如果发生了该异常就需要停掉程序,让程序再执行下去没有意义
例如:
class Test{
public void fun1(){
throw new RuntimeException();
}
public double fun2(double r) {
if (r <= 0) {
throw new RuntimeException("半径不对");
}
return r * r * Math.PI;
}
}
public static void main(String[] args) {
Test test = new Test();
double fun2 = test.fun2(0);
System.out.println(fun2);
}
自定义异常
自定义异常:类名要见名知意并且跟系统学习
例如:
class AgeOutOfBoundsException extends Exception{
/**
* 序列化时使用的id
*/
private static final long serialVersionUID = 1L;
public AgeOutOfBoundsException() {
super();
}
public AgeOutOfBoundsException(String message) {
super(message);
}
}
public void setAge(int age) throws Exception {
if (age >=0 && age <= 120) {
this.age = age;
} else {
throw new AgeOutOfBoundsException("你是��吗");
}
}
Throwable 中的方法
public static void main(String[] args) {
Exception exception = new Exception("这里可以写错误信息");
String message = exception.getMessage();
System.out.println(message);
System.out.println(exception.toString());
exception.printStackTrace();
}
打印结果
// getMessage()
这里可以写错误信息
// toString
java.lang.Exception: 这里可以写错误信息
// printStackTrace()
java.lang.Exception: 这里可以写错误信息
at com.lanou3g.Demo07.main(Demo07.java:7)
继承中 方法重写异常
1.如果父类没有抛出编译异常,子类不能抛出编译异常
2.如果在子类重写父类的方法中调用了一个有异常的方法,这时只能选择 try ... catch处理,不能抛出异常
3.如果父类有抛出编译异常,子类可以不抛出异常也可以抛出异常
代码实例:
class Father {
public void fun(){
}
}
class Son extends Father{
@Override
public void fun() {
try {
method();
} catch (Exception e) {
e.printStackTrace();
}
}
public void method() throws Exception {
}
}
异常处理练习
需求:无限输入整数存放到集合中打印 输入quit停止 希望在输入字符串的时候让程序也能继续运行
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
while (true) {
String string = scanner.nextLine();
if (string.equals("quit")) {
break;
}
try {
int num = Integer.parseInt(string);
list.add(num);
} catch (Exception e) {
System.out.println("输入错误");
}
}
System.out.println(list);
}
public class IntTools {
private IntTools() {
}
public static int getIntNum() {
System.out.println("请输入一个数");
Scanner scanner = new Scanner(System.in);
String string = scanner.nextLine();
try {
int num = Integer.parseInt(string);
return num;
} catch (Exception e) {
return getIntNum();
}
}
}
public class MyNum {
private int num1;
private int num2;
public MyNum() {
super();
}
public MyNum(int num1, int num2) {
super();
this.num1 = num1;
this.num2 = num2;
}
public int getNum1() {
return num1;
}
public void setNum1(int num1) {
this.num1 = num1;
}
public int getNum2() {
return num2;
}
public void setNum2(int num2) {
this.num2 = num2;
}
}
public class DivNotZeroException extends Exception{
/**
*
*/
private static final long serialVersionUID = 1L;
public DivNotZeroException() {
super();
}
public DivNotZeroException(String message) {
super(message);
}
}
public class Operation {
public MyNum getNum() {
int num1 = IntTools.getIntNum();
int num2 = IntTools.getIntNum();
MyNum myNum = new MyNum(num1, num2);
return myNum;
}
public String getMethod() {
System.out.println("输入数字1是加法 2是除法(输入错误 要重新输入)");
int num = IntTools.getIntNum();
if (num == 1) {
return "+";
} else if(num == 2) {
return "/";
} else {
return getMethod();
}
}
public int sum(MyNum myNum) {
return myNum.getNum1() + myNum.getNum2();
}
public int div(MyNum myNum) throws DivNotZeroException {
try {
return myNum.getNum1() / myNum.getNum2();
} catch (Exception e) {
throw new DivNotZeroException("被除数不能为0");
}
}
public int getResultByOperationAndNum(String operation,MyNum myNum) {
if (operation.equals("+")) {
return sum(myNum);
}
try {
return div(myNum);
} catch (DivNotZeroException e) {
System.out.println(e.getMessage());
System.out.println("请重新输入两个数:");
MyNum newNum = getNum();
return getResultByOperationAndNum(operation, newNum);
}
}
}
public class Test {
public static void main(String[] args) {
Operation operation = new Operation();
String method = operation.getMethod();
MyNum num = operation.getNum();
int result = operation.getResultByOperationAndNum(method, num);
System.out.println(result);
}
}