关于类型Type
每一个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的更多相关文章
- orcle自定义类型type/create or replace type
一.type / create or repalce type 区别联系 相同: 可用关键字create type 或者直接用type定义自定义类型, 区别: create type 变量 as ta ...
- 初识Haskell 二:基本操作符、类型Type、数据结构
对Discrete Mathematics Using a Computer的第一章Introduction to Haskell进行总结.环境Windows 1. 在安装了ghci后,便可以进行Ha ...
- 转载:oracle 自定义类型 type / create type
标签:type create oracle object record 一:Oracle中的类型有很多种,主要可以分为以下几类: 1.字符串类型.如:char.nchar.varchar2.nvarc ...
- 关于语法节点Tree、类型Type和符号Symbol
每个语法节点Tree都有Type属性,部分的语法节点有Symbol属性,如下: 与Symbol类型与Type类型之间的关系如下: 下面是Symbol与Type之间的关系: (1)MethodSymbo ...
- oracle 自定义类型 type / create type
一:Oracle中的类型有很多种,主要可以分为以下几类: 1.字符串类型.如:char.nchar.varchar2.nvarchar2. 2.数值类型.如:int.number(p,s).integ ...
- C# 与.NET2.0 中类型Type的GetMethod方法
C#中类型Type有个GetMethod方法,调用该方法可获取指定方法名的方法信息实例. 使用时,其参数一般为2个,一个是方法名称字符串(可设置条件忽略大小写),另外一个参数为搜索方法的条件枚举. 该 ...
- 类型type:clusterip和service内部的关系
类型type:clusterip和service内部的关系 待办 https://stackoverflow.com/questions/41509439/whats-the-difference-b ...
- java基础之反射类型Type
Java在加入泛型之后,仅仅Class已经不足以描述数据的类型了,比如List<String>类型的数据,其Class的类型为List.class,但是其类型包含了泛型参数,所以java引 ...
- r语言之散点图类型type参数
type参数用来控制所生成散点图的类型,有如下几个选项: type=“p”表示绘制单独的点 type=“l”表示绘制点连成的折线 type=“b”表示有线连接的点 type=“o”表示将点绘在线上 t ...
- 深入理解.net - 3.类型Type
说到类型,.NET技术是基于通用类型系统(CTS,Common Type System)的,而CTS又是构建于公共语言架构(CLI,Common Language Infrastructure)之上, ...
随机推荐
- 获取手机的唯一标示uuid
NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
- MySQL性能调优与架构设计——第12章 可扩展设计的基本原则
第12章 可扩展设计的基本原则 前言: 随着信息量的飞速增加,硬件设备的发展已经慢慢的无法跟上应用系统对处理能力的要求了.此时,我们如何来解决系统对性能的要求?只有一个办法,那就是通过改造系统的架构体 ...
- jacob将word转换为html
1.导包jacob.jar 2.将下面两个文件复制到C:\Windows\System32路径下 3.代码如下 // 8 代表word保存成html public static final int W ...
- 关闭父类弹出的ifream窗口
parent.document.getElementById('zhuce').style.display = 'none';
- Linux应用程序中使用math库报undefined reference to `sin'等
出现该问题是因为在Linux中,sin,sqrt等函数是在libm.so库文件中,并非在math.h中. 解决办法:在Ubuntu的gcc编译环境下,直接使用lm参数即可,例如gcc -o Gen G ...
- hdu 1300 Deck
题目 分析:对于n张卡片的最佳摆法,我们只需要在n-1张卡片的摆法下面加一张边缘与桌檐重合的卡片,并将所有卡片一起向桌檐外移动.对于一种最佳摆法,其中心一定在桌檐上,所以一定符合杠杆原理,支点是桌檐. ...
- bolg迁移
博客已迁移至:http://www.s0nnet.com 欢迎大家继续关注!!! 2015-7-4
- java web前端调试手段
1.console.log() 2. jQuery.ajax({ url:"/task1/com/guodiantong/servlet/JsonTo ...
- web.xml中Filter,Listener,Servlet的区别
一.Servlet Servlet是基本的服务端程序,他来自接口Servlet,接口中有方法service.而Servlet的一个重要实现类,则是tomcat服务器的核心,那就是HttpServlet ...
- 学习sqlserve的一些笔记
创建表: create table 表名 { //定义列名 id ,) primary key,//自动编号:从1开始每次增长1,约束:主键约束 name ) not null //非空约束 } 表数 ...