Type
Type
是Java
中所有类型的父接口。
其子类和子接口如下:
Class<T>
TypeVariable<D>
ParameterizedType
GenericArrayType
WildcardType
Type
只有一个默认方法:
// 返回描述类型的字符串
default String getTypeName() {
return toString();
}
Class<T>
Class<T>
封装了一个具体类的属性操作和反射操作,T
是具体类;
Class<T>
实现了以下四个接口:
- Serializable
- GenericDeclaration
- Type
- AnnotatedElement
Serializable
并无接口方法,作为序列化标记;
GenericDeclaration
GenericDeclaration
是所有声明了类型变量的类的公用接口;
只有一个接口方法:
// 用于获取类型变量的数组
public TypeVariable<?>[] getTypeParameters();
用法如下:
val clazz = Map::class.java
val list = clazz.typeParameters
list.forEach {
println("${it.name} ${it.bounds.map { bound-> bound.typeName }}")
}
运行结果:
K [java.lang.Object]
V [java.lang.Object]
Map
类的声明如下:
public interface Map<K, out V> {
......
}
Type
Class<T>
实现了Type
唯一的接口方法,具体实现如下:
public String getTypeName() {
if (isArray()) {
try {
Class<?> cl = this;
int dimensions = 0;
while (cl.isArray()) {
dimensions++;
cl = cl.getComponentType();
}
StringBuilder sb = new StringBuilder();
sb.append(cl.getName());
for (int i = 0; i < dimensions; i++) {
sb.append("[]");
}
return sb.toString();
} catch (Throwable e) { /*FALLTHRU*/ }
}
return getName();
}
对数组类型和非数组类型分别处理,具体细节按下不表;
用法如下:
val clazz = Map::class.java
println(clazz.typeName)
val array = Array<IntArray>(3){
it -> intArrayOf(0)
}
println(array.javaClass.typeName)
结果如下:
java.util.Map
int[][]
AnnotatedElement
定义了一系列获取注解的接口方法,所有可以被注解标记的元素都应该实现这个接口;
在讲解接口方法之前需要了解各种注解的分类:
directly present
直接出现在元素上的注解;
indirectly present
被@Repeatable
标记的注解,然后该注解出现在元素上;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Persons {
Person[] value();
}
@Repeatable(Persons.class)
public @interface Person{
String role() default "";
}
@Person(role="CEO")
@Person(role="husband")
@Person(role="father")
@Person(role="son")
public class Man {
String name= "";
}
Person
注解相对于Man
就是indirectly present
的,Persons
相对于Man
是directly present
,Person
是Persons
的参数;
present
分为两种情况:
- directly present
- 被
@Inherited
标记的注解A
,然后注解A
出现在B
的父类C
上,则A
相对与B
是present
的;
associated
分为三种情况:
- directly present
- indirectly present
- 第三种情况有四个小条件,注解为
A
,元素为E
- 注解
A
没有直接或者间接出现在元素E
上 - 元素
E
是一个类 - 注解
A
被@Inherited
标记 - 注解
A
和元素E
的父类的关系为associated
isAnnotationPresent()
方法声明:
default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
指定注解是否为present
状态;
getAnnotation()
方法声明:
<T extends Annotation> T getAnnotation(Class<T> annotationClass)
如果给定的注解处于present
状态,则返回注解,否则返回null
;
getAnnotations()
方法声明:
Annotation[] getAnnotations();
获取所有处于present
状态的注解,若无符合条件的数组,则返回大小为0
的数组;
getAnnotationsByType()
方法声明:
default <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass)
获取所有处于associated
状态的注解;
getDeclaredAnnotation()
方法声明:
default <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass)
如果给定的注解处于directly present
状态,则返回注解,反则返回null
;
getDeclaredAnnotationsByType()
方法声明:
default <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass)
如果给定的注解处于directly present
或者indirectly present
状态,返回注解数组;
getDeclaredAnnotations()
方法声明:
Annotation[] getDeclaredAnnotations()
获取所有处于directly present
状态的注解;
具体方法讲解
toString()
public String toString() {
return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
+ getName();
}
描述当前Class
文件,文件类型和文件的全限定名;
toGenericString()
描述当前Class
文件,包括修饰符和类型变量;
forName()
静态方法,根据全限定名获取Class
;
newInstance()
调用无参的构造函数,返回实例;
isInstance()
同instanceof
关键字作用相同;
isAssignableFrom()
如果给定的参数为当前Class
的父类或者父接口,则返回true
,否则返回false
;
isInterface()
当前Class
是否为接口;
isArray()
当前Class
是否为数组;
isPrimitive()
当前Class
是否为基础数据类型;
包括:Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE;
isAnnotation()
当前Class
是否为注解;
isSynthetic()
当前Class
是否为合成类;
合成类指的是在编译时引入的类,例如匿名类;
getName()
获取当前Class
的名称;
分为三种情况:
-
Class
是引用类型,则返回其全限定名; -
Class
是基本数据类型,则返回相应的关键字; -
Class
是数组类型,规则如下
getClassLoader()
获取当前Class
的类加载器;
getTypeParameters()
详见 GenericDeclaration ;
getSuperclass()
获取其父类的Class
;
getGenericSuperclass()
获取其直接父类的Type
;
getPackage()
获取当前Class
的package
;
getInterfaces()
获取当前Class
所有实现的接口Class
数组;
getGenericInterfaces()
获取当前Class
所有直接实现的接口Type
数组;
getComponentType()
如果当前Class
是数组,则返回数组元素类型Class
;
如果当前Class
不是数组,则返回null
;
getModifiers()
获取当前Class
的修饰符;
getEnclosingMethod()
如果当前Class
是一个函数中的匿名类,则返回该函数,否则返回null
;
getEnclosingConstructor()
如果当前Class
是一个构造函数中的匿名类,则返回构造函数,否则返回null
;
getDeclaringClass()
如果当前Class
是另一个Class B
的成员变量,则返回Class B
,否则返回null
;
getEnclosingClass()
返回声明当前Class
的外部类;
getSimpleName()
对于普通类和基本类型返回其类名;
对于匿名类返回空串;
对于数组返回"${类名}[]";
getTypeName()
详见 Type ;
getCanonicalName()
返回其全限定名;
isAnonymousClass()
是否为匿名类;
isLocalClass()
是否为local class
;
local class
指的是声明在函数体内部的类;
isMemberClass()
当前Class
是否为内部类;
getClasses()
获取定义在当前类内部的public
类或者接口,包括来自父类的内部类和接口;
getFields()
获取当前类的所有公开字段,包括来自父类的字段;
getMethods()
获取当前类的所有公开方法,包括来自父类和父接口的公开方法;
getConstructors()
获取当前类的所有公开构造方法;
getField()
根据给定的字符串返回当前类的公开字段;
getMethod()
根据方法签名,获得当前的类的指定公开方法;
getConstructor()
根据给定参数,获取当前类的公开构造方法;
getDeclaredClasses()
获取定义在当前类内部的类或者接口,包括来自父类和父接口的任何修饰符的类;
getDeclaredFields()
获取当前类的所有字段,不包括继承自其他类的的字段;
getDeclaredMethods()
获取当前类的所有方法,不包括继承自其他类的方法;
getDeclaredConstructors()
获取当前类的所有构造方法;
getDeclaredField()
根据给定的字段名,获取字段,包括私有字段;
getDeclaredMethod()
根据方法签名,获取指定方法,包括私有方法;
getDeclaredConstructor()
根据给定参数,获取指定构造方法;
getResourceAsStream()
根据参数返回InputStream
,具体实现在类加载器中;
getResource()
根据参数返回URL
,具体实现在类加载器中;
getProtectionDomain()
返回ProtectionDomain
,这个类封装类一些权限安全相关的代码;
isEnum()
判断是否类枚举类;
cast()
进行类型转换;
asSubclass()
如果当前类是给定类的子类,则进行类型转换;否则抛出异常;
getAnnotatedSuperclass()
获取父类的注解类型;
Class clazz = java.util.HashMap.class;
System.out.println(
clazz.getAnnotatedSuperclass().getType().getTypeName());
结果如下:
java.util.AbstractMap<K, V>
getAnnotatedInterfaces()
获取当前类的所有父类和父接口的注解类型;
Class clazz = java.util.HashMap.class;
AnnotatedType[] typeList = clazz.getAnnotatedInterfaces();
for (AnnotatedType type : typeList) {
System.out.println(type.getType().getTypeName());
}
结果如下:
java.util.Map<K, V>
java.lang.Cloneable
java.io.Serializable
TypeVariable
public static class GenericBean<K> {
// 类型变量
K key;
// 参数化类型
List<K> kList;
}
public static void main(String[] args) {
try {
GenericBean bean = new GenericBean<String>();
Field fk;
fk = GenericBean.class.getDeclaredField("key");
Type eyType = fk.getGenericType();
if (eyType instanceof ParameterizedType) {
System.out.println("ParameterizedType: true");
}
if (eyType instanceof TypeVariable) {
System.out.println("TypeVariable: true");
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
执行结果:
TypeVariable: true
getBounds()
获取该泛型的上下界;
public static class GenericBean<K> {
// 类型变量
K key;
// 参数化类型
List<K> kList;
}
public static void main(String[] args) {
try {
GenericBean bean = new GenericBean<String>();
Field fk;
fk = GenericBean.class.getDeclaredField("key");
Type eyType = fk.getGenericType();
if (eyType instanceof TypeVariable) {
System.out.println("TypeVariable: true");
TypeVariable variable = (TypeVariable) eyType;
Type[] bounds = variable.getBounds();
for (Type bound : bounds) {
System.out.println(bound.getTypeName());
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
执行结果:
TypeVariable: true
java.lang.Object
getGenericDeclaration()
获取当前类的泛型声明;
public static class GenericBean<K, V> {
// 类型变量
K key;
// 参数化类型
List<K> kList;
}
public static void main(String[] args) {
try {
GenericBean bean = new GenericBean<String, String>();
Field fk;
fk = GenericBean.class.getDeclaredField("key");
Type eyType = fk.getGenericType();
if (eyType instanceof TypeVariable) {
System.out.println("TypeVariable: true");
TypeVariable variable = (TypeVariable) eyType;
GenericDeclaration declaration = variable.getGenericDeclaration();
TypeVariable<?>[] parameters = declaration.getTypeParameters();
for (TypeVariable parameter : parameters) {
System.out.println(parameter.getName());
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
执行结果:
TypeVariable: true
K
V
可以根据泛型声明获取当前所有的泛型;
getName()
返回泛型名称;
public static class GenericBean<K, V> {
// 类型变量
K key;
// 参数化类型
List<K> kList;
}
public static void main(String[] args) {
try {
GenericBean bean = new GenericBean<String, String>();
Field fk;
fk = GenericBean.class.getDeclaredField("key");
Type eyType = fk.getGenericType();
if (eyType instanceof TypeVariable) {
System.out.println("TypeVariable: true");
TypeVariable variable = (TypeVariable) eyType;
System.out.println(variable.getName());
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
执行结果:
TypeVariable: true
K
getAnnotatedBounds()
获取上下界的注解类型;
public static class GenericBean<K, V> {
// 类型变量
K key;
// 参数化类型
List<K> kList;
}
public static void main(String[] args) {
try {
GenericBean bean = new GenericBean<String, String>();
Field fk;
fk = GenericBean.class.getDeclaredField("key");
Type eyType = fk.getGenericType();
if (eyType instanceof TypeVariable) {
System.out.println("TypeVariable: true");
TypeVariable variable = (TypeVariable) eyType;
AnnotatedType[] list = variable.getAnnotatedBounds();
for (AnnotatedType type : list) {
System.out.println(type.getType().getTypeName());
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
执行结果:
TypeVariable: true
java.lang.Object
ParameterizedType
public static class GenericBean<K, V> {
// 类型变量
K key;
// 参数化类型
List<V> kList;
}
public static void main(String[] args) {
try {
GenericBean bean = new GenericBean<String, String>();
Field fk;
fk = GenericBean.class.getDeclaredField("kList");
Type eyType = fk.getGenericType();
if (eyType instanceof ParameterizedType) {
System.out.println("ParameterizedType: true");
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
执行结果:
ParameterizedType: true
getActualTypeArguments()
获取该字段生命的所有泛型数组;
public static class GenericBean<K, V> {
// 类型变量
K key;
// 参数化类型
Map<K,V> kMap;
}
public static void main(String[] args) {
try {
GenericBean bean = new GenericBean<String, String>();
Field fk;
fk = GenericBean.class.getDeclaredField("kMap");
Type eyType = fk.getGenericType();
if (eyType instanceof ParameterizedType) {
System.out.println("ParameterizedType: true");
ParameterizedType variable = (ParameterizedType) eyType;
Type[] list = variable.getActualTypeArguments();
for (Type type : list) {
System.out.println(type.getTypeName());
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
执行结果:
ParameterizedType: true
K
V
getRawType()
获取参数化类型字段的原生类型;
public static class GenericBean<K, V> {
// 类型变量
K key;
// 参数化类型
Map<K,V> kMap;
}
public static void main(String[] args) {
try {
GenericBean bean = new GenericBean<String, String>();
Field fk;
fk = GenericBean.class.getDeclaredField("kMap");
Type eyType = fk.getGenericType();
if (eyType instanceof ParameterizedType) {
System.out.println("ParameterizedType: true");
ParameterizedType variable = (ParameterizedType) eyType;
Type type = variable.getRawType();
System.out.println(type.getTypeName());
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
执行结果:
ParameterizedType: true
java.util.Map
getOwnerType()
解释比较复杂,请看代码:
public class Test {
public static class GenericBean<K, V> {
// 类型变量
K key;
// 参数化类型
Map<K,V> kMap;
MemberBean<K> bean;
}
public static class MemberBean<K> {
}
public static void main(String[] args) {
try {
GenericBean bean = new GenericBean<String, String>();
Field fk;
fk = GenericBean.class.getDeclaredField("bean");
Type eyType = fk.getGenericType();
if (eyType instanceof ParameterizedType) {
System.out.println("ParameterizedType: true");
ParameterizedType variable = (ParameterizedType) eyType;
Type type = variable.getOwnerType();
if (type == null) {
System.out.println("type is null");
} else {
System.out.println(type.getTypeName());
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
执行结果:
ParameterizedType: true
Test
GenericArrayType
泛型数组;
getGenericComponentType()
获取泛型名称;
public static class GenericBean<K extends InputStream, V> {
// 类型变量
K key;
// 参数化类型
Map<K, V> kMap;
K[] kArray;
}
public static void main(String[] args) {
try {
GenericBean bean = new GenericBean<FileInputStream, String>();
Field fk;
fk = GenericBean.class.getDeclaredField("kArray");
Type eyType = fk.getGenericType();
if (eyType instanceof GenericArrayType) {
System.out.println("GenericArrayType: true");
GenericArrayType variable = (GenericArrayType) eyType;
Type type = variable.getGenericComponentType();
System.out.println(type.getTypeName());
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
执行结果:
GenericArrayType: true
K
WildcardType
通配符泛型;
public static class GenericBean {
List<? extends String> kList;
}
public static void main(String[] args) {
try {
Field fk = GenericBean.class.getDeclaredField("kList");
Type eyType = fk.getGenericType();
if (eyType instanceof ParameterizedType) {
System.out.println("ParameterizedType: true");
ParameterizedType parameterizedType = (ParameterizedType) eyType;
WildcardType variable = (WildcardType) parameterizedType.getActualTypeArguments()[0];
Type[] upperBounds = variable.getUpperBounds();
Type[] lowerBounds = variable.getLowerBounds();
if (upperBounds.length == 0) {
System.out.println("upperBounds is empty");
} else {
for (Type type : upperBounds) {
System.out.println(type.getTypeName());
}
}
System.out.println();
if (lowerBounds.length == 0) {
System.out.println("lowerBounds is empty");
} else {
for (Type type : lowerBounds) {
System.out.println(type.getTypeName());
}
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
执行结果:
ParameterizedType: true
java.lang.String
lowerBounds is empty