Java反射机制的实现详解

很多主流框架都使用了反射技术.像ssh框架都采用两种技术 xml做配置文件+反射技术.

与反射有关的类包.

java.lang.reflect.*;和java.lang.Class;

Java中所有类型(包括基本类型)都对应一个Class对象,这个Class就是java.lang.Class。即每一个类型,在Class中都有一个Class对象跟它对应.Class 没有公共构造方法。注意不是没有,是没有公共的.

如何获得Class对象


复制代码 代码如下:

.针对每一个对象.getCalss(),可以得到对应的Class.
.Class.forName(String),String的写法:包名.类名.就会创建包名.类名对应的那个对象
注:1.2只适用于引用类型
.对于基本类型:封装类.TYPE代表了对应的基本类型的Class对象.Integer.TYPE对应的是int的Class对象
注:3只适用于基本类型
.类型,Class。<第4种是通用的.>
上面的4种方法,只有方法2是动态的,只要换一个包就可以了.它具有动态潜质.所以真正意义的想体现动态编程只能使用方法2.

每种类型的Class对象只有一个,即他们的地址只有一个,但是不同类型是不同的.

所以下面的打印结果都为true.


复制代码 代码如下:

//对与引用类型
Class c1 = "".getClass();
Class c2 =     Class.forName("java.lang.String");
Class c3 = String.class;
System.out.println(c1 ==c2);//true
//对于基本类型
Class num1 = Integer.TYPE;
Class num2 = int.class;
System.out.println(num1 == num2);//true

反射获取类中的成员的相关方法

[获取构造<根据参数类型>](使用时一般用不带declared的)


复制代码 代码如下:

Constructor<T> getConstructor(Class<?>... parameterTypes)
      返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
 Constructor<?>[] getConstructors()
      返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
 Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
      返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
 Constructor<?>[] getDeclaredConstructors()
      返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。

[获取属性<根据属性名>](使用时一般用是带declared的,因为属性一般都是私有的)


复制代码 代码如下:

Field getField(String name)
      返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。
 Field[] getFields()
      返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。
 Field getDeclaredField(String name)
      返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
 Field[] getDeclaredFields()
      返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。

[获取方法<方法名加上参数类型>](使用时一般用不带declared的)


复制代码 代码如下:

Method getMethod(String name, Class<?>... parameterTypes)
      返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
 Method[] getMethods()
      返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
 Method getDeclaredMethod(String name, Class<?>... parameterTypes)
      返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
 Method[] getDeclaredMethods()
      返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
 T newInstance()
      创建此 Class 对象所表示的类的一个新实例。 <new Instance()可以动态的创建对象>
 String toString()
      将对象转换为字符串。

注意:

new Instance()调用的是无参构造,如果该类没有无参构造方法,则newInstance()会产生异常.

有declared的方法是支持私有,但是不支持继承,无declared的方法支持继承,不支持私有,且只能取出public的东西.

因此取属性的时候一般来说是带declared的,因为属性一般都是私有的,取方法时一般是不带declared的,取构造时一般也是不带declared的.

实例模拟反射获取类中的相关属性和方法

利用反射对属性赋值

Field中的方法

Object get(Object obj)

返回指定对象上此 Field 表示的字段的值。

Field f = c.getXXField(属性名);

值 = f.get(对象);

void set(Object obj, Object value)

将指定对象变量上此 Field 对象表示的字段设置为指定的新值。

f.set(对象,值);

Class<?> getType()

返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。

用于获取属性的类型(返回Class对象).


复制代码 代码如下:

Class c = Student.class;
    Object obj  = c.newInstance();            //创建Student类的对象
    Field f = c.getDeclaredField("name");        //获取name属性
    f.setAccessible(true);                    //设置私有可以访问.
    f.set(obj, "zhangsan");
    System.out.println(f.get(obj));             //获取obj的name属性的值.

利用反射调用构造

对于构造真正调用是在调用newInstance()方法时.


复制代码 代码如下:

Class c = Class.forName("com.clazz.reflect.Student");
    Constructor con = c.getConstructor();         //没有执行构造,
    Object cObj = c.getConstructor().newInstance();//调用无参的构造方法
    Constructor conAll = c.getConstructor(int.class,String.class,int.class);
    Object caobj = conAll.newInstance(1001,"zjamgs",234235);//调用含参的构造方法.
    System.out.println(caobj);                  //打印输出

利用反射调用方法

对象.方法名(值1,2,3);

Method m = c.getMethoed(方法名,参数类型...);

