java编程思想代码分析(一)12.4.1:异常

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.logging.Logger;

/**
 * Created by 2017 on 2017/11/10.
 */
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);
        }
    }
}

结果如下

十一月 10, 2017 9:34:31 上午 LoggingException <init>
严重: LoggingException
    at LoggingExceptions.main(LoggingExceptions.java:20)

CaughtLoggingException

静态的Logger方法创建了一个string参数的logger对象,这个logger对象会将输出发送到system.err(也就是发送到logger对象初始化的字符串到缓冲区中),执行到构造器新建对象trace的时候,trace就已经拿到了这个logger对象输出到流缓冲区的字符,但是由于我们只是获得了字符,所以我们调用 printStackTrace(new PrintWriter(trace))获取到了其中的异常信息,并通过trace获取错误信息到缓冲区中,然后我们要输出缓冲区重的字符串,调用 logger.severe(trace.toString()); 方法对字符串进行打印,并把结果写入到logger中,最后在main方法里执行try语句的时候会加载LoggingException的构造器,从而通过logger.severe(trace.toString());来打印出logger里的信息到控制台


12.6.3异常链

/**
 * Created by 2017 on 2017/11/12.
 */
public class Test {

    public static void main(String[] args) {
        DynamicFields df = new DynamicFields(3);
        System.out.println(df);
        try {
            df.setField("d", "a value of d");
            df.setField("killer47", 47);
            df.setField("fatkiller48", 48);
            System.out.println(df);
            df.setField("d", "a new value of d");
            df.setField("thinkiller", 11);
            System.out.println("df:" + df);
            System.out.println("df.getField(\"d\")" + df.getField("d"));
            Object field = df.setField("d", null);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (DynamicFieldException e) {
            e.printStackTrace();
        }
    }
}

class DynamicFieldException extends Exception {}
class DynamicFields {
    private Object[][] fields;
    public DynamicFields(int initialSize) {
        this.fields = new Object[initialSize][2];
//        这里的长度是由用户指定的,里面存储的是initialsize个一唯数组,每一个一唯数组的长度是2
        for (int i = 0; i < initialSize; i++) {
//            这里开始遍历1唯数组,然后给1唯数组里的每个元素进行赋值
            fields[i] = new Object[]{null, null};
        }
    }

    public String toString() {
        StringBuilder result = new StringBuilder();
        for (Object[] object : fields) {
//            object遍历的数组是1唯数组的个数,1唯数组有几个就遍历几次,
//            由于object取出的是每一个一唯数组,所以object[0]取出的是每一个一唯数组里每一个元素的值,由于上面指定1唯数组的长度是2,所以取0,和1两个下标进行遍历,添加到缓冲区然后返回数组里的所有内容
//            object[0]取出的是每一个1唯数组,
            result.append(object[0] + ": " + object[1] + "\n");
        }
        return result.toString();
    }

    private int hasField(String id) {
        for (int i = 0; i < fields.length; i++) {
            if (id.equals(fields[i][0]))
                return i;
        }
        return -1;
    }

    private int getFieldNumber(String id) throws NoSuchFieldException {
        int fieldNum = hasField(id);
        if (fieldNum == -1) {
            throw new NoSuchFieldException();
        }
        return fieldNum;
    }

    private int makeField(String id) {
        for (int i = 0; i < fields.length; i++) {
            if (fields[i][0] == null) {
                fields[i][0] = id;
                return i;
            }
        }
        // 如果空间满了,那就在造一个空间
        Object[][] temp = new Object[fields.length + 1][2];
        for (int i = 0; i < fields.length; i++) {
            temp[i] = fields[i];
        }
        temp[fields.length] = new Object[]{null, null};
        fields = temp;
        return makeField(id);
    }

    public Object getField(String id) throws NoSuchFieldException {
        return fields[getFieldNumber(id)][1];
    }

    public Object setField(String id, Object value)
            throws DynamicFieldException {
        if (value == null) {
            DynamicFieldException dfe = new DynamicFieldException();
            dfe.initCause(new NullPointerException());
            throw dfe;
        }
        int fieldNumber = hasField(id);
        if (fieldNumber == -1) {
            fieldNumber = makeField(id);
        }
        Object result = null;
        try {
            result = getField(id);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
//            e.printStackTrace();
        }
        fields[fieldNumber][1] = value;
        return result;
    }
}

底层类似于一个MAP的容器,我们通过调用DynamicFieldException的initcause方法来把其他的异常链接起来,也可以通过exception的构造器来传入一个异常,这样我们可以追踪到异常最初发生的位置,不过需要注意的是,在调用setfiled的时候,如果跑出文件找不到异常(属于查找才有的异常类型,而不是设置字段应该抛出的异常类型),所以我们需要用接受cause参数的构造器把文件找不到异常转换成运行时异常

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值