一、预先需要掌握的知识(java虚拟机) 

  1)java虚拟机的方法区: 

  java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区。方法区的主要作用是存储被装载的类 的类型信息,当java虚拟机装载某个类型的时候,需要类装载器定位相应的class文件,然后将其读入到java虚拟机中,紧接着虚拟机提取class 中的类型信息,将这些信息存储到方法区中。这些信息主要包括:

  1. 这个类型的全限定名
  2. 这个类型的直接超类的全限定名
  3. 这个类型是类类型还是接口类型
  4. 这个类型的访问修饰符
  5. 任何直接超接口的全限定名的有序列表
  6. 该类型的常量池
  7. 字段信息
  8. 方法信息
  9. 除了常量以外的所有类变量
  10. 一个到class类的引用

  等等(读者可以参考《深入java虚拟机》这本书的叙述)

  2)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() -- 获得类声明的所有方法

  4)应用反射的基本步骤: 

  1、获得你想操作的类的Class对象;

    方法一:Classc=Class.forName("java.lang.String") //这种方式获得类的Class对象需要 包名.类名

    方法二:对于基本数据类型可以用形如Class c=int.class或Class c=Integer.TYPE的语句

    方法三:Class c=MyClass.class

  2、调用Class中的方法得到你想得到的信息集合,如调用getDeclaredFields()方法得到类的所有属性;

  3、处理第2步中得到的信息,然后进行你想做的实际操作。

  三、反射实例: 

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

  1)构造器

  步骤为:通过反射机制得到某个类的构造器,然后调用该构造器创建该类的一个实例

package cn.test.reflect;

import java.lang.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("cn.test.reflect.ConstructorDemo"); // 这里一定要加上包名
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Constructor ct = cls.getConstructor(partypes);
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj = ct.newInstance(arglist);
} catch (Throwable e) {
System.err.println(e);
}
}
}

  2)属性

  步骤为:通过反射机制得到某个类的某个属性,然后改变对应于这个类的某个实例的该属性值

package cn.test.reflect;

import java.lang.reflect.*;

public class FieldDemo1 {
public double d; public static void main(String args[]) {
try {
Class cls = Class.forName("cn.test.reflect.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)方法

  步骤为:通过反射机制得到某个类的某个方法,然后调用对应于这个类的某个实例的该方法

package cn.test.reflect;

//通过使用方法的名字调用方法
import java.lang.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("cn.test.reflect.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) {
System.err.println(e);
}
}
}

  四、java反射的应用(Hibernate) 

  我们在第二部分中对java反射进行了比较系统的阐述,也举了几个简单的实例,下面我们就来讨论一下java反射的具体应用。前面我们已经知 道,Java反射机制提供了一种动态链接程序组件的多功能方法,它允许程序创建和控制任何类的对象(根据安全性限制)之前,无需提前硬编码目标类。这些特 性使得反射特别适用于创建以非常普通的方式与对象协作的库。例如,反射经常在持续存储对象为数据库、XML或其它外部格式的框架中使用。下面我们就已 Hibernate框架为例像大家阐述一下反射的重要意义。 
  Hibernate是一个屏蔽了JDBC,实现了ORM【对象关系映射(Object/Relation Mapping)】的java框架,利用该框架我们可以抛弃掉繁琐的sql语句而是利用Hibernate中 Session类的save()方法直接将某个类的对象存到数据库中,也就是所涉及到sql语句的那些代码Hibernate帮我们做了。这时候就出现了 一个问题,Hibernate怎样知道他要存的某个对象都有什么属性呢?这些属性都是什么类型呢?如此,它在向数据库中存储该对象属性时的sql语句该怎 么构造呢?解决这个问题的利器就是我们的java反射! 
  下面我们以一个例子来进行阐述,比如我们定义了一个User类,这个User类中有20个属性和这些属性的get和set方法,相应的在数据库中 有一个User表,这个User表中对应着20个字段。假设我们从User表中提取了一条记录,现在需要将这条记录的20个字段的内容分别赋给一个 User对象myUser的20个属性,而Hibernate框架在编译的时候并不知道这个User类,他无法直接调用myUser.getXXX或者 myUser.setXXX方法,此时就用到了反射,具体处理过程如下:

  1. 根据查询条件构造PreparedStament语句,该语句返回20个字段的值;
  2. Hibernate通过读取配置文件得到User类的属性列表list(是一个String数组)以及这些属性的类型;
  3. 创建myUser所属类的Class对象c;c=myUser.getClass();
  4. 构造一个for循环,循环的次数为list列表的长度;

    4.1 读取list[i]的值,然后构造对应该属性的set方法;

    4.2 判断list[i]的类型XXX,调用PreparedStament语句中的getXXX(i),进而得到i出字段的值;

    4.3 将4.2中得到的值作为4.1中得到的set方法的参数,这样就完成了一个字段像一个属性的赋值,如此循环即可;

  看到了吧,这就是反射的功劳,如果没有反射很难想象如果完成同样的功能会有多么难!但是反射也有缺点,比如性能比较低、安全性比较复杂等。

  参考资料:http://blog.csdn.net/lilin_xdu/article/details/6872785

【java基础】Java反射机制的更多相关文章

  1. java基础之反射机制

    一.概念 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...

  2. java基础篇---反射机制

    一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反 ...

  3. Java基础教程——反射机制

    Java反射机制 Java反射机制是Java语言的一个重要特性,使得Java语言具备"动态性": 在运行时获取任意一个对象所属的类的相关信息; 在运行时构造任意一个类的对象: 在运 ...

  4. 【Java基础】反射机制

    反射 反射可以使我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码链接.反射允许我们在编写和执行时,使我们的代码能够接入装载到JVM中的类的内部信息,而不是源代码中选定的类 ...

  5. [ 原创 ] Java基础7--Java反射机制主要提供了以下哪些功能?

    AVA反射机制主要提供了以下哪些功能? 在运行时判断一个对象所属的类 在运行时构造一个类的对象 在运行时判断一个类所具有的成员变量和方法 在运行时调用一个对象的方法

  6. Java基础加强-反射机制

    反射的基石 -> Class 类(字节码)/*只要是在源程序中出现的类型,都要各自的Class实例对象,例如:int,int[],void*/如何得到各个字节码对应的实例对象(Class类型) ...

  7. 【Java基础】java中的反射机制与动态代理

    一.java中的反射机制 java反射的官方定义:在运行状态下,可以获取任意一个类的所有属性和方法,并且可通过某类任意一对象实例调用该类的所有方法.这种动态获取类的信息及动态调用类中方法的功能称为ja ...

  8. 浅说Java中的反射机制(二)

    写过一篇Java中的反射机制,不算是写,应该是抄了,因为那是别人写的,这一篇也是别人写的,摘抄如下: 引自于Java基础--反射机制的知识点梳理,作者醉眼识朦胧.(()为我手记) 什么是反射? 正常编 ...

  9. 黑马程序员:Java基础总结----反射

    黑马程序员:Java基础总结 反射   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 反射 反射的基石:Class类 Class类代表Java类,它的各个实例对象又分别 ...

  10. Java基础之一反射

    反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))   一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够 ...

