《Java编程思想》第12章 通过异常处理错误

第12章 通过异常处理错误

0、异常层次结构:

Throwable---Error(Java运行时系统的内部错误和资源耗尽错误,无需考虑)

                 ---Exception---RuntimeException(程序错误导致的异常)---以上两类并不需要程序员进行处理

                                     ---其他

1、异常链示例代码

//: exceptions/DynamicFields.java
// A Class that dynamically adds fields to itself.
// Demonstrates exception chaining.

class DynamicFieldsException extends Exception {}

public class DynamicFields {
    private Object[][] fields;

    public DynamicFields(int initialSize) {
        fields = new Object[initialSize][2];
        for (int i = 0; i < initialSize; i++)
            fields[i] = new Object[]{null, null};
    }

    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        for (Object[] obj : fields) {
            result.append(obj[0]);
            result.append(": ");
            result.append(obj[1]);
            result.append("\n");
        }
        return result.toString();
    }

    private int hasFields(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 = hasFields(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[][] tmp = new Object[fields.length + 1][2];
        for (int i = 0; i < fields.length; i++)
            tmp[i] = fields[i];
        for (int i = fields.length; i < tmp.length; i++)
            tmp[i] = new Object[]{null, null};
        fields = tmp;
        return makeField(id);
    }

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

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

    public static void main(String[] args) {
        DynamicFields df = new DynamicFields(3);
        System.out.println(df);
        try{
            df.setField("d", "A value for d");
            df.setField("number", "47");
            df.setField("number2", "48");
            System.out.println(df);
            df.setField("d", "A new value for d");
            df.setField("number3", 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(System.out);
        }
        catch(DynamicFieldsException e){
            e.printStackTrace(System.out);
        }
    }
} /* Output:
null: null
null: null
null: null

d: A value for d
number: 47
number2: 48

df: d: A new value for d
number: 47
number2: 48
number3: 11

df.getField("d"): A new value for d
DynamicFieldsException
	at DynamicFields.setField(DynamicFields.java:59)
	at DynamicFields.main(DynamicFields.java:88)
Caused by: java.lang.NullPointerException
	at DynamicFields.setField(DynamicFields.java:60)
	... 1 more
*///:~

2、finally 语句块:https://www.ibm.com/developerworks/cn/java/j-lo-finally/index.html

  • 只有与 finally 相对应的 try 语句块得到执行的情况下,finally 语句块才会执行。
  • 当一个线程在执行 try 语句块或者 catch 语句块时被打断(interrupted)或者被终止(killed),与其相对应的 finally 语句块可能不会执行。
  • 程序首先执行try语句,如果不存在异常将跳过控制转移语句(return,continue,break,throw)而直接执行finally语句,执行完finally语句再返回执行try中的控制转移语句;但如果存在异常,将转入对应的catch语句(之后的try语句将被忽略),之后同样在控制转移语句前执行finally语句,并最终返回执行catch中的控制转移语句。不过,如果finally中存在控制转移语句,将直接跳转而不执行try或者catch中的控制转移语句。
  • 但在跳转到finally语句执行之前,程序会将try或catch中的变量入栈保存,待finally语句执行完之后,将入栈数据重新加载,因此并不能通过finally语句来实现对try或catch语句中的返回值进行修改

3、子类的异常相比于基类只能更加具体,而如果基类没有异常,那么子类将不允许抛出异常。

4、对于可能存在异常的方法,要么通过catch捕获异常(也可以经过处理之后再抛出另一个异常)或者在方法声明时通过throws声明该方法可能抛出的异常。

5、但try语句中存在打开的资源(文件,数据库)需要关闭时,相比于通过finally语句进行处理,使用带资源的try语句(try(Resource res=...))通常更好。这样能够保证这类资源在出现异常时能够被正确的关闭。

6、日志处理

  • 创建日志
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Abc.class); 
  • 记录日志时间
logger.warning("This is a warning!");
logger.setLevel(Level.WARNING);
  • 日志实例
import java.util.logging.Logger;

public class LoggerTest {
    public static void main(String[] args) {
        Logger logger = Logger.getLogger(LoggerTest.class.getName());

        logger.finest("this is finest");
        logger.finer("this is finer");
        logger.fine("this is fine");
        logger.config("this is config");
        logger.info("this is info");
        logger.warning("this is a warning");
        logger.severe("this is severe");
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值