12.17 Java基础15

  • 昨日知识点回顾

public static void main(String[] args) {

        // Error 错误 ->不可挽救,通过异常处理无法解决.
        // OutOfMemoryError StackOverflowError
        // F4
//        Object->Throwable->Exception
//        Object->Throwable->Error

        // Exception 异常
        // - 运行时异常 RuntimeException
        // - 检查异常 simple.parse

        // F4 Object->Throwable->Exception->RuntimeException->NullPointerException
//        NullPointerException

//        ParseException

        // 异常处理方式1 抛出异常,我不处理,谁调用我谁处理,一直向上抛,最终抛给虚拟机

               //    try...catch捕捉异常,处理。
    }

 

  • 异常处理剩余部分
  • 掌握异常的处理-捕获异常try...catch...finally
  • 把所有可能抛出异常的,或者肯定抛出异常的代码都写到try代码块中;catch语句紧随try语句后,用来捕获异常并进行处理;
  • 结构:

try{

      可能抛出异常的代码块;

}catch(异常类型  变量名){

       处理异常的代码;

}

抛出异常--》捕获异常--》捕获失败(当catch的异常类型与抛出异常类型不匹配时,捕获失败 )/捕获成功(当catch的异常类型与抛出的异常类型匹配时,捕获成功) --》异常(未)被处理,程序中断(继续)运行。

若没有抛出异常,则运行时会跳过catch代码块

  • catch语句里都写什么代码?

可以写任意需要对异常进行处理的代码;

可以调用异常对象的方法,例如printStackTrace,查看异常发生的栈轨迹。

System.out.println(e.getMessage());可以在控制台打印异常详细信息。

注意:catch部分有一个给程序员看 e.printStackTrace(); ->保存到日志文件中

输出或者返回一个字符串,给客户看 System.out.println(e.getMessage());

相关代码:

public class Person {
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age<1) {
            throw new RuntimeException("年龄不能小于1。");//括号里的内容就相当于getMessage()
        }
        this.age=age;
    }
}

  • 多catch捕获

catch语句的异常类型必须从子类到父类的顺序,否则编译错误;异常只要被成功捕获一次,就被处理了,不会再继续抛出了。

相关代码:

public static void main(String[] args) {

        try {
            System.out.println("start");

            String str = null;
            System.out.println(str.length());

            System.out.println(1 / 0);
            System.out.println("end");
        } catch (ArithmeticException | NullPointerException ex) { //运用了逻辑或
            System.out.println("ex :" + ex.getMessage());
        } finally {
            // 这里是释放资源 [不管是否发生异常,都会执行]
            System.out.println("finally");
        }
    }

  • finally块

一般用于资源的清理和释放工作。如:关闭已打开的文件、删除临时文件、释放数据库连接。

再比如:IO[finally 流关闭 ].JDBC.[资源释放]

finally{

             不管什么情况,一定被执行的代码块;

}

  • try catch finally的搭配

必须有try,catch可以有1个或多个,finally最多1个,也可以没有;

还有另外一种组合:只有try和finally,没有catch。如果try块中抛出了异常,则肯定不能被捕获,程序中断,但是finally代码块依然会被执行。

  • 异常的层层抛出
  • throw关键字在方法体中使用

 

throw 异常对象;

例如:

throw new Exception();

或者

catch(Exception e){

    throw e;

}

运行时异常是JVM自动抛出,非运行时异常需要程序员用throw关键字抛出;由于抛出了Exception,是非运行时异常,所以编译期检测,要求必须处理,处理的方式有两种:

使用try/catch/finally进行处理;不处理,用throws声明异常。而当用throw抛出异常后,基本都使用throws进行声明!

throws用在方法声明处,声明该方法可能发生的异常类型;一个方法如果使用了throws,那么调用该方法时,编译器会提醒必须处理这些异常,否则编译错误;throws后可以声明多种类型,用逗号隔开即可;而抽象方法也可以使用throws声明该方法可能抛出的异常类型。

如果希望对异常先统一处理,可以处理后再抛出,调用的时候可以继续处理。

 

  • 了解finally与return和System类的exit方法
  • try,catch,finally顺序

在try中没有异常的情况下try、catch、finally的执行顺序 try --- finally
如果try中有异常,执行顺序是try --- catch --- finally

