异常
目录
运行时,由于各种原因导致的不能正常运行,使用java语言异常处理机制,控制的,后面代码可以正常运行的
广义 所有的异常
侠义 运行时异常,可以处理的
异常可分类:
根据在程序中执行所发正的异常可分类
- Eroor:针对虚拟机无法解决的严重问题 jvm系统内部错误,资源耗尽,不能针对代码进行处理
- Exception 编程错误或偶然的错误, 空指针,下标越界,读取不存在文件,
网络中断使用java语言异常处理机制,控制的,后面代码可以正常运行的
处理方式:
针对异常,一般两种解决方式:
- 终止程序,
- 在感受到异常的时候,就应该检测到异常,异常提示等处理
异常处理
- jvm默认异常处理方式:在控制台抛出对应类型的异常类对象(异常信息),
终止JVM运行 - 也可以使用异常处理机制来处理
捕获异常最理想的是在编译期间,有的在运行时才能得到
- 编译时异常
- 运行时异常
常见的异常
- 数组索引越界异常
ArrayIndexOutOfBoundsException
- 类型转换异常
ClassCastException
- 算术异常
ArithmeticException
- 数字格式化转换异常
NumberFormatException
- 控制指针已成. 空指针异常
NullPointerException
案例
数组索引越界异常ArrayIndexOutOfBoundsException
//用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引。
//ArrayIndexOutOfBoundsException
//.数组索引越界异常
int[] a = new int[5];
a[5] = 1;
类型转换异常ClassCastException
//当试图将对象强制转换为不是实例的子类时,抛出该异常。例如,以下代码将生成一个
// ClassCastException:
//类转换异常
Object x = new Integer(0);
System.out.println((String)x);
String s="saad";
Object obj=s;
Integer j= (Integer) obj;
算术异常ArithmeticException
//算术异常
//当出现异常的运算条件时,抛出此异常
//ArithmeticException
int a=10;
int b=0;
System.out.println(a/0);
数字格式化转换异常NumberFormatException
//数字格式化异常
//NumberFormatException
//当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
int i = Integer.parseInt("afasf");
控制指针已成. 空指针异常NullPointerException
//控制指针异常
//NullPointerException
//当应用程序试图在需要对象的地方使用 null 时,抛出该异常
String s=null;
s.length();
异常体系结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-89BObJH3-1605508981793)(2222.png)]
try-catch
-
try-执行可能产生 异常的代码
-
catch-捕获异常
try{
//可能出现异常的类型
//尽可能最少
}catch (异常类型){
//当try出现异常,执行catch
}
int a = 10;
int b = 0;
try {
System.out.println(a / 0);
} catch (ArithmeticException e) {
System.out.println("算数异常:除数不饿能为零");
}
//输出:算数异常:除数不饿能为零
try catch 嵌套
注意:有异常 下面的try 跳过 直接运行 对应的catch
try {
System.out.println(a / 0);//有异常 下面的try 跳过 直接运行 对应的catch
try {
String s = null;//有异常
s.length();
} catch (NullPointerException n) {
System.out.println("空");
}
} catch (ArithmeticException e) {
System.out.println("算数异常:除数不饿能为零");
}
//输出:算数异常:除数不饿能为零
一个try可以对应及格catch
有多个异常 下面的try 跳过下面 直接到对应的 直接运行 对应的catch
try {
System.out.println(a / 0);//有多个异常 下面的try 跳过下面 直接到对应的 直接运行 对应的catch
System.out.println("111111");
String s = null;
s.length();
System.out.println("222222");
} catch (ArithmeticException e) {
System.out.println("算数异常:除数不饿能为零");
} catch (NullPointerException n) {
System.out.println("空指针异常");
}
catch (类型 a)
- 编程人员知道具体错误时候用
catch (NullPointerException n)
- 不知道具体错误可用具体错误的父类
Exception
即catch (Exception e)
catch中没有对应的异常类型
catch中没try()有对应的异常类型.jvm也会停止,直接停止运行 进行提示报错
try {
System.out.println(a / 2);//有多个异常 下面的try 跳过下面 直接到对应的 直接运行 对应的catch
Integer.parseInt("frf");//catch中没有对应的异常类型.jvm也会停止 进行提示报错
} catch (ArithmeticException e) {
System.out.println("算数异常:除数不饿能为零");
} catch (NullPointerException n) {
System.out.println("空指针异常");
}
System.out.println("aaaaa");
输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AlrbHp8M-1605508981797)(image-20201114145313641.png)]
getMessage()parintStackTrace
- getMessage() 获取异常信息,返回字符串
- parintStackTrace 获取异常类名和异常信息,以及异常出现在程序中的位置.返回值未void
catch (Exception e) {
System.out.println("系统繁忙");//给用户提示
System.out.println(e.getMessage());//程序人员自己看 后期可使用第三方日志组件,向文件中输出信息
e.printStackTrace();//打印异常信息到控制台
}
- 当有catch 有 return时候 执行catch中的reatch 以及finally最终执行
- 当finally有return,后面全不执行
- 当有异常时 返回值 异常的return ; 和finally的return; 均会执行 但是执行的结果值执行 finally return
public static int test1() {
int a = 10;
int b = 0;
int c = 1;
/*
一个try 对应多个catch
*/
try {
System.out.println(a / 0);
} catch (ArithmeticException e) {
System.out.println("算数异常:除数不饿能为零");
return ++c;
} finally {
System.out.println("222222");
return ++c; //当finally有return,后面全不执行
//当有异常时 返回值 异常的return ; 和finally的return; 均会执行 但是执行的结果值执行 finally return
}
// System.out.println("333333");
// return 2;
}
输出:
算数异常:除数不饿能为零
222222
3
throws
- throws声明此方法可能会出现算数异常, 声明的如果是运行时异常,调用时可以不处理,而交给方法调用处进行处理。
public void test throws 异常1,异常2,异常3{
}
-
任何方法都可以使用throws关键字声明异常类型,包括抽象方法。
-
子类重写父类中的方法,子类方法不能声明抛出比父类类型更大的异常。
-
使用了throws的方法,调用时必须处理声明的异常,要么使用try-catch,要么继续使用throws声明。
案例1
package com.nie.day1;
import java.text.ParseException;
public class Demo08 {
public static void main(String[] args) {
// chu(2, 0);
try {
chu(2, 0);
} catch (ArithmeticException a) {
System.out.println("算数异常");
}
System.out.println("主线程后面的代码,可以继续执行");
try {
test();//在此处的调用处,就需要try catch 处理
} catch (ParseException e) {
e.printStackTrace();
System.out.println("系统忙");
}
}
/**
* 除法运算 throws声明此方法可能会出现算数异常
* 声明如果是运行时异常,调用时可以不处理
*
* @param a
* @param b
* @return
* @throws ArithmeticException
*/
public static int chu(int a, int b) throws ArithmeticException {
return a / b;
}
public static void test() throws ParseException {//编译器异常
test1();//调用,不处理 用throws ParseException 继续抛出
}
public static void test1() throws ParseException, UnknownError {
System.out.println("test2");
}
}
子类重写父类中的方法,子类方法不能声明抛出比父类类型更大的异常
public abstract class Demo09 {
public abstract void test1() throws ParseException;
public abstract void test2() throws ArithmeticException;
}
package com.nie.day1;
import java.text.ParseException;
public class Demo09Child extends Demo09 {
//子类重写父类中的方法,子类方法不能声明抛出比父类类型更大的异常
@Override
public void test1() throws ParseException {
}
@Override
public void test2() throws ArithmeticException {
}
}
throw
- throw关键字用于显示抛出异常,抛出的时候是抛出的是一个异常类的实力化对象
- 在异常处理中,try语句要捕获的是一个异常对象,那么此异常对象也可以自己抛出
public static void someMethod() {
if (1==1) {
throw new RuntimeException("错误原因");
}
}
使用
throw用于方法体中,用来抛出一个实际的异常对象,使用throw后要么使用try catch捕获异常,要么使用throws声明异常
package com.nie.day1;
public class Demo11 {
/*
throw用于方法体中,用来抛出一个实际的异常对象,使用throw后
要么使用try catch捕获异常,要么使用throws声明异常
*/
public static void main(String[] args) {
try {
c(1111);
} catch (RuntimeException r) {
System.out.println(r.getMessage());
}
}
public static int c(int a) throws RuntimeException {
if (a >= 10) {
throw new RuntimeException("不及格");
}
return a;
}
}
自定义异常
自定义异常就是自己定义的异常类,也就是API中标准异常类的直接或者间接的子类
作用:用自定义的异常标记业务逻辑的异常,避免与标准混淆
使用
-
基本语法
public class 异常类名 extends Exception/RuntimeException{ public 异常类名(String msg){ super(msg); } }
-
自定义异常类中往往不写其他方法,只重载需要使用的构造方法
-
继承Exception,在方法中使用throw抛出后,必须在方法中try-catch或throws抛出
package com.nie.day1;
public class Demo10 {
public static void main(String[] args) {
try {
c(1111) ;
} catch (ScoreException e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
System.out.println("----");
}
public static int c(int a) throws ScoreException{
if (a>=10){
throw new ScoreException("不及格");
}
return a;
}
}
当分数不满足条件时,抛出此对象
public class ScoreException extends Exception {
public ScoreException() {
super();
}
public ScoreException(String message) {
super(message);
}
}
总结
throws
- 作为子啊方法的声明,此方法可能会出现异常,
- throws后面声明多个异常类型,多为编译期异常
throw
- 在方法体中主动抛出异常对象,想当于程序出现异常的情况,后面的程序不执行
- 在不满足条件的情况下以抛出异常的形式告诉调用处
自定义异常
- 由于java中封装的异常类都是与语法相关的
- 在我们业务中出现一些不满足条件的情况时,也可以自定义异常类,来表示某种情况