首页 > 其他分享 >Reflection

Reflection

时间:2023-01-06 09:57:32浏览次数:37  
标签:Reflection System 获取 泛型 println class out

package com.tenpay.risk.aml.cdd.batch.apisvr.core.basic;

import lombok.Data;
import org.junit.jupiter.api.Test;

import java.io.Serializable;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 1、获取指定的构造函数,并创建新的实例
 * 2、获取私有成员方法并调用
 * 3、获取静态方法并调用
 * 4、访问私有字段
 * 5、访问注解Annotation
 * 6、访问成员变量的泛型、方法参数的泛型、方法返回值的泛型  method.getGenericReturnType,listField.getGenericType(),setListMethod.getGenericParameterTypes()
 */
@Data
public class ReflectionTest {

    @Test
    void test() throws Exception{

        /**获取类的Class*/
        Class<Person> personClass = Person.class;
        System.out.println(personClass);
        System.out.println(personClass.getName());
        System.out.println(personClass.getSimpleName());
        System.out.println(personClass.getModifiers());

        /**获取所有构造函数 Declared*/
        Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }

        /**指定具体的构造函数创建实例*/
        Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor(Integer.class, String.class);
        Person binfire = declaredConstructor.newInstance(1, "binfire");
        System.out.println(binfire);

        /**访问私有方法*/
        Method sayHello = personClass.getDeclaredMethod("sayHello");
        sayHello.setAccessible(true);
        sayHello.invoke(binfire);

        /**访问静态方法*/
        Method sayHelloMessage = personClass.getDeclaredMethod("sayHelloMessage",String.class,Integer.class,String.class);
        sayHelloMessage.setAccessible(true);
        sayHelloMessage.invoke(null,"binfire",30,"您好");

        /**访问字段*/
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        Field name = personClass.getDeclaredField("name");
        name.setAccessible(true);
        name.set(binfire,"中国");
        Object o = name.get(binfire);
        System.out.println(o);
        Field age = personClass.getDeclaredField("age");
        age.setAccessible(true);
        age.setInt(binfire,123);
        int anInt = age.getInt(binfire);
        System.out.println(anInt);

        /**Annotation注解*/
        if(name.isAnnotationPresent(MyAnnotation.class)){
            MyAnnotation declaredAnnotation = name.getDeclaredAnnotation(MyAnnotation.class);
            if(declaredAnnotation!=null){
                System.out.println(declaredAnnotation.testA()+":"+declaredAnnotation.testB());
            }

        }




    }

    @Test
    void testGenerialInfo() throws NoSuchMethodException {
        getMethodReturnValueGeneric();
    }

    /**
     * 获取方法返回值的泛型类型信息
     *
     * @throws NoSuchMethodException
     */
    public void getMethodReturnValueGeneric() throws NoSuchMethodException {
        // 获取名为"getList"的方法,在MyClass类中
        Method getListMethod = MyClass.class.getMethod("getList");
        // 获取返回值类型,getGenericReturnType()会返回值带有泛型的返回值类型
        Type genericReturnType = getListMethod.getGenericReturnType();
        // 但我们实际上需要获取返回值类型中的泛型信息,所以要进一步判断,即判断获取的返回值类型是否是参数化类型ParameterizedType
        if (genericReturnType instanceof ParameterizedType) {
            // 如果要使用ParameterizedType中的方法,必须先强制向下转型
            ParameterizedType type = (ParameterizedType) genericReturnType;
            // 获取返回值类型中的泛型类型,因为可能有多个泛型类型,所以返回一个数组
            Type[] actualTypeArguments = type.getActualTypeArguments();
            // 循环数组,遍历每一个泛型类型
            for (Type actualTypeArgument : actualTypeArguments) {
                Class typeArgClass = (Class) actualTypeArgument;
                System.out.println("成员方法返回值的泛型信息:" + typeArgClass);
            }
        }
    }

    /**
     * 获取类中成员变量的泛型类型信息
     *
     * @throws NoSuchFieldException
     */
    public static void getMemberVariablesGeneric() throws NoSuchFieldException {
        // 获取MyTestClass类中名为"list"的字段
        Field listField = MyClass.class.getField("list");
        // 获取该字段的类型信息,getGenericType()方法能够获取带有泛型的类型信息
        Type genericType = listField.getGenericType();
        // 但我们实际上需要获取返回值类型中的泛型信息,所以要进一步判断,即判断获取的返回值类型是否是参数化类型ParameterizedType
        if (genericType instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) genericType;
            // 获取成员变量的泛型类型信息
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                Class fieldArgClass = (Class) actualTypeArgument;
                System.out.println("成员变量的泛型信息:" + fieldArgClass);
            }
        }
    }

    /**
     * 获取方法参数的泛型类型信息
     *
     * @throws NoSuchMethodException
     */
    public static void getMethodParametricGeneric() throws NoSuchMethodException {
        // 获取MyTestClass类中名为"setList"的方法
        Method setListMethod = MyClass.class.getMethod("setList", List.class);
        // 获取该方法的参数类型信息(带有泛型)
        Type[] genericParameterTypes = setListMethod.getGenericParameterTypes();
        // 但我们实际上需要获取返回值类型中的泛型信息,所以要进一步判断,即判断获取的返回值类型是否是参数化类型ParameterizedType
        for (Type genericParameterType : genericParameterTypes) {
            ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
            // 获取成员方法参数的泛型类型信息
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                Class realType = (Class) actualTypeArgument;
                System.out.println("成员方法参数的泛型信息:" + realType);
            }
        }
    }

}