m.invoke(对象,方法调用的参数 )如果底层方法所需的形参数为 0,则所提供的 args 数组长度可以为 0 或 null。


复制代码 代码如下:

Class c = Class.forName("com.clazz.reflect.Student");
    Object obj = c.newInstance();    //创建Sutdent对象.
    Method msetName = c.getMethod("setName", String.class);//obj无须转换类型
    msetName.invoke(obj, "zhangsan");//调用方法setName, 并传参.
    Method msetId = c.getMethod("setId", int.class);
    msetId.invoke(obj, 409090202);
    System.out.println(obj);

反射应用实例

实体类


复制代码 代码如下:

package org.dennisit.reflect.entity;
import java.io.Serializable;
/**
 *
 *  User.java   
 *
 *  @version : 1.1
 * 
 *  @author  : 苏若年    <a href="mailto:DennisIT@163.com">发送邮件</a>
 *   
 *  @since     : 1.0        创建时间:    2013-2-26        下午01:43:56
 *    
 *  TODO     :    class User.java is used for ...
 *
 */
public class User implements Serializable{

private String test;

public void execute(String name,int age){
        System.out.println("name=" + name + ",age=" + age);
    }
}

反射测试类


复制代码 代码如下:

package org.dennisit.reflect.main;
import java.lang.reflect.Field;
/**
 *
 *  ReflectEx.java   
 *
 *  @version : 1.1
 * 
 *  @author  : 苏若年    <a href="mailto:DennisIT@163.com">发送邮件</a>
 *   
 *  @since     : 1.0        创建时间:    2013-2-26        下午01:46:00
 *    
 *  TODO     :    class ReflectEx.java is used for ...
 *
 */
public class ReflectEx {

public static void main(String[] args)throws Exception {
        Class cls = Class.forName("org.dennisit.reflect.entity.User");
        Object obj = cls.newInstance();       //创建User的对象
        Field f = cls.getDeclaredField("test");    //获取test属性
        f.setAccessible(true);                    //打开私有属性test的访问权限
        f.set(obj, "zhangsan");                    //为test重新复制
        System.out.println(f.get(obj));            //获取obj的test属性值
        //根据方法名execute获取方法
        java.lang.reflect.Method m = cls.getMethod("execute", String.class, int.class);
        m.invoke(obj, "dennisit",23);            //调用execute方法
    }
}

运行效果


复制代码 代码如下:

zhangsan
name=dennisit,age=23

编写一个反射动态实例化类的例子


复制代码 代码如下:

package org.dennisit.reflect.main;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
/**
 *
 *  DynamicReflect.java   
 *
 *  @version : 1.1
 * 
 *  @author  : 苏若年    <a href="mailto:DennisIT@163.com">发送邮件</a>
 *   
 *  @since     : 1.0        创建时间:    2013-2-26        下午01:58:12
 *    
 *  TODO     :    利用反射动态实例化的例子
 *
 */
public class DynamicReflect {

public static Object getInstance(String className,Map<String,Object> map)throws Exception{
        Class c = Class.forName(className);
        Object obj = c.newInstance();                //对象对象
        Set<String> keys = map.keySet();            //获取对应的所有属性
        Field[] fAll = c.getDeclaredFields();        //获取类中所有属性
        for(int i=0;i<fAll.length;i++){
            for(String key:keys){                    //循环匹配
                if(fAll[i].getName().equals(key)){    //如果用户传入的属性跟获取到的类中的属性名匹配
                    Field f = c.getDeclaredField(key);//获取该属性
                    //构建setXxx()方法名
                    String methodName = "set" + key.substring(0,1).toUpperCase()+key.substring(1);
                    Method method = c.getMethod(methodName, f.getType());//根据构建的用户名获取对应的方法
                    method.invoke(obj, map.get(key));//方法调用
                }else{
                    continue;
                }
            }
        }
        return obj;
    }
}

接下来我们测试我们编写的动态反射实例化例子

实体类


复制代码 代码如下:

package org.dennisit.reflect.entity;
import java.io.Serializable;
/**
 *
 *  User.java   
 *
 *  @version : 1.1
 * 
 *  @author  : 苏若年    <a href="mailto:DennisIT@163.com">发送邮件</a>
 *   
 *  @since     : 1.0        创建时间:    2013-2-26        下午01:43:56
 *    
 *  TODO     :    实体类
 *
 */
public class User implements Serializable{

private String name;
    private int age;
    private String email;

public User() {  //必须有无参构造

}

//getter() and setter()

}

