java里的反射机制

原创 2006年06月06日 23:09:00

题外话:

下个周末世界杯就开始了,对于一个地道的球迷而言,这无疑是一个期盼以久的盛大的节日,无论从生理上还是心理上我都做好了充分的准备,准备全身心的投入到这个四年一度的节日中去,祝天下球迷朋友们节日快乐,好好享受吧!

什么是反射机制

正像物理中的反射一样,就像我们站在镜子面前能看到自己的模样。但是这里的反射机制又有别于物理中的反射,这里的反射机制着重强调的是“动态的”。反射机制是指能在class(自己)运行的情况下,看到自己主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。由于设计的时候加入了这种机制使得java语言具有了一定的动态能力(所谓一定的动态能力是指:java语言并不能象python,ruby那样在程序运行时,允许改变程序结构和变量的类型,但是他可以在程序运行的时候检测自己的状态和行为,并能修改字段的值)。正是由于反射机制的存在,所以java语言又有别于“硬编码”的c,c++,同时也正是这个机制的优势,使得微软在后来模仿java语言发明了c#语言,同样c#语言也具备了这个优势。

如何实现:

java里面所有对象都继承于一个基本对象class object,这个对象不是我们通过程序手动写出来的,他是在每一个class使用的时候由jvm自动生成的。这个类提供了若干个Reflection API,我们可以调用这些Reflection API来检查class的相关方法,变量,名字,接口以及继承…………相关信息。而我们通过SUN提供的这些Reflection API来检查各种各样的class信息的过程就是反射(下面我写的这个例子就是做的这件事),象这种事,每天JVM都在做,任何一个时候都在不停的做,只要有一个class生成,被操作,jvm都会调用反射API去得到他的方法,属性,变量。罗列几个常用的API有:getName() 得到class/interface 名称;getDeclaredMethods() 得到方法;getDeclaredFields() 得到变量……。

例子(三个例子,得到字段,方法,名字)

以下是我使用反射机制的三个例子,分别是得到名字,方法,以及属性和修改属性。

例子一:

/*得到方法名字*/

Class c = null;

c = Class.forName(args[0]);

Package p;

p = c.getPackage();

if (p != null)

System.out.println("package "+p.getName()+";");

執行結果(例):

package java.util;

该例子摘自侯捷老师一书《java反射机制》“Java Reflection API 運用示例”一节,正像我们常常问的那样,我们在EJB里面写了个方法,或者引入了一个包,客户端怎么知道是哪一个包,是哪一个方法,就像上面一样,JVM其实在背后做了上面这段代码的事,然后打印了上面这个结果,也就是说JVM通过反射知道了他想知道的信息。明白了吧,JVM就是这样得到了这些信息。刚开始我学习反射的时候,有一个疑问在我脑海里困惑了很久“反射只能动态的时候看自己的方法,函数,变量,又不能象动态语言那样操作,这样做意义何在,似乎找不到一点好处”,通过这里,我明白了,其实反射不是给你看的,是给JVM看的,让他或者容器(例如EJB)知道到底该得到什么方法,什么class

例子二:

/*得到所有方法*/

package src;

 

import java.lang.reflect.*;

 

public class reflectiontest {   

 

    public static void main(String args[]) {

        try {           

 

            Class c = Class.forName("java.lang.String");//转化为class object对象,可以反射。

            Method m[] = c.getDeclaredMethods();

            System.out.println(m[0].toString());

/****查看自己的所有方法******/

            for (int i = 0; i < m.length; i++)

                System.out.println(m[i].toString());

/****************************/

 

 

/****查看自己的第一个方法****/

System.out.println(m[0].toString());

/****************************/

           }

               catch (Throwable e) {

            System.err.println(e);  

            }   

 

    }

}

由于java是完全面相对象的编程,所以在java里面string型,int型,这些常量类型也是对象化了的,我们可以把他们当作一个对象来看待和操作。通过上面的例子得到的结果是所有string的公共方法。

例子三:

/*得到属性以及修改属性,也就是我们常常使用的setget方法*/

public class Test {

public double d;

public static void main(String args[])

{

Class c = Class.forName("Test");

Field f = c.getField("d"); //指定field 名稱

Test obj = new Test();

System.out.println("d= " + (Double)f.get(obj));

f.set(obj, 12.34);

System.out.println("d= " + obj.d);

}

}

该例子摘自侯捷老师一书《java反射机制》倒数第二小节“執行期變更fields 內容”,这个方法大家用得多了吧,其实里面也包含了反射机制得原理,即使说我们通过实名把我们要操作的对象转换成class object对象Class c = Class.forName("Test");然后通过c.getField()方法(该方法就是反射制的体现) 就可以动态(这里所谓的动态就是指在程序在运行的时候)取得自己的变量,并且修改和设置。

为什么用reflection,他有什么好处:

其实JNDI就是reflection的一个具体表现。举个例:ejb里面我们放了一个类,客户端怎么知道我们要使用什么类的什么方法,我们知道用的是jndi,其实JNDI就是反射机制的一个具体表现,Class c = Class.forName("java.lang.String");双音号里面是调用的函数或者方法的名字,通过名字来找到我们要调用的方法,这就是我们说的JNDIJVM在内部实例化了一个class object,正如我们上面提到的这个class object里面有很多方法,通过这些方法就可以看到他得到的那个类的所有的公用方法,并且调用相应的方法。否则客户端也不能知道我们调用的是什么类。

同样我们常常使用getXXX()setXXX()方法也是一样的道理。

总结起来可以概括为:“动态的来选择执行的方法和变量,不是静态的写出来。”

相关文章推荐

java反射机制

  • 2016年06月05日 21:04
  • 7KB
  • 下载

Java反射机制

  • 2015年02月27日 21:08
  • 845KB
  • 下载

利用java反射机制实现读取excel表格中的数据

如果直接把excel表格中的数据导入数据库,首先应该将excel中的数据读取出来。 为了实现代码重用,所以使用了Object,而最终的结果是要获取一个list如List、List等,所以需要使用泛型机...

Java 语言的反射机制

  • 2013年08月29日 22:43
  • 185KB
  • 下载

关于Java的反射机制,你需要理解这些..

反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。...
  • forezp
  • forezp
  • 2016年12月18日 21:53
  • 12877

Java泛型和反射机制

  • 2014年01月07日 11:20
  • 626KB
  • 下载

Java中类的反射机制

  • 2013年12月18日 19:58
  • 245KB
  • 下载

java中使用反射机制获取实体类集合的某个属性值

需求今天遇到一个需求。需要从几个对象的集合中取出对象的某些属性。怎么办呢?哪就利用反射机制写个方法吧。思路入参首先是几个对象的集合,那么方法的入参就是 list 因为是不同对象所以还是得用泛型。用反射...

JAVA反射机制和动态代理PDF

  • 2012年12月13日 14:55
  • 263KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java里的反射机制
举报原因:
原因补充:

(最多只允许输入30个字)