文章目录
一、异常
1.什么是异常
就是因为程序在执行过程中,出现的废正常状态,会导致程序的提前结束
例如我们用程序进行一个除法运算,如果除数为0,那么程序就会报错,然后非正常终止。
**示例:**a/b的除法
public class Test {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
boolean flage = true;
while(flage){
System.out.println("请输入除数:");
int a = in.nextInt();
System.out.println("请输入除数");
int b = in.nextInt();
int c = 0;
c = a/b;
System.out.println("a除以b结果="+c);
System.out.println("y或Y继续,任意键结束");
String s = in.next();
flage = s.equals("Y") || s.equals("y");
}
}
}
从控制台输入12/0
发现程序报错,并且异常的终止了。这就是一个异常
在java语言中,异常是一个类,针对异常建立了一整个体系结构
2.异常的体系结构
Throwable
是所有Error(错误)和Exception(异常)的父类
1.Error错误
Error是程序无法处理的,例如OutOfMemoryErro(内存溢出)r,出现只能交给JVM去执行,且通常JVM都会选择杀死这个线程。
2.Exception
Exception是程序可以处理的异常,异常又分为
-
CheckedException
(受检查异常)和受检查异常发生在程序编译的过程中,且编译器会提示你这里有异常,需要用
try.....catch
捕获或throw
把异常抛出 -
UnCheckedException
(不受检查异常)受检查异常是指由于代码逻辑性的原因,使得在代码编译阶段不能检查出的异常。一般都会在程序运行时报出异常。
这种异常一般难以发现,需要对整个程序的逻辑足够清晰,或者通过异常信息的报错提示去寻找代码中的逻辑错误
3.处理异常
1.try…catch处理异常
捕捉异常并把异常进行处理,
try
与catch
成双成对存在,catch一定要跟在try后面使用,否则会报错。
使用案例:
public class Test {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
boolean flage = true;
while(flage){
System.out.println("请输入除数:");
int a = in.nextInt();
System.out.println("请输入除数");
int b = in.nextInt();
int c = 0;
try {
c = a/b;
} catch (Exception e) {
e.printStackTrace();
System.out.println("算术异常!!!!!!!!!!!!!!!!!");
}
System.out.println("a除以b结果="+c);
System.out.println("y或Y继续,任意键结束");
String s = in.next();
flage = s.equals("Y") || s.equals("y");
}
}
}
将可能会产生异常的部分用try包裹
当异常没有产生时,值执行try里面的语句
当产生异常时,停止try里面的语句执行,进入catch代码块
创建Exception 对象,并调用它的printStackTrace(),输出异常信息
如图所示,当程序没有异常时(即除数不为0的时候),正常执行try里面的语句,catch里面的不会被执行。当出现异常(除数为0时),进入catch输出异常信息
扩展:try-catch-finally
try-catch-finally中加了一个finally,是指无论try中有没有捕捉到异常,都会执行finally中的代码
通常用来释放内存资源,垃圾回收
代码示例:
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
boolean flage = true;
while(flage){
System.out.println("请输入除数:");
int a = in.nextInt();
System.out.println("请输入除数");
int b = in.nextInt();
int c = 0;
try {
c = a/b;
} catch (Exception e) {
e.printStackTrace();
System.out.println("算术异常!!!!!!!!!!!!!!!!!");
}finally {
System.out.println("谢谢使用");
}
System.out.println("a除以b结果="+c);
System.out.println("y或Y继续,任意键结束");
String s = in.next();
flage = s.equals("Y") || s.equals("y");
}
}
}
总结:
1.try…catch必须连起来用
2.捕捉到异常才进入到catch语句,没有异常则不进入
3.try后面可以跟多个catch语句,但记住前面的范围不能比后面的大
4.fianlly无论捕捉到异常没有都会执行
2.throw抛出异常
当遇到异常的时候,将异常信息封装为对象,并抛给调用它的方法,让调用它的方法去捕捉异常。在抛给方法的过程中需要用throws 后接java异常对象,来告诉这个方法抛给它的是什么类型的异常
案例:控制台输入三边,判断能否构成三角形
IllegalArgumentException(不合法的参数异常)
import java.util.Scanner;
public class Test2 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
boolean flage = true;
while(flage){
try {
isTriangle(in.nextInt(),in.nextInt(),in.nextInt());
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
System.out.println("y或Y继续,任意键结束!");
String s = in.next();
flage = s.equals("Y") || s.equals("y");
}
}
public static void isTriangle(int a , int b , int c) throws IllegalArgumentException{ //throws接收抛出异常的类型
if (a + b > c && a - b < c){
System.out.println("可以构成三角形");
}else
throw new IllegalArgumentException("不能构成三角形"); //将异常信息封装成对象抛出
}
}
代码运行结果:
注意:throws后面可以接多个异常类型,用逗号隔开
4.异常信息的分析
5.自定义异常类
当系统提供提供的异常信息不足以满足我们的异常需求时,我们可以自定义异常类
1.语法:
自定义异常类,语法和普通格式一样但一定要继承Exception或其子类,并习惯性的包装一下父类构造方法
2.用法
在发生异常的地方将其抛出,然后在通过try…catch将这个异常捕捉并抛出
3.代码
异常类
//自定义的三角形异常类
public class TriangleException extends Exception{
public TriangleException() {
super();
}
public TriangleException(String message) {
super(message);
}
public TriangleException(String message, Throwable cause) {
super(message, cause);
}
public TriangleException(Throwable cause) {
super(cause);
}
protected TriangleException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
测试类:
public class Test {
public static void main(String[] args) throws TriangleException {
Scanner in = new Scanner(System.in);
boolean flage = true;
while(flage){
try {
isTriangle(in.nextInt(),in.nextInt(),in.nextInt());
} catch (TriangleException e) {
e.printStackTrace();
}
System.out.println("y或Y继续,任意键结束!");
String s = in.next();
flage = s.equals("Y") || s.equals("y");
}
}
public static void isTriangle(int a , int b , int c) throws TriangleException{
if (a + b > c && a - b < c){
System.out.println("可以构成三角形");
}else
throw new TriangleException("不能构成三角形");
}
}
运行结果:
从下图可以看到,提示的异常类型变为了TringleException类型
6.常件的异常类
常件的一些异常类
NullPointerException: 空指针异常,当操作一个 null 对象的方法或属性时会抛出这个异常
String str = null;
sout(str.split(","));
ClassCastException:类转换异常,将一个不是该类的实例转换成这个类就会抛出这个异常。
Object x = new Integer(0);
Sout((String)x);
IndexOutOfBoundsException:数组下标越界异常
int arry[] = new int[]{1,2,3,4};
sout(arry[4]);
ArithmeticException:算术异常
sout(2/0);
SQLException:sql异常
NoSuchMethodException:没有这个方法异常,一般发生在反射调用方法的时候(大概率,可能版本更新,以前的方法被禁用)
ClassNotFoundException:在类路径下不能加载指定的类,类找不到异常(大概率版本问题)
FileNotFoundException:文件找不到异常
IOException:文件IO异常
UnsupportedClassVersionError:不支持的类版本错误
IllegalAccessException:违法的访问异常。当应用试图通过反射方式创建某个类的实例、访问该类属性、调用该类方法,而当时又无法访问类的、属性的、方法的或构造方法的定义时抛出该异常。