Java反射经典实例 2007-08-29 17:55:25

分类: Java

Java提供了一套机制来动态执行方法和构造方法,以及数组操作等,这套机制就叫——反射。反射机制是如今很多流行框架的实现基础,其中包括Spring、Hibernate等。原理性的问题不是本文的重点,接下来让我们在实例中学习这套精彩的机制。

1. 得到某个对象的属性

1 public Object getProperty(Object owner, String fieldName) throws Exception {
2     Class ownerClass = owner.getClass();

4     Field field = ownerClass.getField(fieldName);

6     Object property = field.get(owner);

8     return property;
9 }

Class ownerClass = owner.getClass():得到该对象的Class。

Field field = ownerClass.getField(fieldName):通过Class得到类声明的属性。

Object property = field.get(owner):通过对象得到该属性的实例,如果这个属性是非公有的,这里会报IllegalAccessException。

2. 得到某个类的静态属性

 1 public Object getStaticProperty(String className, String fieldName)
 2             throws Exception {
 3     Class ownerClass = Class.forName(className);
 4 
 5     Field field = ownerClass.getField(fieldName);
 6 
 7     Object property = field.get(ownerClass);
 8 
 9     return property;
10 }

Class ownerClass = Class.forName(className) :首先得到这个类的Class。

Field field = ownerClass.getField(fieldName):和上面一样,通过Class得到类声明的属性。

Object property = field.get(ownerClass) :这里和上面有些不同,因为该属性是静态的,所以直接从类的Class里取。

3. 执行某对象的方法

 1 public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {
 2 
 3     Class ownerClass = owner.getClass();
 4 
 5     Class[] argsClass = new Class[args.length];
 6 
 7     for (int i = 0, j = args.length; i < j; i++) {
 8         argsClass[i] = args[i].getClass();
 9     }
10 
11     Method method = ownerClass.getMethod(methodName, argsClass);
12 
13     return method.invoke(owner, args);
14 }

Class owner_class = owner.getClass() :首先还是必须得到这个对象的Class。

5~9行:配置参数的Class数组,作为寻找Method的条件。

Method method = ownerClass.getMethod(methodName, argsClass):通过Method名和参数的Class数组得到要执行的Method。

method.invoke(owner, args):执行该Method,invoke方法的参数是执行这个方法的对象,和参数数组。返回值是Object,也既是该方法的返回值。

4. 执行某个类的静态方法

 1 public Object invokeStaticMethod(String className, String methodName,
 2             Object[] args) throws Exception {
 3     Class ownerClass = Class.forName(className);
 4 
 5     Class[] argsClass = new Class[args.length];
 6 
 7     for (int i = 0, j = args.length; i < j; i++) {
 8         argsClass[i] = args[i].getClass();
 9     }
10 
11     Method method = ownerClass.getMethod(methodName, argsClass);
12 
13     return method.invoke(null, args);
14 }

基本的原理和实例3相同,不同点是最后一行,invoke的一个参数是null,因为这是静态方法,不需要借助实例运行。

5. 新建实例

 1 
 2 public Object newInstance(String className, Object[] args) throws Exception {
 3     Class newoneClass = Class.forName(className);
 4 
 5     Class[] argsClass = new Class[args.length];
 6 
 7     for (int i = 0, j = args.length; i < j; i++) {
 8         argsClass[i] = args[i].getClass();
 9     }
10 
11     Constructor cons = newoneClass.getConstructor(argsClass);
12 
13     return cons.newInstance(args);
14 
15 }

这里说的方法是执行带参数的构造函数来新建实例的方法。如果不需要参数,可以直接使用newoneClass.newInstance()来实现。

Class newoneClass = Class.forName(className):第一步,得到要构造的实例的Class。

第5~第9行:得到参数的Class数组。

Constructor cons = newoneClass.getConstructor(argsClass):得到构造子。

cons.newInstance(args):新建实例。

6. 判断是否为某个类的实例

1 public boolean isInstance(Object obj, Class cls) {
2     return cls.isInstance(obj);
3 }

7. 得到数组中的某个元素

1 public Object getByArray(Object array, int index) {
2     return Array.get(array,index);
3 }

附完整源码:

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Java Reflection Cookbook
 *
 * @author Michael Lee
 * @since 2006-8-23
 * @version 0.1a
 */

public class Reflection {
    /**
     * 得到某个对象的公共属性
     *
     * @param owner, fieldName
     * @return 该属性对象
     * @throws Exception
     *
     */
    public Object getProperty(Object owner, String fieldName) throws Exception {
        Class ownerClass = owner.getClass();

Field field = ownerClass.getField(fieldName);

Object property = field.get(owner);

return property;
    }

/**
     * 得到某类的静态公共属性
     *
     * @param className   类名
     * @param fieldName   属性名
     * @return 该属性对象
     * @throws Exception
     */
    public Object getStaticProperty(String className, String fieldName)
            throws Exception {
        Class ownerClass = Class.forName(className);

Field field = ownerClass.getField(fieldName);

Object property = field.get(ownerClass);

return property;
    }

/**
     * 执行某对象方法
     *
     * @param owner
     *            对象
     * @param methodName
     *            方法名
     * @param args
     *            参数
     * @return 方法返回值
     * @throws Exception
     */
    public Object invokeMethod(Object owner, String methodName, Object[] args)
            throws Exception {

Class ownerClass = owner.getClass();

Class[] argsClass = new Class[args.length];

for (int i = 0, j = args.length; i < j; i++) {
            argsClass[i] = args[i].getClass();
        }

Method method = ownerClass.getMethod(methodName, argsClass);

return method.invoke(owner, args);
    }

/**
     * 执行某类的静态方法
     *
     * @param className
     *            类名
     * @param methodName
     *            方法名
     * @param args
     *            参数数组
     * @return 执行方法返回的结果
     * @throws Exception
     */
    public Object invokeStaticMethod(String className, String methodName,
            Object[] args) throws Exception {
        Class ownerClass = Class.forName(className);

Class[] argsClass = new Class[args.length];

for (int i = 0, j = args.length; i < j; i++) {
            argsClass[i] = args[i].getClass();
        }

Method method = ownerClass.getMethod(methodName, argsClass);

return method.invoke(null, args);
    }

/**
     * 新建实例
     *
     * @param className
     *            类名
     * @param args
     *            构造函数的参数
     * @return 新建的实例
     * @throws Exception
     */
    public Object newInstance(String className, Object[] args) throws Exception {
        Class newoneClass = Class.forName(className);

Class[] argsClass = new Class[args.length];

for (int i = 0, j = args.length; i < j; i++) {
            argsClass[i] = args[i].getClass();
        }

Constructor cons = newoneClass.getConstructor(argsClass);

return cons.newInstance(args);

}

/**
     * 是不是某个类的实例
     * @param obj 实例
     * @param cls 类
     * @return 如果 obj 是此类的实例,则返回 true
     */
    public boolean isInstance(Object obj, Class cls) {
        return cls.isInstance(obj);
    }
    