class MyClass {
    // 带有泛型的成员变量
    public List<Object> list = new ArrayList<>();

    // 方法返回值中带有泛型
    public List<Object> getList() {
        return list;
    }

    // 方法参数带有泛型
    public void setList(List<Object> list) {
        this.list = list;
    }
}


@Data
class Person implements Cloneable, Serializable {

    /**
     * default VersionUID
     */
    private static final long serialVersionUID = 1L;

    private int age;

    @MyAnnotation(testA = "123",testB = "456")
    private String name;

    private Person(){
        this.age=0;
        this.name=null;
    }

    public Person(Integer age, String name) {
        this.setAge(age);
        this.setName(name);
    }

    private void sayHello(){
        System.out.println("say hello");
    }

    private static void sayHelloMessage(String name,Integer age,String message){
        System.out.printf("%s;%d;%s;%n",name,age,message);
    }

    public int getResult(int[] array){
        int sum=0;
        for(int e:array){
            sum=e+sum;
        }
        return sum;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return String.format("%d:%s", this.getAge(),this.getName());
    }

}


/**
 * 注解 @interface开头
 * 元注解, 标记在注解上的注解
 * @Retention,@Documented,@Target,@Inherited,@Repeatable
 * @Retention: 保留期,
 *
 * RetentionPolicy.CLASS (默认)
 * 注解被编译器在编译阶段写入字节码文件,但它并不会在运行时被加载到 JVM 中
 *RetentionPolicy.RUNTIME
 * 注解被编译器在编译阶段写入字节码文件,而且会在运行时加载到 JVM 中,所以在程序运行时可以获取到它们。
 *
 * @Inherited
 * 继承的子类同样继承
 *
 * 注解成员变量:无参的构造函数
 *
 */
@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    String testA() default "";
    String testB() default "";
}

  

标签:Reflection,System,获取,泛型,println,class,out
From: https://www.cnblogs.com/binfirechen/p/17029505.html

相关文章

  • 反射Reflection in C#
    在这篇文章中,我们将用C#示例讨论一下反射。在C#中反射提供了可以描述程序集、模块和类型的对象。你可使用反射自动创建一个类型的实例,绑定类型到已存的对象上,或是从现有对......
  • C#反射(Reflection)详解
    原文网址:https://www.cnblogs.com/vaevvaev/p/6995639.html1、什么是反射2、命名空间与装配件的关系3、运行期得到类型信息有什么用4、如何使用反射获取类型5、如何......
  • java 反射 Reflection
    一.什么是反射:Relection(反射):是Java被视为动态语言的关键,反射机制允许程序在执行期间借助于ReflectionAPI取得任何类的内部信息,并能直接操作任意对象的内部属性及方法公式......
  • 反射(Reflection)
    反射(Reflection)所谓反射就是在Java运行期间,程序可以拿到一个对象的所有信息。反射是为了解决在对一个对象完全未知的情况下调用其方法还产生的。通过Class实例获取class......
  • 反射Reflection
    1.1简介反射是框架设计的灵魂将类的各个组成部分封装为其他对象Source源代码阶段->Class类对象阶段->Runtime运行时阶段1.2获取Class对象Class.forName("全类名......
  • ctfshow web101(反射类Reflectionclass的使用)
    <?php/*#-*-coding:utf-8-*-#@Author:h1xa#@Date:2020-09-1611:25:09#@LastModifiedby:h1xa#@LastModifiedtime:2020-09-2200:26:48#@link......
  • Reflection 反射
    Reflection反射反射的基本概念反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法Class<?>aClass=Class.forName("ming......
  • .NET教程 - 反射 & 元数据(Reflection & Metadata)
    更新记录转载请注明出处:2022年10月5日发布。2022年10月5日从笔记迁移到博客。反射(Reflection)介绍说明大多数情况下,我们都是运行程序集中的代码处理数据但有时需......
  • 反射(Reflection)的概念
    反射指程序可以访问、检测和修改它本身状态或行为的一种能力。程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。您可以使用反射......
  • Unity3d反射(Reflection)
    无论是VR、AR,还是游戏开发,都绕不开反射材质,一些童鞋说用反射探测器(ReflectionProbe)制作反射,总感觉地板的反射不正确,本文小姐姐就这一话题,和大家一起探讨一下反射材质的制......