• Thinking in Java异常笔记与习题


    Thinking in Java异常笔记

    创建自定义异常

    package exception;
    
    class MyException extends Exception {
        public MyException() {}
    
        public MyException(String message) {
            super(message);
        }
    }
    
    public class FullConstructors {
        public static void f() throws MyException {
            System.out.println("Throwing My exception from f()");
            throw new MyException();
            }
        public static void g() throws MyException {
            System.out.println("Throwing My exception from g()");
            throw new MyException("Originated in g()");
        }
    
        public static void main(String[] args) {
            try {
                f();
            } catch (MyException e) {
                e.printStackTrace(System.out);
            }
            try {
                g();
            } catch (MyException e) {
                e.printStackTrace(System.out);
            }
        }
    }
    /* output
    Throwing My exception from f()
    exception.MyException
    	at exception.FullConstructors.f(FullConstructors.java:14)
    	at exception.FullConstructors.main(FullConstructors.java:23)
    Throwing My exception from g()
    exception.MyException: Originated in g()
    	at exception.FullConstructors.g(FullConstructors.java:18)
    	at exception.FullConstructors.main(FullConstructors.java:28)
    */
    

    如果使用e.printStackTrace(System.err)将错误发送给标准错误流,通常这比错误输出到System.out要好,因为System.out也许会被重定向,System.err不会,更容易引起用户注意

    调用在Throwable类(Exception 从此类继承)中声明的printStackTrace()方法,将打印从方法调用处直到异常抛出处,信息被发送到System.out。但如果调用了默认版本e.printStackTrace(),则输入到标准错误流。

    异常说明

    属于方法声明的一部分,紧跟在参数列表之后,使用了附加的关键字throws,后面接一个所有潜在异常类型的列表。使你告知客户端程序员某个方法可能会抛出的异常类型,然后客户端程序员就可以进行相应的处理。代码必须与异常保持一致,如果方法里面的代码产生了异常,却没有进行处理,编译器会发现这个问题

    异常丢失

    某些特殊的方式使用finally造成异常丢失

    package exceptions;
    
    class VeryImportantException extends Exception {
        @Override
        public String toString() {
            return "A very important exception!";
        }
    }
    
    class ImportantException extends Exception {
        @Override
        public String toString() {
            return "An important exception!";
        }
    }
    class HoHumException extends Exception {//HoHum令人生厌的
        @Override
        public String toString() {
            return "A trivial exception!";//trivial:不重要的
        }
    }
    
    
    public class LostMessage {
        void f() throws VeryImportantException {
            throw new VeryImportantException();
        }
    
        void g() throws ImportantException {
            throw new ImportantException();
        }
    
        void dispose() throws HoHumException {
            throw new HoHumException();
        }
    
        public static void main(String[] args) {
            try {
                LostMessage lm = new LostMessage();
                try {
                    lm.f();
                } finally {
                    lm.dispose();
                }
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }
    /* 
    A trivial exception!
    */
    

    更加简单的丢失异常的方式:从finally子句中返回

    package exceptions;
    
    public class ExceptionSilencer {
        public static void main(String[] args) {
            try {
                throw new RuntimeException();
            } finally {
                return;
            }
        }
    }
    
    

    异常匹配

    抛出异常的时候,异常处理系统会按照代码的书写顺序找出“最近”的处理程序,找的匹配的处理程序之后,它就认为异常得到处理,然后不再查找。查找的时候并不要求异常完全匹配,派生类的对象也可以匹配其基类的处理程序。

    package exceptions;
    
    class Annoyance extends Exception {}
    class Sneeze extends Annoyance {}
    
    public class Human {
        public static void main(String[] args) {
            try {
                throw new Sneeze();
            } catch (Sneeze s) {
                System.out.println("Caught Sneeze");
            } catch (Annoyance a) {
                 System.out.println("Caught Annoyance");
            }
    
            try {
                throw new Sneeze();
            } catch (Annoyance a) {
                System.out.println("Caught Annoyance");
            }
        }
    }
    
    

    基本日志功能(将输出 记录到日志中)

    package exception;
    
    import java.util.logging.*;
    import java.io.*;
    class LoggingException extends Exception {
        private static Logger logger = Logger.getLogger("LoggingException");    
        public LoggingException() {
            StringWriter trace = new StringWriter();
            printStackTrace(new PrintWriter(trace));
            logger.severe(trace.toString());
        }
    
    }
    public class LoggingExceptions  {
        public static void main(String[] args) {
            try {
                throw new LoggingException();
            } catch(LoggingException e) {
                System.err.println("Caught" + e);
            }
            try {
                throw new LoggingException();
            } catch (LoggingException e) {
                System.err.println("Caught" + e);
            }
        }
    
    }
    
    public static Logger getLogger(String name)
    //name是Logger的名称,此名称创建过再次创建则返回原来的Logger
    logger.severe(trace.toString());
    /*output:
    8月 12, 2020 5:02:56 下午 exception.LoggingException <init>
    严重: exception.LoggingException at   exception.LoggingExceptions.main(LoggingExceptions.java:17)*/
    StringWriter trace = new StringWriter();
    public StringWriter() {
            buf = new StringBuffer();
            lock = buf;
    }
    
    

    Logger级别

    severe 严重
    warning 警告
    info 信息
    config 配置
    fine 良好
    finer 较好
    finest 最好
    all 开启所有级别日志记录
    off 关闭所有级别日志记录

    习题

    练习1:编写一个类,在其main()方法的try块里抛出一个Exception类的对象。穿第一个字符串参数给Exception的构造器。在catch子句里捕获此异常对象,并且打印字符串参数。添加一个finally子句,打印一条信息以证明这里确实得到了执行。

    package exceptions;
    
    public class Test01 {
        public static void main(String[] args) {
            try {
                throw new Exception("This is a exception");
            } catch (Exception e) {
                System.out.println(e.getMessage());
                e.printStackTrace();
            } finally {
                System.out.println("try - catch finished");
            }
        }
    }
    /* 
    This is a exception
    try - catch finished
    */
    

    练习2:定义一个对象引用并初始化为null,尝试用此引用调用方法。把这个引用放在try-catch子句里以捕获异常。

    package exceptions;
    
    class Monkey {
        void eat() {
            System.out.println("eating");
        }
    }
    
    public class Test02 {
        public static void main(String[] args) {
            Monkey monkey = null;
            try {
                monkey.eat();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    /*
    java.lang.NullPointerException
    	at exceptions.Test02.main(Test02.java:13)
    */
    

    练习3:编写能产生并能捕获ArrayIndexOutOfBoundsException异常的代码。

    package exceptions;
    
    public class Test03 {
        public static void main(String[] args) {
            int[] a = new int[10];
            try {
                System.out.println(a[11]);
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("数组越界");
            }
        }
    }
    /*
    数组越界
    */
    

    练习4:使用extends关键宇建立-个自定义异常类。为这个类写一个接受字符串参数的构造器,把此参数保存在对象内部的字符串引用中。写一个方法显示此字符串。写- -个try-catch子句,对这个新异常进行测试。

    package exceptions;
    
    class Exception04 extends Exception {
        private String msg;
    
        public Exception04() {
        }
    
        public Exception04(String msg) {
            this.msg = msg;
        }
        public String getMsg() {
            return msg;
        }
    }
    
    public class Test04 {
        public static void main(String[] args) {
            try {
                throw new Exception04("异常内部字符串");
            } catch (Exception04 e) {
                System.out.println(e.getMsg());
            }
        }
    }
    
    /* 
    异常内部字符串
    */
    

    练习5:使用while循环建立类似恢复模型的异常处理行为,它将不断重复,直到异常不再抛出。

    package exceptions;
    
    public class Test05 {
        public static void main(String[] args) {
            int[] a = new int[] {1, 2, 3, 4, 5};
            byte index = 10;
            while (true) {
                try {
                    System.out.println(a[index]);
                    break;
                } catch (ArrayIndexOutOfBoundsException e) {
                    System.out.println("Index: " + index + " is out of bounds");
                    --index;
                }
            }
        }
    }
    
    /* 
    Index: 10 is out of bounds
    Index: 9 is out of bounds
    Index: 8 is out of bounds
    Index: 7 is out of bounds
    Index: 6 is out of bounds
    Index: 5 is out of bounds
    5
    */
    

    练习18:为LostMessage.java添加第二层异常丢失,以便用第三个异常来替代HoHumException异常。

    package exceptions;
    
    class VeryImportantException extends Exception {
        @Override
        public String toString() {
            return "A very important exception!";
        }
    }
    
    class ImportantException extends Exception {
        @Override
        public String toString() {
            return "An important exception!";
        }
    }
    class HoHumException extends Exception {//HoHum令人生厌的
        @Override
        public String toString() {
            return "A trivial exception!";//trivial:不重要的
        }
    }
    
    
    public class LostMessage {
        void f() throws VeryImportantException {
            throw new VeryImportantException();
        }
    
        void g() throws ImportantException {
            throw new ImportantException();
        }
    
        void dispose() throws HoHumException {
            throw new HoHumException();
        }
    
        public static void main(String[] args) {
            try {
                LostMessage lm = new LostMessage();
                try {
                    lm.f();
                } finally {
                    try {
                        lm.g();
                    } finally {
                        lm.dispose();
                    }
                }
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }
    
  • 相关阅读:
    Python-Basis-9th
    Python-Basis-8th
    Python-Basis-7th
    Ubuntu-Basis-4th
    Ubuntu-Basis-3rd
    Ubuntu-Basis-2nd
    Ubuntu-Basis-1st
    疯狂java第五章&&第六章-面向对象
    疯狂java第四章-流程控制与数组
    疯狂java第三章-数据类型和运算符
  • 原文地址:https://www.cnblogs.com/Glov/p/13498474.html
Copyright © 2020-2023  润新知