JavaNote4

class Life{   
  public static void main(String[] args){
      int alive;
          while(alive)
          {
              eat();  
              sleep();
              code();
              repeat();
      }
    }
}

老人说,这不丢脸,也无损真正的骄傲.

关于异常,你不知道的是?

​ 什么是异常:非正常的,不同于平常的,异常指的并不是语法错误,语法错了,编译不通过,不会产生字节码文件,根本不能运行。异常处理是衡量一门语言是否成熟的标准之一,主流的语言Java,C++,C#等支持异常处理机制。异常处理机制可以让程序有更好的容错性,使我们的代码更健壮。C语言却没有异常,此时只能程序员通常使用方法的特定返回值来表示异常情况,并且使用if语句来判断正常和非正常情况。

如果没有异常处理机制?

  1. 使用方法的返回值来表示异常情况有限,无法穷举所有的异常情况.
  2. 异常流程代码和正常流程代码混合一起,增大了程序的复杂性,可读性也不好.
  3. 随着系统规模的不断扩大,程序的可维护性极低.

异常体系(java.lang.Throwable):Java语言中所有错误和异常的超类。

  1. Error:错误,一般情况下,不编写针对性的代码进行处理,通常是 jvm 发生的,
    需要对程序进行修正。
  2. Exception:异常,可以有针对性的处理方式。
  3. 无论是错误还是异常,它们都有具体的子类体现每一个问题,它们的子类都有一个共性,就是都以父类名才作为子类的后缀名(NullPointerException),这个体系中的所有类和对象都具备一个独有的特点,就是可抛性。

捕获异常

  1. 使用try-catch捕获单个异常,try和catch都不能单独使用,必须连用。

       try{
            编写可能会出现异常的代码
       }catch(异常类型  e){
            处理异常的代码
            //记录日志/打印异常信息/继续抛出异常
       }
  2. 使用try-catch捕获多个异常。

       try{
            编写可能会出现异常的代码
       }catch(异常类型A  e){  当try中出现A类型异常,就用该catch来捕获.
            处理异常的代码
            //记录日志/打印异常信息/继续抛出异常
       }catch(异常类型B  e){  当try中出现B类型异常,就用该catch来捕获.
            处理异常的代码
            //记录日志/打印异常信息/继续抛出异常
       }
       /*注意:
    *   1:一个catch语句,只能捕获一种类型的异常,如果需要捕获多种异常,就得使用多个catch语句.
    *   2):代码在一瞬间只能出现一种类型的异常,只需要一个catch捕获,不可能同时出现多个异常.
    */

    3.finally 代码块(常用于关闭资源,无论是否发生异常,资源都必须进行关闭)

    //finally语句块表示最终都会执行的代码,无论有没有异常.
    //finally也不能单独使用
    //如果在try,catch中调用了退出JVM的相关方法便不再执行,程序都关闭了还执行什么
    try {
            System.out.println("begin...");
            int  ret = 10/0;
            System.out.println("结果= "+ ret);
        } catch (ArithmeticException e) {
            System.out.println("出现异常情况");
        //  System.exit(0); //退出JVM
        }finally{
            System.out.println("关闭资源"); //如果有system.exit语句 ,则此处不执行
        }
        System.out.println("end...");
  1. finally 的两种语法:

    1. try…finally: 此时没有catch来捕获异常,因为此时根据应用场景,我们会抛出异常,自己不处理。
    2. try…catch….finally:自身需要处理异常,最终还得关闭资源。

获取异常信息

  1. String getMessage():获取异常的描述信息,原因(提示给用户的时候,就提示错误原因)。
  2. String toString():获取异常的类型和异常描述信息。
  3. void printStackTrace():打印异常的跟踪栈信息并输出到控制台。不需要使System.out.println。

异常分类

  1. 编译时被检查的异常,只要是 Exception 及其子类都是编译时被检测的异常。

  2. 运行时异常,其中 Exception 有一个特殊的子类 RuntimeException,以及RuntimeException 的子类是运行异常,也就说这个异常是编译时不被检查的异常。

