关于符号Symbol第二篇
来看一下继承自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第二篇的更多相关文章
- 关于符号Symbol第一篇
Symbol类的一个实例代表一个符号.对于语法树来说,并不是每个节点都有一个符号实例.下面列举了哪些语法树节点具有符号的引用,如下表格: 其中JCNewClass.JCAssignOp.JCUnary ...
- 前端工程师技能之photoshop巧用系列第二篇——测量篇
× 目录 [1]测量信息 [2]实战 [3]注意事项 前面的话 前端工程师使用photoshop进行的大量工作实际上是测量.本文是photoshop巧用系列第二篇——测量篇 测量信息 在网页制作中需要 ...
- Python开发【第二篇】:初识Python
Python开发[第二篇]:初识Python Python简介 Python前世今生 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏 ...
- python-集合(第二篇(七):集合)
第二篇(七):集合 python 集合 集合标准操作 摘要: 说明: ·类似于数学中学的集合,Python中的集合可以实现去重的功能,通过set()函数来实现: ·sets支持x in set, ...
- 轻松学C#----第二篇笔记
第二篇: 分析下第一篇的代码,见下图: 2.同其他语言一样,C#语言在编写时也遵守一定的语法规范. A.标识符(identify):指为方法.变量.其他任何用户自定义项指定的名称.标识符必须遵循一定的 ...
- 【开源.NET】 轻量级内容管理框架Grissom.CMS(第二篇前后端交互数据结构分析)
这是 CMS 框架系列文章的第二篇,第一篇开源了该框架的代码和简要介绍了框架的目的.作用和思想,这篇主要解析如何把sql 转成标准 xml 配置文件和把前端post的增删改数据规范成方便后台解析的结构 ...
- 小白两篇博客熟练操作MySQL 之 第二篇
小白两篇博客熟练操作MySQL 之 第二篇 一. 视图 视图是一个虚拟表,其本质是根据SQL语句获取动态的数据集,并为其命名,用户使用时只需使用名称即可获取结果集, 并可以将其当做表来使用. s ...
- 【ABAP系列】SAP ABAP7.40新语法简介第二篇
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP7.40新语法简 ...
- [ 高并发]Java高并发编程系列第二篇--线程同步
高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...
随机推荐
- 使用OpenCV进行相机标定
1. 使用OpenCV进行标定 相机已经有很长一段历史了.但是,伴随着20世纪后期的廉价针孔照相机的问世,它们已经变成我们日常生活的一种常见的存在.不幸的是,这种廉价是由代价的:显著的变形.幸运的是, ...
- js 面向对象 定义对象
js面向对象看了很多,却没有完全真正的理解,总是停留在一定的阶段,这次再认真看一下. 面向对象包含两种:定义类或对象:继承机制:都是通过工厂模式,构造函数,原型链,混合方法这四个阶段,原理也一样,只是 ...
- centos7 源码安装python3
1.非常重要!必须得先安装py3所依赖的软件包,否则可能会出现py3安装成功,却缺少相应的pip yum groupinstall "Development tools" yum ...
- JAVA服务器与C#客户端的通信技术调研
JAVA服务器与C#客户端的通信技术调研 研究背景及目的: ARPG项目的需求:需要将现有的服务器从C++的编写平台换为java语言.在对需求进行分析的过程中,发现几点需要研究实现的问题 java与c ...
- [C#]SharpSSH-一个可以使用SSH连接的.NET库
A Secure Shell (SSH) library for .NET 觉得有用,就记录下来了 http://www.tamirgal.com/blog/page/SharpSSH.aspx ht ...
- Android 如何修改gen下包的名字
前言 当将项目中包进行重命名后,所有包名字修改了,但是在gen目录下android sdk 自动生成的包名并没有修改,如果要引用R.java 中的字段, 又得import以前的包名字. 原因 出现 ...
- BitAdminCore框架更新日志20180529
索引 NET Core应用框架之BitAdminCore框架应用篇系列 框架演示:http://bit.bitdao.cn 框架源码:https://github.com/chenyinxin/coo ...
- WPF ScrollViewer滚动条样式,适合触摸屏使用
触摸屏上客户要求滚动条宽度大些,方便手指上下滚动,之前在网上看了个,原文找不到了,代码记录下. 效果如下: <ControlTemplate x:Key="ScrollViewerCo ...
- 使用math.js进行javascript精确计算
javascript进行浮点运算会有尾差,比如算个0.1+0.7试试,得到的不是0.8 .这个问题可以使用math.js解决. Math.js是一款开源的JavaScript和Node.js数学库,用 ...
- scapy IPv6 NS NA报文构造
NS 报文构造: #! /bin/python from scapy.all import * a=IPv6(src='2a01:4f8:161:5300::40', dst='ff02::1:ff0 ...