7.4 使用断言 - 7.6 调试技巧

7.4 使用断言

断言的概念

假设确信某个属性符合要求,并且代码的执行依赖于这个属性。

代码中需要对属性进行检查,可以抛出异常。测试完毕,代码还是存在不会自动删除,如果存在大量检查程序运行会减慢。

断言机制允许在测试期间向代码插入一些检查语句。代码发布或打包时,插入的检测语句将会被自动移除。

使用 assert 关键字。例如想要断言 x 是一个正数

assert x > 0;//对结果进行检测,如果结果为false,则会抛出一个 AssertionError 异常
assert x > 0 : x;//冒号后面的表达式部分将被传入 AssertionError的构造器
启用或禁用断言

默认情况下断言被禁用,运行程序时,用 -enableassertions 或 -ea 选项启用

启用或禁用断言不必重新编译,启用或禁用断言是类加载器的功能

使用断言完成参数检查
  • 断言的失败是致命的,不可恢复的错误。
  • 断言的检查只用于开发和测试阶段

因此不应该使用断言向程序其他部分报告发生了可恢复性错误。

java.lang.Classloader 类的方法

void setDefaultAssertionStatus(boolean b)//通过类加载器加载的所有类,没有显式说明类或包的断言状态就启用或禁用断言
void setClassAssertionStatus(String className, boolean b)//对于给定的类和它的内部类,启用或禁用断言
void setPackageAssertionStatus(String packageName, boolean b)//对于给定的包和其子包中的所有类,启用或禁用断言
void clearAssertionStatus()//移除所有类和包的显示断言设置,并禁用所有通过这个类加载器加载的类的断言

7.5 记录日志

  • 可以容易的取消全部日志记录,或仅仅取消某个级别的日志。打开和关闭也很容易
  • 可以简单地禁止日志输出
  • 日志记录可以被定向到不同的处理器,用于在控制台中显示,用于储存在文件中
  • 日志记录器和处理器可以对记录进行过滤
  • 日志记录可以采用不同的方式格式化
基本日志

生成简单的日志记录可以使用全局日志记录器(global logger)

Logger.getGlobal().info("File->Open menu item selected");
Logger.getGlobal().setLevel(Level.OFF);//取消所有日志
高级日志

在一个专业的应用程序中,不应该将所有日志记录到全局日志记录器中,而是自定义日志记录器

private static final Logger myLogger = Logger.getLogger("psn.xiongfeng.CoreJavaVolume");
//使用使用静态常量是防止日志记录器没有被变量引用而被回收

父级日志记录器的一些属性将被子级继承,如日志级别。通常有7个日志级别:

  • SEVERE
  • WARNING
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINEST

默认情况下,只记录前三个级别,也可以设置其他的级别。可以使用 Level.ALL 开启所有级别的记录,或是 LEVEL.OFF 关闭所有级别的记录

默认的日志配置记录了 INFO 或更高级别的所有记录, 因此, 应该使用 CONFIG、FINE, FINER 和 FINEST 级别来记录那些有助于诊断,但对于程序员又没有太大意义的调试信息

如果将记录级别设计为 INFO 或者更低, 则需要修改日志处理器的配置。 默认的日志处理器不会处理低于 INFO 级别的信息。

默认的日志记录将显示包含日志调用的类名和方法名, 如同堆栈所显示的那样。 但是,如果虚拟机对执行过程进行了优化,就得不到准确的调用信息。此时,可以调用 logp 方法获得调用类和方法的确切位置

日志常见用途是记录那些不可预料的异常

修改日志管理器配置

默认的日志配置文件路径为 jre/lib/logging.properties 要使用另一个配置文件,要将 java.util.logging.config.file 特性设置为配置文件的存储位置,并使用下列命令启动应用程序:

java -Djava.util.logging.config.file = configFile MainClass

修改配置文件

.level = INFO #默认的日志记录级别
psn.xiongfeng = FINE #指定包的默认日志记录级别
java.util.logging.ConsoleHandler.level = FINE #要在控制台看到 FINE 级别的日志消息
处理器

