JAVAEE细细看 新特性:反射

本文深入探讨Java反射机制的应用,包括如何通过反射操作类、方法、构造器和字段,以及注解的使用和解析。具体示例展示了如何获取类上的注解、调用私有方法、模拟Spring创建Bean的过程,以及属性和方法的动态操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

事例:

自定义注解:


import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(value={ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Documented
@Inherited  //可以继承
public @interface TestAnno {
    String value() default "";
}

测试类

@TestAnno
public class Test {

    @TestAnno("年龄")
    private int age;
    private String name;

    public Test(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public Test() {
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Test{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

    @TestAnno
    private void doPrivate(String str){
        System.out.println("私有方法调用" +str);
    }
}

2. 反射应用

1.注解

//反射-属性示例
public class AnnotationDemo {

    private Object getTest(){
        try {
            Class<?> c4 = Class.forName("com.ittest.javademo.reflection.Test");

            Constructor constructor ;
            Class[] classes = {int.class, String.class};
            try {
                //constructor = c4.getDeclaredConstructor();
                constructor = c4.getDeclaredConstructor(classes);
                try {
                    Object aaa = constructor.newInstance(1, "aaa");
                    return aaa;
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }

            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        return  null;
    }

    //遍历所有方法、属性,获取注解响应的内容
    @org.junit.Test
    public void field1() throws NoSuchFieldException, IllegalAccessException {
        Class<Test> testClass = Test.class;
        TestAnno declaredAnnotation = testClass.getDeclaredAnnotation(TestAnno.class);
        if(declaredAnnotation != null){
            System.out.println("类上包含了TestAnno注解");
        }

        Method[] declaredMethods = testClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            if(declaredMethod.getAnnotation(TestAnno.class) != null){
                System.out.println(declaredMethod.getName() + "方法包含TestAnno注解");
            }
        }

        Field[] declaredFields = testClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            TestAnno declaredAnnotation1 = declaredField.getDeclaredAnnotation(TestAnno.class);
            if(declaredAnnotation1 != null){
                System.out.println(declaredField.getName() + "属性包含TestAnno注解");
                System.out.println("注解的value为"+declaredAnnotation1.value());
            }
        }
    }
}

2.构造器

//反射-构造方法示例
public class ConstructDemo {

    //获取所有构造方法
    @org.junit.Test
    public void constuct(){
        Class c4 = Test.class;
        Constructor[] constructors ;
        constructors = c4.getDeclaredConstructors();

        for (Constructor constructor : constructors) {
            // Modifier 类提供了 static方法和常量,对类和成员访问修饰符进行解码。
            System.out.print(Modifier.toString(constructor.getModifiers()) + "参数:");
            Class[] parametertypes = constructor.getParameterTypes();
            //打印所有的参数
            for(Class clazz : parametertypes){
                System.out.print(clazz.getName() + " ");
            }
            System.out.println("");
        }

    }



    //获取指定的构造方法
    @org.junit.Test
    public void constuct2(){
        Class c4 = Test.class;
        Constructor constructor ;
        Class[] classes = {int.class,java.lang.String.class};
        try {
            //constructor = c4.getDeclaredConstructor();
            constructor = c4.getDeclaredConstructor(classes);
            // Modifier 类提供了 static方法和常量,对类和成员访问修饰符进行解码。
            System.out.print(Modifier.toString(constructor.getModifiers()) + "参数:");
            Class[] parametertypes = constructor.getParameterTypes();
            //打印所有的参数
            for(Class clazz : parametertypes){
                System.out.print(clazz.getName() + " ");
            }
            System.out.println("");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

    }

    //调用构造方法
    @org.junit.Test
    public void constuct3(){
        Class c4 = Test.class;
        Constructor constructor ;
        Class[] classes = {int.class,java.lang.String.class};
        try {
            //constructor = c4.getDeclaredConstructor();
            constructor = c4.getDeclaredConstructor(classes);
            try {
                Object aaa = constructor.newInstance(1, "aaa");

                System.out.println(aaa);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

    }

    //案例:模拟一下spring创建bean
    @org.junit.Test
    public void constuct4(){
        try {
            Class<?> c4 = Class.forName("com.ittest.javademo.reflection.Test");

            Constructor constructor ;
            Class[] classes = {int.class,java.lang.String.class};
            try {
                //constructor = c4.getDeclaredConstructor();
                constructor = c4.getDeclaredConstructor(classes);
                try {
                    Object aaa = constructor.newInstance(1, "aaa");

                    System.out.println(aaa);
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }

            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

3.属性

//反射-属性示例
public class FieldDemo {

    private Object getTest(){
        try {
            Class<?> c4 = Class.forName("com.ittest.javademo.reflection.Test");

            Constructor constructor ;
            Class[] classes = {int.class, String.class};
            try {
                //constructor = c4.getDeclaredConstructor();
                constructor = c4.getDeclaredConstructor(classes);
                try {
                    Object aaa = constructor.newInstance(1, "aaa");
                    return aaa;
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }

            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        return  null;
    }

    //设置和获取属性
    @org.junit.Test
    public void field1() throws NoSuchFieldException, IllegalAccessException {
        Class<Test> testClass = Test.class;
        Field field = testClass.getDeclaredField("name");
        Object test = getTest();
        field.setAccessible(true);
        field.set(test,"张三");
        System.out.println(field.get(test));
    }

    //案例:map和实体类之间的转换
    /**
     * Map转成实体对象
     * @param map map实体对象包含属性
     * @param clazz 实体对象类型
     * @return
     */
    public static Object map2Object(Map<String, Object> map, Class<?> clazz) {
        if (map == null) {
            return null;
        }
        Object obj = null;
        try {
            obj = clazz.newInstance();

            Field[] fields = obj.getClass().getDeclaredFields();
            for (Field field : fields) {
                int mod = field.getModifiers();
                if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                    continue;
                }
                field.setAccessible(true);
                field.set(obj, map.get((field.getName())));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }

    /**
     * 实体对象转成Map
     * @param obj 实体对象
     * @return
     */
    public static Map<String, Object> object2Map(Object obj) {
        Map<String, Object> map = new HashMap<String, Object>();
        if (obj == null) {
            return map;
        }
        Class clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                map.put(field.getName(), field.get(obj));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    @org.junit.Test
    public void field2(){
        Map<String,Object> map = new HashMap<String, Object>();
        map.put("name","张三");
        map.put("age",18);

        Object r = map2Object(map, Test.class);
        System.out.println(r);

        Map<String, Object> stringObjectMap = object2Map(r);
        System.out.println(stringObjectMap);

    }
}

4.方法

//反射-调用方法示例
public class MethodDemo {

    private Object getTest(){
        try {
            Class<?> c4 = Class.forName("com.ittest.javademo.reflection.Test");

            Constructor constructor ;
            Class[] classes = {int.class,java.lang.String.class};
            try {
                //constructor = c4.getDeclaredConstructor();
                constructor = c4.getDeclaredConstructor(classes);
                try {
                    Object aaa = constructor.newInstance(1, "aaa");
                    return aaa;
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }

            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        return  null;
    }
    //调用私有方法
    @org.junit.Test
    public void method1() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Object obj = getTest();
        /**
         * public Method[] getMethods()返回某个类的所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法。
         * public Method[] getDeclaredMethods()对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。当然也包括它所实现接口的方法。
         */
        Method method = Test.class.getDeclaredMethod("doPrivate", String.class);
        method.setAccessible(true);
        method.invoke(obj,"aaa");
    }

    //前置方法
    private void doPre(){
        System.out.println("在方法前调用");
    }


    //后置方法
    private void doPost(){
        System.out.println("在方法后调用");
    }

    //案例:aop的模拟代码
    public Object aop(Object obj){
        doPre();
        Object ret = null;
        try{
            Method method = Test.class.getDeclaredMethod("doPrivate", String.class);
            method.setAccessible(true);
            ret =  method.invoke(obj,"aaa");
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            doPost();
            return null;
        }
    }
    //增加前置和后置方法的调用
    @org.junit.Test
    public void method2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        Object obj = getTest();
        aop(obj);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值