《Java程序设计》第8周学习总结

时间:2022-03-15 19:22:19

20145333 《Java程序设计》第8周学习总结

教材学习内容总结

NIO和NIO2

  • NIO的定义
    InputStream、OutputStream的输入输出,基本上是以字节为单位进行低层次处理,虽然需要直接面对数组,但实际上多半是对字节数组中整个区块进行处理。dump()方法是整块数据读入后又整块数据写出。

  • NIO2的定义
    现今世界上存在着各式各样的文件系统,不同的文件系统会提供不同的存取方式,文件属性,权限控制等操作。在JDK7出现以前,常需要对特定的文件撰写特定的程序,不仅撰写方式没有标准,针对特定功能撰写的程序也会增加应用程序开发者的负担。
    NIO2文件系统API提供一组标准类接口与类,应用程序开发者只要基于这些标准接口与类进行文件系统操作,底层实际如何进行文件系统的操作,是由文件系统提供者负责。

通用API

  • 日志API简介

使用日志的起点是logger类,logger实例的创建有许多要处理的要素,必须使用logger的静态方法getLogger().

通常在哪个类上取得的logger,名称空间就会命名为哪个类的全名,使用getName()就可以取得类全名,输出信息时可以使用静态成员指定信息层级。

Logger是起点,必须先通过Logger的Level与Filter过滤,再通过Handler的Level与Filter过滤,格式化信息的动作交给Formatter,输出信息的动作实际上是Handler负者。

Logger处理完自己的日志动作后,会向父Logger传播。

  • 指定日志层级

取得的Logger实例之父Logger组态,就是Logger.GLOBAL_LOGGER_NAME名称空间Logger实例,可通过getParent()取得设定的Logger实例,可通过getLevel()取得设定的Level实例。

Logger的信息处理会往父Logger传播,在没有做任何组态设定的情况下,默认取得的Logger实例,层级必须大于或等于Logger.GLOBAL_LOGGER_NAME名称空间Logger实例设定的Lever.INFO,才有可能输出信息。

可以通过setLevel()设定Level实例,若log()时指定的Lever实例内含的int值小于Logger设定的Level实例内含的int值,Level就不会记录信息。

在经过Logger过滤之后,还得再经过Handler的过滤,一个Logger可以拥有多个Handler,可通过Logger的addHandler()新增Handler实例。实际上进行信息输出时,目前Logger的Handler处理完,还会传播给父Logger的所有Handler处理,可通过getHandlers()方法取得目前已有的Handler实例数组。

  • 使用Handler与Formatter

标准API提供了几个操作类:MemoryHandler不会格式化日志信息,信息会暂存于内存缓冲区,直至超过大小才将信息输出至指定的目标Handler。
StreamHandler可自行指定信息输出时使用的OutputStream。
ConsoleHandler创建时,会自动指定OutputStream为System.err。
SocketHandler创建时可以指定主机位置与端口。
在建立FileHandler指定模式字符串时,可以使用“%h”来表示用户的根目录,还可以使用“%t”取得系统暂存目录,或者使用“%g”自动为文档编号。

  • 自定义Handler、Formatter与Filter

handler是负责输出,Formatter负责格式化,而信息过滤是由Filter。
自定义Formatter,可以继承Formatter后操作抽象方法format(),这个方法会传入logRecord,储存所有日志信息。

  • 使用logging.properties

可以通过logging.properties改变Logger组态。

国际化基础

  • 使用ResourceBundle

对于日后可能变动的文字信息,可以考虑将信息移至程序之外,方法是使用ResourceBundle来做信息绑定。
准备一个.properties文档,如messages.properties,文档内容如下:

cc.openhome.welcome=Hello
cc.openhome.name=World

import static java.lang.System.out;
import java.util.ResourceBundle;
public class Hello {
public static void main(String[] args) {
    ResourceBundle res = ResourceBundle.getBundle("messages");
    out.print(res.getString("cc.openhome.welcome") + "!");
    out.println(res.getString("cc.openhome.name") + "!");
}
}

以后想改变显示的信息,只要改变.properties文档的内容就可以了。

ResourceBundle的静态getBundle()方法会取得一个ResourceBundle实例,所给定的自变量名称是信息文档的主文件名。

  • 使用Locale

使用ResourceBundle时,如何根据基础名称取得对应的信息文档:
(1)使用指定的Locale对象取得信息文档
(2)使用Locale.getDefault()取得的对象取得信息文档
(3)使用基础名称取得信息文档

  • 规则表达式

字面意义字符是指按照字面意义比较的字符。
元字符时不按照字面比较,在不同情境有不同意义的字符。

java.util.regex.Pattern实例是规则表达式在JVM中的代表对象,Pattern的构造函数被标示为private,通过Pattern的静态方法compile()来取得。Pattern.compole()方法的另一版本,可以指定旗标(Flag)。

在取得Pattern实例后,可使用方法:
split()方法:将指定字符串依规则表达式切割
matcher()方法:指定要比较的字符串
find()方法:看看是不是有下一个符合字符串
lookingAt():看看字符串开头是否符合规则表达式
group():可以返回符合的字符串。

在取得Matcher实例后,可使用方法:
replaceAll()可以将符合规则表达式的部分以指定的字符串取代
replaceFirst()取代首个组合规则表达式的部分
replaceEnd()取代最后符合规则表达式的部分
start()方法可以取得符合字符串的初始索引
end()方法可以取得符合字符串最后一个字符后的索引

  • JDK8 API增强功能

StringJoiner、Arrays新增API

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

2.Arrays

Arrays上新增parallelPrefix()、parallelSetAll()与parallelSort()方法,parallelSort()方法,可以将指定的数组分为子数组并以平行化方式分别排序,然后再进行合并排序。指定的数组之元素必须操作`Comparable。

Stream相关API

Files上有lines()、list()、walk()等方法。
Stream、InStream、DoubleStream等都有of()静态方法,可以使用可变长度自变量方式指定元素。

本周代码托管截图

其他(感悟、思考等,可选)

这周的学习目标主要是第十五章,需要我们学会使用日志API、了解国际化基础、认识JDK8增强功能等。通过前面几周的学习,java的核心知识与难点之前都已经学完了,后面的章节大概都是介绍一些类的应用。在不断的学习中,我也在不断的寻找适合自己的学习方法。平时自己要主动敲代码,主动发现问题,提高学习效率。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 3500行 15篇 400小时
第一周 100/100 2/2 20/20
第二周 150/250 1/3 18/38
第三周 100/350 1/4 22/60
第四周 300/650 1/5 30/90
第五周 100/750 1/6 20/110
第六周 350/1100 1/7 25/135
第七周 250/1350 1/8 25/160
第八周 250/1600 1/9 25/185