当前位置:文档之家› 深入理解Java反射机制汇总

深入理解Java反射机制汇总

深入理解Java反射机制本文较为详细的分析了Java反射机制。

分享给大家供大家参考,具体如下:一、预先需要掌握的知识(java虚拟机)java虚拟机的方法区:java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区。

方法区的主要作用是存储被装载的类的类型信息,当java虚拟机装载某个类型的时候,需要类装载器定位相应的class文件,然后将其读入到java虚拟机中,紧接着虚拟机提取class 中的类型信息,将这些信息存储到方法区中。

这些信息主要包括:1、这个类型的全限定名2、这个类型的直接超类的全限定名3、这个类型是类类型还是接口类型4、这个类型的访问修饰符5、任何直接超接口的全限定名的有序列表6、该类型的常量池7、字段信息8、方法信息9、除了常量以外的所有类变量10、一个到class类的引用等等(读者可以参考《深入java虚拟机》这本书的叙述)Class类:Class类是一个非常重要的java基础类,每当装载一个新的类型的时候,java虚拟机都会在java堆中创建一个对应于新类型的Class实例,该实例就代表此类型,通过该Class实例我们就可以访问该类型的基本信息。

上面说到在方法区中会存储某个被装载类的类型信息,我们就可以通过Class实例来访问这些信息。

比如,对于上面说到的信息Class中都有对应的方法,如下:1、getName();这个类型的全限定名2、getSuperClass();这个类型的直接超类的全限定名3、isInterface();这个类型是类类型还是接口类型4、getTypeParamters();这个类型的访问修饰符5、getInterfaces();任何直接超接口的全限定名的有序列表6、getFields();字段信息7、getMethods();方法信息等等(读者可以自己参看jdk帮助文档,得到更多的信息)二、java反射详解反射的概念:所谓的反射就是java语言在运行时拥有一项自观的能力,反射使您的程序代码能够得到装载到JVM中的类的内部信息,允许您执行程序时才得到需要类的内部信息,而不是在编写代码的时候就必须要知道所需类的内部信息,这使反射成为构建灵活的应用的主要工具。

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

其中最核心的就是Class类,它是实现反射的基础,它包含的方法我们在第一部分已经进行了基本的阐述。

应用反射时我们最关心的一般是一个类的构造器、属性和方法,下面我们主要介绍Class 类中针对这三个元素的方法:1、得到构造器的方法Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数,Constructor[] getConstructors() -- 获得类的所有公共构造函数Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关)Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关)2、获得字段信息的方法Field getField(String name) -- 获得命名的公共字段Field[] getFields() -- 获得类的所有公共字段Field getDeclaredField(String name) -- 获得类声明的命名的字段Field[] getDeclaredFields() -- 获得类声明的所有字段3、获得方法信息的方法Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法Method[] getMethods() -- 获得类的所有公共方法Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法Method[] getDeclaredMethods() -- 获得类声明的所有方法应用反射的基本步骤:1、获得你想操作的类的Class对象;方法一:Classc=Class.forName("ng.String") //这种方式获得类的Class对象需要包名.类名方法二:对于基本数据类型可以用形如Class c=int.class或Class c=Integer.TYPE的语句方法三:Class c=MyClass.class2、调用Class中的方法得到你想得到的信息集合,如调用getDeclaredFields()方法得到类的所有属性;3、处理第2步中得到的信息,然后进行你想做的实际操作。

反射实例:下面我将针对类的构造器、属性和方法分别举三个例子,向大家演示一下反射的应用过程。

1、构造器步骤为:通过反射机制得到某个类的构造器,然后调用该构造器创建该类的一个实例import ng.reflect.*; public class ConstructorDemo{ public ConstructorDemo(){ }public ConstructorDemo(int a, int b){ System.out.println("a="+a+"b="+b); } public static void main(String args[]){ try { Class cls =Class.forName("包名.ConstructorDemo"); Class partypes[] =new Class[2]; partypes[0] = Integer.TYPE; partypes[1] =Integer.TYPE; Constructor ct=Constructor(partypes); Object arglist[] =new Object[2]; arglist[0] = newInteger(37); arglist[1] = newInteger(47); Object retobj = ct.newInstance(arglist); } catch (Throwable e) { System.err.println(e);} } }2、属性步骤为:通过反射机制得到某个类的某个属性,然后改变对应于这个类的某个实例的该属性值import ng.reflect.*; public class FieldDemo1{ public double d; public static void main(String args[]){ try { Class cls = Class.forName("FieldDemo1"); Field fld = cls.getField("d"); FieldDemo1 fobj = new FieldDemo1(); System.out.println("d = " + fobj.d); fld.setDouble(fobj, 12.34); System.out.println("d = " + fobj.d); } catch (Throwable e){ System.err.println(e); } } }3、方法步骤为:通过反射机制得到某个类的某个方法,然后调用对应于这个类的某个实例的该方法//通过使用方法的名字调用方法import ng.reflect.*; public class MethodDemo1{ public int add(int a, int b){ return a + b; } public static void main(String args[]){ try { Class cls =Class.forName("MethodDemo1"); Class partypes[] = new Class[2]; partypes[0] = Integer.TYPE; partypes[1] = Integer.TYPE; Method meth = cls.getMethod("add",partypes); MethodDemo1 methobj = new MethodDemo1(); Object arglist[] = new Object[2]; arglist[0] = new Integer(37); arglist[1] = new Integer(47); Object retobj= meth.invoke(methobj, arglist); Integer retval = (Integer)retobj; System.out.println(retval.intValue()); } catch (Throwable e) { println(e); } } }三、java反射的应用(Hibernate)我们在第二部分中对java反射进行了比较系统的阐述,也举了几个简单的实例,下面我们就来讨论一下java反射的具体应用。

前面我们已经知道,Java反射机制提供了一种动态链接程序组件的多功能方法,它允许程序创建和控制任何类的对象(根据安全性限制)之前,无需提前硬编码目标类。

这些特性使得反射特别适用于创建以非常普通的方式与对象协作的库。

例如,反射经常在持续存储对象为数据库、XML或其它外部格式的框架中使用。

下面我们就已Hibernate框架为例像大家阐述一下反射的重要意义。

Hibernate是一个屏蔽了JDBC,实现了ORM的java框架,利用该框架我们可以抛弃掉繁琐的sql语句而是利用Hibernate中Session类的save()方法直接将某个类的对象存到数据库中,也就是所涉及到sql语句的那些代码Hibernate帮我们做了。

这时候就出现了一个问题,Hibernate怎样知道他要存的某个对象都有什么属性呢?这些属性都是什么类型呢?如此,它在向数据库中存储该对象属性时的sql语句该怎么构造呢?解决这个问题的利器就是我们的java反射!下面我们以一个例子来进行阐述,比如我们定义了一个User类,这个User类中有20个属性和这些属性的get和set方法,相应的在数据库中有一个User表,这个User表中对应着20个字段。

相关主题