每一个JC语法节点都含有type属性,因为做为所有JC语法节点的父节点JCTree含有type属性。其继承关系如下图。

下面看一下Type类的定义及重要的属性。

public class Type implements PrimitiveType {

    /** The tag of this type.
     *
     *  @see TypeTags
     */
    public int tag;

    /** The defining class / interface / package / type variable
     */
    public TypeSymbol tsym; // 只有ClassSymbol与PackageSymbol继承了TypeSymbol

    ...

} 

每个Type子类都继承了Type类,也就都有tsym属性。也就是说任何一个类型都有对应的ClassSymbol或者PackageSymbol属性。例如:

BottomType对应的tsym为ClassSymbol(<nulltype>)

JCNoType对应的tsym为ClassSymbol(void)

泛型TypeVar(T)对应的tsym为TypeSymbol(T)

继承了PrimitiveType类,所以Type类本身可以表示一些原始的类型,Type类的注释如下:

/** This class represents Java types. The class itself defines the behavior of the following types:
 *
 *  类本身可以表示的类型如下:
 *
 *  base types (tags: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOLEAN),
 *  type `void' (tag: VOID),
 *  the bottom type (tag: BOT),
 *  the missing type (tag: NONE).
 *
 *
 *
 *  使用静态内部子类来表示的一些类型如下:
 *  The behavior of the following types is defined in subclasses, which are all static inner classes of this class:
 *
 *  class types (tag: CLASS, class: ClassType),
 *  array types (tag: ARRAY, class: ArrayType),
 *  method types (tag: METHOD, class: MethodType),
 *  package types (tag: PACKAGE, class: PackageType),
 *  type variables (tag: TYPEVAR, class: TypeVar),
 *  type arguments (tag: WILDCARD, class: WildcardType),
 *  polymorphic types (tag: FORALL, class: ForAll),
 *  the error type (tag: ERROR, class: ErrorType). *
 *
 */

举个例子,如下:

public class A {
	int a;
	boolean b;
	Integer c;
}

截图如下:

  

Integer的type属性为ClassType,而不是Type。

1、JCNoType(void,缺失类型NONE)与BottomType(null)

对于一些特殊的类型,如void,用JCNoType来表示,null用BottomType表示,对于缺失的类型NONE,其实也用JCNoType来表示,但是已经在Type中预先定义好了,如下:

 /** Constant type: no type at all. */
    public static final JCNoType noType = new JCNoType(NONE); // tag值为NONE

看一下JCNoType类定义,如下:

/** Represents VOID or NONE.
 */
public class JCNoType extends Type implements NoType { // 实现NoType接口
    public JCNoType(int tag) {
        super(tag, null);
    }

    @Override
    public TypeKind getKind() { // tag值为TypeTags.VOID或者TypeTags.NONE
        switch (tag) {
            case VOID:  return TypeKind.VOID;
            case NONE:  return TypeKind.NONE;
            default:
                throw new AssertionError("Unexpected tag: " + tag);
        }
    }

    ...

}

看一下BottomType类定义,如下:

public class BottomType extends Type implements NullType { // 实现NullType接口

    public BottomType() {
        super(TypeTags.BOT, null);  // tag值为TypeTags.BOT
    }

    @Override
    public TypeKind getKind() {
        return TypeKind.NULL;
    }

    ...

}

举个例子,如下:

public class A<T extends InputStream> {
	public void test(){ }
}

查看JCTypeParameter节点的type属性和JCMethodDecl的restype,如下:

  

  

2、PackageType

public class PackageType extends Type implements NoType {

    public PackageType(TypeSymbol tsym) {
        super(PACKAGE, tsym);
    }

    ...
}

JCNoType与PackageType都实现了NoType接口,表示这不是一个类型。这个PackageType做为JCCompilationUnit(JCCompilationUnit节点的type属性为null)语法节点中的package属性(PackageSymbol类型)下的type存在的,如下截图。

 

  

3、ClassType

public class ClassType extends Type implements DeclaredType {

    /** The enclosing type of this type. If this is the type of an inner
     *  class, outer_field refers to the type of its enclosing instance class,
     *  in all other cases it referes to noType.
     *
     */
    protected Type outer_field;

    /** The type parameters of this type (to be set once class is loaded).
     *
     * (1) class Test01<T>{}  TypeVar类型,bound为Object,lower为BottomType
     * (2) class Test01<T extends Number>{}  TypeVar类型,bound为Number,lower为BottomType
     */
    public List<Type> typarams_field;

