Java注解与反射系列——反射示例

110 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天

Java注解与反射系列——反射示例

反射示例

获取反射对象

package example.reflect;



public class demo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //一个类只有一个class对象
        Class stu = Class.forName("example.reflect.entity.Stu");
        System.out.println(stu);

    }
}

在这里插入图片描述

该方法返回类型为Class类,是Java反射的源头!

源码


    /**
     * Returns the {@code Class} object associated with the class or
     * interface with the given string name.  Invoking this method is
     * equivalent to:
     *
     * <blockquote>
     *  {@code Class.forName(className, true, currentLoader)}
     * </blockquote>
     *
     * where {@code currentLoader} denotes the defining class loader of
     * the current class.
     *
     * <p> For example, the following code fragment returns the
     * runtime {@code Class} descriptor for the class named
     * {@code java.lang.Thread}:
     *
     * <blockquote>
     *   {@code Class t = Class.forName("java.lang.Thread")}
     * </blockquote>
     * <p>
     * A call to {@code forName("X")} causes the class named
     * {@code X} to be initialized.
     *
     * @param      className   the fully qualified name of the desired class.
     * @return     the {@code Class} object for the class with the
     *             specified name.
     * @exception LinkageError if the linkage fails
     * @exception ExceptionInInitializerError if the initialization provoked
     *            by this method fails
     * @exception ClassNotFoundException if the class cannot be located
     */
    @CallerSensitive
    public static Class<?> forName(String className)
                throws ClassNotFoundException {
        Class<?> caller = Reflection.getCallerClass();
        return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
    }

通过反射机制动态创建对象

首先明确一点:jdk8以后已不推荐直接使用newInstance来构建对象 在这里插入图片描述 以此代替(调用的是无参构造)

        Class<Stu> stuClass = Stu.class;
        Stu stu1 = stuClass.getDeclaredConstructor().newInstance();

完整代码

package example.reflect;

import example.reflect.entity.Stu;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectClass {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class<Stu> stuClass = Stu.class;
        //无参构造
        Stu stu1 = stuClass.getDeclaredConstructor().newInstance();
        System.out.println(stu1);

    }
}

在这里插入图片描述

通过反射调用方法

package example.reflect;

import example.reflect.entity.Stu;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectClass {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class<Stu> stuClass = Stu.class;
        //无参构造
        Stu stu1 = stuClass.getDeclaredConstructor().newInstance();
//        System.out.println(stu1);

        //通过反射调用普通方法
        Method setAge = stuClass.getDeclaredMethod("setAge", int.class);
        //使用invoke方法进行激活
        setAge.invoke(stu1,18);
        System.out.println(stu1.getAge());
    }
}

在这里插入图片描述

通过反射设置属性

package example.reflect;

import example.reflect.entity.Stu;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectClass {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class<Stu> stuClass = Stu.class;
        //无参构造
        Stu stu1 = stuClass.getDeclaredConstructor().newInstance();
//        System.out.println(stu1);


        //通过反射使用属性
        Field name = stuClass.getDeclaredField("name");
        //关闭安全检测
        name.setAccessible(true);
        name.set(stu1,"张三");
        System.out.println(stu1.getName());

    }
}

在这里插入图片描述

通过反射获取泛型

getGenericReturnType方法用于获取返回值类型

package example.reflect;

import example.reflect.entity.Stu;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class GetExtendType {
    public void test(Map<String, Stu> map, List<Stu> list){
        map.forEach((x,y)->{
            System.out.println(x+y);
        });
    }

    public static void main(String[] args) throws NoSuchMethodException {
        //通过反射获取泛型
        Method test = GetExtendType.class.getMethod("test", Map.class, List.class);
        //获取方法参数类型
        Type[] genericParameterTypes = test.getGenericParameterTypes();
        for (Type genericParameterType : genericParameterTypes) {
//            System.out.println(genericParameterType);
            //判断是否属于参数化类型
            if(genericParameterType instanceof ParameterizedType){
                //获取真实的参数
                Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
                for (Type actualTypeArgument : actualTypeArguments) {

                    System.out.println(actualTypeArgument);
                }
            }
        }
    }
}

在这里插入图片描述

反射操作注解(重要)

package example.reflect;

import example.annotation.AnnoField;
import example.annotation.MyAnno;
import example.reflect.entity.Stu;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class GetAnnotation {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        Class<Stu> stuClass = Stu.class;
//        Stu stu = stuClass.getDeclaredConstructor().newInstance();

        //通过反射获取类上的注解
        Annotation[] annotations = stuClass.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        //获取注解中的值
        MyAnno annotation = stuClass.getAnnotation(MyAnno.class);
        String value = annotation.value();
        System.out.println(value);

        //获取属性上的注解
        Field age = stuClass.getDeclaredField("age");
        AnnoField annotation1 = age.getAnnotation(AnnoField.class);
        System.out.println(annotation1.col());
        System.out.println(annotation1.type());
        
    }
}

在这里插入图片描述