通过反射获取运行时类的对象,属性,构造器,方法,注解

整理了一下反射中常用到的知识点:
先创建一个测试类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 +
                '}';
    }
}

  1. 获取当前运行时类的所有属性
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);
        }

    }
  1. 获取方法的权限修饰符 返回值类型 方法名(参数类型 形参名) 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&&parameterTypes.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}
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_46351306/article/details/113878406