    /** A cache variable for the type parameters of this type,appended to all parameters of its enclosing class.
     *
     */
    public List<Type> allparams_field;

    /** The supertype of this class (to be set once class is loaded).
     */
    public Type supertype_field;

    /** The interfaces of this class (to be set once class is loaded).
     */
    public List<Type> interfaces_field;

    /** All the interfaces of this class, including missing ones.
     */
    public List<Type> all_interfaces_field;

    ...
}

举个例子,如下:

interface K{}
class F implements K{}

interface I{}

public class A<X> {

	class B<T extends InputStream> extends F implements I {
		public void test() {
		}
	}
}

找到类B的JCClassDecl语法节点,查看sym属性的type属性节点,截图如下。

  

allparams_field将把它的封闭类的类型参数也追加进来,如B类将A类的类型参数X追加到这个属性上。这样做的具体作用有待研究。 

JCClassDecl的type属性也有值,但是大部分为空,目前不知道有什么用处,有待继续研究。

4、UnionClassType

// a clone of a ClassType that knows about the alternatives of a union type.
public class UnionClassType extends ClassType implements UnionType {
    final List<? extends Type> alternatives_field;
    ...
}

举个例子如下:

public void test() {
		try {
			int i = 2 / 0;           // ArithmeticException
			Integer.parseInt("abc"); // NumberFormatException
		} catch (ArithmeticException | NumberFormatException e) {
			System.out.println(e);
		}
	}

查找JCTypeUnion语法节点,查看type属性,截图如下。  

5、ErasedClassType

public class ErasedClassType extends ClassType {
	public ErasedClassType(Type outer, TypeSymbol tsym) {
		super(outer, List.<Type>nil(), tsym);
	}

	@Override
	public boolean hasErasedSupertypes() {
		return true;
	}
}

主要是对类中泛型的擦除。在什么情况下需要进行类型擦除呢?  

6、ArrayType

public class ArrayType extends Type implements javax.lang.model.type.ArrayType {

    public Type elemtype;
    ...
}

举个例子,如下:  

Integer[][] x = new Integer[2][];

查找JCVariableDecl语法节点,查看type属性,如下截图。  

6、MethodType

public class MethodType extends Type implements ExecutableType {

    public List<Type> argtypes; // 形式参数类型
    public Type restype;  // 返回值类型
    public List<Type> thrown; // 抛出的异常参数类型
    ...
}

举个例子,如下:  

public class B {
	public <T extends InputStream> T test(T a,Integer x) throws NullPointerException{
		return a;
	}
}

查看JCMethodDecl语法节点的sym和type属性,截图如下。

  

type属性的具体类型为MethodType,其中的属性都是通过泛型推导后得出的。

7、TypeVar

public class TypeVar extends Type implements TypeVariable {

    /** The upper bound of this type variable; set from outside.
     *  Must be nonempty once it is set.
     *
     *  For a bound, `bound' is the bound type itself.
     *  Multiple bounds are expressed as a single class type which has the
     *  individual bounds as superclass, respectively interfaces.
     *
     *  The class type then has as `tsym' a compiler generated class `c',
     *  which has a flag COMPOUND and whose owner is the type variable
     *  itself. Furthermore, the erasure_field of the class
     *  points to the first class or interface bound.
     *
     */
    public Type bound = null;

    /** The lower bound of this type variable.
     *  TypeVars don't normally have a lower bound, so it is normally set to syms.botType.
     *  TODO Subtypes, such as CapturedType, may provide a different value.
     */
    public Type lower;  // 一般没有下界,所以一般设置为BottomType
    ...
}

举个例子,如下:

interface IA{}

interface IB{}

public class B<T extends Number&IA&IB> { }

查找B类的typarams属性,查看type属性,如下截图。  

8、WildcardType

public class WildcardType extends Type implements javax.lang.model.type.WildcardType {

	public Type type;
	public BoundKind kind;
	public TypeVar bound; // 边界是由TypeVar来指定的
        ...
}

e.g1

public class B<T extends Number&IA&IB> {
	public void test1(){
		B<? super T> x ;
	}
}

查找TypeVariable语法节点,如下截图。  

  

如上主要根据B<T extends Number&IA&IB>与 B<? super T>得出如上的WildcardType类型。

e.g2

List<? super InputStream> x = new ArrayList();  

则WildcardType结构的截图如下:

当类型声明为class X<E> 或者 class X<E extends Y>形式时,可以看到WildcardType中的type类型:

(1)形式为 ? 时type=Object

(2)形式为? extends XX 时type=XX

