来看一下继承自Symbol的具体实现类。

1、TypeSymbol

/** A class for type symbols.
 * Type variables are represented by instances of this class,  // 类型变量用这个类来表示
 * classes and packages by instances of subclasses.  // 类和包用子类来表示
 */
public class TypeSymbol extends Symbol implements TypeParameterElement {
   ...
}

其中有两个重要的方法是用来计算fullname与flatname的。TypeSymbol的具体子类有PackageSymbol和ClassSymbol,而PackageSymbol中含有fullname属性,ClassSymbol中含有fullname与flatname属性。

接着看具体的子类定义。  

2、PackageSymbol

/** A class for package symbols
 */
public class PackageSymbol extends TypeSymbol  implements PackageElement {

    public Scope members_field;
    public Name fullname;
    public ClassSymbol package_info; // see bug 6443073
    ...
}

主要有3个属性。  

3、ClassSymbol

/** A class for class symbols
 */
public class ClassSymbol extends TypeSymbol implements TypeElement {

    /** a scope for all class members; variables, methods and inner classes
     *  type parameters are not part of this scope
     *
     *  所有类成员的一个作用域。变量,方法和内部类 类型参数不是这个作用域的一部分
     */
    public Scope members_field;

    /** the fully qualified name of the class, i.e. pck.outer.inner.
     *  null for anonymous classes
     *
     *  类的全限定名,对于匿名类为空
     */
    public Name fullname;

    /** the fully qualified name of the class after converting to flat
     *  representation, i.e. pck.outer$inner,
     *  set externally for local and anonymous classes
     *
     *  类的全限定名,为本地和匿名类也进行设置
     */
    public Name flatname;

    /** the sourcefile where the class came from
     */
    public JavaFileObject sourcefile;

    /** the classfile from where to load this class
     *  this will have extension .class or .java
     */
    public JavaFileObject classfile;

    /** the list of translated local classes (used for generating InnerClasses attribute)
     */
    public List<ClassSymbol> trans_local;

    /** the constant pool of the class
     */
    public Pool pool;
    ...
}

下面就来看一个具体的例子,如下:

package m20170210;

public class A {

	class B {}

	public void test() {
		class C {}
	}
}

1、属性fullname与flatname

下面为PackageSymbol的截图。

下面分别是A类,B类与C类的ClassSymbol截图。

  

结合TypeSymbol相关的计算代码,如下:

 /** form a fully qualified name from a name and an owner
     */
    static public Name formFullName(Name name, Symbol owner) {
        if (owner == null){
            return name;
        }
        if (
             (owner.kind != ERR) &&
             (
                (owner.kind & (VAR | MTH)) != 0 ||
                (owner.kind == TYP && owner.type.tag == TYPEVAR) //TYPEVAR是类型变量
             )
        ){
            return name;
        }
        Name prefix = owner.getQualifiedName();
        if (prefix == null || prefix == prefix.table.names.empty){
            return name;
        } else{
            return prefix.append('.', name);
        }
    }

    /** form a fully qualified name from a name and an owner, after
     *  converting to flat representation
     */
    static public Name formFlatName(Name name, Symbol owner) {
        if (
        		owner == null ||
                (owner.kind & (VAR | MTH)) != 0 ||   // 是变量或者方法
                (owner.kind == TYP && owner.type.tag == TYPEVAR) //  是一个类型的类型变量
        ){
        	return name;
        }

        char sep = (owner.kind == TYP) ? '$' : '.';
        Name prefix = owner.flatName();

        if (prefix == null || prefix == prefix.table.names.empty){
            return name;
        }else{
            return prefix.append(sep, name);
        }
    }

flatname主要用来为各个类生成相应的class文件时进行命名的。fullname就是一般所要求的qualifiedname。

2、属性sourcefile与classfile

sourcefile表示源文件的位置,而classfile表示生成的class类的文件路径。

为什么本地类C的classfile为空呢?

3、属性members_field

这个属性只有PackageSymbol与ClassSymbol含有,其类型是Scope(作用域)。Scope内容将在后面详细讲解。

4、重要的方法

有一个isLocal()方法,具体的实现在Symbol中,如下:

