浅析java反射机制

来源:互联网 发布:印刷晒版用什么软件 编辑:程序博客网 时间:2024/06/07 23:07
     关于反射概述

             Java反射式JAVA被是为动态(或准动态)语言的一个关键特性,这个机制允许程序在运行时通过Refleaction APIS取得任何一个已知名称的            class 的内部信息。

            java反射机制允许程序在运行时加载,探知,使用编译期间完全未知的class(注意:java可以加载一个运行时才得知名称的class,并获得其完整         结构)

     主要用途:

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

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

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

     如何使用:

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

             1.获的逆向操作类的class对象;

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

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

               如何取得操作类的Class对象?,常用的三种方式

                    1.调用Class的静态方法forName  例如 Class<?> cls = Class.forName("类所在包路径.类名");

                2.使用类的.class语法,如Class cls=String.class

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

              获取类的类的属性:调用

                       getDeclaredField(String name)返回一个Field对象,该对象反映此Class对象所表示的类或接口的指定已声明的私有字段

               //通过对象字节码获取私有的字段属性               Field[] fields = clazz.getDeclaredFields();
                 //暴力反射声明

              field.setAccessible(true);              //获取属性名              name = field.getName();

                       获得类的Method(常用的一种:ps可以查看源码了解更多的方式)

                     getMethod(String name,Class<?>...parameterTypes)     返回一个 Method对象,它反映此 Class对象所表示的类或接口的指定公                  共成员方法.

              反射方式执行method方法

            //执行方法            value = method.invoke(obj, null).toString();

         完整例子分析:

                  测试的实体类

   

/** * @Title: Article * @Description: 文章实体类 用于测试 * @Company: * @Author 木易爽【247677857yh@gmail.com】 * @Date: 2016/3/31 * @Time: 20:01 */public class Article {    private Integer id;//标号    private String title;//标题    private String content;//内容    public Article() {    }    public Article(Integer id, String title, String content) {        this.id = id;        this.title = title;        this.content = content;    }    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getTitle() {        return title;    }    public void setTitle(String title) {        this.title = title;    }    public String getContent() {        return content;    }    public void setContent(String content) {        this.content = content;    }}
 测试类

package example;import java.lang.reflect.Field;import java.lang.reflect.Method;/** * @Title: GetContent * @Description: 通过反射获取实体的内容 以String返回 * @Company: * @Author 木易爽【247677857yh@gmail.com】 * @Date: 2016/3/31 * @Time: 20:02 */public class GetContent {    //不让外界new该帮助类    private GetContent() {    }    /**     * 传入obj实体 通过反射机制获取实体对象的内容     *     * @param obj     * @return     * @throws Exception     */    public static String getEntityContent(Object obj) throws Exception {        String content = "";        //获取obj引用的对象的字节码        Class clazz = obj.getClass();        //通过对象字节码获取私有的字段属性        Field[] fields = clazz.getDeclaredFields();        String name;//属性名        String methodName;//方法名        String value;//获取方法的返回值        Method method;//获取方法        for (Field field : fields) {            //暴力反射            field.setAccessible(true);            //获取属性名            name = field.getName();            //拼接方法名            methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);            //获取方法 例如getId()/getTitle()/getContent()            method = clazz.getMethod(methodName, null);            //执行方法            value = method.invoke(obj, null).toString();            //将值加入到string对象中            content += value + ",";        }        return content;    }    public static void main(String[] args) throws Exception {        Article article = new Article(1, "反射", "反射机制是动态语言的特性");        String articleContent = GetContent.getEntityContent(article);        System.out.println(articleContent);    }}

输出结果:

"C:\Program Files\Java\jdk1.8.0_65\bin\java" -Didea.launcher.port=7532 "-Didea.launcher.bin.path=D:\software\idea\IntelliJ IDEA 15.0.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_65\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_65\jre\lib\rt.jar;D:\project\java_project\luceneDemo\target\classes;C:\Users\ShuangYang\.m2\repository\org\apache\lucene\lucene-core\5.3.1\lucene-core-5.3.1.jar;C:\Users\ShuangYang\.m2\repository\org\apache\lucene\lucene-analyzers-common\5.3.1\lucene-analyzers-common-5.3.1.jar;C:\Users\ShuangYang\.m2\repository\org\apache\lucene\lucene-queryparser\5.3.1\lucene-queryparser-5.3.1.jar;C:\Users\ShuangYang\.m2\repository\org\apache\lucene\lucene-queries\5.3.1\lucene-queries-5.3.1.jar;C:\Users\ShuangYang\.m2\repository\org\apache\lucene\lucene-sandbox\5.3.1\lucene-sandbox-5.3.1.jar;C:\Users\ShuangYang\.m2\repository\junit\junit\4.11\junit-4.11.jar;C:\Users\ShuangYang\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Users\ShuangYang\.m2\repository\org\apache\lucene\lucene-memory\5.3.1\lucene-memory-5.3.1.jar;C:\Users\ShuangYang\.m2\repository\org\apache\lucene\lucene-highlighter\5.3.1\lucene-highlighter-5.3.1.jar;C:\Users\ShuangYang\.m2\repository\org\apache\lucene\lucene-join\5.3.1\lucene-join-5.3.1.jar;C:\Users\ShuangYang\.m2\repository\commons-beanutils\commons-beanutils\1.9.2\commons-beanutils-1.9.2.jar;C:\Users\ShuangYang\.m2\repository\commons-logging\commons-logging\1.1.1\commons-logging-1.1.1.jar;C:\Users\ShuangYang\.m2\repository\commons-collections\commons-collections\3.2.1\commons-collections-3.2.1.jar;C:\Users\ShuangYang\.m2\repository\log4j\log4j\1.2.17\log4j-1.2.17.jar;D:\software\idea\IntelliJ IDEA 15.0.1\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain example.GetContent1,反射,反射机制是动态语言的特性,Process finished with exit code 0
        测试说明:

                  这里在反射获取类Class对象的时候采用的是obj.getClass的方式,读者有兴趣可以都其余两种方式进行测试.

            参考链接:

              http://www.cnblogs.com/Quincy/archive/2011/06/19/2084557.html

              http://www.cnblogs.com/gulvzhe/archive/2012/01/27/2330001.html

              http://www.cnblogs.com/jqyp/archive/2012/03/29/2423112.html



0 0