(3)形式为? super XX 时type=XX

也就是type类型与类的声明无关。

e.g3

public class Test5<T extends A<T>,X extends T,Y extends A<? extends T>>{}

查看A<? extends T>这个通配符类型。一般JCWildcard语法节点举个例子,如A<? extends T>,如下:

如A<T extends Number>与A<? extends T>时,截图如下:

9、CapturedType

/** A captured type variable comes from wildcards which can have
 *  both upper and lower bound.  CapturedType extends TypeVar with  a lower bound.
 */
public class CapturedType extends TypeVar {

    public WildcardType wildcard;

	public CapturedType(Name name, Symbol owner, Type upper, Type lower, WildcardType wildcard) {
        super(name, owner, lower);
        this.lower = Assert.checkNonNull(lower);
        this.bound = upper;
        this.wildcard = wildcard;
    }

    @Override
    public <R,S> R accept(Visitor<R,S> v, S s) {
        return v.visitCapturedType(this, s);
    }

    @Override
    public boolean isCaptured() {
        return true;
    }

    @Override
    public String toString() {
        return "capture#" + (hashCode() & 0xFFFFFFFFL) % Printer.PRIME + " of " + wildcard;
    }
}

CapturedType继承自TypeVar,并且有个WildcardType的属性。  

10、DelegatedType (ForAll、UndeterminedVar)

ForAll与UndeterminedVar都继承了DelegatedType类,DelegatedType类定义如下:

public abstract class DelegatedType extends Type {

	public Type qtype;

	public DelegatedType(int tag, Type qtype) {
		super(tag, qtype.typeSymbol);
		this.qtype = qtype;
	}
}

  

public class ForAll extends DelegatedType implements ExecutableType { // 实现了ExecutableType,说明ForAll与方法相关

    public List<Type> typeVariables;

    // 在生成方法签名时,如果有类型变量的声明则使用new ForAll(typeVariables,methodType)
    public ForAll(List<Type> typeVariables, Type qtype) {
        super(FORALL, qtype);
        this.typeVariables = typeVariables;
    }
}

 /** A class for instantiatable variables, for use during type
     *  inference.
     */
    public static class UndetVar extends DelegatedType {
        public List<Type> lobounds = List.nil();
        public List<Type> hibounds = List.nil();
        public Type inst = null;

        @Override
        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
            return v.visitUndetVar(this, s);
        }

        public UndetVar(Type origin) {
            super(UNDETVAR, origin);
        }

        public String toString() {
            if (inst != null) return inst.toString();
            else return qtype + "?";
        }

        public Type baseType() {
            if (inst != null) return inst.baseType();
            else return this;
        }
    }

  

 

/*   A class for instantiatable variables, for use during type inference.

     在类型推断过程中使用
     public <T extends Serializable> void testMethod03(T t){

     }

     public void test(){
        testMethod03(new Integer(2));
     }

     需要对T进行类型推断,那么T要根据传入的参数类型Integer与声明的type parameter结合起来进行推断
     这个T的类型为UndeterminedVar,其中lowbounds为Integer,而highbounds为null。

     qtype的值为TypeVar类型变量,指的就是方法声明中的<T extends Serializable>。

     DelegatedType中的bound为Serializable的ClassType,而lower为BottomType

 */
public class UndeterminedVar extends DelegatedType {

    public List<Type> lowbounds = List.nil(); // 下界
    public List<Type> highbounds = List.nil(); // 上界
    public Type instance = null; // 变量类型
    // ...
}

在类型推断的过程中使用,在Inference类中可看到如下代码:

/** A mapping that turns type variables into undetermined type variables.
     */
	Mapping fromTypeVarFun = new Mapping("fromTypeVarFun") {
		public Type apply(Type t) {
			if (t.typeTag == TYPEVARIABLE){
                return new UndeterminedVar(t);
            }
			else{
                return t.map(this);
            }
		}
	};

  

  

 

  

  

