Java中的屠龙之术

Java中的屠龙之术

JCTree的介绍

CTree(Java Compiler Tree API)是 Java 编译器提供的一组 API,用于操作和分析 Java 代码的抽象语法树(AST)。JCTree API 在 com.sun.tools.javac.tree 包中提供,并且是 Java 编译器的一部分。它允许开发者在编译期间访问和修改 Java 代码的结构,从而实现代码生成、代码检查、代码转换等功能。

JCTree API 允许你以编程方式操作 AST 中的不同元素,如类、方法、字段、表达式等

以下是一些常见的 JCTree API 类和接口,以及它们的一些重要方法:

  1. JCCompilationUnit:表示整个编译单元(源文件)的抽象语法树。它是 AST 的根节点。
  2. JCClassDecl:表示类或接口的声明。
  3. JCMethodDecl:表示方法的声明。
  4. JCVariableDecl:表示变量(字段)的声明。
  5. JCExpression:表示表达式,如赋值、算术运算、方法调用等。
    • JCAssign:赋值语句语法树节点
    • JCIdent:标识符语法树节点,可以是变量,类型,关键字等等
  6. JCStatement:表示语句,如 if、while、for、return 等。
    • JCBlock:语句块语法树节点
    • JCReturn:return语句语法树节点
  7. JCTreeVisitor:用于遍历和访问 AST 的访问者接口。你可以通过实现这个接口来定义如何处理不同类型的节点。

JavacTrees

com.sun.tools.javac.api.JavacTrees 是 Java 编译器(javac)提供的一个工具类,用于在注解处理器中访问和操作抽象语法树(AST)。它为注解处理器提供了一些便捷的方法,使得开发者可以更容易地在编译时处理 Java 源代码的结构。

JavacTrees 类主要用于获取与 AST 相关的一些工具和对象,包括:

  1. TreeMaker:用于创建新的 AST 节点,如创建类、方法、字段、表达式等。

  2. ElementTypeElement 的转换:可以将 Element 对象(表示程序元素)转换为对应的 TypeElementExecutableElement 等对象,以便进行更详细的操作。

  3. getTree(Element element):获取给定程序元素的对应 AST 节点。通过调用这个方法,你可以获取到表示该元素的 AST 节点。

  4. getScope(Element element):获取给定程序元素的对应作用域对象。这个作用域对象可以用于查询和分析元素的可见性等信息。

请注意,com.sun.tools.javac.api.JavacTrees 类属于 com.sun.tools.javac 包,这意味着它位于 javac 编译器的内部实现中。

以下是一个简单的示例,演示了如何在注解处理器中使用 JavacTrees 获取 AST 相关的信息:

TreeMaker

TreeMaker.Modifiers

TreeMaker.Modifiers方法用于创建访问标志语法树节点(JCModifiers)

