每一个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(
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 {
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{} TypeVar类型,bound为Object,lower为BottomType
* (2) class Test01{} TypeVar类型,bound为Number,lower为BottomType
*/
public List typarams_field;
/** A cache variable for the type parameters of this type,appended to all parameters of its enclosing class.
*
*/
public List 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 interfaces_field;
/** All the interfaces of this class, including missing ones.
*/
public List all_interfaces_field;
...
}
举个例子,如下:
interface K{}
class F implements K{}
interface I{}
public class A {
class B 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.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 argtypes; // 形式参数类型
public Type restype; // 返回值类型
public List thrown; // 抛出的异常参数类型
...
}
举个例子,如下:
public class B {
public 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 { }
查找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 {
public void test1(){
B super T> x ;
}
}
查找TypeVariable语法节点,如下截图。
如上主要根据B
e.g2
List super InputStream> x = new ArrayList();
则WildcardType结构的截图如下:
当类型声明为class X
(1)形式为 ? 时type=Object
(2)形式为? extends XX 时type=XX
(3)形式为? super XX 时type=XX
也就是type类型与类的声明无关。
e.g3
public class Test5,X extends T,Y extends A extends T>>{}
查看A extends T>这个通配符类型。一般JCWildcard语法节点举个例子,如A extends T>,如下:
如A
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 accept(Visitor 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 typeVariables;
// 在生成方法签名时,如果有类型变量的声明则使用new ForAll(typeVariables,methodType)
public ForAll(List 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 lobounds = List.nil();
public List hibounds = List.nil();
public Type inst = null;
@Override
public R accept(Type.Visitor 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 void testMethod03(T t){
}
public void test(){
testMethod03(new Integer(2));
}
需要对T进行类型推断,那么T要根据传入的参数类型Integer与声明的type parameter结合起来进行推断
这个T的类型为UndeterminedVar,其中lowbounds为Integer,而highbounds为null。
qtype的值为TypeVar类型变量,指的就是方法声明中的。
DelegatedType中的bound为Serializable的ClassType,而lower为BottomType
*/
public class UndeterminedVar extends DelegatedType {
public List lowbounds = List.nil(); // 下界
public List 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);
}
}
};