异常
1、Throwable:可抛出的,是异常的顶层父类,其他的异常或者错误都是Throwable的子类类型,只有是Throwable的体系类型,才可以使用异常的处理机制
2、Error:错误,是Throwable的子类,用于描述那些无法捕获和处理的错误情况,属于非常严重的错误 StackOverflowError
3、Exception:异常,是Throwable的子类,用于描述那些可以捕获和处理的不正常情况,属于不太严重的错误
NullPointerException
4、RuntimeException:运行时异常,是Exception的一个特殊的子类,在编译阶段是不做检查的一个异常
5、体系图:
Throwable
Error
Exception
RuntimeException
jvm中默认处理异常的机制
1、在代码的某个位置,出现了和正常情况不一致的时候,就会将异常情况封装到异常对象中
2、将异常对象向上抛,抛给调用该方法的方法
3、某个方法接收到底层方法抛上来的异常的时候,也没有办法处理,继续向上抛,最终抛给主方法,主方法也没有办法处理,抛给调用自己的虚拟机,
4、jvm虚拟机也处理不了,只能将异常对象通过错误流,打印出来,结束虚拟机
5、jvm默认处理异常的方式:一层一层向上抛,jvm处理不了,就结束程序
手动处理异常的方式
1、两类
异常的声明:针对的是编译时异常,编译时异常而言,编译阶段不处理异常,编译无法通过,需要在异常所在的方法声明 上,声明该方法可能出现的编译时异常
异常的处理:对于可能出现的异常,或者编译时异常,可以通过某种格式进行捕获和处理,可以让程序在出现异常之后,继续正常的运行,可以定义自己处理异常的逻辑
2、异常捕获的格式
try…catch
try…catch…finally
try…finally(无法捕获异常)
try…catch语句
1、格式
try{
可能出现异常的代码
} catch(可能出现异常的类型 标识符){
针对该异常的处理方式
}
2、运行机制:
(1)运行try中的代码
(2)如果没有发生异常,不会运行catch中的语句
(3)如果发生了catch中声明的异常那么就会捕获这个异常,执行catch语句块中的内容(如果try中的某一行的代码 如果出现异常那么在try语句块中该代码后面的内容都执行不了)
(4)如果在catch中没有捕获到声明的异常,那么就无法捕获异常,该异常的处理就会使用jvm默认的处理机制
try…catch…catch…语句
格式:
try{
可能出现异常的代码
} catch(可能出现异常的类型1 标识符){
针对该异常的处理方式1
} catch(可能出现异常的类型2 标识符){
针对该异常的处理方式2
} catch(可能出现异常的类型3 标识符){
针对该异常的处理方式4
}…
try…catch…finally
格式:
try{
可能出现异常的代码
} catch(可能出现异常的类型 标识符){
针对该异常的处理方式
} finally{
一定要执行的代码;
}
try …finally
1、格式:
try{
可能发生异常的代码
} finally{
一定要执行的代码
}
2、作用:
(1) 无法捕获和处理异常,一旦发生异常就会按照jvm默认的处理方式一层一层向上抛,到jvm,处理不了就结束程序
(2)无论try中的代码是否发生异常,finally的代码都是有一定的执行的机会
(3)如果有两句代码,都需要有执行的机会,不希望第一句代码的执行成功,是否影响到第二句代码的执行,那么就将这两句代码分别放到try。。。finally语句中
编译时异常和运行时异常
1、编译时异常:代码在编译阶段进行检测的异常,一旦代码中出现了编译时异常,那么在编译阶段是不给通过的,只能通过异常处理的手段进行处理(异常的捕获和处理,异常的声明(throws))
2、运行时异常:运行时异常在编译阶段是不做检查的,在编译阶段即使有了运行时异常,也不会编译失败,相当于在编译阶段是没有异常的,可以通过异常处理的手段进行处理,运行时异常进行异常声明是没有意义的,没有这个必要
3、继承体系:
编译时异常就是Exception和Exception的子类类型(除了RuntimeException)
运行时异常就是RuntimeException和RuntimeException的子类类型
常用方法
1、发现在异常的体系中,所有的方法定义在父类Throwable 顶层父类中,子类中几乎没有什么特有的方法。
2、Throwable中的构造方法
Throwable():创建一个没有任何参数的异常对象
Throwable (String mes) 创建一个带有指定消息的异常对象
Throwable(Throwable cause) 创建一个有原因异常的异常对象
3、常用成员方法
getCause() 获取异常对象中的原因异常
getMessage() 获取异常详细消息字符串
toString() 返回此 throwable 的简短描述
printStackTrace() 打印异常的调用栈轨迹
package com.DaYu;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Demo04 {
public static void main(String[] args) {
Throwable th = new Throwable();
System.out.println(th);//java.lang.Throwable
Throwable th1 = new Throwable("你输入年龄不合法");
System.out.println(th1);//java.lang.Throwable: 你输入年龄不合法
Throwable th2 = new Throwable(th1);
System.out.println(th2);//java.lang.Throwable: java.lang.Throwable: 你输入年龄不合法
// 常用的成员方法
System.out.println(th1.getMessage());//你输入年龄不合法
System.out.println(th2.getCause());//java.lang.Throwable: 你输入年龄不合法
System.out.println(th1.toString());//java.lang.Throwable: 你输入年龄不合法
}
}
throw和throws
1、throw是用来抛出异常对象的,throws是对异常的声明
2、throw是实实在在抛出了一个异常对象,一旦使用了throw关键字,就一定有一个异常对象的抛出:throws是对可能出现的异常进行异常类型的声明,在方法中,可能出现这个异常,也可能不出现,只是提醒一下或者告诉调用者,这个方法可能会出现异常,要小心使用
3、throw后面只能跟的是一个异常对象,throws可能跟多个异常类型
4、说明:
如果抛出的是运行时异常,在编译阶段相当于没有异常,可以不处理这个异常
如果抛出的是编译时异常,在编译阶段就会报错,必须进行处理,可以进行异常的声明也可以进行异常的捕获或者处理。 才能编译成功。
自定义异常
自定义异常的步骤:
(1)定义一个类,以Exception结尾,什么样的异常尽量起一个英文名字,例如:IllegalAgeException
(2)让定义的这个类继承一个Exception或者RuntimeException
如果定义的是编译时异常就继承Exception
如果定义的是运行时异常就继承RuntimeException
(3)构造方法不能被继承,需要进行手动的添加,调用父类中的构造
//测试类
package com.DaYu;
public class Deam05 {
public static void main(String[] args) {
Person p = new Person();
try {
p.setAge(3);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
p.setName("DAVA");
int age = p.getAge();
String name = p.getName();
System.out.println(name + " " + age);
}
}
//实体类
package com.DaYu;
public class Person {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
if(name.length() < 1 || name.length() > 4) {
throw new IllegalNameException("名字不合法");
}else {
this.name = name;
}
}
public int getAge() {
return age;
}
public void setAge(int age) throws Exception {
if(age < 0 || age > 120) {
throw new IllegalAgeException("非法年齡");
}else {
this.age = age;
}
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
//自定义异常IllegalAgeException
package com.DaYu;
public class IllegalAgeException extends Exception {
public IllegalAgeException() {
super();
// TODO Auto-generated constructor stub
}
public IllegalAgeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public IllegalAgeException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public IllegalAgeException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public IllegalAgeException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}
//自定义异常IllegalNameException
package com.DaYu;
public class IllegalNameException extends RuntimeException {
public IllegalNameException() {
super();
// TODO Auto-generated constructor stub
}
public IllegalNameException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public IllegalNameException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public IllegalNameException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public IllegalNameException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}