第9章-第4节-再谈Java中的反射

发布时间:2024年01月15日

在运行期探究和使用编译期的内容(编译期配置的注解),要用到Java中的灵魂技术——反射!

1、首先我们需要回顾一下我们之前讲的反射的知识

反射机制:是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意属性和方法;这种动态获取信?? ? 息以及动态调用对象方法的功能称为 java 语言的反射机制;

2、反射知识补充:

1)、Method对象,获取method对象:

方法备注
Method[] getMethods()返回所有[公共]成员方法对象的数组,包括继承的
Method[] getDeclaredMethods()返回所有成员方法对象的数组,不包括继承的Method
getMethod(String name, Class<?>... parameterTypes)返回单个公共成员方法对象Method
getDeclaredMethod(String name, Class<?>... parameterTypes)返回单个成员方法对象
public class Student {
    //私有的,无参无返回值
    private void show() {
        System.out.println("私有的show方法,无参无返回值");
    }
    //公共的,无参无返回值
    public void function1() {
        System.out.println("function1方法,无参无返回值");
    }
    //公共的,有参无返回值
    public void function2(String name) {
        System.out.println("function2方法,有参无返回值,参数为" + name);
    }
    //公共的,无参有返回值
    public String function3() {
        System.out.println("function3方法,无参有返回值");
        return "aaa";
    }
    //公共的,有参有返回值
    public String function4(String name) {
        System.out.println("function4方法,有参有返回值,参数为" + name);
        return "aaa";
    }
}
public class Demo5 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        //method1();
        //method2();
        //method3();
        //method4();
        //method5();
    }
    private static void method5() throws ClassNotFoundException, NoSuchMethodException {
// Method getDeclaredMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象
        Class clazz = Class.forName("com.aaa.Student");
        //获取一个成员方法show
        Method method = clazz.getDeclaredMethod("show");
        System.out.println(method);
    }  
    private static void method4() throws ClassNotFoundException, NoSuchMethodException {
        Class clazz = Class.forName("com.aaa.Student");
        //获取一个有形参的方法function2
        Method method = clazz.getMethod("function2", String.class);
        System.out.println(method);
    }
    private static void method3() throws ClassNotFoundException, NoSuchMethodException {
 //Method getMethod(String name, Class<?>... parameterTypes) :返回单个公共成员方法对象
        Class clazz = Class.forName("com.aaa.Student");
        //获取成员方法function1
        Method method1 = clazz.getMethod("function1");
        System.out.println(method1);
    }  
    private static void method2() throws ClassNotFoundException {
//Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
        Class clazz = Class.forName("com.aaa.Student");
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
    }  
    private static void method1() throws ClassNotFoundException {
 //  Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
        //1.获取class对象
        Class clazz = Class.forName("com.aaa.Student");
        //2.获取成员方法对象
        Method[] methods = clazz.getMethods();
        //3.遍历
        for (Method method : methods) {
            System.out.println(method);
        }
    }
}

?2)、使用Method对象运行方法—Object invoke(Object obj, Object... args)运行方法

public class tDemo6 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
//        Object invoke(Object obj, Object... args):运行方法
//        参数一:用obj对象调用该方法
//        参数二:调用方法的传递的参数(如果没有就不写)
//        返回值:方法的返回值(如果没有就不写)
 
        //1.获取class对象
        Class clazz = Class.forName("com.aaa.Student");
        //2.获取里面的Method对象  function4
        Method method = clazz.getMethod("function4", String.class);
        //3.运行function4方法就可以了
        //3.1创建一个Student对象,当做方法的调用者
        Constructor con = clazz.getConstructor();
        Student student = (Student)con.newInstance();
        //3.2运行方法
        Object result = method.invoke(student, "zhangsan");
        //4.打印一下返回值
        System.out.println(result);
    }
}

3、反射操作获取注解:

public class TestAnnotation {
    public static void main(String[] args){
        try {
            //获取Student的Class对象
            Class stuClass = Class.forName("pojos.Student");

            //说明一下,这里形参不能写成Integer.class,应写为int.class
            Method stuMethod = stuClass.getMethod("study",int.class);

            if(stuMethod.isAnnotationPresent(CherryAnnotation.class)){
                System.out.println("Student类上配置了CherryAnnotation注解!");
                //获取该元素上指定类型的注解
                CherryAnnotation cherryAnnotation = stuMethod.getAnnotation(CherryAnnotation.class);
                System.out.println("name: " + cherryAnnotation.name() + ", age: " + cherryAnnotation.age()
                    + ", score: " + cherryAnnotation.score()[0]);
            }else{
                System.out.println("Student类上没有配置CherryAnnotation注解!");
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}

注意:

  • 如果我们要获得的注解是配置在方法上的,那么我们要从Method对象上获取;如果是配置在属性上,就需要从该属性对应的Field对象上去获取,如果是配置在类型上,需要从Class对象上去获取。总之在谁身上,就从谁身上去获取!

  • isAnnotationPresent(Class<? extends Annotation> annotationClass)方法是专门判断该元素上是否配置有某个指定的注解;

  • getAnnotation(Class<A> annotationClass)方法是获取该元素上指定的注解。之后再调用该注解的注解类型元素方法就可以获得配置时的值数据;

  • 反射对象上还有一个方法getAnnotations(),该方法可以获得该对象身上配置的所有的注解。它会返回给我们一个注解数组,需要注意的是该数组的类型是Annotation类型,这个Annotation是一个来自于java.lang.annotation包的接口。

本电子书目录:

文章来源:https://blog.csdn.net/jnbbwyth/article/details/135597816
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。