默认情况下,日志记录器将记录发送到 ConsoleHandler 中,并由它输出到 System.err 流中。处理器也有日志记录级别。对于一个要被记录的日志记录,它的日志记录级别必须高于日志记录器和处理器的阈值。

要记录 FINE 级别的日志,除了修改配置文件外还可以绕过配置文件,使用自己的处理器

Logger logger = Logger.getLogger("psn.xiongfeng");
logger.setLevel(Level.FINE);
ConsoleHandler handler = new ConsoleHandler();
handler.setLevel(Level.FINE);
logger.addHandler(handler);

要想将日志发送到其他地方,要添加其他处理器 : FileHandler 和 SocketHandler 。SocketHandler 将记录发送到特定的主机和窗口,FileHandler 可以将记录收集到文件。

FileHandler handler = new FileHandler();
logger.addHandler(handler);//将记录发送到默认文件的处理器

这些记录将被发送到用户主目录的 javan.log 文件中

可以通过设置日志管理器配置文件中的参数或利用其它的构造器来修改文件处理器的默认行为。

配置属性 描述 默认值
java.util.logging.FileHandler.level 处理器级别 Level.ALL
java.util.logging.FileHandler.append 控制处理器应该追加到一个已经存在的文件尾部;还是应该为每个运行的程序打开一个新文件 false
java.util.logging.FileHandler.limit 在打开另一个文件之前允许写入一个文件的近似最大字节数(0 表示无限制) 在 FileHandler 类中为 0 ;在默认的日志管理器配置文件中为 50000
java.util.logging.FileHandler.pattern 日志文件名的模式 %h/java%u.log
java.util.logging.FileHandler.count 在循环序列中的日志记录数量 1(不循环)
java.util.logging.FileHandler.filter 使用的过滤器类 没有使用过滤器
java.util.logging.FileHandler.encoding 使用的字符编码 平台的编码
java.util.logging.FileHandler.formatter 记录格式器 java.util.logging.XMLFormatter

日志记录文件模式变量

变量 描述
%h 系统属性 user.home 的值
%t 系统临时目录
%u 用于解决冲突的唯一编号
%g 为循环日志记录生成的数值。(当使用循环功能且模式不包括%g时,使用后缀%g)
%% % 字符

如果多个应用程序使用同一个日志文件,就应该开启 append 标志。应该在文件名模式中使用 %u,以便每个应用程序创建日志的唯一副本。

开启文件循环功能也是一个不错的主意。日志文件以 myapp.log.O, myapp.log.1 , myapp.log.2, 这种循环序列的形式出现 3 只要文件超出了大小限制, 最旧的文件就会被删除, 其他的文件将重新命名, 同时创建一个新文件, 其编号为 0

过滤器

默认情况下,过滤器根据日志的级别进行过滤。每个日志记录器和处理器都可以有一个可选的过滤器来完成附加过滤。并可以实现 Filter 接口自定义过滤器。需要注意同一时刻,每个日志记录器和处理器最多有一个过滤器。

格式化器

想要格式化日志要扩展类 java.util.logging.Formatter 并覆盖 format 方法。已有的两种日志格式化器是XML和文本格式。调用 handler 的 setFormatter 方法将格式化器设置到处理器中。

日志记录说明

使用日志最常用的操作

  1. 为一个简单的应用程序, 选择一个日志记录器,并把日志记录器命名为与主应用程序包一样的名字

    Logger logger = Logger.getLogger("psn.xiongfeng");
    
  2. 默认的日志配置将级别等于或高于 INFO 级别的所有消息记录到控制台。用户可以覆盖默认的配置文件。但改变配置需要相当多的步骤,因此最好在应用程序中添加一个更适合的默认配置

  3. 所有级别为 INFO、WARNING、SEVERE 的消息都江显示到控制台上。因此最好只讲对程序用户有意义的消息设置为这几个级别。将程序员想要的日志记录,设定为 FINE 是一个好的选择。

posted @ 2020-08-23 22:42  PotatoTed  阅读(180)  评论(0)    收藏  举报