/** Is this symbol declared (directly or indirectly) local to a method or variable initializer?
     *  Also includes fields of inner classes which are in turn(反过来) local to a method or variable initializer.
     */
    public boolean isLocal() {
//        return
//                (owner.kind & (VAR | MTH)) != 0 ||
//                        (owner.kind == TYP && owner.isLocal());
        if((owner.kind & MTH ) != 0 ){
            System.out.println(flatName()+"/owner.kind=MTH");
            return true;
        }else if((owner.kind & VAR)!=0){
            System.out.println(flatName()+"/owner.kind=VAR");
            return true;
        }else if(owner.kind == TYP && owner.isLocal()){
        	System.out.println(flatName()+"/owner.kind=TYP");
            return true;
        }
        System.out.println(flatName()+"/false");
        return false;
    }

为了方便测试和打印,我对原来的代码进行了实现的修改并且增加了一些打印,下面是一个例子。  

package m20170217;

public class A {            // m20170217.A/false

	class B {               // m20170217.A$B/false
		B b = new B() {	};  // m20170217.A$B$1/owner.kind=VAR
	}

	B c = new B() {	};      // m20170217.A$1/owner.kind=VAR

	{
		class C { }         // m20170217.A$1C/owner.kind=MTH
	}

	public void test1() {
		class D { }         // m20170217.A$1D/owner.kind=MTH
		D d = new D() {	};  // m20170217.A$2/owner.kind=MTH
	}
}

从如上例子打印结果也可以看出,只有A与B类是非local的,其它都是local。看C类,它的owner.kin为MTH,表示匿名块在编译处理过程中是当作匿名方法来处理的。

4、MethodSymbol

 /** The code of the method. */
    public Code code = null;

    /** The parameters of the method. */
    public List<VarSymbol> params = null;

    /** The names of the parameters */
    public List<Name> savedParameterNames;

    /** For an attribute field accessor, its default value if any.
     *  The value is null if none appeared in the method  declaration.
     *
     *  对于属性字段访问器,其默认值(如果有)。
     */
    public Attribute defaultValue = null; // Attribute类表示的是注解的值

  

1、属性params

举个例子,如下:

public class B {

	@HelloWorldAnnotation(name = "小明")
	public Integer test(int a, String name, Object c) {
		return 1;
	}
}

查看MethodSymbol,如下截图:

 

2、属性defaultValue

@Retention(RetentionPolicy.RUNTIME) // 注解会在class中存在,运行时可通过反射获取
@Target(ElementType.METHOD) // 目标是方法
@Documented // 文档生成时,该注解将被包含在javadoc中,可去掉
public @interface HelloWorldAnnotation {

	public String name() default "xxxxx";

}

查看MethodSymbol,如下截图:

  

5、OperatorSymbol

/** A class for predefined operators.
 *
 * OperatorSymbol继承MethodSymbol是由于操作符有操作数和返回类型,和方法参数与返回类型相似
 */
public class OperatorSymbol extends MethodSymbol {

    public int opcode;

    public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
        super(PUBLIC | STATIC, name, type, owner);
        this.opcode = opcode;
    }

    public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
        return v.visitOperatorSymbol(this, p);
    }
}

OperatorSymbol继承自MethodSymbol。其中有个opcode属性,表示操作的字节码指令。这都是JVM先前定义好的,如:0x03表示将int类型0推送至栈顶。

  

6、VarSymbol

/** A class for variable symbols
 */
public class VarSymbol extends Symbol implements VariableElement {

    public int pos = Position.NOPOS;

    /** The variable's address. Used for different purposes during
     *  flow analysis, translation and code generation.
     *
     *  Flow analysis:
     *    If this is a blank final or local variable, its sequence number.
     *  Translation:
     *    If this is a private field, its access number.
     *  Code generation:
     *    If this is a local variable, its logical slot number.
     */
    public int adr = -1;
}

其中的adr属性还有待继续研究。  

 

  

