zoukankan      html  css  js  c++  java
  • 浅析Java反射机制

    目前,在项目中使用Java反射机制(除Spring框架)的地方不多,但为后续准备,简单将最近的反射体会总结如下:

    1. 按光学中的反射,可以将java中的反射理解为“镜像”。有以下用途:  

          Java反射机制主要提供下面几种用途:

    • 在运行时判断任意一个对象所属的类
    • 在运行时构造任意一个类的对象
    • 在运行时判断任意一个类所具有的成员变量和方法
    • 在运行时调用任意一个对象的方法

    2. 使用java的反射机制,一般需要遵循三步:

    1. 获得类的Class对象
    2. 取得操作类的方法或属性名
    3. 操作第二步取得的方法或属性

    3. 获得类的Class对象,有3种方法:

      1. 调用Class的静态方法forName

      2. 使用类的.class语法,如:Class<?> cls = String.class

      3. 调用对象的getClass方法

    4. 在Java的反射机制中,类与Class对象对应;类方法与Method对应;类属性与Field对应。

    5. 在获得类的方法、属性、构造函数时,会有getXXX和getDeclaredXXX两种对应的方法。区别在于前者返回的是访问权限为public的方法和属性,包括父类中的;后者返回的是所有访问权限的方法和属性,但不包括父类的。

    6. 实例:用反射机制完成对象的copy (浅复制)

    public static void main(String[] args) {
            Student student = new Student();
            student.setStuAge(29);
            student.setStuName("Chris");
            Persons persons = new Persons();
            persons.setFriend("Chen");
            persons.setTeacher("All people");
            student.setPersons(persons);
    
            Student copyStu = copyObject(student);
            System.out.println("-------- " + copyStu.getStuName() + " : " + copyStu.getStuAge() + " - " +copyStu.getPersons().getFriend() + " - " + copyStu.getPersons().getTeacher());
    
            student.getPersons().setTeacher("hehe");
            System.out.println("-------- " + copyStu.getStuName() + " : " + copyStu.getStuAge() + " - " +copyStu.getPersons().getFriend() + " - " + copyStu.getPersons().getTeacher());
    
        }

    Persons类:

    public class Persons {
        private String friend;
        private String teacher;
    
        public String getFriend() {
            return friend;
        }
    
        public void setFriend(String friend) {
            this.friend = friend;
        }
    
        public String getTeacher() {
            return teacher;
        }
    
        public void setTeacher(String teacher) {
            this.teacher = teacher;
        }
    }

    Student类:

    public class Student {
        /** 姓名 */
        private String stuName;
        /** 年龄 */
        private int stuAge;
        /** Persons */
        private Persons persons;
    
        public Persons getPersons() {
            return persons;
        }
    
        public void setPersons(Persons persons) {
            this.persons = persons;
        }
    
        public String getStuName() {
            return stuName;
        }
    
        public void setStuName(String stuName) {
            this.stuName = stuName;
        }
    
        public int getStuAge() {
            return stuAge;
        }
    
        public void setStuAge(int stuAge) {
            this.stuAge = stuAge;
        }
    }

    copyObject方法:

    private static <T> T copyObject(T t) {
            Class<?> cls = t.getClass();
            Field[] fields = cls.getDeclaredFields();
            T o = null;
            try {
                o = (T)cls.newInstance();
                for (Field field : fields){
                    field.setAccessible(true);
                    Object o1 = field.get(t);
                    field.set(o,o1);
                }
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
    
            return o;
        }

    在写copyObject方法时,尝试了下泛型方法。原来泛型方法中的标志<T>是必须的。

    由以上例子可知,即使用反射机制来实现copy对象的功能,也只能是浅复制。

      由这个例子延伸到copy对象的实现上,如下:

    http://blog.sina.com.cn/s/blog_70e6618b0100om09.html

      (1) 对象复制分浅复制和深复制。二者的区别在于对非基本数据类型的复制上。前者复制引用,后者复制子对象。

      (2) 浅复制对象:

        1. 实现方式:

        第一步:实现java.lang.Cloneable接口;

        第二步:重写java.lang.Object.clone()方法,设置方法为public

        2. Object类中的clone()方法是native的,执行效率更高。但执行的仍是浅复制!!!所以,重写的clone()方法执行浅复制。

      (3) 深复制对象:

        实现方式有多种:

        1. new对象以及子对象,全部重新设置属性;

        2. 所有非基本数据类型的属性,对应的类实现Cloneable接口并重写clone()方法;

        3. 使用对象序列化与反序列化

    清醒时做事,糊涂时读书,大怒时睡觉,独处时思考; 做一个幸福的人,读书,旅行,努力工作,关心身体和心情,成为最好的自己 -- 共勉
  • 相关阅读:
    重温servlet③
    重温servlet②
    修改servlet的模板代码
    Oracle网络服务管理与配置
    Oracle数据库的启动与关闭
    java多线程
    SQL 查询
    Oracle索引表
    Oracle索引(2)索引的修改与维护
    Oracle索引(1)概述与创建索引
  • 原文地址:https://www.cnblogs.com/hello-yz/p/4720697.html
Copyright © 2011-2022 走看看