异常处理:
异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。
比如说,你的代码少了一个分号,那么运行出来结果是提示是错误 java.lang.Error;如果你用System.out.println(11/0),那么你是因为你用0做了除数,会抛出java.lang.ArithmeticException 的异常。
所有的异常市场从java.lang.Excepion类继承的子类, Exception类是Throwable类的子类 .处了Exception类外, Throwable 还有一个字累Error. java成功需通常捕获错误. 错误一般发生再严重故障是, 它们在java程序处理的范畴之外. Error用来指示运行时环境发生的错误. Exception中主要有IOException 和 RunTimeException
Error 系统崩溃 数据库崩溃(和程序代码无关)
Exception 异常(和程序代码有关系)
异常处理的作用:简单来说就是帮你来完善代码 让出现的错误容易找到
RuntimeException 运行时异常
出现异常 系统如何解决?
main函数解决方式
1.main函数自己解决
2.把问题抛出上级去解决(谁调用的main 谁去解决)
交给JVM虚拟机去解决
JVM虚拟机怎么解决 — 给你报错
打印错误信息 错误发生在类中的什么位置
解决异常方式
try … catch … finally
try 指测试这个异常
catch 指捕获这个异常
finally 指异常结束后做的事
捕获异常流程
1.发生异常
2.根据发生的异常 产生对应的异常对象
3.这个异常对象会返回给调用者
4.如果调用者处理了这个异常(添加try … catch), 异常兑现会跟catch进行匹配, 匹配上执行catch中的语句, 程序会继续执行
5.如果调用者没有处理这个异常 默认交给JVM去处理, 根据产生异常对象 打印对应错误信息, 程序停止
例:
public class Demo02 {
public static void main(String[] args) {
TestException test = new TestException();
try {
// 可能发生异常的代码
int num = test.fun(10, 0);
// 相当于这块返回了异常对象
// new ArithmeticException("/ by zero");
System.out.println(num);
} catch (ArithmeticException e) {
// 捕获异常 该怎么办
// catch 如何就能捕获异常?
// ArithmeticException e = new ArithmeticException("/ by zero");
// catch会匹配这个异常对象
// 如果匹配上了就执行catch语句
// 补货异常后 程序会继续执行
System.out.println("吃药了没? 除数为0了!");
}
System.out.println("你猜我执行了吗?");
}
}
class TestException{
//报异常的方法
public int fun(int a, int b) {
/*
* 这里发生了算数异常 相当于产生了一个异常对象
* new ArithmeticException("/ by zero");
* 一旦发生异常 系统会产生一个对应异常对象
* 发生空指针
* new NullPointerException();
* 发生异常后 谁调用我 这个异常就给谁
* 处理不了 就给JVM虚拟机去处理
* JVM默认处理方法: 根据异常对象的类型 去打印对应错误信息
* 打印完 会结束你的程序
*/
return a / b;
// ArithmeticException arithmeticException = new ArithmeticException(“/ by zero”);
}
}
多catch的捕获异常
public static void main(String[] args) {
int[] array = {1,2,3,4};
try {
// 测试代码异常
System.out.println(10/0);
// 产生new ArithmeticException之后 就去匹配
// 匹配成功后 程序继续向下执行
System.out.println(array[10]);
} catch (ArithmeticException e) {
/*
* 注意:如果使用exception直接匹配异常
* 多个catch同时捕获时 需要写在最后
* 写前边 后面的catch相当于白写了
*/
System.out.println("病了治 除数为零了");
} catch (ArrayIndexOutOfBoundsException e) {
// 如果发生多个一唱歌需要匹配多个catch
System.out.println("别放弃 数组越界了");
} catch (Exception e) {
System.out.println("你出错了");
}
System.out.println("你猜我执行了吗?");
}
finally — 不管异常有没有发生 有没有匹配到 都会执行
finally 有什么作用?
可以关闭系统资源 避免资源的浪费(例如 关闭输入流 和 关闭数据库)
例如:
public static void main(String[] args) {
try {
System.out.println(10 / 1);
return;
} catch (ArithmeticException e) {
System.out.println("除0了");
}finally {
System.out.println("我是finally");
}
System.out.println("我是下面的语句");
}
这里的finally不论如何 都会执行
运行时异常 和 编译时异常
除了运行时异常 就是 编译时异常
出现运行时异常 —- 就是代码的问题(程序员犯得错误)
出现编译时异常 —- 问题的提前预警 强制你去处理, 不处理编译不通过
public static void main(String[] args) throws FileNotFoundException {
// 编译时异常
// 系统这时候 不知道你到底有没有这个文件
// 相当于系统问你 要是没有这个文件咋整??
// 系统这时会强制 要求你对这个问题作出解释
// 这就是编译时异常(相当于对问题的 一种提前准备)
/*
* 解决异常有两种方式
* 1.自己处理 try...catch
* (想让程序继续执行就try)
* 2.把异常抛出去(谁调用我 抛给谁 谁去处理)
* (想让程序遇到错误就停止 就抛)
*/
// try {
// FileInputStream fileInputStream = new FileInputStream("wl.txt");
// } catch (Exception e) {
// System.out.println("读入文件 没找到");
// }
FileInputStream fStream = new FileInputStream("wl.txt");
}
}
例:
package com.lanou3g;
/*
* 需求:
* 创建一个人类 有name age
* 要求 人类的年龄赋值时 要在 0 到 120 之间
*
* 不用异常
*/
public class Demo06 {
public static void main(String[] args) throws Exception {
Person person = new Person();
person.setAge(170);
System.out.println(person.getAge());
}
}
class Person{
private String name;
private int age;
public Person() {
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
// 如果这个方法 要跑出异常 给调用者
// 那么必须在方法的声明上 标识这个方法为异常方法
// throws Exception 标识是抛出什么异常
/*
* throws 和 throw 区别
* throws 标识这个方法 可以抛出一个异常(在方法的声明出现)
* throw 抛出一个异常对象(方法中出现)
*/
public void setAge(int age) throws Exception {
if (age > 0 && age < 120) {
this.age = age;
}else {
// System.out.println("输入有误");
// 抛出一个异常 告诉他 你赋值的年龄不对
// throw 关键词 抛出一个异常对象
// 创建一个异常对象
//Exception exception = new Exception("年龄非法");
// 把这个异常对象 抛出去
// 抛给谁? --- 谁用给谁
// 使用匿名对象抛出异常
// 使用自定义类处理异常
AgeOutOfBoundsException aException = new AgeOutOfBoundsException("年龄非法");
throw aException;
}
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
// 创建一个自定义的异常类(继承exception)
// 在创建异常类时 需要直观让人知道这是什么异常
// 所以类名要见名知意
class AgeOutOfBoundsException extends Exception{
/**
* 序列化时 需要id
*/
private static final long serialVersionUID = 1L;
// 重写构造方法
public AgeOutOfBoundsException() {
super();
// TODO Auto-generated constructor stub
}
public AgeOutOfBoundsException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
/*
* Throwable中的方法
*/
public class Demo07 {
public static void main(String[] args) {
Exception exception = new Exception("我是异常信息");
// 调用异常中toString方法
// 打印的 异常的类名 和 异常信息
// System.out.println(exception);
//只打印 异常信息
// System.out.println(exception.getMessage());
// 打印的事异常类名 信息 加 出现的位置
// JVM虚拟机默认就是打印这个方法
exception.printStackTrace();
}
}