    /**
     * 得到数组中的某个元素
     * @param array 数组
     * @param index 索引
     * @return 返回指定数组对象中索引组件的值
     */
    public Object getByArray(Object array, int index) {
        return Array.get(array,index);
    }
}

java反射案例的更多相关文章

  1. java反射案例讲解

    本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象 ...

  2. java反射案例详解

    白首为功名.旧山松竹老,阻归程.欲将心事付瑶琴.知音少,弦断有谁听? [案例1]通过一个对象获得完整的包名和类名 package Reflect; /** * 通过一个对象获得完整的包名和类名 * * ...

  3. 第28章 java反射机制

    java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...

  4. java 反射的应用 以及通过反射 用到的工厂模式

    java反射详解 本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案 ...

  5. JAVA反射其实就是那么一回事

    概念:什么是反射 java反射机制: JAVA反射机制是在运行状态中, 对于任意一个类,都能够知道这个类的所有属性和方法: 对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及 ...

  6. java 反射 动态代理

    在上一篇文章中介绍Java注解的时候,多次提到了Java的反射API.与javax.lang.model不同的是,通过反射API可以获取程序在运行时刻的内部结构.反射API中提供的动态代理也是非常强大 ...

  7. 转:Java反射教程

    原文来自于:http://www.importnew.com/9078.html 什么是反射?反射有什么用处? 1. 什么是反射? “反射(Reflection)能够让运行于JVM中的程序检测和修改运 ...

  8. java反射机制,以及对反射机制的了解,如有差池欢迎点评(初学者勿喷)

    本人学习java时间不长,但是对java很感兴趣,知道有博客园这个平台果断的注册,记录我的java成长日记,这也是我的处女作,虽然很菜但是还是希望大家能见证我的成长,觉得可以的可以和我讨论一起学习 在 ...

  9. 【java提高】---java反射机制

    java反射机制 一.概述 1.什么是反射机制 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态 ...

随机推荐

  1. SQL Server 【附】创建"商品管理数据库"、"学生选课数据库"的SQL语句

    附:(创建“商品管理数据库”的SQL语句) --建立"商品管理数据库"数据库-- create database 商品管理数据库 on(name='商品管理数据库_m', file ...

  2. SQL Server 数据库的安全管理(登录、角色、权限)

    ---数据库的安全管理 --登录:SQL Server数据库服务器登录的身份验证模式:1)Windows身份验证.2)Windows和SQL Server混合验证 --角色:分类:1)服务器角色.服务 ...

  3. 自动化测试第一季-selenium + python(环境搭建与基础代码解释)

    # coding = utf-8              %%%%%%%%%%%%%%%%防止乱码(可加可不加) from selenium import webdriver             ...

  4. Redis从基础命令到实战之集合类型(Set)

    Redis集合类型的基础功能也是存储字符串列表,和列表类型的区别是字符串不能重复且没有顺序.当然,存储元素唯一性也可以通过应用程序保证,单从这一点上并没有体现出对比列表类型的特点. 其实,集合类型的一 ...

  5. 关于js中的for(var in)遍历属性报错问题

    之前遇到过这个问题,但是没找到问题的所在,将for(var i in  array){} 改成了for(var i ;i<array.length;i++)循环,但是今天又遇到了,mark一下错 ...

  6. app跳转openURL,兼容方法

    - (void)openScheme:(NSString *)scheme {   UIApplication *application = [UIApplication sharedApplicat ...

  7. mysql 数据库,表存储 大小

    use information_schema; -- 查询一个数据库存储大小 select concat(round(sum(data_length/1024/1024),2),'MB') as da ...

  8. redis启用持久化

    redis的持久化有rdb和aof两种. rdb是记录一段时间内的操作,一盘的配置是一段时间内操作超过多少次就持久化. aof可以实现每次操作都持久化. 这里我们使用aof. 配置方式,打开redis ...

  9. mac上执行sed的编辑 -i命令报错sed: 1: "test.txt": undefined label ‘est.txt’或sed: 1: "2a\test\": extra characters after \ at the end of a command

    问题一 sed编辑命令:[sed -i 's/a/b/g' test.txt]   报错:sed: 1: "test.txt": undefined label 'est.txt' ...

  10. 调用别人提供的WebService

    在开发过程中,许多时候需要使用到别人提供的WebService接口,使用其中的方法. 在调用别人提供的接口时,会得到接口使用的文档,其中包括接口的网络地址及方法作用等. 找到WebService的ws ...