`

异常与异常类

    博客分类:
  • j2se
 
阅读更多
第一.异常的概念:异常就是程序在运行中的错误,程序中的异常用异常类来描述。

第二:对异常的认识
1.异常是运行时错误,编译时错误不是异常
2.java中对异常的处理是用类来描述的,这种类称为异常类,描述程序运行时候的错误。
3.自定义异常:例如我定义一个类来描述异常WaterException(水灾类)
4.异常类能够继承父类:Throwable(异常类的父类)
5.Throwable的直接子类 是Error和Exception,所以Throwable是所有异常类的父类。而Throwable的父类是Object.
Error:程序没法处理的异常(也就是程序员无法控制的异常),例如程序运行时候电脑没电了,或者内存溢出(原因是自己电脑内存太小),也就是说程序运行的环境出问题了
Exception:程序能够合理的进行捕获的异常。
6.Exception又包含两种情况:运行时异常   和  检查异常(预防)
1).运行时异常:包含RuntimeException和他的子类,出现RuntimeException类型错误,可以修改程序中的代码,也可以处理,(方法一修改程序,方法二处理,两种方法选择其一)
2).检查异常:除了运行时异常之外的异常都是检查异常。如果产生了异常,必须处理,因此程序会有错误提示。处理有两种方式,一个是trycatch结构,一个是throws
异常有不确定性,异常我们对异常的处理也都是预防(如果发生了我们就怎么怎么办)
3).为什么检查异常必须处理呢?因为检查异常是系统定义好的,因此如果不处理他会显示出错误的虚线,当鼠标放在错误虚线上他就会出现处理方法
7.
1).java默认处理异常的方式:
jvm打印错误信息,程序中断(出现异常的时候,jvm自动产生一个该异常对应的异常类的对象,jvm捕获了这个异常,输出错误信息,程序中断)
2).自己处理异常(运行时异常):try catch:试图捕获异常,(这是预防性的),try里面的代码如果出现异常,这段代码会产生一个异常对象,这个异常对象在catch中匹配
3).自己处理异常(检查异常):检查异常必须处理,(看异常类是什么类型的,如果不是运行时异常就必须处理),检查异常两种处理方式:try catch和throws

第三:异常的代码分析:
1.异常的出现:此时产生异常类的对象并被jvm捕获,程序中断。
public class demo {
    public static void main(String[] args) {
Scanner input = new Scanner(System.in);//1,创建对象
System.out.println("请输入一个整数:");
//2.接收键盘输入的值,当输入的不是整数的时候,就会产生输入不匹配异常。遇到异常程序将会中断。这种中断是程序的默认处理方法,由java虚拟机jvm来处理
//java虚拟机怎么知道有异常?答:当程序执行中发生异常,将会产生异常对应的描述的类的对象,该对象会被虚拟机捕获掉,被虚拟机捕获后程序就中断了。因此需要程序员来捕获,不能让虚拟机来捕获
int x=input.nextInt();
System.out.println("x="+x);
}
}

2.分析try catch结构:是试图捕获的意思。
public class demo1 {
public static void main(String[] args) {
try{
Scanner input = new Scanner(System.in);
System.out.println("请输入一个整数:");
int x=input.nextInt();//当这里输入的不是整数的时候,会被catch捕获,去执行catch了。因此不会再执行try里面的内容了
System.out.println("x="+x);//这句话不会输出
System.out.println("哈哈哈哈哈哈");//这句话也不会输出
}catch(Exception ex){//Exception是个类,ex就是具体的对象,ex输出的结果就是类名:java.util.InputMismatchException
System.out.println(ex instanceof InputMismatchException);//返回ture。这里是父类引用子类的对象
System.out.println("发生类型不匹配异常"+ex);
}
   System.out.println("发生异常了");//这句话会被输出,这样保证了程序不会被中断、也就是说异常被处理之后程序就会继续执行
}

}

3.多重catch与finally
//多重catch
public static void main(String[] args) {
try{
Scanner input=new Scanner(System.in);
System.out.println("请输入第一个整数:");
int x=input.nextInt();
System.out.println("请输入第二个整数:");
int y=input.nextInt();
int z=x/y;//除0异常
System.out.println("z"+z);


int[] arr=new int[3];
System.out.println(arr[3]);//数组下标越界了


}catch(InputMismatchException ex){
System.out.println("发送类型不匹配异常,必须输入整数");
}catch(ArithmeticException ex){
System.out.println("除数不能为0异常");
}catch(Exception ex){//在此程序中,他将捕获ArrayIndexOutOfBoundsException异常,数组下标越界异常
//ex.printStackTrace();//打印异常信息,其实跟+ex差不多
System.out.println("如果有上面异常类不能捕获到的异常,我来进行捕获"+ex);
}finally{//有没有异常都会被执行。这个finally经常做的事情是资源的释放,例如关闭数据库连接等
System.out.println("这里的内容是最终都会被执行到的内容,不管是不是有异常都会执行到这个");
}
  
}


4.运行时异常:
//1.检查异常,必须要被处理(抛出或者捕获)。检查异常是系统定义好的,因此如果不处理他会显示出错误的虚线,当鼠标放在错误虚线上他就会出现处理方法(try或throws)。
//2.能出现红线和出现错误的处理方式的原因是系统已经把哪些东西是检查异常提前定义好了。
//throws:声明异常:告诉方法的调用者,该方法可能发生的异常。
//throw:抛出异常

public static void main(String[] args) {
/* try {
Class.forName("");//找不到这个类异常。检查异常必须要处理
} catch (ClassNotFoundException e) {
e.printStackTrace();
}*/
 
   //第一种情况:对运行时异常不捕获的情况
    div(10,0);//调用者没有对异常进行处理,因为div声明的异常是个运行时异常,程序员可以处理也可以不处理,程序员不处理的时候就会走系统默认的处理方式,也就是程序中断。
  
    //第二种情况:对运行时异常捕获的情况
    try{
    div(10,0);
    }catch(Exception ex){//这里这个异常对象就是下面的new ArithmeticException。因此这里输出传入实参有误java.lang.ArithmeticException: 你数学有问题
    System.out.println("传入实参有误"+ex);
    }
   }
   //throws声明该方法可能会发生ArithmeticException异常。会把异常给调用者,让调用者来处理
   public static void div(int x,int y) throws ArithmeticException{
if(y==0){//加了判断如果有错误提前进入异常
   //创建可能产生的异常对象。如果发生异常,本来是在int z=x/y的时候产生异常,现在我提前抛出异常。程序从这一行将会中断。
throw new ArithmeticException("你数学有问题");//这里输出:java.lang.ArithmeticException: 你数学有问题
}
   int z=x/y;
   System.out.println(z);
}


5.检查异常:调用者必须处理
public static void main(String[] args) {
//main方法调用了div方法,因此main方法需要对div的异常进行处理,处理方式有两种,一个是捕获异常trycatch,另一个是继续向上抛出异常throws
          try {
div(10,0);
} catch (Exception e) {
e.printStackTrace();
System.out.println("分母不能为0"+e);
}
}

//这个方法使用了throws对可能发生的异常进行了声明,但是声明的异常类是个Exception类型的,他是所有异常的父类,也就是说他包括检查异常和运行时异常

       //既然包含检查时异常,就要对异常进行捕获,因此需要调用者进行捕获,否则程序将会报错
public static void div(int x,int y) throws Exception{
  int z=x/y;
  System.out.println(z);
}

6.自定义异常:我自己创建了一个洪灾异常

public class WaterException extends Exception{
private int grade=0;//洪灾等级
     public WaterException(){//无参构造
     super("水漫金山....");//异常的具体描述
     this.grade=5;
     }
public WaterException(String msg,int grade){//构造函数
super(msg);//调用的是父类的方法
this.grade=grade;
}
  
    //重写父类的方法
    public void printStackTrace(){
    if(grade==5){
   
    //ex有两个方法:
    //super.getMessage();//得到的是汉字
    //super.getStackTrace();//打印的不是汉字
    System.out.println("WaterException"+super.getMessage());
    }else if(grade==10){
    ......
    }
    }
}

第四:常见的异常类:

ClassCastException:类型转换异常(在多肽的时候经常有类型转换)
InputMismatchException:输入不匹配异常(输入类型不匹配)
ArithmeticException:算数异常(比如说除数不能为0)
ArrayIndexOutOfBoundsException:数组下标越界异常

第五:总结
1.用try-catch直接去“处理”(捕获)异常
2,但是如果我不想去处理(捕获),那我就在我的方法名后面声明这个异常,具体怎么办交给调用者
3,调用者如果调用一个方法(这个方法含有运行时异常),如果这个被调用者声明的是一个运行时异常,调用者可以不“处理”该方法
4.如果调用者调用的一个方法(这个方法是检查异常),如果这个被调用者声明了一个检查异常,那么调用者必须对对该方法进行“处理”,(因为如果不处理,这里会报着错)
“处理”方式有两种,一个是继续抛异常,另一个是用try-catch语句去捕获这个可能出现的异常
5.对于程序员知道可能会发生异常的时候,用throw去抛出异常,抛出之后有具体的异常解释(如果不自己抛出,java虚拟机会给你抛出,但这种抛出不友好,一般人看不懂)。用throw抛出异常之后程序会中断


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics