关于类型Type
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于类型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 ... }
继承了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与BottomType
对于一些特殊的类型,如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); } ... }
这个PackageType是做为JCCompilationUnit(JCCompilationUnit节点的type属性为null)语法节点中的packge属性下的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. * @see #allparams */ 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、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、ForAll
ForAll与UndetVar都继承了DelegatedType类,DelegatedType类定义如下:
public abstract class DelegatedType extends Type { public Type qtype; ... }
public class ForAll extends DelegatedType implements ExecutableType { public List<Type> tvars; ... }
以上是关于关于类型Type的主要内容,如果未能解决你的问题,请参考以下文章
我的Android进阶之旅关于Android平台获取文件的mime类型:为啥不传小写后缀名就获取不到mimeType?为啥android 4.4系统获取不到webp格式的mimeType呢?(代码片段
如何将活动 UI 的点击传递到地图片段以将地图更改为 MAP_TYPE_HYBRID
PutParcelable 不能应用于 Place.Type 错误?
Failed to convert property value of type ‘java.lang.String‘ to required type ‘int‘ for property(代码片段