public JCModifiers Modifiers(long flags) {return Modifiers(flags, List.< JCAnnotation >nil());
}public JCModifiers Modifiers(long flags,List annotations) {JCModifiers tree = new JCModifiers(flags, annotations);boolean noFlags = (flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0;tree.pos = (noFlags && annotations.isEmpty()) ? Position.NOPOS : pos;return tree;
}
  • flags:访问标志
  • annotations:注解列表
treeMaker.Modifiers(Flags.PUBLIC + Flags.STATIC + Flags.FINAL);public static final
TreeMaker.ClassDef

TreeMaker.ClassDef用于创建类定义语法树节点(JCClassDecl)

public JCClassDecl ClassDef(JCModifiers mods,Name name,List typarams,JCExpression extending,List implementing,List defs) {JCClassDecl tree = new JCClassDecl(mods,name,typarams,extending,implementing,defs,null);tree.pos = pos;return tree;
}
  • mods:访问标志,可以通过TreeMaker.Modifiers来创建
  • name:类名
  • typarams:泛型参数列表
  • extending:父类
  • implementing:实现的接口
  • defs:类定义的详细语句,包括字段、方法的定义等等
TreeMaker.MethodDef

TreeMaker.MethodDef用于创建方法定义语法树节点(JCMethodDecl)

public JCMethodDecl MethodDef(JCModifiers mods,Name name,JCExpression restype,List typarams,List params,List thrown,JCBlock body,JCExpression defaultValue) {JCMethodDecl tree = new JCMethodDecl(mods,name,restype,typarams,params,thrown,body,defaultValue,null);tree.pos = pos;return tree;
}public JCMethodDecl MethodDef(MethodSymbol m,Type mtype,JCBlock body) {return (JCMethodDecl)new JCMethodDecl(Modifiers(m.flags(), Annotations(m.getAnnotationMirrors())),m.name,Type(mtype.getReturnType()),TypeParams(mtype.getTypeArguments()),Params(mtype.getParameterTypes(), m),Types(mtype.getThrownTypes()),body,null,m).setPos(pos).setType(mtype);
}
  • mods:访问标志
  • name:方法名
  • restype:返回类型
  • typarams:泛型参数列表
  • params:参数列表
  • thrown:异常声明列表
  • body:方法体
  • defaultValue:默认方法(可能是interface中的哪个default)
  • m:方法符号
  • mtype:方法类型。包含多种类型,泛型参数类型、方法参数类型、异常参数类型、返回参数类型。
TreeMaker.VarDef

TreeMaker.VarDef用于创建字段/变量定义语法树节点

public JCVariableDecl VarDef(JCModifiers mods,Name name,JCExpression vartype,JCExpression init) {JCVariableDecl tree = new JCVariableDecl(mods, name, vartype, init, null);tree.pos = pos;return tree;
}public JCVariableDecl VarDef(VarSymbol v,JCExpression init) {return (JCVariableDecl)new JCVariableDecl(Modifiers(v.flags(), Annotations(v.getAnnotationMirrors())),v.name,Type(v.type),init,v).setPos(pos).setType(v.type);
}
  • mods:访问标志
  • name:参数名称
  • vartype:类型
  • init:初始化语句
  • v:变量符号
TreeMaker.Ident

TreeMaker.Ident用于创建标识符语法树节点

public static class JCIdent extends JCTree.JCExpression implements IdentifierTree {public Name name;//标识符的名字public Symbol sym;//代表类时为包名+类名,代表其他类型数据时为nullprotected JCIdent(Name var1, Symbol var2) {this.name = var1;this.sym = var2;}
}-->创建实例: 获取变量textView的引用
treeMaker.Ident(names.fromString("textView"))))
TreeMaker.Return

TreeMaker.Return用于创建return语句

public static class JCReturn extends JCTree.JCStatement implements ReturnTree {public JCTree.JCExpression expr;//返回语句的结果字段
}-->例子:retrun this.xxx
treeMaker.Return(treeMaker.Select(treeMaker.Ident(names.fromString("this")),names.fromString("xxx")));
TreeMaker.Select

TreeMaker.Select用于创建域访问/方法访问

public JCFieldAccess Select(JCExpression selected,Name selector) 
{JCFieldAccess tree = new JCFieldAccess(selected, selector, null);tree.pos = pos;return tree;
}public JCExpression Select(JCExpression base,Symbol sym) {return new JCFieldAccess(base, sym.name, sym).setPos(pos).setType(sym.type);
}
  • selected:.运算符左边的表达式
  • selector:.运算符右边的表达式
TreeMaker.Select(treeMaker.Ident(names.fromString("this")), names.fromString("name"));this.name
TreeMaker.Apply

TreeMaker.Apply用于创建方法调用语法树节点

public JCMethodInvocation Apply(List typeargs,JCExpression fn,List args) {JCMethodInvocation tree = new JCMethodInvocation(typeargs, fn, args);tree.pos = pos;return tree;
}
  • typeargs:参数类型列表
  • fn:调用语句
  • args:参数列表
TreeMaker.Assign

TreeMaker.Assign用户创建赋值语句语法树节点

ublic JCAssign Assign(JCExpression lhs,JCExpression rhs) {JCAssign tree = new JCAssign(lhs, rhs);tree.pos = pos;return tree;
}
  • lhs:赋值语句左边表达式
  • rhs:赋值语句右边表达式
TreeMaker.Exec

TreeMaker.Exec用于创建可执行语句语法树节点

public JCExpressionStatement Exec(JCExpression expr) {JCExpressionStatement tree = new JCExpressionStatement(expr);tree.pos = pos;return tree;
}

