来看一下继承自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. python5-常用模块

    collection 模块 # pypi 可以查询python的模块在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counte ...

  2. Sensor Fusion-based Exploration in Home Environments using Information, Driving and Localization Gains(基于传感器融合的使用信息、驾驶和定位增益在家庭环境中的探索)

    Authors: Joong-Tae Park, Jae-Bok Song Department:Department  of  Mechanical  Engineering,  Korea  Un ...

  3. 20155223 2016-2017-2 《Java程序设计》第9周学习总结

    20155223 2016-2017-2 <Java程序设计>第9周学习总结 教材学习内容总结 第十六章 JDBC--Java数据库连接是用于执行SQL的解决方案,开发人员无需接触底层数据 ...

  4. codevs 1160

    这道题还是和蛇形填数有关,因为要不停的去转圈圈去判断是否到了最中间的那个位置,所以用到了递归的思想. #include<stdio.h> int n,a[100][100]; void r ...

  5. D3 API总览

    D3图形库API参考 https://github.com/d3/d3/wiki/API--%E4%B8%AD%E6%96%87%E6%89%8B%E5%86%8C d3 官网 API https:/ ...

  6. Chrome For EBS

    https://chrome.google.com/webstore/detail/oracle-ebs-r12-enablement/ekkagabmggbmpmncofhgkfigmeldifnc ...

  7. zookeeper集群崩溃处理

    今天在私有化项目中遇到如下问题: 1.客户反馈用户登录返回303 2.登录服务器查看是大量的log将服务器磁盘空间占用殆尽,导致所有服务进程仍旧存在但是监听端口失败,服务不可用 3.清理日志文件 4. ...

  8. 别具光芒Div CSS 读书笔记(一)

    继承 边框(border).边界(margin).填充(padding).背景(background) 是不能继承的.   table 中td不会继承body的属性,因此需要单独指定.   权重   ...

  9. asp.net core mvc 管道之中间件

    asp.net core mvc 管道之中间件 http请求处理管道通过注册中间件来实现各种功能,松耦合并且很灵活 此文简单介绍asp.net core mvc中间件的注册以及运行过程 通过理解中间件 ...

  10. SinGooCMS 内容管理系统

    功能简介: -------------------------------------------------------------------- 案例 德业基 路升光电 博阅科技 明仁律师 卓兔网 ...