关于类型Type的更多相关文章

  1. orcle自定义类型type/create or replace type

    一.type / create or repalce type 区别联系 相同: 可用关键字create type 或者直接用type定义自定义类型, 区别: create type 变量 as ta ...

  2. 初识Haskell 二:基本操作符、类型Type、数据结构

    对Discrete Mathematics Using a Computer的第一章Introduction to Haskell进行总结.环境Windows 1. 在安装了ghci后,便可以进行Ha ...

  3. 转载:oracle 自定义类型 type / create type

    标签:type create oracle object record 一:Oracle中的类型有很多种,主要可以分为以下几类: 1.字符串类型.如:char.nchar.varchar2.nvarc ...

  4. 关于语法节点Tree、类型Type和符号Symbol

    每个语法节点Tree都有Type属性,部分的语法节点有Symbol属性,如下: 与Symbol类型与Type类型之间的关系如下: 下面是Symbol与Type之间的关系: (1)MethodSymbo ...

  5. oracle 自定义类型 type / create type

    一:Oracle中的类型有很多种,主要可以分为以下几类: 1.字符串类型.如:char.nchar.varchar2.nvarchar2. 2.数值类型.如:int.number(p,s).integ ...

  6. C# 与.NET2.0 中类型Type的GetMethod方法

    C#中类型Type有个GetMethod方法,调用该方法可获取指定方法名的方法信息实例. 使用时,其参数一般为2个,一个是方法名称字符串(可设置条件忽略大小写),另外一个参数为搜索方法的条件枚举. 该 ...

  7. 类型type:clusterip和service内部的关系

    类型type:clusterip和service内部的关系 待办 https://stackoverflow.com/questions/41509439/whats-the-difference-b ...

  8. java基础之反射类型Type

    Java在加入泛型之后,仅仅Class已经不足以描述数据的类型了,比如List<String>类型的数据,其Class的类型为List.class,但是其类型包含了泛型参数,所以java引 ...

  9. r语言之散点图类型type参数

    type参数用来控制所生成散点图的类型,有如下几个选项: type=“p”表示绘制单独的点 type=“l”表示绘制点连成的折线 type=“b”表示有线连接的点 type=“o”表示将点绘在线上 t ...

  10. 深入理解.net - 3.类型Type

    说到类型,.NET技术是基于通用类型系统(CTS,Common Type System)的,而CTS又是构建于公共语言架构(CLI,Common Language Infrastructure)之上, ...

随机推荐

  1. SBIT

    SBIT chmod -R o+t dirs/ 给指定目录设置保护,只有所有者才能删除.

  2. 如何更新world文档的目录

    在想要设置目录的文档页,右键 -> 更新域, 或者在想要设置目录的文档页,按下 F9 即可 拓展: 在目录文档页  ,按Ctrl 并且单击鼠标可以跟踪目标连接 如果内容对您有所帮助,请打赏--- ...

  3. 对C++里面 的知识积累:

    unique()[去重函数] unique()是C++标准库函数里面的函数,其功能是去除相邻的重复元素(只保留一个),所以使用前需要对数组进行排序 上面的一个使用中已经给出该函数的一个使用方法,对于长 ...

  4. EBS查找当前Form文件

    http://www.cnblogs.com/benio/archive/2011/06/10/2077289.html 我们经常会要在ORACLE EBS中寻找我们正在浏览的form页面的执行文件, ...

  5. 使用VSTS进行单元测试练习

    本次作业要求:练习教科书第22~25页单元测试练习,要求自行安装Visual Studio开发平台,版本至少在2010以上,要求把程序安装过程和练习过程写到博客上,越详细越好,要图文并茂,没有书的同学 ...

  6. Python学习-16.Python中的错误处理

    虽然叫错误,但跟 C# 中的异常是一回事.只不过 Python 中叫错误(Error)而 C# 中叫异常(Exception). 先手工产生一个异常: file = open('','r') 上面一句 ...

  7. Windows 8/8.1 及 Windows Phone 8 应用神器 - APP Producer

    继 App studio 以及  Project Siena 之后 微软再次打造应用生成器 APP Producer,这个版本的应用生成器功能相对比之前两个版本要简单许多,更适合入门并且真正的支持全平 ...

  8. Elasticsearch 核心插件Kibana 本地文件包含漏洞分析(CVE-2018-17246)

    不久前Elasticsearch发布了最新安全公告, Elasticsearch Kibana 6.4.3之前版本和5.6.13之前版本中的Console插件存在严重的本地文件包含漏洞可导致拒绝服务攻 ...

  9. C#委托和事件的使用的意义

    转载自:https://www.cnblogs.com/yinqixin/p/5056307.html 每一个初学C#的程序猿,在刚刚碰到委托和事件的概念时,估计都是望而却步,茫然摸不到头脑的.百度一 ...

  10. Windows 安装并配置 MySQL 5.6

    Windows 下安装 MySQL 有两种方式,一种是下载安装包,根据提示一路 next 安装,不需要什么配置,比较简单:另一种是下载压缩包,通过命令和配置来安装,也不难,个人感觉更简单.本篇就采用第 ...