TreeMaker.Apply以及TreeMaker.Assign就需要外面包一层TreeMaker.Exec来获得一个JCExpressionStatement

TreeMaker.Block

TreeMaker.Block用于创建组合语句的语法树节点

public JCBlock Block(long flags,List stats) {JCBlock tree = new JCBlock(flags, stats);tree.pos = pos;return tree;
}
  • flags:访问标志
  • stats:语句列表
public static class JCBlock extends JCTree.JCStatement implements BlockTree {public long flags;//访问修复符public List stats;//多行代码列表
}-->使用例子:
List jcStatementList = List.nil();
treeMaker.Block(0, jcStatementList);//构建代码块
JCIf

if代码块; if(condition) {thenpart} else {elsepart}

public static class JCIf extends JCTree.JCStatement implements IfTree {public JCTree.JCExpression cond;//条件语句public JCTree.JCStatement thenpart;//if的操作语句public JCTree.JCStatement elsepart;//else的操作语句
}
JCForLoop

for循环代码块;for (init; cond; step) {body}

public static class JCForLoop extends JCTree.JCStatement implements ForLoopTree {public List init;public JCTree.JCExpression cond;public List step;public JCTree.JCStatement body;
}
JCTry、JCCatch
public static class JCTry extends JCTree.JCStatement implements TryTree {public JCTree.JCBlock body;//try代码块public List<JCTree.JCCatch> catchers;//JCCatchpublic JCTree.JCBlock finalizer;//final代码块public List<JCTree> resources;//List.nil(),用不上的字段public boolean finallyCanCompleteNormally;//
}-->JCCatch
public static class JCCatch extends JCTree implements CatchTree {public JCTree.JCVariableDecl param;//catch的异常类型public JCTree.JCBlock body;//catch代码块
}

AbstractProcessor

AbstractProcessor 是 Java 注解处理器的一个抽象类,它是 Java 编译器提供的工具,用于处理源代码中的注解。注解处理器可以在编译时扫描和处理源代码中的注解信息,并根据注解生成代码、进行静态分析、执行代码检查等操作。

注解处理器是 Java 编译器的一部分,它可以用于生成额外的代码,修改现有的代码结构,或者在编译期间执行其他任务。这使得注解处理器非常适用于一些元编程和自动化的场景。

AbstractProcessor 作为注解处理器的抽象类,提供了一些常用的方法和操作,使得开发者可以更方便地编写自定义的注解处理器。它是 Java 标准库中的一部分,位于 javax.annotation.processing 包中。

以下是 AbstractProcessor 类的一些重要方法和用途:

  1. init 方法:在注解处理器被初始化时调用。开发者可以在这里进行初始化操作。

  2. getSupportedAnnotationTypes 方法:返回一个字符串集合,表示该处理器支持处理哪些注解。这些注解可以是完全限定名,也可以使用通配符。

  3. getSupportedSourceVersion 方法:返回一个表示支持的 Java 源代码版本的枚举值。通常返回 SourceVersion.latestSupported()

  4. process 方法:核心方法,用于处理注解。在这个方法中,你可以获取到编译器提供的注解信息和相关元素,然后执行处理逻辑。

ProcessingEnvironment

javax.annotation.processing.ProcessingEnvironment 是 Java 注解处理器的一个核心接口,它提供了注解处理器在编译时与编译环境进行交互的能力。通过 ProcessingEnvironment,注解处理器可以访问编译器提供的各种工具和信息,从而实现自定义的代码生成、静态分析、代码检查等功能。

ProcessingEnvironment 接口定义了许多有用的方法,使得注解处理器能够获取有关编译环境的各种信息。以下是一些 ProcessingEnvironment 接口中常用的方法:

  1. Messager getMessager():获取用于输出消息的 Messager 对象,允许注解处理器在编译时输出信息、警告和错误。

  2. Filer getFiler():获取用于生成文件的 Filer 对象,允许注解处理器生成新的源代码文件、类文件等。

  3. Elements getElementUtils():获取用于访问程序元素的 Elements 对象,允许注解处理器访问和操作源代码中的各种元素。

  4. Types getTypeUtils():获取用于处理类型信息的 Types 对象,允许注解处理器执行类型检查、类型转换等操作。

  5. Map getOptions():获取注解处理器的选项集合,允许注解处理器获取外部传递的参数和选项。

  6. Locale getLocale():获取当前环境的语言设置,可以用于在不同语言环境下生成本地化的消息。

