JavaWriter源码分析

Posted zhangjiaofa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaWriter源码分析相关的知识,希望对你有一定的参考价值。

为何要实现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);

  • 代码分析如下

    空格符、修饰符、返回类型、方法名、括号、参数列表、括号、是否存在异常抛出的定义、花括号、代码语句
    “`

以上是关于JavaWriter源码分析的主要内容,如果未能解决你的问题,请参考以下文章

验证全名的 Java 正则表达式只允许空格和字母

AQS源码分析 - exclusive mode(独占模式 )

Dubbo 2.7.3源码分析——JDK SPI篇

Java - 全名的正则表达式

GSVA全名Gene set variation analysis(基因集变异分析)简介

jQuery 源码分析(十四) 数据操作模块 类样式操作 详解