错误Error类
错误: Error -> 严重问题, 内存相关, 必须要解决的,有可能是程序员解决不了的.(如:StackOverError)
异常Exception类
1.异常通常分为未检查/运行时异常,和已检查/编译时异常
2.构造方法:new xxxException(String message);
3.API:printStackTrace();—>打印出异常的栈路径
getMessage();
错误Error和异常Exception拥有一个统一的父接口–Throwable,意味着所有的异常/错误都是可抛出的,都可以用throws抛出异常处理
未检查/运行时异常RuntimeException()
1.未检查/运行时异常RuntimeException()的常见的三个子类:
ArrayIndoxOutOfBoundsException();–数组下标越界异常
ClassCastException();–类型转换异常
NullPointerException();–空指针异常
2.未检查/运行时异常RuntimeException()的特点:
不用检查,可处理可不处理,通常不做处理.
已检查/编译时异常–直接继承Exception
1.已检查/编译时异常常见的子类:
ParseException();–格式化异常
IOException();–输入/输出异常
UnsupportedEncodingException();–转码异常
2.已检查/编译时异常的特点:必须处理.
处理异常
处理异常的方式有两种:
try-catch(); —捕获异常
Throw—抛出异常
try-catch()处理异常
1.遇到一个未处理的运行时异常,程序回直接终止,并打印出错误栈路径.如果不想让程序终止,就处理它—建议用 try-catch()处理
2.使用 try-catch()处理异常的注意点:
try{
ArraysDemo.m1(); //可能出现异常的代码,必须写在try{ }里
}catch(NullPointerException e){ //e–>异常名,可以随便给
}
<1>可能出现异常的代码必须写在try{ }里
<2>catch()里捕获的异常必须符合try{ }里异常的类型,捕获的异常不符合try{ }里的异常类型,程序仍会终止
<3>try{ }里的代码出现异常,程序不会终止,而是在try{ }里出现异常的代码后的所有代码不能执行了
<4>e.printStackTrace();–>打印出异常栈路径,就是把异常的信息在控制台显示出来,不影响程序是否终止—控制台打印异常信息与程序是否终止没有因果关系
<5>try-catch 可以嵌套–一个try后面可以跟多个catch捕获不同的异常,多个catch一定是父类型异常放在子类型异常后面,无关的异常类型, 顺序不作要求,catch中定义的是父类异常, 那么可以将父类所有的子类异常一起捕获
<6>如果两个异常执行执行同样的代码,但这两个异常没有父子关系,那么可以用"|"(或者)一次捕捉多个异常
try{
ArraysDemo.m1();
}catch(异常名1){
System.out.println("哈哈");
}catch(异常名2){
System.out.println("哈哈");
}
------------------------------------------------------------
try{
ArraysDemo.m1();
}catch(异常名1|异常名2){
System.out.println("哈哈");
}
<7>finally 无论有没有出现异常, 都会执行到的语句块即使在try 或者 catch 写了return, 也会执行到finally,finally 扫尾工作, 比如用来释放资源。且finally中的一些计算不会影响到主方法的调用。
throws–抛出异常
抛出异常
*运行时异常可以直接抛出,已检查异常必须要处理
*throws 声明在方法上, 等同于将异常交给方法调用者继续处理,上级调用者又需要继续处理这个异常,因此不是一劳永逸的,套娃
*主方法向外抛出异常, 是抛给JVM, JVM接收到异常会直接中断程序–建议主方法上的异常用try-catch()处理.
产生异常的情况:
代码有误, 执行会主动抛出异常
手动抛出异常对象
throw new 异常对象
// 手动抛出异常
public class Demo05 {
// 主方法向外抛出异常, 是抛给JVM, JVM接收到异常, 中断处理
public static void main(String[] args) throws ParseException {
// try {
// 会产生一个ParseException, 属于已检查异常, 必须处理
method1();
// } catch (ParseException e) {
// }
}
// method1方法声明了异常信息, 那么调用这个方法的时候就会可能产生一个声明的异常
// throws声明异常, 等同于将异常抛给调用者来处理
public static void method1() throws ParseException {
// 已检查异常 - 必须要处理
// 第一种处理方式: try-catch
try {
throw new IOException("IO异常是因为什么产生的");
} catch (IOException e) {
}
// 第二种处理方式: 在方法声明上添加 throws 声明
//所有的异常几乎用的都是它的有参构造器,()里输入一段自定义的字符串
throw new ParseException("这是格式错了", 0);
// 运行时异常,可以不处理
// throw new NullPointerException("对象是null");
// throw new RuntimeException("这个运行时异常是你代码哪里写错了");
}
结论
异常处理的原则:
自己能解决的, 就自己解决, try-catch
自己不能解决的, 再向外抛出, throws
自定义异常
自定义一个类,继承异常Exception
class MyException extends Exception: 已检查异常
class MyException extends RuntimeException: 运行时异常
只需要自动生成构造方法即可
// 自定义的已检查异常
public class MyException extends Exception {
// 只需要添加构造方法即可
public MyException() {
}
public MyException(String message) {
super(message);
}
public MyException(String message, Throwable cause) {
super(message, cause);
}
public MyException(Throwable cause) {
super(cause);
}
public MyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
----------------------------------------------------------------------------------------------------------
// 使用自定义异常
public class Demo06 {
public static void main(String[] args) {
// 模拟用户登录的过程
try {
login("lucy", "1234");
System.out.println("lucy欢迎你登录成功! - 页面跳转");
} catch (MyException e) {
System.out.println(e.getMessage());//获得异常信息
System.out.println("页面不跳转, 重新登录");
}
}
public static int login(String name, String password) throws MyException {
// 模拟登录业务逻辑处理
if ("lucy".equals(name) && "123".equals(password)) {
return 0;
} else {
// throw 抛出异常, 等同于return 方法结束
// 方法如果需要返回值, 相当于将异常返回
throw new MyException("用户名/密码错误");
}
}
}