A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘博 黑马帝   /  2012-1-5 08:42  /  3311 人查看  /  16 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

又看了一下张老师的反射视频,可是还是不是全部理解,谁能说说反射的窍门?感觉反射更抽象了

16 个回复

倒序浏览
我是这么看的,反射就是在研究Class这个类,就跟我们平时学习的类一类,它也有成员方法,成员变量.平时我们是通过类来操作成员,而反射就是用成员来操作类.这是我的一点理解,不知道能不能帮到你.

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
反射就是将类的各个成分映射成其相应的类。再调用相应的字段
或者方法进行一系列的操作。已达到访问类的私用成员,创建类的
实例对象等等

评分

参与人数 1技术分 +1 收起 理由
吴上储 + 1

查看全部评分

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

评分

参与人数 1技术分 +1 收起 理由
吴上储 + 1

查看全部评分

回复 使用道具 举报
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

评分

参与人数 1技术分 +1 收起 理由
吴上储 + 1

查看全部评分

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

1. 得到某个对象的属性

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;                                                               
}                                                                                 

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

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

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



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

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;                                                   
}                                                                       

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

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

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


3. 执行某对象的方法

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);     
}   
Class owner_class = owner.getClass() :首先还是必须得到这个对象的Class。

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

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

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


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

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);                                             
}                                                                                 
基本的原理和实例3相同,不同点是最后一行,invoke的一个参数是null,因为这是静态方法,不需要借助实例运行。



5. 新建实例

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);                                                
                                                                                 
}                                                                                 
这里说的方法是执行带参数的构造函数来新建实例的方法。如果不需要参数,可以直接使用newoneClass.newInstance()来实现。

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

第6~第10行:得到参数的Class数组。

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

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


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

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

回复 使用道具 举报
7. 得到数组中的某个元素

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

附完整源码:

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);   
    }   
}   

评分

参与人数 1技术分 +2 收起 理由
吴上储 + 2

查看全部评分

回复 使用道具 举报
上面 是例子  你可以 仔细看看  这是我看到别人的  给你 传过来的  我看上面写的很详细 你可以参考下 如果真的看不懂 我也么办法了!
回复 使用道具 举报
反射就一句话:就是把java类中的各种成分映射成各种相应的java类,有了这个类,剩下的就是对其中的元素的操作了

评分

参与人数 1技术分 +1 收起 理由
吴上储 + 1

查看全部评分

回复 使用道具 举报
小白 黑马帝 2012-1-6 09:45:47
10#
我的理解是,把硬盘中的编译好的字节码文件,加载到内存中,然后对其操作!
回复 使用道具 举报
zl918 黑马帝 2012-1-8 15:58:49
11#
Java的动态运行时机制、反射机制是Java的显著特点,运行时加载。
       在Java中,主要是通过java.lang包中的Class类和Method类来实现内存反射机制的。
       ClassName.forName():运行时以字符串参数传递一个类名,就可以得到这个类的所有信息,
      包括它所有的方法,和方法的详细信息。还可以实例化一个对象,并通过查到的方法名来调用该对象的任何方法。

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。反射就是得到你想要得到类的各种状态

---------------------------------------------------------------------

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
王涛 黑马帝 2012-1-9 20:00:51
13#
Java反射机制可以   
在运行时判断任意一个对象所属的类型
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法,甚至可以调用private方法
不过这些都是在运行时环境中,而不是在编译时环境中
回复 使用道具 举报
反射就是将类的各个成分映射成其相应的类。再调用相应的字段
或者方法进行一系列的操作
回复 使用道具 举报
大梅 黑马帝 2012-1-11 13:35:46
15#
反射就是当你不知道一个类里面是什么样的结构,但是还想用这个类的对象的时候,用Class提供的方法,可以窥视里面的东西。
回复 使用道具 举报
曾辉 黑马帝 2012-1-12 14:03:00
16#
说白了就是Java类的自省机制,暴露自身的一些方法、属性等自身状况
回复 使用道具 举报
王_涛 黑马帝 2012-1-13 20:28:48
17#
我觉得楼上理论说的太多了
楼主想知道怎么理解反射,其实你别把反射想的多么的神奇
其实反射就是一个java类的应用
是什么应用呢
就是如何去读其他的类。
这样理解就OK了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马