黑马程序员技术交流社区

标题: 为什么要用反射 [打印本页]

作者: 周朋飞    时间: 2012-6-18 23:09
标题: 为什么要用反射
本帖最后由 周朋飞 于 2012-6-19 00:28 编辑

      在网上看了那么多的关于反射的理解,以及别人解释的为什么要用反射,可是还是有点不太理解,既然你给我一个类,我直接创建对象不就行了,有人说当你不知道类名的时候怎么创建,有没有比较通俗的例子或者比喻给说一下
作者: 陈嘉宾    时间: 2012-6-18 23:11
本帖最后由 陈嘉宾 于 2012-6-18 23:14 编辑

反射就是把java类中的各种成分映射成相应的java类,例如,一个java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的java类来表示,就想汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示java类的class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field,Method,Contructor,Package等等。比如你定义了一个类里面有很多方法,你可以用反射得到这个类里的各个属性和方法,包括私有的属性及方法
作者: 余银桂    时间: 2012-6-18 23:11
反射其实就是程序能够自检查自身信息。就像程序会照镜子反光看自己。

在程序中可以检查某个类中的方法属性等信息,并且能够动态调用。
这样可以写出很灵活的程序。
比如要把一个对象中的数据copy到另外一个对象中,规则是属性名相同就copy,
就可以用反射来做,不需要指定每个属性的名字,只要动态从类中取得信息,
再判断属性名是否相同即可。当然应用还有很多。

反射可以结合Java的字节码,使用ASM和cglib等库,还能动态生成类。
hibernate的延迟载入,spring的AOP都是这么实现的

反射给Java带来了一些动态性。不过虽然很好,但毕竟还是有一定局限性的。另外ASM,cglib使用还是不放便。因此一些纯动态语言现在是一个重要发展趋势,比如ruby,python等,程序很容易动态生成。
作者: 刘笑    时间: 2012-6-18 23:16
反射其实就是程序能够自检查自身信息。就像程序会照镜子反光看自己。

在程序中可以检查某个类中的方法属性等信息,并且能够动态调用。
这样可以写出很灵活的程序。
比如要把一个对象中的数据copy到另外一个对象中,规则是属性名相同就copy,
就可以用反射来做,不需要指定每个属性的名字,只要动态从类中取得信息,
再判断属性名是否相同即可。当然应用还有很多。


作者: 周朋飞    时间: 2012-6-18 23:49
一楼的大哥太强了,直接把张孝祥老师的话原翻不动的给我搬了过来  你们说的我都知道 ,SpringAOP 和动态代理都需要用到反射,或许以后用的多了就会理解的更深了吧  
作者: 周朋飞    时间: 2012-6-19 00:20
当你做一个软件可以安装插件的功能,你连插件的类型名称都不知道,你怎么实例化这个对象呢?
因为程序是支持插件的(第三方的),在开发的时候并不知道 。所以,无法在代码中 New出来 ,但反射可以,通过反射,动态加载程序集,然后读出类,检查标记之后再实例化对象,就可以获得正确的类实例。
反射的目的就是为了扩展未知的应用。比如你写了一个程序,这个程序定义了一些接口,只要实现了这些接口的dll都可以作为插件来插入到这个程序中。那么怎么实现呢?就可以通过反射来实现。就是把dll加载进内存,然后通过反射的方式来调用dll中的方法。
很多工厂模式就是使用的反射。

我查了查资料,并且我仔细想了想,就好像我们张老师讲的一个题目,让你写一个程序去调另一个类的Main方法,假设你连类的名字都不知道,就给一串字符串,然后你也不知道这些字符串代表什么意思,没有关系,只要知道这些字符串肯定是一些java代码,只要加载到内存之后就是一些字节码,然后我们就可以通过字节码获得这串字符串的一些内容,譬如Main方法之类的 我是这么理解的
作者: 孙浩迪    时间: 2012-6-19 01:26
 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。   Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。   有时候我们说某个语言具有很强的动态性,有时候我们会区分动态和静态的不同技术与作法。我们朗朗上口动态绑定(dynamic binding)、动态链接(dynamic linking)、动态加载(dynamic loading)等。然而“动态”一词其实没有绝对而普遍适用的严格定义,有时候甚至像对象导向当初被导入编程领域一样,一人一把号,各吹各的调。   一般而言,开发者社群说到动态语言,大致认同的一个定义是:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。   尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。   Java如何能够做出上述的动态特性呢?这是一个深远话题,本文对此只简单介绍一些概念。整个篇幅最主要还是介绍Reflection APIs,也就是让读者知道如何探索class的结构、如何对某个“运行时才获知名称的class”生成一份实体、为其fields设值、调用其methods。本文将谈到java.lang.Class,以及java.lang.reflect中的Method、Field、Constructor等等classes。
作者: 胡大强    时间: 2012-6-19 01:45
如果你使用Java ,那么你应该知道 Java 中有一个 Class 类。 Class 类本身表示 Java 对象的类型,我们可以通过一个 Object (子)对象的 getClass 方法取得一个对象的类型,此函数返回的就是一个 Class 类。
java反射机制是java程序开发语言的特征之一,在Java运行时环境中,对于任意一个类,都可以知道这个类有哪些属性和方法,对于任意一个对象,都可以调用它的任意一个方法。这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射机制。
下面来看一下反射的使用:
反射的使用:1.获得一个类的类模版
              Class c = 对象名.getClass();
                     Class c = Class.forName(包名+类名);
              c.newInstance();  //根据模版来获取其对应的类对象

根据类模版获取类的信息:
获取类的属性:
Filed类----c.getFiled(String pname)  //获得指定属性(公共字段)
Filed类----c.getDeclearedFiled(String pname)  //获得指定属性(所有权限字段)

反射这一知识太复杂,可以去多看几遍张孝祥老师讲解的视频~!





作者: 郑冬    时间: 2012-6-19 11:37
Java程序中许多对象在运行时都会出现两种类型,编译时类型和运行时类型,例如如下代码:
Person p = new Student();这行代码将会生成一个p变量,该变量的编译类型为Person,运行时类型为Student,除此之外,还有更极端的情形,程序在运行时接收到外部传入的一个对象,该对象的编译类型是object,但程序又需要调用该对象运行时的方法,为了解决这个问题,程序需要在运行时发现对象和类的真实信息,编译时根本无法预知该对象和类可能属于哪个类,程序只能靠运行时信息来发现该对象和类的真实信息,这时就必须使用反射
作者: 黑马---邢志伟    时间: 2012-6-19 11:48
首先通过java反射机制,可以让你更深入地控制程序的运行过程,如在程序运行时对用户输入的信息进行验证,还可以逆向控制程序的执行过程。再者,通过JAVA反射机制,可以再程序中访问已经装载到JVM中的Java对象的描述,实现访问。检测和修改Java对象本身信息的功能。因为他的一些强大功能,所以用JAVA反射机制是很有必要的。。。{:soso_e100:}




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2