201711671224 《Java程序设计》第15章学习总结

教材学习内容总结

日志API

使用日志的起点是Logger类,LOgger实例的创建有许多要处理的要素,LOgger类的构造函数标识为protected,不是java.util.logging同包的类不能直接以new创建,要取得Logger实例,必须使用Logger的静态方法getlogger()。

调用getLogger()是,必须指定Logger实例所属名称空间,名称空间以“.”作为层级区分,名称空间层级相同的Logger其父Logger组态相同。

通常在那个类中取得的Logger,名称空间就会命名为那个类全名。经常的,也会通过以一下方式取得Logger。

import java.util.logging.*;

public class LoggerDemo {
public static void main(String[] args) {
    Logger logger = Logger.getLogger(LoggerDemo.class.getName());
    logger.log(Level.WARNING, "WARNING 訊息");
    logger.log(Level.INFO, "INFO 訊息");
    logger.log(Level.CONFIG, "CONFIG 訊息");
    logger.log(Level.FINE, "FINE 訊息");
}
}

运行结果如下:

如果客户端调用了Logger实例的log()方法,首先会依据Level过滤信息,再看看Logger有无设定Filter接口的实例,如果有且其isLoggable()返回true,才会调用handle实例的publish()方法,handle也可设定自己的Filter实例,如果有且其isLoggable()返回true,就调用Formatter实例的format()方法格式化信息,最后在调用输出对象将格式化的信息输出。

Handle与Formatter

Handle分为MemoryHandle和StreamHandle,其中StreamHandle又分为ConsoleHandle、FileHandle和SockeHandle。

Logger可以使用addHandle()新增Handle实例,使用removeHandle()移除Handle。例如一下实例:


public class HandlerDemo {
public static void main(String[] args) throws IOException {
    Logger logger = Logger.getLogger(HandlerDemo.class.getName());
    logger.setLevel(Level.CONFIG);
    FileHandler handler = new FileHandler("%h/config.log");
    handler.setLevel(Level.CONFIG);
    logger.addHandler(handler);
    logger.config("Logger 組態完成");
}
}

在建立FileHandle指定模式字符串时,可以使用"%h"来表示用户的根目录,还可以用"&t"来取得系统暂存目录,或者使用"%g"自动为文档编号。

FileHandle默认的Formatter是XMLFormatter,前面看过的ConsoleHandle默认使用SimpleFormatter,这两类是Formatter的子类,可以通过Handle的setFormatter()方法设定Formatter。

Pattern与Matcher

  • 在程序中使用表示式,必须先针对规则表示式做剖析、验证等动作,确定规则表示式语法无误,对字符串进行比较。
  • java.util.regex.Pattern实例是规则表示式在JVM中的代表对象,Pattern的构造函数被标示为private,必须通过Pattern的静态方法compile()来取得。

  • 在取得Pattern的实例后,可以使用split()方法将指定字符串依规则表示式切割,效果等于使用String的split()方法。

JDK8 API增强功能

String,join():String新增join()静态方法可以指定每个字符串间以逗号分隔进行连接。

Arrays:

  • Arrays上新增parallelPrefix()、parallelSetAll()与parallelSort()方法。
  • parallelPrefix()方法,可以指定xxxBinaryOperator实例,执行类似Stream的reduce()过程。
  • parallelSetAll()方法,用来对数组进行初始化或全面重设每个索引元素。
  • parallelSort()方法,可以将指定的数组分为子数组并以平行化方式分别排序,然后再进行合并排序。

国际化基础

应用程序根据不同的地区用户,呈现不同的语言、日期格式等称为本地化,如果应用程序设计是,可以爱不修改应用程序情况下,根据不同用户直接采用不同语言日期格式等,这样的设计考虑成为国际化,简称i18n。

国际化的三个重要概念是地区信息、资源包与基础名称。地区信息的对应类Locale,ResourceBundle对象是JVM中资源包的代表对象。代表同一组信息但不同地区的各个资源包会共享相同的基础名称,使用ResourceHandle的getBundle()时指定的名称就是在指定基础名称。

使用ReasourceBUndle是,如何根据基础名称取得对应的信息文档:

  1. 使用指定的Locale对象取得信息文档。
  2. 使用Locale.getDefault()取得的对象取得信息文档。
  3. 使用基础名称取得信息文档

可以使用Date来取得完整的日期时间,可单纯使用toString()取得日期文字描述,或使用DateFormat格式化日期。若查看Date的API文件,会发现许多方法都不再建议使用,建议使用Calendar的相关方法取代。

日志API简介

java.util.logging包提供了日志功能相关类与接口。不必额外配置日志组件,就可在标准Java平台使用是其好处,使用日志的起点是Logger类,Logger类的构造函数标示为protected,不是java.util.logging同包的类不能直接以new创建,要取得Logger实例,必须使用Logger的静态方法getLogger()。调用getLogger()时,必须指定Logger实例所属名称空间。名称空间以“.”作为层级区分。名称空间层级相同的Logger,其父Logger组态相同。通常在哪个类中取得的Logger,名称空间就会命名为哪个类全名。简单来说,Logger是记录信息的起点,要输出的信息,必须先通过Logger的Level与Filter过滤,再通过Handler的Level与Filter过滤,格式化信息的动作交给Formatter,输出信息的动作实际上是Handler负责。

指定日志层级

Logger与Handler默认都会先依据Level过滤信息,如果没有做任何修改,取得的Logger实例之父Logger组态,就是Logger.GLOBALLOGGERNAME名称空间Logger实例的组态,这个实例的组态设定为INFO,可以通过Logger实例的getParent()取得父Logger实例,可通过getLevel()取得设定的Level实例。Logger的信息处理会往父Logger传播,也就是说,在没有做任何组态设定的情况下,默认取得的Logger实例,层级必须大于或等于Logger.GLOBALLOGGERNAME名称空间Logger实例设定的Level.INFO,才有可能输出信息。

使用Handler与Formatter

MemoryHandler不会格式化日志信息,信息会暂存于内存缓冲区,直到超过缓冲区大小,才将信息输出至指定的目标Handler。StreamHandler可自行指定信息输出时使用的OutputStream实例,它与子类都会使用指定的Formatter格式化信息,ConsoleHandler创建时,会自动指定OutputStream为System.err,所以日志信息会显示在控制台上。FileHandler创建时会建立日志输出时使用的FileOutputStream,文档位置与名称可以使用模式(Pattern)字符串指定。

自定义Handler、Formatter、Filter

如果java.util.logging包中提供的Handler成果都不符合需求,可以继承Handler类,操作抽象方法publish(),flush(),close()来自定义Handler,建议操作时考虑信息过滤与格式化。

代码调试中的问题和解决过程

暂无

其他(感悟、思考等)

参考资料

  • 《Java程序设计》

猜你喜欢

转载自blog.csdn.net/nemeziz/article/details/85042795