RoundEnvironment

在 Java 注解处理器中,RoundEnvironment 是一个用于表示当前编译轮次的对象,它提供了有关编译期间的注解信息和元素的访问接口。注解处理器在每个编译轮次都会被调用一次,并且每轮的 RoundEnvironment 对象都会提供当前轮次中的注解和元素信息。

每一轮的 RoundEnvironment 对象会包含一组元素,这些元素是被处理器所关注的注解所标注的程序元素(例如类、方法、字段等)。通过 RoundEnvironment,注解处理器可以获取到在当前轮次中被标注的元素,并进行相应的处理。

下面是一些常见的 RoundEnvironment 方法和用途:

  1. getElementsAnnotatedWith(Class a):返回一个被给定注解标注的元素集合。通过传递注解的类对象,可以获取到被标注的类、方法、字段等元素。

  2. getElementsAnnotatedWith(TypeElement a):与上述方法类似,但是接受一个 TypeElement 参数。

  3. getElementsAnnotatedWith(javax.lang.model.element.ElementKind kind):返回指定元素类型的元素集合,例如 ElementKind.CLASSElementKind.METHOD 等。

  4. getRootElements():返回当前轮次中所有被处理的根元素,通常是源文件中的类。

ElementKind

javax.lang.model.element.ElementKind 是 Java 注解处理器中的一个枚举类型,用于表示程序元素(element)的种类或类型。程序元素是源代码中的各种构造,如类、接口、方法、字段等。ElementKind 枚举为每种元素提供了一个常量,帮助注解处理器在处理过程中判断和识别不同类型的元素。

以下是 ElementKind 中的一些常见元素种类和对应的常量:

  1. PACKAGE:表示包(package)元素。

  2. ENUM:表示枚举类型(enum)元素。

  3. CLASS:表示类(class)元素。

  4. INTERFACE:表示接口(interface)元素。

  5. ANNOTATION_TYPE:表示注解类型(annotation type)元素。

  6. ENUM_CONSTANT:表示枚举常量(enum constant)元素。

  7. FIELD:表示字段(field)元素。

  8. PARAMETER:表示方法或构造函数的参数(parameter)元素。

  9. LOCAL_VARIABLE:表示局部变量(local variable)元素。

  10. EXCEPTION_PARAMETER:表示异常参数(exception parameter)元素。

  11. METHOD:表示方法(method)元素。

  12. CONSTRUCTOR:表示构造函数(constructor)元素。

  13. STATIC_INIT:表示静态初始化块(static initializer)元素。

  14. INSTANCE_INIT:表示实例初始化块(instance initializer)元素。

  15. OTHER:表示其他未知类型的元素。

通过使用 ElementKind,注解处理器可以在处理不同类型的元素时执行不同的逻辑。例如,你可以根据元素的种类来判断是否生成额外的代码,或者是否进行特定类型的静态分析。

以下是一个简单的示例,演示如何使用 ElementKind 判断不同类型的元素:

import javax.annotation.processing.*;
import javax.lang.model.element.*;
import javax.lang.model.SourceVersion;
import java.util.Set;@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class ElementKindExample extends AbstractProcessor {@Overridepublic boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {for (Element element : roundEnv.getRootElements()) {ElementKind kind = element.getKind();System.out.println("Element: " + element.getSimpleName() + ", Kind: " + kind);if (kind == ElementKind.CLASS) {System.out.println("Found class: " + element.getSimpleName());} else if (kind == ElementKind.METHOD) {System.out.println("Found method: " + element.getSimpleName());} else if (kind == ElementKind.FIELD) {System.out.println("Found field: " + element.getSimpleName());}}return true;}
}

在上述示例中,ElementKindExample 注解处理器遍历所有根元素,并根据元素的种类输出相应的信息。这有助于你了解不同类型的元素在注解处理器中的表现和处理方式。

通过熟悉和使用 ElementKind,你可以更好地理解和操作程序元素,从而在注解处理器中实现各种功能。

ExecutableElement