关于符号Symbol第二篇的更多相关文章

  1. 关于符号Symbol第一篇

    Symbol类的一个实例代表一个符号.对于语法树来说,并不是每个节点都有一个符号实例.下面列举了哪些语法树节点具有符号的引用,如下表格: 其中JCNewClass.JCAssignOp.JCUnary ...

  2. 前端工程师技能之photoshop巧用系列第二篇——测量篇

    × 目录 [1]测量信息 [2]实战 [3]注意事项 前面的话 前端工程师使用photoshop进行的大量工作实际上是测量.本文是photoshop巧用系列第二篇——测量篇 测量信息 在网页制作中需要 ...

  3. Python开发【第二篇】:初识Python

    Python开发[第二篇]:初识Python   Python简介 Python前世今生 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏 ...

  4. python-集合(第二篇(七):集合)

    第二篇(七):集合   python 集合 集合标准操作 摘要: 说明: ·类似于数学中学的集合,Python中的集合可以实现去重的功能,通过set()函数来实现: ·sets支持x in set, ...

  5. 轻松学C#----第二篇笔记

    第二篇: 分析下第一篇的代码,见下图: 2.同其他语言一样,C#语言在编写时也遵守一定的语法规范. A.标识符(identify):指为方法.变量.其他任何用户自定义项指定的名称.标识符必须遵循一定的 ...

  6. 【开源.NET】 轻量级内容管理框架Grissom.CMS(第二篇前后端交互数据结构分析)

    这是 CMS 框架系列文章的第二篇,第一篇开源了该框架的代码和简要介绍了框架的目的.作用和思想,这篇主要解析如何把sql 转成标准 xml 配置文件和把前端post的增删改数据规范成方便后台解析的结构 ...

  7. 小白两篇博客熟练操作MySQL 之 第二篇

    小白两篇博客熟练操作MySQL  之   第二篇 一. 视图 视图是一个虚拟表,其本质是根据SQL语句获取动态的数据集,并为其命名,用户使用时只需使用名称即可获取结果集, 并可以将其当做表来使用. s ...

  8. 【ABAP系列】SAP ABAP7.40新语法简介第二篇

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP7.40新语法简 ...

  9. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

随机推荐

  1. 20170908工作日记--Volley源码详解

    Volley没有jar包,需要从官网上下载源码自己编译出来,或者做成相关moudle引入项目中.我们先从最简单的使用方法入手进行分析: //创建一个网络请求队列 RequestQueue reques ...

  2. 让tableView的某行移动到tableView的某位置

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:lineNumber inSection:0]; [lrcTableView selectR ...

  3. (KMP)Count the string -- hdu -- 3336

    http://acm.hdu.edu.cn/showproblem.php?pid=3336 Count the string Time Limit: 2000/1000 MS (Java/Other ...

  4. sublime text 插件 -- 获取文件名到剪贴板

    日常开发使用 sublime text 有好长一段时间了,有时候想拷贝当前正在编辑的文件名时发现没有很快捷的方法,一般都是先点击右键菜单栏中的 Reveal in Side Bar 对文件进行定位(在 ...

  5. Java类与类之间的继承关系

    Java父类与子类继承关系,调用的各种关系 示例一(子类调用父类函数): // 定义一类 A public class A { // 此方法打印一句话 public void a() { System ...

  6. [翻译]NUnit---TestCase Attributes(二十一)

    TestCaseAttribute (NUnit 2.5) TestCase特性有两个效果,包括标记一个方法使用参数并且在调用的时候提供内置数据.示例如下,本示例会使用不同数据集执行3次: [Test ...

  7. JS代码指导原则

    一.什么是平稳退化? 如果含有JS代码的网页在用户浏览器不支持JS(或者禁用JS)时,用户仍然能够顺利浏览(网站功能正常,只是视觉效果可能差一些),那么这个网页就能够平稳退化 网页能够平稳退化是很必要 ...

  8. C# 基础篇

    全篇依据 C#高级编程(第9版) 内容记录: 基础知识C# 5.0 基础 分为15章内容来介绍 核心C# 对象和类型 继承 泛型 数组 运算符和类型强制转换 委托和lambda表达式,事件 字符串和正 ...

  9. Prism 的 TabControl 导航

    基于Prism 7.1 最近工作中可能会用到TabControl所以作为小菜的我提前预习了一下,结果并没有我想的那么简单,于是乎 各种网上查,本来用wpf的人就不多 prism 的可查的资料就更少的可 ...

  10. UE4随笔 二 第一印象

    打开UE4,短暂的兴奋过后,开始大概扫一扫UE4的编辑器,整个界面比UE3更有现代气息: 之前看其他人写的文章,虚幻4最重要的改动集中在下面几个方向上: 跨平台: WIN和MAC平台都能使用,这就意味 ...