如果try中没有异常并且try中有return这时候正常执行顺序是try ---- finally --- return
如果try中有异常并且try中有return这时候正常执行顺序是try----catch---finally--- return

如果try有异常,相应catch中有return,顺序是try---catch---finally---return

总之 finally 永远执行!除非前面有System.exit(0)退出虚拟机

相关代码:

  • System类的exit方法

当try中有异常时,在catch中加System.exit(1);--->(退出虚拟机的方法)

当try中没有异常时加System.exit(1);--->(退出虚拟机的方法)

System.exit(参数);

    参数: 0   或 1    都代表退出虚拟机

         0:正常退出

        1:非正常退出

相关代码:

public static void main(String[] args) {

        for (int i = 0; i < 1000; i++) {

            if (i == 100) {
                System.exit(1);
            }
            System.out.println(i);
        }
        System.out.println("over");
    }

  • 自定义异常

为了能够标记项目中的异常事件,需要使用throw抛出异常;而如果抛出的是API中的标准异常,那么很可能与API中方法抛出的异常混淆,因此需要自定义异常,对团队合作非常有意义。

一般自定义异常类中不写其他方法,只重载必要的构造方法。

相关代码:(找一个运行时异常的子类异常,把它的方法全部复制,粘贴到我们新建的自定义异常类中,相当于我们的自定义异常重写了运行时异常的方法,由此使这个自定义异常和之前的子类异常成为同级)

/**
 * 自定义异常 继承RuntimeException
 * 
 * @author Administrator
 *
 */
public class MyException extends RuntimeException {
    /**
     * Constructs a {@code MyException} with no detail message.
     */
    public MyException() {
        super();
    }

    /**
     * Constructs a {@code MyException} with the specified detail message.
     *
     * @param s the detail message.
     */
    public MyException(String s) {
        super(s);
    }
}

 

综合代码:

public static void main(String[] args) {
        System.out.println(t1());
        System.out.println(t2());
        System.out.println(t3());
        System.out.println(t4());

    }
    
    public static int t1() {
        try {
            return 1;//1
        } catch (Exception e) {
            // TODO: handle exception
            return 2;
        } finally {

        }

    }
    
    public static int t2() {
        try {
            return 1;
        } catch (Exception e) {
            // TODO: handle exception
            return 2;
        } finally {
            return 3;// 特例,finally一定会执行 3

        }

    }
    
    public static int t3() {
        int n = 1;
        try {
            System.out.println(n/0);
            return ++n;//不运行
        } catch (Exception e) {
            // TODO: handle exception
            return ++n;
        } finally {
            return ++n;// 特例,finally一定会执行 3

        }

    }
    
    public static int t4() {
        try {
            return 1;
        } catch (Exception e) {
            // TODO: handle exception
            return 2;
        } finally {
            return 3;//特例,finally一定会执行            
        }
        //return 4;//编译错误
    }

  • 断言

JDK1.4版本开始,增加了断言机制;

断言用来进行调试不在生产环境中使用

断言使用关键字assert表示,语法非常简单,有两种形式:

assert <布尔表达式>

assert <布尔表达式> : <错误信息>

当布尔表达式的值是true时,忽略assert

当布尔表达式的值是false时,发生AssertionError错误,程序中断;如果用第二种形式,同时显示错误信息。

  • 断言的开启方法

Eclipse默认没有开启断言功能,要使用需要开启。

Window->Preferences->Java->Installed JREs

选中安装的一个JRE->Edit JRE->在默认VM参数框输入-ea->finish->apply and close 由此开启断言

相关代码:

public static void main(String[] args) {
        t2(null);

    }
    
    public static void t2(String str) {
        assert str != null : "字符串不能为null";
        System.out.println(str.length());
    }

运行得到:Exception in thread "main" java.lang.AssertionError: 字符串不能为null 报断言错误

 

感想:总体不难。非要说难点,那就在于对try...catch...finally结构的运行结果的仔细判断。

(Ps:今年好多基金经理离职。。唉,钱亚风云离职没多久,周应波大概率也要离职了,又要转换。。)

21:53:13 2021-12-19

posted on 2021-12-19 21:58  heyiyang1312  阅读(5)  评论(0)    收藏  举报

导航