抛出异常

  1. throw: 运用于方法内部,用于给调用者返回一个异常对象,和return一样会结束当前方法.

    public class ThrowDemo {
    public static void main(String[] args) {
        System.out.println("------------");
        try {
            int ret = divide(10,2);
            System.out.println(ret);
        } catch (ArithmeticException e) {
            System.out.println(e.getMessage());
        }
    }
    private static int divide(int num1, int num2) {
        System.out.println("begin...");
        if (num2 == 0) {
            // System.out.println("除数不能为0");
            // return 1;
            throw new ArithmeticException("除数不能为0");
        }
        System.out.println("==================");// 当num2 =0的时候,此处代码执行不到,
                                            // throw相当于return,返回的是一个错误结果
        try {
            int ret = num1 / num2;
            System.out.println("结果 =" + ret);
            return ret;
        } catch (ArithmeticException e) {
            e.printStackTrace();
        }
        System.out.println("end....");
        return 0;
    }
    }
  2. throws: 运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常).

    public class ThrowsDemo {
    public static void main(String[] args) throws Exception {
        divide(10, 0);
    }
    //在本方法中不处理某种类型的异常
    private static int divide(int num1, int num2) throws Exception {
    System.out.println("begin...");
    if (num2 == 0) {
        throw new Exception("除数不能为0");//此处如果为RuntimeException就不会编译出错
    }                                           
    try {
        int ret = num1 / num2;
        System.out.println("结果 =" + ret);
        return ret;
    } catch (ArithmeticException e) {
        e.printStackTrace();
    }
    System.out.println("end....");
    return 0;
    }    
    }

3.如果每一个方法都放弃处理异常都直接通过throws声明抛出,最后异常会抛到main方法,如果此时main方法不处理,继续抛出给JVM,底层的处理机制就是打印异常的跟踪栈信息.

自定义异常类

  1. 为什么需要自定义异常:Java中不同的异常类,分别表示着某一种具体的异常情况,那么在开发中总是有些异常情况是SUN没有定义好的,此时我们根据自己业务的异常情况来定义异常类.

  2. 自定义异常的步骤:

    1. 定义一个子类继承 Exception 或 RuntimeException,让该类具备可抛性(既可以使用 throw 和 throws 去调用此类)。
    2. 通过 throw 或者 throws 进行操作。
  3. 异常的转换思想:当出现的异常是调用者处理不了的,就需要将此异常转换为一个调用者可以处理的异常抛出。

class LogicException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    public LogicException() {
        super();
    }

    public LogicException(String message, Throwable cause) {
        super(message, cause);
    }

    public LogicException(String message) {
        super(message);
    }
}

public class RegisterDemo {
    // 假设数据库中已经存在的账号
    public static void main(String[] args) {
        try {
            // 可能出现的异常代码
            isExist("will");
            System.out.println("注册成功");
        } catch (Exception e) {
            // 处理异常
            System.out.println("用户:" + e.getMessage());// 对不起,用户名will已存在
        }
    }

    // 判断当前注册的账号是否存在
    private static boolean isExist(String username) {
        String[] data = { "will", "lucy", "xiaoming" };
        for (String name : data) {
            if (name.equals(username)) {
                throw new LogicException("该名字已经被注册"); // 返回错误的结果给catch(调用者)
            }
        }
        return true;
    }
}

处理异常的原则

  1. 异常只能用于非正常情况,try-catch的存在也会影响性能.
  2. 需要为异常提供说明文档,比如Java doc,如果自定义了异常或某一个方法抛出了异常,我们应该记录在文档注释中.
  3. 尽可能避免异常.
  4. 异常的粒度很重要,应该为一个基本操作定义一个 try-catch 块,不要为了简便,将几百行代码放到一个 try-catch 块中.
  5. 不建议在循环中进行异常处理,应该在循环外对异常进行捕获处理(在循环之外使用try-catch).
  6. 自定义异常尽量使用RuntimeException类型的.

Note中的Code是从学习笔记上Copy下来的,这些天被多线程玩得欲仙欲死。

CNcots CN Caprice of the stone的简写, 译为石头的随想曲.

博客中有网上摘抄的资料. 有个人的一些小心得 ,有什么不对的地方, 还请各位观客老爷们指出.

JavaNote系列博客, 纯属个人学习时间段整理的一些笔记, 会坚持每周至少一更,多多关照.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值