一、概念:
异常是程序在运行时出现的不正常情况
异常的由来:问题也是现实生活中的一个具体事物,也可以通过java类的形式进行描述。并封装成对象。其实java对不正常情况进行描述后的对象体现。
异常的体系
Throwable
|--Error:通常出现重大问题如:运行的类不存在或者内存溢出等。不编写针对代码对其处理
|--Exception :在运行时运行出现的一起情况,可以通过try catch finally
Throwable中的方法
getMessage()
获取异常信息,返回字符串。
toString()
获取异常类名和异常信息,返回字符串。
printStackTrace()
获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
printStackTrace(PrintStream s)
通常用该方法将异常内容保存在日志文件中,以便查阅
二、异常的处理格式
try
{
需要检测的代码;
}
catch(异常类 变量)
{
异常处理代码;
}
finally
{
一定会执行的代码;(Finally代码块只有一种情况不会被执行。就是在之前执行了System.exit(0)。)
}
try:一般会将可能引起异常的代码写入try代码块中,try代码块中的代码可以是一行或者多行。你可以将每行异常代码写入一个try代 码块中,然后分别用catch代码块对其捕获处理。也可以将整个可能引起异常的代码写入try代码块中并对其进行捕获。
catch:try代码块之后直接跟着一个或者多个catch代码块,对异常进行捕获和处理。catch代码块中的参数必须声明异常的类型,并且最好使用从throwable类中继承的异常类型名称,以便catch更好的对异常进行捕获和处理。在try代码块和catch代码块之间不允许有任何代码。你可以在catch代码块中打印这个异常的信息,也可以什么都不做。
finally: 如果try代码块存在,finally代码块是必须被执行的。即使无法预知的异常发生,finally里的代码也是会被执行的。finally的存在可以避免编程人员在之前代码中写入break,return,continue而引起的错误。即使没有任何异常发生,finally的存在对于程序正常运行也是非常有用的。
代码示例
class Demo {
void div(int x, int y) throws ArithmeticException,ArrayIndexOutOfBoundsException {
int arr[] = new int[x];
System.out.println(arr[4]);
System.out.println(x / y);
}
}
public class ExceptionDemo {
public static void main(String[] args) {
Demo d = new Demo();
try {
d.div(4, 0);
} catch (ArithmeticException e) {
System.out.println("被〇除了");
}catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数组越界了");
}
System.out.println("over");
}
}
throw 和throws的区别
1、throws使用在函数上,throw使用在函数内
2、throws后面跟的是函数类,后面可以跟多个,用逗号隔开
throw后面跟的是异常对象
3、Exception中有一个特殊的异常RuntimeException
如果在函数内抛出异常,函数上可以不用声明 如果在函数上声明了该异常 调用者可以不用处理
三、自定义异常:
步骤:1、自定义类继承Exception或者其子类。
2、通过构造函数定义异常信息。
3、通过throw将自定义异常抛出。
代码示例
class FushuException extends Exception{注意:
private int value;
FushuException(String msg,int value){
super(msg);
this.value=value;
}
public int getValue(){
return value;
}
}
class DivDemo {
int div(int x, int y) throws FushuException{
if(y<0){
throw new FushuException("除数出现了负数",y);
}
return x/y;
}
}
public class ExceptionDemo2 {
public static void main(String[] args) {
DivDemo d=new DivDemo();
try {
d.div(4, -1);
} catch (FushuException e) {
System.out.println(e.getMessage());
System.out.println("负数是:"+e.getValue());
}
}
}
对于异常分两种:
1、编译时被检测的异常
2、编译时不被检测的异常 就是RuntimeException及其子类
覆盖时候的异常:
1、子类覆盖父类时,如果父类的方法抛出异常、那么子类的覆盖方法只能抛出父类的异常或者该异常的子类
2、如果父类抛出多个异常,那么重写(覆盖)方法必须抛出那些异常的一个子集,不能抛出新的异常