FiveteenDay_java 异常

1、异常结构

  • 异常是以类和对象的形式存在的

  • 在java.lang包下

  • Throwable(可抛出的) 分为两个分支:error(不可处理的,一旦发生直接退出jvm),Exception(可处理的)

  • Exception分为两个分支:编译时异常(Exception的直接子类),RuntimeException(运行时异常)

  • 编译时异常:是在编写程序时对所出现的异常进行预处理,如果不处理编译器就会报错。又叫做 受检异常,受控异常(CheckException)

  • 运行异常:可以预先处理,也可以不管。又叫做 未受检异常 非受控异常(unCheckException)

  • 编译时异常与运行时异常都是在运行时发生的,编译阶段异常是不会发生的 两者区别编译时异常发生概率较高,运行异常发生概率较低

  • 异常处理方式 1、在方法声明的位置上,使用throws关键字,抛给上一级 2、使用try...catch语句进行异常捕捉。

     

public static void main(String[] args) {
  int a=10;
  int b=0;
  int c=a/b;//在这里发现b为0,jvm会new一个ArithmeticException异常对象:
  // new ArithmeticException("/ by zero");然后抛出异常,打印输出。
  System.out.println(c);

2、运行时异常举例

public static void main(String[] args) {
  /*
  此程序未输出“执行成功”,原因是程序在此处发生了
  ArithmeticException异常,底层new了一个ArithmeticException对象
  然后抛出了,由于是main方法调用了10/0所以这个异常对象抛给了main方法
  main方法没有处理,将这个异常自动抛给了JVM,JVM最终终止程序的执行。

  在此处编写时未出现提示,原因是ArithmeticException extends RuntimeException
  此异常是运行时异常。不需要预先处理。
    */
  System.out.println(10/0);
  System.out.println("执行成功!");
}

3、编译时异常

public static void main(String[] args) {
  /*
  调用dosome的时候会出现报错,原因是
  dosome方法抛出了类没找到异常,此异常是编译时异常,main在调用的时候
  需要对dosome可能抛出的异常做预处理,如果不做 编译过不去
  编译报错:Unhandled exception: java.lang.ClassNotFoundException
  未处理的异常...
    */
  //dosome();
}
/*
写一个方法dosome抛出ClassNotFoundExceptiony异常(类没找到异常)
因为ClassNotFoundException父类继承Exception 故是编译时异常
*/
public static void dosome() throws ClassNotFoundException{
  System.out.println("dosome!");
}

4、异常处理方式

//第一种处理方式:继续上抛 main方法上抛给JVM
/*public static void main(String[] args) throws ClassNotFoundException {
  dosome();
}
*/
//第二种处理方式:try...catch...捕捉异常
public static void main(String[] args){
  try {
      dosome();
  } catch (ClassNotFoundException e) {
      e.printStackTrace();
  }
}
public static void dosome() throws ClassNotFoundException{
  System.out.println("dosome!!");
}

5、捕捉异常与抛出异常合用

public static void main(String[] args) {
  /*
  在main方法中最好使用try...catch..捕捉异常。原因 我们的目的是解决异常而不是中断程序
  若使用throws 抛出异常,main方法把异常抛给JVM,JVM会中断程序的执行。
  try{
      //方法体
  }catch(捕捉的异常 异常变量名){
      //处理方法
  }
    */
  try {
      m1();
      System.out.println("这一行如果m1不出错就执行,否则不执行");
  } catch (FileNotFoundException e) {
      e.printStackTrace();
  }
  System.out.println("这一行在捕捉异常后 继续执行");
}
public static void m1() throws FileNotFoundException {
  /*
  m2抛出FileNotFoundException异常,编译时异常 可采用throws异常来解决
  可写 throws FileNotFoundException 或 throws IOException 或
  throws Exception 或者捕捉异常try...catch...。
    */
  m2();
}

private static void m2() throws FileNotFoundException {
  /*
  m3抛出FileNotFoundException异常,编译时异常 可采用throws异常或者捕捉异常来解决
    */
  m3();
}

private static void m3() throws FileNotFoundException {
  /*
  FileInputStream对象在源代码里抛出了throws FileNotFoundException异常
  FileNotFoundException继承IOException,IOException有又继承了Exception
  故它是编译时异常,m3在调用FileInputStream("")方法时,需要对它抛出的FileNotFoundException
  异常进行预处理操作,操作方式有上抛与捕捉异常两种
    */
  new FileInputStream("");
  System.out.println("上面代码出现异常,此行不执行!");
}

6、try...catch...

  • catch后面的括号里可以写精确的异常,也可以写此异常的父类异常

  • catch可以写多个。catch写多个的时候,必须从上到下,从小到大的原则。

public static void main(String[] args) {
  try {
      //创建输入流
      FileInputStream fs= new FileInputStream("D:\\java\\work");
      //读文件
      fs.read();
      System.out.println(10/0);//这个异常属于运行时异常,可处理也可不处理
  } catch (FileNotFoundException | ArithmeticException e) {//java8之后可支持这样写多个
      System.out.println("文件没找到!或不存在!");
  } catch (IOException e) {
      System.out.println("读文件出错!");
  }
}

7、异常对象的两个重要方法

获取异常简单的信息描述
    String msg=exception.getMessage();
打印异常追踪的堆栈信息
  exception.printStackTrace();
public static void main(String[] args) {
  NullPointerException npe=new NullPointerException("空指针异常asd");
  //获取异常描述信息
  String msg=npe.getMessage();
  System.out.println(msg);//空指针异常asd
  //打印异常堆栈信息
  //java后台打印异常堆栈追踪信息的时候,采用的是异步线程的方式打印的
  npe.printStackTrace();
  /*
  输出结果:java.lang.NullPointerException: 空指针异常
at FiveteenDay.Exception07.main(Exception07.java:11)
    */

}

8、关于try...catch中的finally

  • 在finally中的语句,try...catch..执行完后一定会执行。(finally一定是与try..catch..搭配使用的)

  • finally在什么情况下使用? 多半在关闭输出,输入流的时候使用

public static void main(String[] args) {
  FileInputStream f=null;
  try {
      //创建输入流
        f= new FileInputStream("D:\\java\\wor");
      /*
      若把f.close()写在这一行,如果以上代码出现异常,则不会执行关闭流。
      故通常把关闭流写在 finally中。
        */
      //f.close();
  } catch (FileNotFoundException e) {
      e.printStackTrace();
  }finally {
      System.out.println("我要关闭流!");
      //一开始这样写会报错 f.close(),因为在finally中没有f,f在try中是局部变量,故要把f定义为全局变量
      //定义为全局变量后会出现空指针异常 故要判断f是否为空
      //因为 close() throws IOException 故需要处理异常 try..catch..
      if(f!=null) {
          try {
              f.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  }
}

9、try与finally连用

public static void main(String[] args) {
  /*
  try和finally可以连用
  执行顺序是先执行try...
  在执行fianlly...
  最后执行return
    */
  try{
      System.out.println("try....");
      return;
  }finally{
      System.out.println("finally...");
  }
}

运行结果:

try.... finally...

try{
  System.out.println("try....");
  System.exit(0);//这条语句可以不让finally语句执行
}finally{
  System.out.println("finally...");
}

运行结果:

try....

特殊情况:

public static void main(String[] args) {
  int result=sum();
  System.out.println(result);//这个返回值不是11,而是10
  /*
  原因:java语法规定 自上而下执行方法体(亘古不变)
  反编译之后的代码:
  public static int sum(){
      int i=10;
      int j=i;
      i++;
      return j;
....
    */
}
public static int sum(){
  int i=10;
  try{
      return i;
  }finally {
      i++;
      System.out.println(i);//11
  }
}

10、final,finally,finalize 的区别

 

  final:

  final修饰的方法不能被覆盖

  final修饰的类不能被重写

  final修饰的变量值不能改变

 

 

  finally:

   与try联合使用 finally中的程序一定会被执行

 

 

  finalize:

  这个是Object中的方法名 由垃圾回收器GC负责调用

 

11、自定义异常类

异常出现概率高就可以继承Exception

低的话就继承RuntimeException

/*
自定义异常类
有的时候sun公司写的异常类不能够满足程序需求,我们可以自己编写异常类
定义异常类的步骤:
1>编写一个异常类继承Exception或者RuntimeException
2>提供两个构造方法:无参构造与带有String参数的有参构造
*/
//这个是编译时异常
public class MyException extends Exception{
public MyException() {
}
public MyException(String s){
super(s);
}
}
/*这个是运行时异常
public class MyException extends RuntimeException{
public MyException() {
}
public MyException(String s){
super(s);
}
}
*/

posted @ 2021-07-08 08:26  别不开心,过得去  阅读(65)  评论(0)    收藏  举报