javax.lang.model.element.ExecutableElement 是 Java 注解处理器中的一个接口,它表示可执行元素,即方法和构造函数。ExecutableElement 继承自 Element 接口,提供了访问和操作方法和构造函数的属性和信息的方法。

在注解处理器中,你可以使用 ExecutableElement 来获取方法和构造函数的相关信息,例如方法名、参数、返回类型、注解等。

以下是 ExecutableElement 接口中的一些常用方法:

  1. List getParameters():获取方法或构造函数的参数列表。

  2. TypeMirror getReturnType():获取方法的返回类型。

  3. List getThrownTypes():获取方法可能抛出的异常类型列表。

  4. TypeElement getEnclosingElement():获取包含该方法或构造函数的元素,通常是类或接口。

  5. boolean isVarArgs():检查方法是否为可变参数方法。

  6. boolean isDefault():检查方法是否为接口的默认方法。

  7. List getTypeParameters():获取方法或构造函数的类型参数列表。

  8. List getThrownTypes():获取方法可能抛出的异常类型列表。

  9. ExecutableType asType():将此 ExecutableElement 转换为 ExecutableType,用于进行类型检查。

TypeElement

javax.lang.model.element.TypeElement 是 Java 注解处理器中的一个接口,它表示程序元素中的类或接口。TypeElement 继承自 Element 接口,提供了访问和操作类和接口的属性和信息的方法。

在注解处理器中,你可以使用 TypeElement 来获取类和接口的相关信息,例如类名、父类、实现的接口、内部类、注解等。

以下是 TypeElement 接口中的一些常用方法:

  1. Name getQualifiedName():获取类或接口的限定名,以 Name 对象表示。

  2. TypeMirror getSuperclass():获取类的父类的类型。

  3. List getInterfaces():获取类或接口实现的接口的类型列表。

  4. List getEnclosedElements():获取类或接口中的成员元素,如字段、方法、内部类等。

  5. TypeMirror asType():将此 TypeElement 转换为 DeclaredType,用于进行类型检查。

  6. boolean isInterface():检查是否为接口。

  7. boolean isEnum():检查是否为枚举类型。

  8. boolean isAnnotation():检查是否为注解类型。

  9. boolean isClass():检查是否为类类型。

Messager

javax.annotation.processing.Messager 是 Java 注解处理器中的一个接口,它提供了向注解处理器的使用者(通常是开发者)报告消息、警告和错误的能力。通过 Messager,注解处理器可以向编译器输出信息,帮助开发者了解代码处理过程中的情况,以及可能需要修复的问题。

Messager 接口定义了一些方法,允许注解处理器输出消息、警告和错误。以下是 Messager 接口中常用的方法:

  1. void printMessage(Diagnostic.Kind kind, CharSequence msg):输出一条消息,可以是信息、警告或错误。

  2. void printMessage(Diagnostic.Kind kind, CharSequence msg, Element e):输出一条消息,并指定与该消息关联的元素。

  3. void printMessage(Diagnostic.Kind kind, CharSequence msg, Element e, AnnotationMirror a):输出一条消息,并指定与该消息关联的元素和注解镜像。

  4. void printMessage(Diagnostic.Kind kind, CharSequence msg, Element e, AnnotationMirror a, AnnotationValue v):输出一条消息,并指定与该消息关联的元素、注解镜像和注解值。

  5. void printMessage(Diagnostic.Kind kind, CharSequence msg, Element e, AnnotationMirror a, AnnotationValue v, AnnotationValue v1):输出一条消息,并指定与该消息关联的元素、注解镜像、注解值等。

  6. void printMessage(Diagnostic.Kind kind, CharSequence msg, Element e, AnnotationMirror a, AnnotationValue v, AnnotationValue v1, AnnotationValue v2):输出一条消息,并指定与该消息关联的元素、注解镜像、注解值等。

在编写注解处理器时,通常会使用 Messager 输出信息、警告和错误,以便在编译时向开发者传达处理结果和可能的问题。下面是一个简单的示例,展示了如何在注解处理器中使用 Messager 输出消息和警告:

