温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java框架设计之反射怎么应用

发布时间:2022-06-22 09:40:44 来源:亿速云 阅读:141 作者:iii 栏目:开发技术

这篇文章主要讲解了“Java框架设计之反射怎么应用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java框架设计之反射怎么应用”吧!

    框架:半成品软件。可以在框架的基础上进行软件开发,简化编码。

    反射就是把Java类中的各个成员映射成一个个的Java对象。

    即在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;

    对于任意一个对象,都能调用它的任意一个方法和属性。

    这种动态获取信息及动态调用对象方法的功能叫Java的反射机制。

    好处:

    1. 可以在程序运行过程中,操作这些对象。

    2. 可以解耦,提高程序的可扩展性。

    获取Class对象的方式

    1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象

    多用于配置文件,将类名定义在配置文件中。读取文件,加载类。

    2. 类名.class:通过类名的属性class获取

    多用于参数的传递

    3. 对象.getClass():getClass()方法在Object类中定义着。

    多用于对象的获取字节码的方式

    //1.Class.forName("全类名")
    Class cls1 = Class.forName("com.zjq.javabase.base25.domain.Person");
    System.out.println(cls1);
    //2.类名.class
    Class cls2 = Person.class;
    System.out.println(cls2);
    //3.对象.getClass()
    Person p = new Person();
    Class cls3 = p.getClass();
    System.out.println(cls3);

    结论:

    同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。

    Class对象功能

    测试的Person类:

    package com.zjq.javabase.base25.domain;
     
    /**
     * @author zjq
     */
    public class Person {
        private String name;
        private int age;
     
        public String a;
        protected String b;
        String c;
        private String d;
     
     
        public Person() {
        }
     
        public Person(String name, int age) {
     
            this.name = name;
            this.age = age;
        }
     
        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;
        }
     
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", a='" + a + '\'' +
                    ", b='" + b + '\'' +
                    ", c='" + c + '\'' +
                    ", d='" + d + '\'' +
                    '}';
        }
     
     
        public void eat(){
            System.out.println("eat...");
        }
     
        public void eat(String food){
            System.out.println("eat..."+food);
        }
    }

    获取成员变量们

    Field[] getFields() :获取所有public修饰的成员变量

    Field getField(String name)   获取指定名称的 public修饰的成员变量

    Field[] getDeclaredFields()  获取所有的成员变量,不考虑权限修饰符

    Field getDeclaredField(String name)  

    案例:

    //0.获取Person的Class对象
    Class personClass = Person.class;
    //1.Field[] getFields()获取所有public修饰的成员变量
    Field[] fields = personClass.getFields();
    for (Field field : fields) {
        System.out.println(field);
    }
     
    System.out.println("------------");
    //2.Field getField(String name)
    Field a = personClass.getField("a");
    //获取成员变量a 的值
    Person p = new Person();
    Object value = a.get(p);
    System.out.println(value);
    //设置a的值
    a.set(p,"张三");
    System.out.println(p);
     
    System.out.println("===================");
     
    //Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
    Field[] declaredFields = personClass.getDeclaredFields();
    for (Field declaredField : declaredFields) {
        System.out.println(declaredField);
    }
    //Field getDeclaredField(String name)
    Field d = personClass.getDeclaredField("d");
    //忽略访问权限修饰符的安全检查
    d.setAccessible(true);//暴力反射
    Object value2 = d.get(p);
    System.out.println(value2);

    获取构造方法们

    Constructor<?>[] getConstructors()  

    Constructor<T> getConstructor(类<?>... parameterTypes)  

    Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)  

    Constructor<?>[] getDeclaredConstructors()  

    案例:

    //0.获取Person的Class对象
    Class personClass = Person.class;
     
    //Constructor<T> getConstructor(类<?>... parameterTypes)
    Constructor constructor = personClass.getConstructor(String.class, int.class);
    System.out.println(constructor);
    //创建对象
    Object person = constructor.newInstance("张三", 23);
    System.out.println(person);
     
    System.out.println("----------");
     
     
    Constructor constructor1 = personClass.getConstructor();
    System.out.println(constructor1);
    //创建对象
    Object person1 = constructor1.newInstance();
    System.out.println(person1);
     
    Object o = personClass.newInstance();
    System.out.println(o);

    获取成员方法们

    Method[] getMethods()  

    Method getMethod(String name, 类<?>... parameterTypes)  

    Method[] getDeclaredMethods()  

    Method getDeclaredMethod(String name, 类<?>... parameterTypes)  

    案例:

    //0.获取Person的Class对象
    Class personClass = Person.class;
    //获取指定名称的方法
    Method eat_method = personClass.getMethod("eat");
    Person p = new Person();
    //执行方法
    eat_method.invoke(p);
     
     
    Method eat_method2 = personClass.getMethod("eat", String.class);
    //执行方法
    eat_method2.invoke(p,"饭");
     
    System.out.println("-----------------");
     
    //获取所有public修饰的方法
    Method[] methods = personClass.getMethods();
    for (Method method : methods) {
        System.out.println(method);
        String name = method.getName();
        System.out.println(name);
        //method.setAccessible(true);
    }
     
    //获取类名
    String className = personClass.getName();
    System.out.println(className);//com.zjq.javabase.base25.domain.Person

    获取全类名  

    String getName()  

    Field:成员变量

    操作:

    1. 设置值

    void set(Object obj, Object value)  

    2. 获取值

    get(Object obj) 

    3. 忽略访问权限修饰符的安全检查

    setAccessible(true):暴力反射

    Constructor:构造方法

    创建对象:

    T newInstance(Object... initargs)  

    如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法

    Method:方法对象

    执行方法:

    Object invoke(Object obj, Object... args)  

    获取方法名称:

    String getName:获取方法名

    案例

    需求:写一个"框架",不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法

    实现:

    1. 配置文件

    2. 反射

    步骤:

    1. 将需要创建的对象的全类名和需要执行的方法定义在配置文件中

    2. 在程序中加载读取配置文件

    3. 使用反射技术来加载类文件进内存

    4. 创建对象

    5. 执行方法

    代码:

    pro.properties文件内容如下:

    className=com.zjq.javabase.base25.domain.Student
    methodName=sleep

    Student类:

    public class Student {
     
        public void sleep() {
            System.out.println("sleep...");
        }
    }

    反射操作:

    //1.加载配置文件
    //1.1创建Properties对象
    Properties pro = new Properties();
    //1.2加载配置文件,转换为一个集合
    //1.2.1获取class目录下的配置文件
    ClassLoader classLoader = ReflectTest.class.getClassLoader();
    InputStream is = classLoader.getResourceAsStream("pro.properties");
    pro.load(is);
     
    //2.获取配置文件中定义的数据
    String className = pro.getProperty("className");
    String methodName = pro.getProperty("methodName");
     
     
    //3.加载该类进内存
    Class cls = Class.forName(className);
    //4.创建对象
    Object obj = cls.newInstance();
    //5.获取方法对象
    Method method = cls.getMethod(methodName);
    //6.执行方法
    method.invoke(obj);

    感谢各位的阅读,以上就是“Java框架设计之反射怎么应用”的内容了,经过本文的学习后,相信大家对Java框架设计之反射怎么应用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI