1、有try,catch语句块,用JLS4,*2,你要告诉parser需要解析的内容类型。ASTParser支持对以下四种内容的解析:a. K_COMPILATION_UNIT: 一个编译单元,一般就是完整的Java文件b. K_STATEMENTS: Java statements,比如赋值语句,或是if语句块,while语句块等。此类型不需要文件是完整的编译单元,但需要是完整的statements。比如if语句块要作为一个完整的statement输入,否则会报错。c. K_EXPRESSION: Java expressionsd. K_CLASS_BODY_DECLARATIONS: Jav
2、a class里的元素*3,设置java代码,java代码可以通过文件流从java文件中得到,也可以自己拼接String,记得需要的是一个char*4,如果解析的内容类型的一个完整的java类,则可以不用设置,如果只是片断,则需要设定为true.*5,需要Parser得到一个AST根对象CompilationUnit1-2,在Util类添加一个读取java文件的方法:public static String getJavaFromFile(String javaFilePath) throws Exception FileInputStream reader = new FileInputSt
3、ream(new File(javaFilePath); byte bs = new bytereader.available(); reader.read(bs, 0, reader.available(); String javaContent = new String(bs); return javaContent;2-1,ASTNode结构图2-2,java结构说明:2-2-1,一个java文件中:主要包含三大块(如图):其中包引入可以有多个,类申明也可以有多个。当然还有注释和注解两部分:2-2-2 在类中也主要包含三大块:全局变量(Field),方法(Method),内部类(Inne
4、rClass),另外还有:方法注解,变量注解,方法注释,字段注释,static块,如图:2-3, 解释ASTNode 通过上面对java结构的介绍,以及2-1的图,我们可以通过 CompilationUnit unit = (CompilationUnit) parser.createAST(null);得到ASTNode得到ast的根节点,即:ASTNode rootNode = unit.getAST(); 他表示一个java文件,或者一个完事的java片段,我们以一个完事的java文件为例,如果是一个java文件,那么,unit相对的子节点就是多个:package1,import*,cl
5、ass*,javadoc*,annotation*, 而其中java代码主要是写类中的,所以class又有多个子节点:field*,constructor*,method*,javadoc*,annotation*,static block*, constructor(构造方法)只是特殊的方法,所以可以归为一类, 在java中,java的表达式,逻辑主要是在method中,method中还很多了节点,即各种表达式的子节点,这个这里就不说了。这样一来,一个java文件就够成了一棵java方法树了。下面就开始对java结构按上面的分析出的结构逐一的分析与遍历Eclipse JDT - AST 遍历
6、(2)JAVA结构遍历1, 遍历整个java文件:(以附件的java内容为例),如果有不理解的地方,请仔细看上面的结构图1-1 包申明PackageDeclaration packageDeclaration = unit.getPackage();得到申明的包,即:package xm.bean;packageDeclaration.toString(); = package xm.beanpackageDeclaration.getName(); xm.bean1-2 导入包遍历List importDeclarations = unit.imports();for(Object obje
7、ct : importDeclarations) ImportDeclaration importDec = (ImportDeclaration) object;System.out.println(importDec.getName(); /print: java.util.ListSystem.out.println(importDec); /print: import java.util.ListSystem.out.println(importDec.isOnDemand();/print: 如果是:import java.util.*; true 如果是静态导入:import st
8、atic java.lang.Math.*; true;System.out.println(importDec.isStatic();1-2 java类遍历(在一个java文件中,如果class关键字没有public申明,则一个java文件中可以存在多个类,如果用public申明,则只有一个java类),所以TypeDeclaration 得到的是一个集合:List typeDeclarations = unit.types();如果java文件中有一个类,则:TypeDeclaration clazzNode = (TypeDeclaration)typeDeclarations.get(
9、0);如果有多个类,则:for (Object object : typeDeclarations) TypeDeclaration clazzNode = (TypeDeclaration) object; System.out.println(clazzNode.getName(); if(Balance.equals(clazzNode.getName() /遍历类里面 else if(.) . .2 遍历整个java类头部:2-1,注释遍历:java的注释分为如下三种:a:doc注释,这个注释可以在javadoc里面体现出来,格式:/* * Description 金融行业记录帐户余额
10、信息 * 一般分为:opening balance, coloseing balance, available balence等 * author .x.m * Time 2013/04/22 */b:块注释,与类注释不同的是:类注释开头是:/* 而块注释是:/*c:行注释 /后面跟注释内容2-2,注释遍历:注释在AST的分析与解释以上类注释的解释,AST,将类注释javadoc视为由多个TagElement组成的List = javadoc.tags();注释文件从头开始,每遇到一个则视为一个TagElement,如上图则有4个TagElement,而每个TagElement都是由optin
11、onalTagName (author)和多个TextElement,每换一次行则视为一个TextElement。如图:Description 这个TagElement则一个optinonalTagName (Description)和两个TextElement组成。2-3,注释遍历:代码,有了如上的分析,则可以很轻松的遍历出每一行注释,当然如果没有其它的必要的话,你就可以直接javadoc.toString();Javadoc classdoc = clazz.getJavadoc(); /得到类上面的注释javadocList targs = classdoc.tags(); /得到Tag
12、Element集合 targs) TagElement tagElement = (TagElement) object; String optionalTagName = tagElement.getTagName(); /得到注释名如:author List textElements = tagElement.fragments(); /得到注释的内容集合:List TextElement for (Object object2 : textElements) TextElement textElement = (TextElement) object2; System.out.print
13、ln(textElement.getText(); /得到一个TextElement的内容 2-4,java类信息:public class Adapter /这个包含修饰符:public, 类名:Adapterpublic abstract class Adapter /这个包含修饰符:public, abstract, 类名: Adapterpublic class Adapter extends AbsAdapter /修饰符:public, 父类:AbsAdapter, 类名:public class Adapter extends AbsAdapter /修饰符: Adapter,泛
14、型:Entity public class Adapter extends absAdapterpublic interface Adapterpublic interface MyAdapter extends Adapterpublic interface MyAdapter extends Adapterpublic class Adapter2-5: 得到各种类型信息(代码如下)TypeDeclaration clazz = (TypeDeclaration)typeDeclarations.get(1);System.out.println(Class Name:+clazz.get
15、Name();for (Object obj : clazz.modifiers() /得到修辞符如:public,static, abstract, Modifier modifier = (Modifier) obj; modifier.getKeyword();clazz.isInterface(); /是不是接口/得到类型信息 pulic class MyAdapter 中的 clazz.typeParameters() TypeParameter typeParameter = (TypeParameter) object; SimpleName genericName = type
16、Parameter.getName(); /T typeParameter.typeBounds() /Entity SimpleType superGrnericType = (SimpleType) object2; String superGrnericName = superGrnericType.getName().getFullyQualifiedName();/extends AdapterType superType = clazz.getSuperclassType();System.out.println(superType);/implements Adapter, Ba
17、seBeanList interfaceType = clazz.superInterfaceTypes();for(Object obj : interfaceType) ParameterizedType parameterizedType = (ParameterizedType) obj; for (Object obj1 : parameterizedType.typeArguments() SimpleType simpleType = (SimpleType) obj1; simpleType.getName().getFullyQualifiedName();Eclipse J
18、DT - AST 遍历(3)Java类遍历 到目前已经遍历了java的大致结构了,接下来就是进行java类里面的信息进行遍历,由上面可知道,java类主要由三部分组成,这里只对这三部分来做分析(FieldDeclaration, MethodDeclaration, 内部类: TypeDeclaration),这部分遍历有两种方式:1,整体遍历:因为FieldDecliaration,MethodDeclaration,TypeDeclaration都是BodyDeclaration的子类,所以可以将他们归结为同一类型的结点,于是就有:List bodyDecliarations = claz
19、z.bodyDeclarations();然后循环得到每一个节点,如下: clazz.bodyDeclarations() System.out.println(obj.getClass(); /print field if(obj instanceof TypeDeclaration) /inner class TypeDeclaration innerClass = (TypeDeclaration) obj; for(Object bodyType : innerClass.bodyDeclarations() if(bodyType instanceof MethodDeclarati
20、on) MethodDeclaration innerMethod = (MethodDeclaration) bodyType; innerMethod.getBody(); System.out.println(innerClass.toString(); else if(obj instanceof FieldDeclaration) /field else if(obj instanceof MethodDeclaration)/ method2:分类遍历2-1,字段遍历: 先分析下,字段由注释,注解,修辞符(public static等),变量类型,变量名, 变量值(变量值可以是常量
21、,一个表达示,也可是调用某个类的某个方法),这里省略:注释,注解,变量值也只针对常值的解析),其它情况在针对方法体遍历的时候说明。下面代码片段用于字段遍历说明:import java.util.Date;import java.util.List;public class FieldTest /基本类型 private int intA; /对象类型 private Date date; /数组类型 private String xmAccounts; /泛型类型 private List xmAccountList; /多个修辞符 public final static double PI=
22、3.141592653; /赋空值的 private String xm = null; /调用方法的 private long currentTimes = System.currentTimeMillis(); /表达式的 private boolean flag = 100/5=20 ? true : false;2-1-1,变量类型的说明(这里只是按ast中变量类型归类说明)基本数据类型:PrimitiveType, java中的基本数据类型,如:int,float等, 可以通过isPrimitiveType来判断是不是基本数据类型复杂数据类型(对象):SimpleType, java
23、中的对象类型,isSimpleType断是不是对象数据类型数组数据类型:ArrayType, java中的数组类型泛型数据类型:ParameterizedType,泛型2-1-2,由于一个类可以有多个字段申明,所以我们可以通过到getFieldDeclarations(),得到一个List数组。然后我们通过for循环遍历这个数组,得到这个字段的相关信息,如修辞符(private,static等)field.modifiers();字段的类型信息:isPrimitiveType, isSimpleType, isArrayType, isParameterizedType等方法来判断是什么类型,
24、这样就可以得到类型名。变量名:注意:一个类型可以申明多个变量:比如:private int a,b,c;所以会返回一个数组如果只有一个变量名,我们可以直接get(0),如果多个,我们也可以遍历逐个得到。相关代码如下:FieldDeclaration fields = clazz.getFields();for (FieldDeclaration fieldDeclaration : fields) String field = ; List modifier = fieldDeclaration.modifiers(); for(int i=0;imodifier.size();i+) fie
25、ld+=modifier.get(i)+ /这里得到字段类型 Type fieldType= fieldDeclaration.getType(); if(fieldType.isPrimitiveType() PrimitiveType p = (PrimitiveType) fieldType; field+=p.getPrimitiveTypeCode()+ else if(fieldType.isArrayType()/数组 ArrayType a = (ArrayType) fieldType; field += a.getComponentType()+ else if(fieldType.isSimpleType()/对象 SimpleType s = (SimpleType) fieldType; field+=s.getName().getFullyQualifiedName()+ else if(fieldType.isParameterizedType()/泛型,泛型, /泛型的类型,也可能是上面两种类型,也有可能是还是泛型对象(泛型不能是基本类型) /List, ListO
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1