作用到类上捕获异常
package com.jct.demo.processor;/*** CatchAndLogProcessor* 

* Description*

* Creation Time: 2023/8/14.** @author zhennan.Xu* @since terry-boot*/import com.sun.source.util.Trees; import com.sun.tools.javac.api.JavacTrees; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.model.JavacElements; import com.sun.tools.javac.processing.JavacProcessingEnvironment; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.Names;import javax.annotation.processing.*; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import javax.tools.Diagnostic; import java.util.Set;@SupportedAnnotationTypes("com.jct.demo.processor.CatchAndLog") @SupportedSourceVersion(SourceVersion.RELEASE_8) public class CatchAndLogProcessor extends AbstractProcessor {private Trees trees;protected Messager messager;// 封装了创建AST节点的一些方法protected TreeMaker treeMaker;// 提供了创建标识符的方法protected Names names;/*** 用来处理Element的工具类* Elements接口的对象,用于操作元素的工具类。*/private JavacElements elementUtils;@Overridepublic synchronized void init(ProcessingEnvironment processingEnv) {super.init(processingEnv);trees = Trees.instance(processingEnv);this.trees = JavacTrees.instance(processingEnv);Context context = ((JavacProcessingEnvironment) processingEnv).getContext();this.treeMaker = TreeMaker.instance(context);this.names = Names.instance(context);messager = processingEnv.getMessager();elementUtils = (JavacElements) processingEnv.getElementUtils();}@Overridepublic boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {System.out.println("进入process");messager.printMessage(Diagnostic.Kind.NOTE, "TakeTimeProcessor注解处理器处理中");TypeElement currentAnnotation = null;// 遍历注解集合,也即@SupportedAnnotationTypes中标注的类型for (TypeElement annotation : annotations) {messager.printMessage(Diagnostic.Kind.NOTE, "遍历本注解处理器处理的所有注解,当前遍历到的注解是:" + annotation.getSimpleName());currentAnnotation = annotation;}Set<? extends Element> elementSet = roundEnv.getElementsAnnotatedWith(CatchAndLog.class);messager.printMessage(Diagnostic.Kind.NOTE, "CatchAndLogProcessor注解处理器处理@CatchAndLog注解");for (Element element : elementSet) {if (element.getKind() == ElementKind.METHOD) {JCTree tree = (JCTree) trees.getTree(element);System.out.println("进入循环");if (tree instanceof JCTree.JCMethodDecl) {JCTree.JCMethodDecl methodDecl = (JCTree.JCMethodDecl) tree;// 方法名称String methodName = element.getSimpleName().toString();// 类的全限定名称String className = element.getEnclosingElement().toString();messager.printMessage(Diagnostic.Kind.NOTE, "当前被标注注解的方法所在的类是:" + className);messager.printMessage(Diagnostic.Kind.NOTE, currentAnnotation.getSimpleName().toString() + "当前被标注注解的方法是:" + methodName);enhanceMethodDecl(methodDecl);}}}return true;}private void enhanceMethodDecl(JCTree.JCMethodDecl methodDecl) {//try {////}catch (Exception ex) {// ex.printStackTrace();//}JCTree.JCBlock tryBlock = methodDecl.body;JCTree.JCVariableDecl exVar = createVarDef(treeMaker.Modifiers(0),"ex",treeMaker.Ident(names.fromString("Exception")),null);JCTree.JCBlock catchBlock = treeMaker.Block(0L, List.of(treeMaker.Exec(treeMaker.Apply(List.nil(),treeMaker.Select(treeMaker.Ident(names.fromString("ex")),names.fromString("printStackTrace")),List.nil()))));JCTree.JCCatch catchClause = treeMaker.Catch(exVar, catchBlock);JCTree.JCTry tryCatchTree = treeMaker.Try(tryBlock, List.of(catchClause), null);methodDecl.body = treeMaker.Block(0L, List.of(tryCatchTree));System.out.println(methodDecl.body.toString());}private com.sun.tools.javac.util.Name getNameFromString(String s) {return names.fromString(s);}/*** 创建变量语句** @param modifiers* @param name 变量名* @param varType 变量类型* @param init 变量初始化语句* @return*/private JCTree.JCVariableDecl createVarDef(JCTree.JCModifiers modifiers, String name, JCTree.JCExpression varType, JCTree.JCExpression init) {return treeMaker.VarDef(modifiers,//名字getNameFromString(name),//类型varType,//初始化语句init);} }


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部