主测试类


复制代码 代码如下:

package org.dennisit.reflect.main;
import java.util.HashMap;
import java.util.Map;
import org.dennisit.reflect.entity.User;
/**
 *
 *  ReflectEx.java   
 *
 *  @version : 1.1
 * 
 *  @author  : 苏若年    <a href="mailto:DennisIT@163.com">发送邮件</a>
 *   
 *  @since     : 1.0        创建时间:    2013-2-26        下午01:46:00
 *    
 *  TODO     :    class ReflectEx.java is used for ...
 *
 */
public class ReflectEx {

public static void main(String[] args)throws Exception {
        Class cls = Class.forName("org.dennisit.reflect.entity.User");
        String className = "org.dennisit.reflect.entity.User";
        Map<String,Object> map = new HashMap<String, Object>();
        map.put("name", "dennisit");
        map.put("age", 22);
        map.put("email", "dennisit@163.com");

User user = (User)DynamicReflect.getInstance(className, map);
        System.out.println(user.getName() + "," + user.getAge() + "," + user.getEmail());
    }
}

程序运行结果


复制代码 代码如下:

dennisit,22,dennisit@163.com

时间: 2013-05-03

通过java反射机制动态调用某方法的总结(推荐)

如下: public Object invokeMethod(String className, String methodName, Object[] args) throws Exception{ Class ownerClass = Class.forName(className); Object owner = ownerClass.newInstance(); Class[] argsClass = new Class[args.length]; for (int i = 0, j =

Java反射机制的学习总结

一.什么是反射机制 简单的来说,反射机制指的是程序在运行时能够获取自身的信息.在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息. 二.哪里用到反射机制 有些时候,我们用过一些知识,但是并不知道它的专业术语是什么,在刚刚学jdbc时用过一行代码, Class.forName("com.mysql.jdbc.Driver.class").newInstance();但是那时候只知道那行代码是生成驱动对象实例,并不知道它的具体含义.听了反射机制这节课后,才知道,原来这

JAVA反射机制实例教程

本文以实例形式详细讲述了Java的反射机制,是Java程序设计中重要的技巧.分享给大家供大家参考.具体分析如下: 首先,Reflection是Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性.例如,使用它能获得 Java 类中各成员的名称并显示出来. Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性.例如,Pascal.C 或者 C++ 中就没有办法在程序中获得函数

Java的反射机制---动态调用对象的简单方法

唉!我还真是在面试中学习新东东啊,一个公司刚刚给了个测试,不过我很奇怪的是为什么web developer的职位居然考java的反射机制题,不过学习研究一下反射机制对我来说是件好事啦! 先说说什么是java反射机制吧,在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这 种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制.主要功能:在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对 象:在运行时判断任意一个

利用java反射机制调用类的私有方法(推荐)

试想一下,如果你可以轻易地调用一个类的私有方法,那么是不是说你的封装都失效了?最近在看java的反射机制,发现居然可以利用java的反射机制去调用其他类的私有方法,至于这能干什么,那就见人见智了.. 我写的一段简易实例代码如下: import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @author thomaslwq * @version 创建时间:Sep 4, 201

Java通过反射机制动态设置对象属性值的方法

/** * MethodName: getReflection<br> * Description:解析respXML 在通过反射设置对象属性值 * User: liqijing * Date:2015-7-19下午12:42:55 * @param clzzName * @param respXML * @return * @throws ClassNotFoundException * @throws DocumentException * @throws IllegalArgumentE

Java反射机制及Method.invoke详解

JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对象:在运行时判断任意一个类所具有的成员变量和方法:在运行时调用任意一个对象的方法:生成动态代理. 1. 得到某个对象的属性 复制代码 代码如下: public Object get

java 利用反射机制,获取实体所有属性和方法,并对属性赋值

一个普通的实体Person: private int id; private String name; private Date createdTime; ... //其它字段 // get set方法 ............... 现在需要把通过webService传过来的实体Person里面的所有字段的null值,换成"" 实现思路: 1.获取实体的所有字段,遍历 2.获取字段类型 3.调用字段的get方法,判断字段值是否为空 4.如果字段值为空,调用字段的set方法,为字段赋值

Java反射机制概念、原理与用法总结

本文实例讲述了Java反射机制概念.原理与用法.分享给大家供大家参考,具体如下: 反射机制是什么 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 反射机制能做什么 反射机制主要提供了以下功能: ① 在运行时判断任意一个对象所属的类: ② 在运行时构造任意一个类的对象: ③ 在运行时判断任意一个类所具有的成员变量和方法: ④ 在运行时调用任意一个

java基于线程池和反射机制实现定时任务完整实例

本文实例讲述了java基于线程池和反射机制实现定时任务的方法.分享给大家供大家参考,具体如下: 主要包括如下实现类: 1. Main类: 任务执行的入口: 调用main方法,开始加载任务配置并执行任务 package com.yanek.task; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import ja

java 利用java反射机制动态加载类的简单实现

如下所示: ////////////////// Load.java package org.bromon.reflect; import java.util.ArrayList; import java.util.List; public class Load implements Operator { @Override public List<?> act(List<?> params) { // TODO Auto-generated method stub List<

利用java反射机制实现自动调用类的简单方法

1. 新建TestServlet类 package com.yanek.test; import java.io.IOException; import java.lang.reflect.Method; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.ht

JQuery页面随滚动条动态加载效果的简单实现(推荐)

Google阅读器上有一个AJAX scollLoad效果很不错,就是阅读项目时不需要翻页,浏览器滚动条往下拉到一定位置时自动加载新的一批项目进来,一直到所有项目加载完为止.要知道,数据量增加很频繁时,要通过定位页码来找到目标数据似乎并没有什么意义.我觉得用户体验成熟的WEB应用程序应当引导用户使用TAG或搜索等功能来找到目标数据.至于浏览数据,尤其是浏览最新的数据,利用浏览器滚动条来加载,是很好的尝试-- 我试着用jquery来实现这个功能.先要得到滚动条的总长属性值:scrollHeight

Java如何基于反射机制获取不同的类

什么是反射机制 Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法.这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制.反射被视为动态语言的关键(在运行阶段可以改变其结构) 特点: 1.极大的提高了程序的灵活性和扩展性,降低模块的耦合性,提高自身的适应能力 2.通过反射机制可以让程序创建和控制任何类的对象,无需提前硬编码目标类 3.能够在运

动态加载js文件简单示例

本文实例讲述了动态加载js文件的方法.分享给大家供大家参考,具体如下: function loadScript(url){ var hd = document.getElementsByTagName('head')[0], js = document.createElement('script'); js.src = url; js.type = "text/JavaScript"; if(js.addEventListener){ js.addEventListener("

Java反射之静态加载和动态加载的简单实例

静态加载: package com.imooc.加载类; public class Office_Static { public static void main(String[] args) { //new 创建对象,是静态加载类,在编译时刻就需要加载所有的可能使用到的类 if("Word".equals(args[0])){ Word w = new Word(); w.start(); } if("Excel".equals(args[0])){ Excel

java 动态加载的实现代码

java 动态加载的实现代码 Java动态加载类的意义和目的: Java动态加载类主要是为了不改变主程序代码,通过修改配置文件就可以操作不同的对象执行不同的功能.主要有利于系统的扩展,例如当我要改变一个功能,只需要做一个类,然后编写相应的功能,通过配置文件就可以使用新的功能,不需要修改系统的任何地方,只需要添加一个类:充分实现了松散耦合.满足了开闭原则(对修改关闭,对添加或删除开放): public abstract class AbstractAction { public abstract

Android中的动态加载机制的学习研究

在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势.本文对网上Android动态加载jar的资料进行梳理和实践在这里与大家一起分享,试图改善频繁升级这一弊病. Android应用开发在一般情况下,常规的开发方式和代码架构就能满足我们的普通需求.但是有些特殊问题,常常引发我们进一步的沉思.我们从沉思中产生顿悟,从而产生新的技术形式. 如何开发一个可以自定

Python实现动态加载模块、类、函数的方法分析

本文实例讲述了Python实现动态加载模块.类.函数的方法.分享给大家供大家参考,具体如下: 动态加载模块: 方式1:系统函数__import__() 方式2:imp, importlib 模块 方式3:exec 函数 动态加载类和函数 首先,使用加载模块,使用内置函数提供的反射方法getattr(),依次按照层级获取模块->类\全局方法->类对象\类方法. test_import_module.py class ClassA: def test(self): print('test') in

解析Java虚拟机中类的初始化及加载器的父委托机制

类的初始化 在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值. 在程序中,静态变量的初始化有两种途径: 1.在静态变量的声明处进行初始化: 2.在静态代码块中进行初始化. 没有经过显式初始化的静态变量将原有的值. 一个比较奇怪的例子: package com.mengdd.classloader; class Singleton { // private static Singleton mInstance = new Singleton();// 位置1 // 位置1输