Java学习笔记6-异常处理

异常处理

Java异常

  • 调用方法如何获取调用失败的信息:

    • 约定返回错误码;

      int code = processFile("C:/demo.txt");
      if (code == 0) {
          // ok:
      } else {
          // error:
          switch (code) {
          case 1:
              // file not found:
          case 2:
              // no read permission:
          default:
              // unknown error:
          }
      }
      
    • 在语言层面提供一个异常处理机制;

      try {
          String s = processFile("C:/demo.txt");
          // ok:
      } catch (FileNotFoundException e) {
          // file not found:
      } catch (SecurityException e) {
          // no read permission:
      } catch (IOException e) {
          // io error:
      } catch (Exception e) {
          // other error:
      }
      
  • Java异常的分类

    • 必须捕获的异常,包括Exception及其子类,但不包含RuntimeException及其子类,此种类型异常被称为Checked Exception
    • 无需捕获的异常,包括Error及其子类,RuntimeException及其子类;

异常捕获

异常捕获使用try...catch语句,将可能发生异常的代码放入try{...}中,然后使用catch捕获对应Exception及其子类。当有多个catch语句时,JVM会从上到下匹配catch语句,直到匹配某一catch后不再执行,注意:catch的顺序要将子类放在前边

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        byte[] bs = toGBK("中文");
        System.out.println(Arrays.toString(bs));
    }

    static byte[] toGBK(String s) {
        try {
            // 用指定编码转换String为byte[]:
            return s.getBytes("GBK");
        } catch (UnsupportedEncodingException e) {
            // 如果系统不支持GBK编码,会捕获到UnsupportedEncodingException:
            e.printStackTrace();
            System.out.println(e); // 打印异常信息
            return s.getBytes(); // 尝试使用用默认编码
        }
    }
}
  • finally:捕获异常时,不论是否发生异常,都将执行finally中的语句,主要有如下特点:

    • finally非必须,可写可不写;
    • finally总是最后执行;
    public static void main(String[] args) {
        try {
            process1();
            process2();
            process3();
        } catch (UnsupportedEncodingException e) {
            System.out.println("Bad encoding");
        } catch (IOException e) {
            System.out.println("IO error");
        } finally {
            System.out.println("END");
        }
    }
    

异常抛出

  • 当程序中的某一方法抛出异常时,若当前方法未捕获异常,异常就会被抛到上层调用方法,直到遇见某一try...catch被捕获;

  • 抛出异常的步骤:

    • 创建某个Exception的实例;
    • throw语句抛出;
    void process(String str){
        if(str == null){
            // 创建某个Exception的实例
            NullPointerException e = new NullPointerException();
            // throw语句抛出
            throw e;
            
            // 上述步骤可合并为一行,等价于
            // throw new NullPointerException();
        }
    }
    
  • catch中抛出异常时,不会影响finally的执行,JVM会优先执行finally,然后再抛出异常;

  • 异常屏蔽

    finally执行时若抛出异常,catch中的异常就会被屏蔽,但是可以通过将原始异常进行保存,然后调用Throwable.addSuppresssed(),将原始异常添加出来,最后在finally中抛出;

    扫描二维码关注公众号,回复: 10050614 查看本文章
    public class Main{
        public static void main(String[] args){
            Exception origin = null;
            try{
                System.out.println(Interger.parseInt("ab"));
            }catch(Exception e){
                origin = e;
                throw e;
            }finally{
                Exception e = new IllegalArgumentException();
                if(origin != null){
                    e.addSuppressed(origin);
                }
                throw e;
            }
        }
    }
    

自定义异常

  • Java标准库定义的常用异常:

  • 自定义异常时,推荐从RuntimeException派生根异常,再派生出业务异常,而且需要提供多种构造方法;

断言

断言(Assertion)是一种调试程序的方式,利用assert关键字来实现断言。当断言失败时会抛出AssertionError,导致程序退出,只适合在开发和测试阶段启用;

public static void main(String args){
    double x = Math.abs(-123.4);
    assert x >= 0;
    System.out.println(x);
}

JDK Logging

  • Logging定义了7个日志级别,从严重到普通:
    • SEVERE
    • WARNING
    • INFO(默认级别)
    • CONFIG
    • FINE
    • FINER
    • FINEST
  • Logging存在的局限:
    • Logging系统在JVM启动时会读取配置文件并完成初始化,一旦开始main()方法,就不能再改配置;
    • 配置不方便,需要在JVM启东市传递参数-Djava.util.logging.config.file=<config-file-name>
import java.io.UnsupportedEncodingException;
import java.util.logging.Logger;

public class Main(){
    public static void main(String[] args){
        Logger logger = Logger.getLogger(Main.class.getName());
        logger.info("进程开始。。。");
        try{
            "".getBytes("不可用的字符集");
        }catch(UnsupportedEncodingException e){
            e.printStackTrace();
            logger.severe(e.toString());
        }
        logger.info("进程结束");
    }
}

Commons Logging

  • Apache创建的第三方日志模块,可以挂接不通日志系统,并通过配置文件制定挂接的日志系统;

  • Commons Logging只需与两个类打交道,且只需要两步:

    • 通过LogFactory获取Log类的实例;
    • 使用Log实例的方法打印日志;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Main{
    public static void main(String[] args){
        Log log = LogFactory.getLog(Main.class);
        log.info("开始。。。");
        log.warn("结束。。。")
    }
}
  • Commons Logging的6个日志级别:
    • FATAL
    • ERROR
    • WARNING
    • INFO(默认级别)
    • DEBUGE
    • TRACE

Log4j

  • Log4j时一个组件化设计的日志系统,其架构如下:

  • Log4j输出日志的不同目的地:

    关键字 功能
    console 输出到屏幕
    file 输出到文件
    socket 通过网络输出到远程计算机
    jdbc 输出到数据库
发布了104 篇原创文章 · 获赞 69 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/github_39655029/article/details/104977444
今日推荐