定义:
在程序正常运行的时候,发生不正常的事件;不正常事件会阻断程序的运行。
处理:
异常三种情况:
第一种情况:代码块1未产生异常,catch块不执行,执行catch块后的代码块3
try{
代码块1(未产生异常)
}catch(异常类型 异常类型对象 ){
代码块2
}
代码块3
第二种情况:代码块1产生异常,异常类型匹配,执行catch块及之后的代码块3
try{
代码块1(产生异常)
}catch(异常类型 异常类型对象 ){
代码块2
}
代码块3
第三种情况:代码块1产生异常,异常类型不匹配,终止整个程序的运行!
try{
代码块1(产生异常)
}catch(异常类型 异常类型对象 ){
代码块2
}
代码块3
异常类型:
try catch finally 的使用只有以下三种情况:
public class Test {
public static void main(String[] args) {
try {
} catch (Exception e) {
}
try {
} finally {
}
try {
} catch (Exception e) {
}finally {
}
}
}
验证结果:
System.exit(status); status有两种取值情况:
0的时候表示正常退出jvm,非0的时候表示非正常退出jvm。(结果都是一样的,从此处终止程序继续运行)
System.exit(status)不管status为何值都会退出程序。和return 相比有以下不同点: return是回到上一层,而System.exit(status)是回到最上层;
在一个if-else判断中,如果我们程序是按照我们预想的执行,到最后我们需要停止程序,那么我们使用System.exit(0),而System.exit(1)一般放在catch块中,当捕获到异常,需要停止程序,我们使用System.exit(1)。这个status=1是用来表示这个程序是非正常退出。
按照以下顺序执行return的前提——return有机会被执行且存在finally块!
try块中有return语句,与上图类似;
下图注意事项:父类只能放在最后(否则编译错误)
package org.gaofuzhi.test2;
public class Test {
public static void main(String[] args) {
try {
String str ;
str = null;
System.out.println(str.equals("test"));
System.out.println("我执行了");
}catch (ArithmeticException e) {
System.out.println("我执行了1");
}catch (NullPointerException e) {
System.out.println("我执行了2");
}catch (Exception e) {
System.out.println("我执行了3");
}
finally {
System.out.println("谢谢您的使用");
}
}
}
结果:
体系结构:
注意事项:
因为Exception为yChecked异常与Runtime异常的父类,jvm无法预料到异常是属于Checked异常或Runtime异常,所以要求必须处理(因为Checked异常在编译的时候即需要进行处理)。
声明异常:
使用关键字throws 声明某个方法可能出现的异常,如果有多个异常,用” ,“隔开即可。
通常定义方法时声明异常,而由调用者处理异常;如果调用者继续声明异常,最后(main方法声明的也一样)的异常由java虚拟机进行 ”处理“(实际上结果类似声明,约等于报错)。
RuntimeExeption异常无论定义方法中是否声明或处理(try-catch),调用方法中可处理可不处理;
Checked异常如果在定义方法时声明异常,则调用方法必须声明异常然后由java虚拟机进行处理(try-catch)或直接进行try-catch处理;
Checked异常如果在定义方法时处理异常(不推荐),则调用方法没有必要进行声明或处理(try-catch)。
抛出异常:
程序员自己设置抛出异常的条件(比如年龄大于150岁就抛出异常)!
如果抛出的异常为Checked类型异常,则必须进行声明或处理。eg:
throw new Exception (“年龄必须介于1~150岁之间”);//必须进行处理或声明(建议声明)
在调用方法中进行处理(建议)(catch中可使用e.getMessage();获取以上异常输出信息(“年龄必须介于1~150岁之间”))。
自定义异常类:
package exception;
/**
* @author gaofuzhi
*/
public class Person {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) throws AgeException {
if(age<0||age>150){
throw new AgeException("年龄介于1~150岁之间");
}
this.age = age;
}
}
package exception;
/**
* 自定义异常类
* @author gaofuzhi
*/
public class AgeException extends Exception{
private static final long serialVersionUID = 1L;
public AgeException() {
super();
}
public AgeException(String message) {
super(message);
}
}
package exception;
/**
* 年龄测试类
* @author gaofuzhi
*/
public class AgeExceptionTest {
public static void main(String[] args) {
Person lily = new Person();
try {
lily.setAge(190);
System.out.println(lily.getAge());
} catch (AgeException e) {
e.printStackTrace();
}
}
}
异常链:
将两个或多个异常类的异常信息像链一样传递下去!
package exception;
/**
* 自定义异常类1
* @author gaofuzhi
*/
public class MyException1 extends Exception{
private static final long serialVersionUID = 1L;
public MyException1() {
super();
}
public MyException1(String message) {
super(message);
}
}
package exception;
/**
* 自定义异常类2
* @author gaofuzhi
*/
public class MyException2 extends Exception{
private static final long serialVersionUID = 1L;
public MyException2() {
super();
}
public MyException2(String message) {
super(message);
}
public MyException2(String message, Throwable cause) {
super(message,cause);
}
}
package exception;
/**
* 年龄测试类
* @author gaofuzhi
*/
public class MyExceptionTest {
public static void main(String[] args) {
MyExceptionTest e = new MyExceptionTest();
try {
e.A();
} catch (MyException2 e2) {
e2.printStackTrace();
}
}
public void A() throws MyException2{
try {
B();
} catch (MyException1 e1) {
//这里将MyException1的对象通过有参构造方法传递给MyException2
//像链一样将二者联系了起来——称之为异常链
throw new MyException2("我是异常类2的异常信息",e1);
}
}
public void B() throws MyException1{
throw new MyException1("我是异常类1的异常信息");
}
}