随机推荐

  1. JS构造函数内的方法与构造函数prototype属性上方法的对比

    本文的目的是让大家理解什么情况下把函数的方法写在JavaScript的构造函数上,什么时候把方法写在函数的 prototype 属性上;以及这样做的好处. 为了阅读方便,我们约定一下:把方法写在构造函 ...

  2. [Canvas]走近的女孩

    动态效果请点此下载文件并使用Chrome或者FireFox浏览器观看. 图例: 代码: <!DOCTYPE html> <html lang="utf-8"> ...

  3. MongoDB数据库遭大规模勒索攻击,被劫持26000多台服务器 #精选GITHUBMYSQL

    昨天,一个大新闻爆出,MongoDB数据库叕被攻击了.就在上周末,三个黑客团伙劫持了MongoDB逾26000多台服务器,其中规模最大的一组超过22000台. “MongoDB启示录”再临?   此次 ...

  4. logback-kafka-appender

    logback 日志写入kafka队列 logback-kafka-appender Logback incompatibility Warning Due to a bug in logback-c ...

  5. 公共Maven库

    <repository><id>codelds</id><url>https://code.lds.org/nexus/content/groups/m ...

  6. iOS DES ECB 模式加密

    //iOS DES ECB 模式加密 #import <CommonCrypto/CommonCryptor.h> ,,,,,,,}; +(NSString *) encryptUseDE ...

  7. Mysql删除所有表

    SELECT CONCAT('DROP TABLE IF EXISTS ', table_name, ';') FROM information_schema.tables WHERE table_s ...

  8. Mongodb3安装授权

    (1) mongodb 官网下载解压包mongodb-win32-x86_64-3.0.7.zip解压释放在d盘,目录为mongodb,接下来手动创建data文件夹和log文件夹分别用于存放数据和日志 ...

  9. JavaScript公共函数

    [在此处输入文章标题] // JScript 文件 /* ================================================================== JS 公 ...

  10. WINDOWS7 下 xclient 802.1x 客户端 停止运行的解决办法

    昨天下午,由于FOXMAIL 出现问题,修改了一个地方,导致xclient 停止运行.具体解决办法如下:右击“计算机”-进入“系统属性”-->“高级”-->"设置"-- ...