1.什么是类的声明信息
通常类的声明可以包括如下信息:
- 类的修饰符
- 类的标准名称
- 类的泛型参数
- 类的继承类以及实现的接口
- 类的注解信息
下面将学习如何获得这些信息:
我们将用到Class类中的下面关键方法
forName(String className) //根据给定的名称获取Class对象
getAnnotations() //返回此Class对象上存在的注解
getCanonicalName()//返回Java Language Specification中所定义的底层类的规范化名称
getGenericInterfaces()//返回泛型形式的对象类所实现的接口
getGenericSuperclass()//返回泛型形式的对象类所直接继承的父类
getModifiers() //返回此类或接口以整数编码的java语言修饰符,
//与Modifier.toString()搭配使用
getTypeParameters() //按声明顺序返回TypeVariable(泛型)对象的一个数组
2.实例学习
首先编写测试Bean:
package ReflectStudy.Exa3;
import javax.annotation.Resource;
import java.io.Serializable;
import java.util.*;
/**
* 我是测试的Bean
*/
@Resource
public class TestBean<String> extends AbstractList<String> implements Serializable {
public String name;
public String code;
private String password;
@Override
public int size() {
return 0;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public boolean contains(Object o) {
return false;
}
@Override
public String get(int index) {
return null;
}
}
然后进行程序的编写:
package ReflectStudy.Exa3;
import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
/**
* 通过反射获得类的声明信息,包括:
* 1.类的标准名称
* 2.类的修饰符
* 3.类的泛型参数类型名称
* 4.类继承的类名
* 5.类实现的接口
* 6.类的注解信息
*/
public class ClassDeclarationViewer {
public static void main(String[] args) throws ClassNotFoundException {
// 获得TestBean的Class对象
Class<?> clazz = Class.forName("ReflectStudy.Exa3.TestBean");
//获得类TestBean的名称
System.out.println("类TestBean的规范名称:" + clazz.getCanonicalName());
System.out.println("类TestBean的全称:"+clazz.getName());
//获得类TestBean的修饰符信息
System.out.println("类TestBean的修饰符:" + Modifier.toString(clazz.getModifiers()));
//输出类的泛型参数信息
TypeVariable<?>[] typeVariables = clazz.getTypeParameters();
System.out.print("类TestBean的泛型参数:");
if (typeVariables.length != 0) {
for (TypeVariable<?> typeVariable : typeVariables) {
System.out.println(typeVariable + "\t");
}
} else {
System.out.println("空");
}
// 输出类所实现的所有接口
Type[] interfaces = clazz.getGenericInterfaces();
System.out.println("类TestBean所实现的接口:");
if (interfaces.length != 0) {
for (Type type : interfaces) {
System.out.println("\t" + type);
}
} else {
System.out.println("\t" + "空");
}
// 输出类的直接继承类,如果是继承自Object则返回空
Type superClass = clazz.getGenericSuperclass();
System.out.print("类TestBean的直接继承类:");
if (superClass != null) {
System.out.println(superClass);
} else {
System.out.println("空");
}
// 输出类的所有注解信息,有些注解信息是不能用反射获得的
Annotation[] annotations = clazz.getAnnotations();
System.out.print("类TestBean的注解:");
if (annotations.length != 0) {
for (Annotation annotation : annotations) {
System.out.println("\t" + annotation);
}
} else {
System.out.println("空");
}
}
}
运行之,查看结果:注意(关于类的注解,并不是所有的注解都能获取到的,有些是不能获取的)
3 总结
当我们获得一个类的Class对象clazz时,我们可以用Class对象获得类的一些声明信息,
1).获得类的修饰符信息
String modifierStr = Modifier.toString(clazz.getModifiers());
2).获得类的泛型参数信息
//首先通过getTypeParameters()获取一个TypeVariable数组,
//这个数组存储的类的泛型信息,然后遍历这个数组即可
TypeVariable<?>[] typeVariables = clazz.getTypeParameters();
System.out.print("类TestBean的泛型参数:");
if (typeVariables.length != 0) {
for (TypeVariable<?> typeVariable : typeVariables) {
System.out.println(typeVariable + "\t");
}
} else {
System.out.println("空");
}
3).获得类实现的接口信息
//先通过class的getGenericInterfaces()的方法得到一个Type类型的数组
//然后遍历这个数组就能得到类实现的接口的信息
Type[] interfaces = clazz.getGenericInterfaces();
System.out.println("类TestBean所实现的接口:");
if (interfaces.length != 0) {
for (Type type : interfaces) {
System.out.println("\t" + type);
}
} else {
System.out.println("\t" + "空");
}
4).获得类的直接父类的信息
//可以直接通过class的getGenericSuperclass方法的一个Type类型的对象
Type superClass = clazz.getGenericSuperclass();
System.out.print("类TestBean的直接继承类:");
if (superClass != null) {
System.out.println(superClass);
} else {
System.out.println("空");
}
5).获得类的注解信息
//通过class的getAnnotations方法获得一个Annotation数组,然后遍历这个数组即可
Annotation[] annotations = clazz.getAnnotations();
System.out.print("类TestBean的注解:");
if (annotations.length != 0) {
for (Annotation annotation : annotations) {
System.out.println("\t" + annotation);
}
} else {
System.out.println("空");}