为何要实现Closeable的接口
Closeable的英文注释
A {@code Closeable} is a source or destination of data that can be closed.
The close method is invoked to release resources that the object is
holding (such as open files).
@since 1.5翻译如下
Closable是一个数据的起始源与目的源能够被释放掉。关闭的方法将会触发去释放资源,而这些资源是被对象所持有。比如说正在处于打开的文件。
importedTypes的变量的作用
- importedTypes的英文注释
Map fully qualified type names to their short names.
- 翻译如下
HashMap中存储的是键值是合法的名称与他们的名称缩写的映射。
枚举Scope的定义是个什么鬼
- 枚举内部定义如下
TYPE_DECLARATION,
INTERFACE_DECLARATION,
ABSTRACT_METHOD,
NON_ABSTRACT_METHOD,
CONSTRUCTOR,
CONTROL_FLOW,
ANNOTATION_ATTRIBUTE,
ANNOTATION_ARRAY_VALUE,
INITIALIZER
- 代码块的分析
枚举内部定义的是类型定义、接口声明、抽象方法、非抽象方法、构造函数、控制流、注解属性、注解数组的数值。
一个Java源文件的构造用
private final Deque scopes = new ArrayDeque();
private final Deque types = new ArrayDeque();
来进行封装。
构造函数是怎样的
代码定义如下:
public JavaWriter(Writer out) {
this.out = out;
}稍加说明
参数中的输出流是Java源文件将要被写入。其中Writer应该是一个Buffer 的流。
如何利用Writer的流来构造Package的定义
- 代码定义如下
if (this.packagePrefix != null) {
throw new IllegalStateException();
}
if (packageName.isEmpty()) {
this.packagePrefix = "";
} else {
out.write("package ");
out.write(packageName);
out.write(";\n\n");
this.packagePrefix = packageName + ".";
}
整体的Package的拼接风格与日常的代码的编写保持一致。
如何构造import语句
- 代码定义如下
for (String type : new TreeSet<String>(types)) {
Matcher matcher = TYPE_PATTERN.matcher(type);
if (!matcher.matches()) {
throw new IllegalArgumentException(type);
}
if (importedTypes.put(type, matcher.group(1)) != null) {
throw new IllegalArgumentException(type);
}
out.write("import ");
out.write(type);
out.write(";\n");
}
其中数据结构有用到TreeSet,TreeSet类实现了SortedSet接口,能够对集合中的对象进行排序。
compressType是干什么用得
为了与我们正常的代码保持一致,在导入相应的包以后,很多的类就不用写全名,也就是类名的缩写的算法的定义。
成员变量的定义是如何写入到源文件中的
代码的定义
indent();
emitModifiers(modifiers);
emitCompressedType(type);
out.write(" ");
out.write(name);
if (initialValue != null) {
out.write(" =");
if (!initialValue.startsWith("\n")) {
out.write(" ");
}
String[] lines = initialValue.split("\n", -1);
out.write(lines[0]);
for (int i = 1; i < lines.length; i++) {
out.write("\n");
hangingIndent();
out.write(lines[i]);
}
}
out.write(";\n");大致说明一下
一个变量的定义写入到源文件,大致分下面的过程:空格符写入、变量的修饰符的写入、变量的类型的构造(因为可能存在缩写)、接下来就是等于号、变量的数值的写入(由于数值有可能过长,考虑到换行的代码的逻辑。)
成员方法的定义是如何写入到源文件中
代码定义如下
indent();
emitModifiers(modifiers);
if (returnType != null) {
emitCompressedType(returnType);
out.write(" ");
out.write(name);
} else {
emitCompressedType(name);
}
out.write("(");
if (parameters != null) {
for (int p = 0; p < parameters.size();) {
if (p != 0) {
out.write(", ");
}
emitCompressedType(parameters.get(p++));
out.write(" ");
emitCompressedType(parameters.get(p++));
}
}
out.write(")");
if (throwsTypes != null && throwsTypes.size() > 0) {
out.write("\n");
indent();
out.write(" throws ");
for (int i = 0; i < throwsTypes.size(); i++) {
if (i != 0) {
out.write(", ");
}
emitCompressedType(throwsTypes.get(i));
}
}
if (modifiers.contains(ABSTRACT) || Scope.INTERFACE_DECLARATION.equals(scopes.peek())) {
out.write(";\n");
scopes.push(Scope.ABSTRACT_METHOD);
} else {
out.write(" {\n");
scopes.push(returnType == null ? Scope.CONSTRUCTOR : Scope.NON_ABSTRACT_METHOD);}代码分析如下
空格符、修饰符、返回类型、方法名、括号、参数列表、括号、是否存在异常抛出的定义、花括号、代码语句
“`