zoukankan      html  css  js  c++  java
  • Java中的反射机制

    Java反射的概念

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

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

    1.在运行时判断任意一个对象所属的类

    2.在运行时构造任意一个类的对象

    3.在运行时判断任意一个类所具有的成员变量和方法

    4.在运行时调用任意一个对象的方法

    首先看一个简单的例子,通过这个例子来理解Java的反射机制是如何工作的

    import java.lang.reflect.Method;
    
    /**
     * Java 反射练习。
     * 
     * @author Wanggc
     */
    public class ForNameTest {
        /**
         * 入口函数。
         * 
         * @param args
         *            参数
         * @throws Exception
         *             错误信息
         */
        public static void main(String[] args) throws Exception {
            // 获得Class
            Class<?> cls = Class.forName(args[0]);
            // 通过Class获得所对应对象的方法
            Method[] methods = cls.getMethods();
            // 输出每个方法名
            for (Method method : methods) {
                System.out.println(method);
            }
        }
    }
    代码示例如下

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

    1.获得你想操作类的Class对象

    2.通过第一步获得的Class对象去取得操作类的方法或是属性名

    3.操作第二步取得的方法或是属性

     Java运行的时候,某个类无论生成多少个对象,他们都会对应同一个Class对象,它表示正在运行程序中的类和接口。如何取得操作类的Class对象,常用的有三种方式:

    1.调用Class的静态方法forName,如上例;

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

    3.调用对象的getClass方法,如:String str = "abc";Class<?> cls = str .getClass();

    下面将通过实例讲述如何通过前面所诉的三步来执行某对象的某个方法:

     3 import java.lang.reflect.Method;
     4 
     5 /**
     6  * Java 反射练习。
     7  * 
     8  * @author Wanggc
     9  */
    10 public class ReflectionTest {
    11     public static void main(String[] args) throws Exception {
    12         DisPlay disPlay = new DisPlay();
    13         // 获得Class
    14         Class<?> cls = disPlay.getClass();
    15         // 通过Class获得DisPlay类的show方法
    16         Method method = cls.getMethod("show", String.class);
    17         // 调用show方法
    18         method.invoke(disPlay, "Wanggc");
    19     }
    20 }
    21 
    22 class DisPlay {
    23     public void show(String name) {
    24         System.out.println("Hello :" + name);
    25     }
    26 }
    代码示例如下

     上例讲述了如何通过反射调用某个类的方法,下面将再通过一个实例讲述如何通过反射给某个类的属性赋值:

      3 import java.lang.reflect.Field;
      4 
      5 /**
      6  * Java 反射之属性练习。
      7  * 
      8  * @author Wanggc
      9  */
     10 public class ReflectionTest {
     11     public static void main(String[] args) throws Exception {
     12         // 建立学生对象
     13         Student student = new Student();
     14         // 为学生对象赋值
     15         student.setStuName("Wanggc");
     16         student.setStuAge(24);
     17         // 建立拷贝目标对象
     18         Student destStudent = new Student();
     19         // 拷贝学生对象
     20         copyBean(student, destStudent);
     21         // 输出拷贝结果
     22         System.out.println(destStudent.getStuName() + ":"
     23                 + destStudent.getStuAge());
     24     }
     25 
     26     /**
     27      * 拷贝学生对象信息。
     28      * 
     29      * @param from
     30      *            拷贝源对象
     31      * @param dest
     32      *            拷贝目标对象
     33      * @throws Exception
     34      *             例外
     35 */
     36     private static void copyBean(Object from, Object dest) throws Exception {
     37         // 取得拷贝源对象的Class对象
     38         Class<?> fromClass = from.getClass();
     39         // 取得拷贝源对象的属性列表
     40         Field[] fromFields = fromClass.getDeclaredFields();
     41         // 取得拷贝目标对象的Class对象
     42         Class<?> destClass = dest.getClass();
     43         Field destField = null;
     44         for (Field fromField : fromFields) {
     45             // 取得拷贝源对象的属性名字
     46             String name = fromField.getName();
     47             // 取得拷贝目标对象的相同名称的属性
     48             destField = destClass.getDeclaredField(name);
     49             // 设置属性的可访问性
     50             fromField.setAccessible(true);
     51             destField.setAccessible(true);
     52             // 将拷贝源对象的属性的值赋给拷贝目标对象相应的属性
     53             destField.set(dest, fromField.get(from));
     54         }
     55     }
     56 }
     57 
     58 /**
     59  * 学生类。
     60  */
     61 class Student {
     62     /** 姓名 */
     63     private String stuName;
     64     /** 年龄 */
     65     private int stuAge;
     66 
     67     /**
     68      * 获取学生姓名。
     69      * 
     70      * @return 学生姓名
     71 */
     72     public String getStuName() {
     73         return stuName;
     74     }
     75 
     76     /**
     77      * 设置学生姓名
     78      * 
     79      * @param stuName
     80      *            学生姓名
     81 */
     82     public void setStuName(String stuName) {
     83         this.stuName = stuName;
     84     }
     85 
     86     /**
     87      * 获取学生年龄
     88      * 
     89      * @return 学生年龄
     90 */
     91     public int getStuAge() {
     92         return stuAge;
     93     }
     94 
     95     /**
     96      * 设置学生年龄
     97      * 
     98      * @param stuAge
     99      *            学生年龄
    100 */
    101     public void setStuAge(int stuAge) {
    102         this.stuAge = stuAge;
    103     }
    104 }
    代码示例如下

    前面讲述了如何用Java反射机制操作一个类的方法和属性,下面再通过一个实例讲述如何在运行时创建类的一个对象:

     3 import java.lang.reflect.Field;
     4 
     5 /**
     6  * Java 反射之属性练习。
     7  * 
     8  * @author Wanggc
     9  */
    10 public class ReflectionTest {
    11     public static void main(String[] args) throws Exception {
    12         // 建立学生对象
    13         Student student = new Student();
    14         // 为学生对象赋值
    15         student.setStuName("Wanggc");
    16         student.setStuAge(24);
    17         // 建立拷贝目标对象
    18         Student destStudent = (Student) copyBean(student);
    19         // 输出拷贝结果
    20         System.out.println(destStudent.getStuName() + ":"
    21                 + destStudent.getStuAge());
    22     }
    23 
    24     /**
    25      * 拷贝学生对象信息。
    26      * 
    27      * @param from
    28      *            拷贝源对象
    29      * @param dest
    30      *            拷贝目标对象
    31      * @throws Exception
    32      *             例外
    33 */
    34     private static Object copyBean(Object from) throws Exception {
    35         // 取得拷贝源对象的Class对象
    36         Class<?> fromClass = from.getClass();
    37         // 取得拷贝源对象的属性列表
    38         Field[] fromFields = fromClass.getDeclaredFields();
    39         // 取得拷贝目标对象的Class对象
    40         Object ints = fromClass.newInstance();
    41         for (Field fromField : fromFields) {
    42             // 设置属性的可访问性
    43             fromField.setAccessible(true);
    44             // 将拷贝源对象的属性的值赋给拷贝目标对象相应的属性
    45             fromField.set(ints, fromField.get(from));
    46         }
    47 
    48         return ints;
    49     }
    50 }
    51 
    52 /**
    53  * 学生类。
    54  */
    55 class Student {
    56     /** 姓名 */
    57     private String stuName;
    58     /** 年龄 */
    59     private int stuAge;
    60 
    61     /**
    62      * 获取学生姓名。
    63      * 
    64      * @return 学生姓名
    65 */
    66     public String getStuName() {
    67         return stuName;
    68     }
    69 
    70     /**
    71      * 设置学生姓名
    72      * 
    73      * @param stuName
    74      *            学生姓名
    75 */
    76     public void setStuName(String stuName) {
    77         this.stuName = stuName;
    78     }
    79 
    80     /**
    81      * 获取学生年龄
    82      * 
    83      * @return 学生年龄
    84 */
    85     public int getStuAge() {
    86         return stuAge;
    87     }
    88 
    89     /**
    90      * 设置学生年龄
    91      * 
    92      * @param stuAge
    93      *            学生年龄
    94 */
    95     public void setStuAge(int stuAge) {
    96         this.stuAge = stuAge;
    97     }
    98 }
    代码示例如下

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

  • 相关阅读:
    浅谈css中的盒模型(框模型)
    Linux 字符设备驱动及一些简单的Linux知识
    java实现person类 override(重写) comparable接口
    java之内部类
    mac下sublime text3 安装px转rem插件
    python pip安装扩展报错
    curl http_code 状态码
    sed 批量替换文件
    centos 7 开机优化shell
    一个tcp连接可以发多少http请求
  • 原文地址:https://www.cnblogs.com/daixiumei/p/6910801.html
Copyright © 2011-2022 走看看