异常、断言 和 日志

目录

一 异常

1.1 异常分类图

 1.2 声明检查型异常

1.3 抛出异常

1.4 自定义异常类:

1.5 捕获异常

二 断言

2.1 启用断言与禁用断言

2.2 使用断言

 三 日志


一 异常

1.1 异常分类图

        异常对象都是派生于Throwable类

        Error 类层次结构描述了Java运行时系统的内部错误和资源消耗用尽错误, 对这种错误,程序几乎无能为力

        RuntimeException 类与 Error 类及其子类的所有异常被称为非检查型异常, 除此之外的其他异常被称为检查型异常。

 1.2 声明检查型异常

        一个方法,必须声明所有可能抛出的检查型异常, 非检查型异常(RuntimeExcep)要避免出现(如: 数组越界, 除0异常, 空指针异常)。

如: 单个异常

public void load(String s) throws IOException{
    ...
}

多个异常:

public void load(String s) throws FileNotFoundException,IOException{
    ...
}

备注: 

        使用 throws 关键字, 在方法在方法首部声明这个方法可能会抛出异常

        子类覆盖了父类的方法, 子类的方法的检查型异常不能比父类方法中声明的异常更通用。

        不允许子类的 throws 出现超类未列出的异常类

1.3 抛出异常

示例:

    public void load(String s) throws IOException {
        if (new FileInputStream(s) == null) {
            throw new IOException();
        }
    }

备注:

        通过 throw 关键字, 可以将一个异常对象抛出。 

1.4 自定义异常类:

        实际场景中可能还有一些情况需要我们对异常类进行扩展, 创建符合我 们实际情况的异常。

示例:

public class Test { 
 private static String userName = "admin"; 
 private static String password = "123456"; 

 public static void main(String[] args) { 
     login("admin", "123456"); 
 } 

 public static void login(String userName, String password) { 
     if (!Test.userName.equals(userName)) { 
         // TODO 处理用户名错误
     } 
     if (!Test.password.equals(password)) { 
         // TODO 处理密码错误
     } 
     System.out.println("登陆成功"); 
 } 
}

根据以上情况, 我们可以创建两个自定义异常:

class UserError extends Exception { 
 public UserError(String message) { 
     super("用户名错误"); 
 } 
}
 
class PasswordError extends Exception { 
 public PasswordError(String message) { 
     super("密码错误"); 
 } 
}

 应用自定义异常:

public static void login(String userName, String password) throws UserError, PasswordError{
    if (!Test.userName.equals(userName)) {
        throw new UserError("用户名错误");
    }

    if (!Test.password.equals(password)) {
        throw new PasswordError("密码错误");
    }

    System.out.println("登陆成功");
}

备注:

        自定义异常通常会继承自 Exception 或其子类
        继承自 Exception 的异常默认是受查异常

1.5 捕获异常

        一旦出现异常, 而没有在任何地方捕获这个异常, 程序就会终止。

基本语法
try{ 
 有可能出现异常的语句 ; 
}catch (异常类型 异常对象) {
} 
finally {
 异常的出口
}

备注:

  • try 代码块中放的是可能出现异常的代码.
  • catch 代码块中放的是出现异常后的处理行为.
  • finally 代码块中的代码用于处理善后工作, 会在最后执行.
  • 其中 catch fifinally 都可以根据情况选择加或者不加.

示例1 :

int[] arr = {1, 2, 3};
try {
    System.out.println("before");
    System.out.println(arr[100]);
    System.out.println("after");
} catch (ArrayIndexOutOfBoundsException e) {
    // 打印出现异常的调用栈
    e.printStackTrace();
}
System.out.println("after try catch");

// 执行结果
before
java.lang.ArrayIndexOutOfBoundsException: 100
 at demo02.Test.main(Test.java:10)
after try catch

备注:

        try 中出现异常 , 那么 try 代码块中的程序就不会继续执行 , 而是交给 catch 中的代码来执行。  catch 执行完毕会继续往下执行。

示例2 : 

int[] arr = {1, 2, 3};
try {
    System.out.println("before");
    arr = null;
    System.out.println(arr[100]);
    System.out.println("after");
} catch (ArrayIndexOutOfBoundsException e) {
    e.printStackTrace();
}
System.out.println("after try catch");
// 执行结果
before
Exception in thread "main" java.lang.NullPointerException
 at demo02.Test.main(Test.java:11)

备注:

        catch 语句不能捕获到空指针异常, 因此程序中途终止。

 示例3 :

int[] arr = {1, 2, 3};
try {
    System.out.println("before");
    arr = null;
    System.out.println(arr[100]);
    System.out.println("after");
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("这是个数组下标越界异常");
    e.printStackTrace();
} catch (NullPointerException e) {
    System.out.println("这是个空指针异常");
    e.printStackTrace();
}

 备注:

        可以同时捕获多个异常

示例4 :

int[] arr = {1, 2, 3};
try {
    Scanner sc = new Scanner(System.in);
    System.out.println("before");
    arr = null;
    System.out.println(arr[100]);
    System.out.println("after");
} catch (Exception e) {
    e.printStackTrace();
} finally {
    sc,close();
    System.out.println("end code");
}
// 执行结果
before
java.lang.NullPointerException
 at demo02.Test.main(Test.java:12)
end code

备注:

        无论是否存在异常, fifinally 中的代码一定都会执行到。

示例5 :
try (Scanner sc = new Scanner(System.in)) {
    int num = sc.nextInt();
    System.out.println("num = " + num);
} catch (Exception e) {
    e.printStackTrace();
}

备注:

        try括号中声明的资源对象,会自动关闭。更加实用(防止null指针异常)

错误示例1 :

public static int parseInt(String s){
    try {
        return Integer.parseInt(s);
    }finally {
        return 0;
    }
}

 备注: 

        调用parseInt("a"), Integer.parseInt(s)会抛出一个异常, 但finally子句的return语句会"吃掉"这个异常!

错误示例2 :

public class Demo {
    public static void main(String[] args) {
        parseInt(new LinkedList());
    }

    public static void parseInt(Deque s) {
        long time = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            try {
                s.pop();
            } catch (Exception e) {

            }
        }
        System.out.println(System.currentTimeMillis() - time);  //输出 4625
        time = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            if (!s.isEmpty())
                s.pop();
        }
        System.out.println(System.currentTimeMillis() - time);   //输出 1

    }
}

 备注:        

        捕获异常的时间开销远远大于普通语句s.pop()语句。

总结: 

        通常, 最好的选择是什么也不做, 将异常传递给调用者, 由调用者来处理异常。

        finally子句不要使用控制流语句(如: return,throw, break, continue)

二 断言

2.1 启用断言与禁用断言

        默认情况下, 断言是禁用的

IDEA启用断言:

1) 点击运行, 选择编辑配置

 2)选择add VM选项

 3)输入 -ea

 4)输入 -da 禁用断言

2.2 使用断言

示例1:

public class Demo {
    public static void main(String[] args) {
        int a = 5;
        assert a != 5;
    }
}

        当 assert 结果为false 则会抛出 AssertionError 异常。

示例2: 

public class Demo {
    public static void main(String[] args) {
        int a = 5;
        assert a != 5:"a不能等于5";
    }
}

        "a不能等于5" 表达式会传入AssertError对象的构造器, 并转化成一个消息字符串。

备注:

        相比异常, 断言机制可以在测试期间插入检查, 而在生存代码中会自动删除这些检查。

 三 日志

        暂略 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值