黑马程序员技术交流社区

标题: 疑点 [打印本页]

作者: 风云    时间: 2013-6-12 07:54
标题: 疑点
本帖最后由 孙百鑫 于 2013-6-22 01:00 编辑

反射的原理以及它的作用还有为什么使用反射,始终有一点迷惑,自己也理的不是很清楚,希望高手指点一下
作者: Heart    时间: 2013-6-12 10:48
反射的概念:
所谓的反射就是java语言在运行时拥有一项自观的能力,反射使您的程序代码能够得到装载到JVM中的类的内部信息,允许您执行程序时才得到需要类的内部信息,而不是在编写代码的时候就必须要知道所需类的内部信息,这使反射成为构建灵活的应用的主要工具。简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。

反射的常用类和函数:
Java反射机制的实现要借助于4个类:Class,Constructor,Field,Method;其中class代 表的是类对象,Constructor-类的构造器对象,Field-类的属性对象,Method-类的方法对象,通过这四个对象我们可以粗略的看到一个类的各个组成部分。其中最核心的就是Class类,它是实现反射的基础。

Java 语言反射提供一种动态链接程序组件的多功能方法。它允许程序创建和控制任何类的对象,无需提前硬编码目标类。这些特性使得反射特别适用于创建以非常普通的 方式与对象协作的库。Java reflection 非常有用,它使类和数据结构能按名称动态检索相关信息,并允许在运行着的程序中操作这些信息。Java 的这一特性非常强大,并且是其它一些常用语言,如 C、C++、Fortran 或者 Pascal 等都不具备的。

但反射有两个缺点。第一个是性能问题。用于字段和方法接入时反射要远 慢于直接代码。性能问题的程度取决于程序中是如何使用反射的。如果它作为程序运行中相对很少涉及的部分,缓慢的性能将不会是一个问题。即使测试中最坏情况 下的计时图显示的反射操作只耗用几微秒。仅反射在性能关键的应用的核心逻辑中使用时性能问题才变得至关重要。
作者: 麦子    时间: 2013-6-12 11:29
JAVA反射机制
  JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
  Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
  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数组,作为寻找Method的条件
  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。
 
  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。
  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);
  }

作者: x.love    时间: 2013-6-12 12:31
用张老师学员一句经典的话说:反射就是把java类中的各种成分映射成相应的java类。(概念)

通过反射可以得到其他程序员源码中的东西,而无需知道其源码是什么。更方便我们使用,扩展。
作者: 孙百鑫    时间: 2013-6-13 06:17
楼主您好!如果问题得到解决请将题目改成"已解决"
编辑文章-->修改 如果问题没有得到解决请继续发问谢谢您的配合{:soso_e100:}




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