参考博文:
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编译该泛型前的信息.
如对于ListClassDemo<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
对于ClassDemo<List<String>, String, String>
,获取的结果就是
java.util.List<? extends java.lang.String>
class java.lang.String
class java.lang.String
Type getRawType
返回参数化类型的原始类型,例如List
获取声明泛型的类或者接口,也就是泛型中<>前面的那个值。
Type getOwnerType
返回类型所属的类型。例如A
- GenericArrayType
表示的是数组类型且组成元素是ParameterizedType 或TypeVariable。例如List
对于代码:
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 条评论