整理了一下反射中常用到的知识点:
先创建一个测试类Persons,用反射来获取类中的结构
package ReflectionUse02;
/**
* @Author:CT
* @Date:2021/2/18
* @Description:ReflectionUse02
* @Version 1.0
*/
@MyAnnotation(value = "Hello")
public class Persons extends Creature<String> implements Comparable<String>,MyInterface {
String name;
int age;
public int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Persons(){
}
private Persons(String name){
this.name=name;
}
Persons(String name,int age){
this.name=name;
this.age=age;
}
String show(String nation){
System.out.println("我的国籍是"+nation);
return nation;
}
@MyAnnotation
public String display(String interests){
return interests;
}
@Override
public int compareTo(String o) {
return 0;
}
@Override
public void info() {
System.out.println("我是一个人");
}
public static void study(){
System.out.println("学习");
}
@Override
public String toString() {
return "Persons{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
}
- 获取当前运行时类的所有属性
package ReflectionUse02;
import org.junit.Test;
import java.lang.reflect.Field;
/**
* @Author:CT
* @Date:2021/2/18
* @Description:ReflectionUse02
* @Version 1.0
*/
/*
获取当前运行时类的所有属性
*/
public class ReflectionMethod02 {
@Test
public void test(){
Class<Persons> personsClass = Persons.class;
// 获取属性结构 当前类的所有属性结构
Field[] fields = personsClass.getFields();
for (Field field:fields){
System.out.println(field);//获取当前运行时类,及其父类当中所有申明为public 的属性
//public int ReflectionUse02.Persons.id public double ReflectionUse02.Creature.weight
}
// 获取当前类所有的属性和方法 不包含父类(当前运行时类的属性 包括私有的权限和protected)
Field[] declaredFields = personsClass.getDeclaredFields();
for (Field d:declaredFields){
System.out.println(d);
/*
private java.lang.String ReflectionUse02.Persons.name
int ReflectionUse02.Persons.age
public int ReflectionUse02.Persons.id
*/
}
}
//权限修饰符 数据类型 变量名
@Test
public void test3(){
// 获取当前类的权限修饰符
Class<Persons> personsClass = Persons.class;
Field[] declaredFields = personsClass.getDeclaredFields();
for (Field field:declaredFields){
int modifiers = field.getModifiers();//获取当前类的权限修饰符 返回值为int类型
System.out.println(modifiers);
//获取数据类型
Class<?> type = field.getType();
System.out.println(type.getName());
// 变量名
String name = field.getName();
System.out.println(name);
}
}
}
2.获取当前运行时类及其父类中的所有方法
public class ReflectionMethod03 {
@Test
public void test(){
//获取当前运行时类及其父类所有权限修饰为public 的方法
Class<Persons> personsClass = Persons.class;
Method[] methods = personsClass.getMethods();
for (Method m:methods){
System.out.println(m);
}
// 获取当前运行时类的所有方法权限修饰符声明为public 的方法
Method[] declaredMethods = personsClass.getDeclaredMethods();
for (Method method:declaredMethods){
System.out.println(method);
}
}
- 获取方法的权限修饰符 返回值类型 方法名(参数类型 形参名) throws XXXException 以及注解
public void test1(){
//1.获取方法声明的注解
Class<Persons> personsClass = Persons.class;
Method[] declaredMethods = personsClass.getDeclaredMethods();
for (Method method:declaredMethods){
Annotation[] annotations = personsClass.getAnnotations();
for(Annotation annotation:annotations){
System.out.println(annotation);
}
//2.权限修饰符
System.out.println(Modifier.toString(method.getModifiers()));
//3.返回值类型
System.out.println(method.getReturnType().getName()+"\t");
//4.方法名
System.out.println(method.getName());
//5.形参列表
Class<?>[] parameterTypes = method.getParameterTypes();
if (!(parameterTypes==null&¶meterTypes.length==0)){
for (Class c:parameterTypes){
System.out.println(c.getName());
}
}
//6.抛出的异常
Class<?>[] exceptionTypes = method.getExceptionTypes();
if (!(exceptionTypes==null&&exceptionTypes.length==0)){
System.out.println(exceptionTypes);
}
}}
4.获取当前运行时类的构造器
public class ReflectionMethod04 {
@Test
public void test() throws NoSuchMethodException {
Class<Persons> personsClass = Persons.class;
// 获取构造器包括父类中的构造器 但是只获取权限修饰符为public 的
Constructor<?>[] constructors = personsClass.getConstructors();
for (Constructor constructor:constructors){
System.out.println(constructor);
}
Constructor constructor1 = personsClass.getConstructor();
System.out.println(constructor1);
//获取当前类的构造器 所有类型的包括 private
Constructor<?>[] declaredConstructors = personsClass.getDeclaredConstructors();
for (Constructor con:declaredConstructors){
System.out.println(con);//private ReflectionUse02.Persons(java.lang.String)
}
}
5.获取运行时类的父类,获取当前运行时类所在的包 获取当前运行时类的注解
// 获取运行时类的父类
@Test
public void test2(){
Class<Persons> personsClass = Persons.class;
//获取运行时类父类的泛型
Type genericSuperclass = personsClass.getGenericSuperclass();
// 获取带参数的泛型
ParameterizedType genericSuperclass1 = (ParameterizedType) genericSuperclass;
//获取泛型的参数(泛型类型) 返回的是一个数组类型 泛型可能存在键值对
Type[] actualTypeArguments = genericSuperclass1.getActualTypeArguments();
System.out.println(actualTypeArguments[0].getTypeName());//java.lang.String
}
// 获取运行时类的接口 获取运行时类父类的接口
@Test
public void test3(){
Class<Persons> personsClass = Persons.class;
// 获取运行时类的接口
Class<?>[] interfaces = personsClass.getInterfaces();
//获取运行时类父类的接口
Class<?>[] interfaces1 = personsClass.getSuperclass().getInterfaces();
}
// 获取当前运行时类所在的包 获取当前运行时类的注解
@Test
public void test4(){
Class personsClass = Persons.class;
// 获取当前运行时类的包
// Package aPackage = personsClass.getPackage();
// 获取当前运行时类的注解
Annotation[] annotations = personsClass.getAnnotations();
for (Annotation a:annotations){
System.out.println(a);
}
6.获取当前运行时类中的指定属性方法和构造器
package ReflectionUse02;
import ReflectionUse.Person;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @Author:CT
* @Date:2021/2/19
* @Description:ReflectionUse02
* @Version 1.0
*/
/*
通过反射调用运行时类的结构: 属性,方法,构造器
*/
public class ReflectionMethod05 {
@Test
public void test() throws NoSuchFieldException, IllegalAccessException, InstantiationException {
Class<Persons> personsClass = Persons.class;
Persons persons =(Persons) personsClass.newInstance();
//获取指定的属性包括 私有的方式所修饰
Field name = personsClass.getDeclaredField("name");
name.setAccessible(true);
name.set(persons,"帅哥");
System.out.println(name.get(persons));//使用时注意权限的问题 如果属性设置为private 类型则会导致非法访问 或者在修改之前调用SetAccessible()方法把属性设为可见的
}
// 如何操作运行时类的方法 非静态的
@Test
public void test2() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class<Persons> personsClass = Persons.class;
Persons persons = (Persons) personsClass.newInstance();
Method show = personsClass.getDeclaredMethod("show", String.class);
show.setAccessible(true);
Object aa = show.invoke(persons, "aa");
System.out.println(aa);
}
// 如何操作调用运行时类的静态方法
@Test
public void test3() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class<Persons> personsClass = Persons.class;
Persons persons = personsClass.newInstance();
Method study = personsClass.getDeclaredMethod("study");
study.setAccessible(true);
Object invoke = study.invoke(null);
}
// 如何调运行时类的构造器 方法的形参 指定方法形参的构造器
@Test
public void test4() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<Persons> personsClass = Persons.class;
Constructor<Persons> declaredConstructor = personsClass.getDeclaredConstructor(String.class);
declaredConstructor.setAccessible(true);//设置构造器可见
// 通过构造器去创建运行时类的对象
Persons p = (Persons) declaredConstructor.newInstance("chentao");
System.out.println(p);//Persons{name='chentao', age=0, id=0}
}
}