Java chapter7 异常,断言,日志
1.Java中继承于Error,和RuntimeException的异常被称作unchecked 异常
2.代码中建议抛出异常的四种情况
(1)调用方法扔出checked异常。如FileInputStream构造函数
(2)检测到错误,使用关键字throw 抛出checked异常
(3)你导致了程序错误,如a[-1]=0;抛出数组越界
(4)虚拟机运行库的内部异常。
3.如果你覆盖了超类的方法,子类的方法声明中声明的checked异常不能比超类的方法的异常更一般化。只能更特殊化。
如果超类方法不扔出异常,子类覆盖方法也不能扔出异常。
创建异常类
class FileFormatException extends IOException{
public FileFormatException();
pulbic FileFormatException(String gripe){
super(gripe);
}
}
7.4使用断言
assert condition;
assert condition:expression;
断言失败是致命的,不可恢复的错误。
打开断言检查仅当你在开发测试环境中。
不要使用断言在信号恢复环境,和用户交互。断言仅在内部测试定位错误中被使用。
7.5 日志
7.5.1 基础日志
global logger with info method
Logger.getGlobal().info("File->Open menu item selected");
Logger.getGlobal().setLevel(Level.OFF);
7.5.2 高级日志
调用getLogger方法创建或撤回logger
注意logger没有被任何变量调用会启动垃圾回收,所以要使用静态final来定义。
private static final Looger my Logger=Logger.getLogger("com.mycompany.app");
日志等级:
1.SEVERE 2.WARNING 3.INFO 4.CONFIG 5.FINE 6.FINER 7.FINEST
前三级是日志记录的。你可以更改等级:
logger.setLevel(Level.FINE);
这样1-5级,FINE以上的等级都会被记录。
Level.ALL 开启所有等级记录,Level.OFF关闭所有等级记录。
logger.warning(message);
logger.fine(message);
logger.log(Level.FINE,message);
如果你设置了FINE等级以下的日志等级,你还需改变log处理器的配置。默认的Log处理器会抑制INFO以下的消息。
使用logp方法精确定位调用类和方法
void logp(Level l,String className,String methodName,String message);
使用entering exiting来跟踪处理流
int read(String file,String pattern){
logger.entering("com.mycompany.mylib.Reader","read",new Object[]{file,pattern});
...
logger.exiting("com.mycompany.mylib.Reader","read",count);
return count;
}
使用日志记录未预料到的异常
void throwing(String className,String methodName,Throwable t)
void log(Level l,String message,Throwable t)
示范:
if(...){
var e=new IOException("...");
logger.throwing("com.mycompany.mylib.Reader","read",e);
throw e;
}
try{
...
}catch(IOException e){
Logger.getLogger("com.mycompany.myapp").log(Level.WARNING,"Reading image",e);
}
7.5.3 改变Log管理器配置
P610
7.5.4 本地化
P613
7.5.5 处理器
处理器有日志等级。
记录日志等级为FINE ,改变logger level 和handler level
Logger logger=Logger.getLogger("com.mycompany.myapp");
logger.setLevel(LEVEL.FINE);
logger.setUseParentHandlers(false);
var handler =new ConsoleHandler();
handeler.setLevel(Level.FINE);
logger.addHandler(handler);
默认情况下,logger发送记录到它自身的处理器和父亲的处理器。我们不想重复看到信息,所以设定setUseParentHandlers(false)。
发送日志记录到其他地方。添加另一个处理器,日志API提供了两个非常有用的处理器,FileHandler,SocketHandler
你可以简单的讲记录发送到默认的file handler就像:
var handler=new FileHandler();
logger.addHandler(handler);
7.5.6 过滤器
默认情况下,记录会按照他们的等级过滤。定义一个过滤器的方法是实现Filter接口,并定义方法
boolean isLoggable(LogRecord record);
7.5.7 格式化器
ConsoleHandler 和FileHandler类写日志用文本格式或xml格式,你可以定义你自己的格式。通过继承Formatter类,并覆盖方法
String format(LogRecord record)
实现你自己的格式,并返回字符串。在你的Format方法中你可以调用
String formatMessage(LogRecord record);
这个方法生成信息,由记录,替代参数,应用定位生成。
需要文本形式如XML需要包含格式化记录的头或者尾,通过覆盖下面方法实现
String getHead(Handler h);
String getTail(Handler h);
最后,调用setFormatter方法来安装这些格式化器到处理器
7.5.7日志食谱
1.对于简单应用,选择单独的日志记录器,创建一个与你应用所在包同名的日志记录器
Logger logger=Logger.getLogger("com.mycompany.myprog");
如果有很多日志行为可以
private static final Logger logger=Logger.getLogger("com.mycompany.myprog");
2.默认日志配置记录了INFO以上的信息到控制台。你可以覆盖默认配置,你可以对你的程序定义默认行为
略p622