关于类型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(代码片段

关于类型Type