断言(Assertion)是一种调试程序的方式。在Java中,使用assert关键字来实现断言。
假设确信某个属性符合要求, 并且代码的执行依赖于这个属性。例如, 需要计算:
double y = Math.sqrt(x);
确信,这里的 X 是一个非负数值。原因是:X 是另外一个计算的结果,而这个结果不可能是负值;或者 X 是一个方法的参数,而这个方法要求它的调用者只能提供一个正整数。 当然还应当进行检查, 以避免让“ 不是一个数” 的数值参与计算操作。
可以抛出一个异常:
if (x < 0) throw new 111egalArgumentException("x < 0");
但是这段代码会一直保留在程序中, 即使测试完毕也不会自动地删除。如果在程序中含有大量的这种检查,程序运行起来会相当慢。
断言机制允许在测试期间向代码中插入一些检査语句。当代码发布时,这些插人的检测语句将会被自动地移走。
Java 语言引人了关键字 assert。这个关键字有两种形式:
assert 条件;
assert 条件:表达式;
这两种形式都会对条件进行检测, 如果结果为 false, 则抛出一个 AssertionError 异常。
在第二种形式中,表达式将被传人 AssertionError 的构造器, 并转换成一个消息字符串。
在默认情况下, 断言被禁用。可以在运行程序时用 -enableassertions 或 -ea 选项启用:
java -enableassertions MyApp
需要注意的是, 在启用或禁用断言时不必重新编译程序。启用或禁用断言是类加载器( class loader) 的功能。当断言被禁用时, 类加载器将跳过断言代码, 因此,不会降低程序运行的速度。
也可以在某个类或整个包中使用断言, 例如:
java -ea:MyClass -eaiconi.inycompany.inylib.. , MyApp
这条命令将开启 MyClass 类以及在 com.mycompany.mylib 包和它的子包中的所有类的断言。选项 -ea 将开启默认包中的所有类的断言。
也可以用选项 -disableassertions 或 -da 禁用某个特定类和包的断言:
ava -ea:... -da:MyClass MyApp
每个 Java 程序员都很熟悉在有问题的代码中插入一些 System.out.println 方法调用来帮助观察程序运行的操作过程。 当然, 一旦发现问题的根源, 就要将这些语句从代码中删去。如果接下来又出现了问题, 就需要再插入几个调用 System.out.println方法的语句。
记录日志API 就是为了解决这个问题而设计的。
下面先讨论这些 API 的优点。
要生成简单的日志记录,可以使用全局日志记录器(global logger) 并调用其 info 方法:
Logger.getClobal 0,info("File->Open menu item selected");
在默认情况下,这条记录将会显示以下内容:
May 10, 2013 10:12:15 PM LogginglmageViewer fileOpen
INFO: File->0pen menu item selected
但是, 如果在适当的地方(如 main 开始)调用
Logger.getClobal ().setLevel (Level .OFF);
将会取消所有的日志。
从前面已经看到“ 虚拟日志”,下面继续看一下企业级( industrial-strength) 日志。在一个专业的应用程序中,不要将所有的日志都记录到一个全局日志记录器中,而是可以自定义日志记录器。
可以调用 getLogger 方法创建或获取记录器:
private static final Logger myLogger = Logger.getLogger("com.mycompany.myapp"):
与包名类似,日志记录器名也具有层次结构。事实上, 与包名相比,日志记录器的层次性更强。 对于包来说,一个包的名字与其父包的名字之间没有语义关系,但是日志记录器的父与子之间将共享某些属性。例如, 如果对 com.mycompany 日志记录器设置了日志级别,它的子记录器也会继承这个级别 。
通常, 有以下 7 个日志记录器级别:
在默认情况下,只记录前夂个级别。 也可以设置其他的级別。例如:
logger,setLevel (Level .FINE);
现在, FINE 和更高级别的记录都可以记录下来。 另外, 还可以使用 Level.ALL 开启所有级别的记录, 或者使用 Level.OFF 关闭所有级别的记录。 对于所有的级别有下面几种记录方法:
logger.warning(message):
logger,fine(message) ;
同时, 还可以使用 log 方法指定级别, 例如:
logger.log(Level .FINE, message);
日志记录常用的操作:
可以通过调用下列方法得到日志记录器:
Logger logger = Logger.getLogger("com.mycompany.myprog");
为了方便,可以利用一些日志操作将下面的静态域添加到类中:
private static final Logger logger = Logger.getLogger("com.mycompany.nyprog"):
下列代码确保将所有的消息记录到应用程序特定的文件中。可以将这段代码放置在应用程序的 main方法中。
if (System,getProperty("java,util.logging.config.dass") == null
&& System.getPropertyC'java.util.logging.config.file") == null) {
try
{
Logger.getLogger("").setLevel(Level.ALL);
final int L0C_R0TATI0N_C0UNT = 10;
Handler handler = new FileHandler('Wmyapp.log", 0, L0G_R0TATI0N_C0UNT):
Logger.getLogger("").addHandler(handler): }
catch (IOException e) {
logger.log(Level.SEVERE, "Can't create log file handler", e);
}
}
当调用 System.out.println 时, 实际上生成了下面的日志消息:
logger.fine("File open dialog canceled";
记录那些不可预料的异常也,例如:
try
{}
catch (SonreException e) {
logger,log(Level.FINE, "explanation", e);
}
在Intellij IDEA中使用Debug how2j.java:如何在Eclipse中调试Java程序 W3Cschool:jUnit教程 Spring Boot干货系列:(十二)Spring Boot使用单元测试
参考: 【1】:《Java核心技术 卷一》 【2】:廖雪峰的官方网站:使用断言 【3】:廖雪峰的官方网站:使用JDK Logging 【4】:廖雪峰的官方网站:使用Commons Logging 【5】:廖雪峰的官方网站:使用Log4j 【6】:廖雪峰的官方网站:使用SLF4J和Logback 【7】:how2j.java: Log4j系列教材