参考博文:
https://cloud.tencent.com/developer/article/1121266?from=14588

https://www.jianshu.com/p/bc21159c0549

https://www.cnblogs.com/baiqiantao/p/7460580.html

https://blog.csdn.net/u010884123/article/details/78189395?locationNum=6&fps=1

https://blog.csdn.net/kaisnm/article/details/105839169

Type官方介绍

/**
 * Type is the common superinterface for all types in the Java
 * programming language. These include raw types, parameterized types,
 * array types, type variables and primitive types.
 *
 * @since 1.5
 */

Type是Java中所有类型的公共超级接口

无论是类、方法、变量,都可以获取Type。

Type类型

Type有四个直接子类:Class、TypeVariable、WildcardType、ParameterizedType、GenericArrayType

  • Class
    当类与泛型无关,java可以直接将这个type类强转为Class。

  • TypeVariable<D extends GenericDeclaration>
    类型变量, 范型信息在编译时会被转换为一个特定的类型, 而TypeVariable就是用来反映在JVM编译该泛型前的信息.

如对于List类,它的TypeVariable就是T;对于ClassDemo<T:List<String>,K,M>,它的泛型就是T,K,M

注意:TypeVariable既可以指类的泛型,也可以指方法的泛型

-------------获取TypeVariable的方法:-------------

Class getTypeParameters()方法

获取类上声明的泛型
http://www.yiidian.com/java-lang/java-class-gettypeparameters.html

Method getTypeParameters()方法

获取方法上声明的泛型

-------------TypeVariable的方法:-------------

String getName()

对于`"List<T>"`,获取的就是T。

Type[] getBounds()

获取类型变量的上边界, 若未明确声明上边界则默认为Object
对于T,获取的就是Object
对于`K : List<String>`

D getGenericDeclaration()方法

下面的代码
class Test {
    fun <T,K : List<String>,M> testType(
        a1: List<String?>?, a2: List<ArrayList<String?>?>?, a3: List<T>?,  //
        a4: List<Number?>?, a5: List<Array<ArrayList<String?>?>?>?, a6: Map<String?, Int?>?
    ) {
    }
}

对于类Test获取的TypeVariable,执行getGenericDeclaration方法返回的是
class com.example.reflectdemo.Test
对于方法testType获取的TypeVariable,执行getGenericDeclaration方法返回的是

public final void com.example.reflectdemo.Test.testType(java.util.List,java.util.List,java.util.List,java.util.List,java.util.List,java.util.Map)
  • ParameterizedType
    -------------获取ParameterizedType的方法:-------------
    对于代码:
open class AbsParameterizedTypeClassDemo<T:List<String>,K,M>{
    fun test(){

    }
}
class AbsParameterizedTypeClassDemoImpl() :
    AbsParameterizedTypeClassDemo<List<String>, String, String>() {

}

getGenericSuperclass获取带泛型的父类Type,类型为ParameterizedTypeImpl。

@RequiresApi(Build.VERSION_CODES.N)
fun parameterizedTypeTest(){
    val type: Type = AbsParameterizedTypeClassDemoImpl::class.java.getGenericSuperclass()
    println(type)
    println("type class name = ${type.javaClass}")

    var pt:ParameterizedType = type as ParameterizedType
    for (item in  pt.actualTypeArguments){
        println(item)
    }
}

-------------ParameterizedType的方法:-------------

Type[] getActualTypeArguments()

获取参数化类型。通常,我们可以使用该接口来检验泛型是否被参数化。通过instance判断是已经参数化了之后,再通过getActualTypeArguments方法获取参数化类型。

返回参数化类型的原始类型,例如List 的原始类型List

对于ClassDemo<List<String>, String, String>,获取的结果就是

java.util.List<? extends java.lang.String>
class java.lang.String
class java.lang.String

Type getRawType

返回参数化类型的原始类型,例如List 的原始类型List
获取声明泛型的类或者接口,也就是泛型中<>前面的那个值。

Type getOwnerType

返回类型所属的类型。例如A类,其中定义了内部类InnerA,则InnerA所属类型为A,如果是顶层类型则返回null。如Map.Entry<K,V>的所属类型为Map<K,V>.
- GenericArrayType

表示的是数组类型且组成元素是ParameterizedType 或TypeVariable。例如List[] 或T[]。该接口只有Type getGenericComponentType()一个方法,它返回数组的组成元素。

对于代码:

open class AbsParameterizedTypeClassDemo{
    var key1 : Array<M> = TODO()
    var key2 : Array<List<String>>
}

fun genericArrayTypeTest(){
    val type1: GenericArrayType =
        AbsParameterizedTypeClassDemo::class.java.getDeclaredField("key1").genericType as GenericArrayType
    println(type1.javaClass)
    println(type1.genericComponentType)

    val type2: GenericArrayType =
        AbsParameterizedTypeClassDemo::class.java.getDeclaredField("key2").genericType as GenericArrayType
    println(type2.javaClass)
    println(type2.genericComponentType)

}

打印结果为:

class sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl
M
class sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl
java.util.List<java.lang.String>
  • WildcardType
    通配符泛型,包含2个方法:

Type[] getUpperBounds

Type[] getLowerBounds

对于代码:

public class TestType {
    private List<? extends Number> a;  // // a没有下界, 取下界会抛出ArrayIndexOutOfBoundsException
    private List<? super String> b;
    public static void main(String[] args) throws Exception {
        Field fieldA = TestType.class.getDeclaredField("a");
        Field fieldB = TestType.class.getDeclaredField("b");
        // 先拿到范型类型
        ParameterizedType pTypeA = (ParameterizedType) fieldA.getGenericType();
        ParameterizedType pTypeB = (ParameterizedType) fieldB.getGenericType();
        // 再从范型里拿到通配符类型
        WildcardType wTypeA = (WildcardType) pTypeA.getActualTypeArguments()[0];
        WildcardType wTypeB = (WildcardType) pTypeB.getActualTypeArguments()[0];
        // 方法测试
        System.out.println(wTypeA.getUpperBounds()[0]);   // class java.lang.Number
        System.out.println(wTypeB.getLowerBounds()[0]);   // class java.lang.String
        // 看看通配符类型到底是什么, 打印结果为: ? extends java.lang.Number
        System.out.println(wTypeA);
        System.out.println(wTypeB);
    }
}

打印结果为:

class java.lang.Number
class java.lang.String
? extends java.lang.Number
? super java.lang.String
分类: 反射

0 条评论

发表回复

您的电子邮箱地址不会被公开。