- 浏览: 919835 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (537)
- Java SE (114)
- Struts (18)
- Hibernate (25)
- Spring (3)
- Page_Tech (41)
- Others (87)
- Database (29)
- Server (24)
- OpenSource_Tools (15)
- IDE_Tool (22)
- Algorithm (28)
- Interview (22)
- Test (28)
- Hardware (1)
- Mainframe (25)
- Web application (4)
- Linux (3)
- PHP (17)
- Android (1)
- Perl (6)
- ubuntu (1)
- Java EE (9)
- Web Analysis (5)
- Node.js (2)
- javascript (2)
最新评论
-
一键注册:
request.getRequestURL()和request.getRequestURI() -
SuperCustomer:
...
SED的暂存空间和模式空间 -
juyo_ch:
讲得挺好理解的,学习了
java 死锁及解决 -
chinaalex:
最后一题答案正确,但是分析有误.按照如下过程,上一行为瓶,下一 ...
zz智力题 -
liaowuxukong:
多谢博主啦,弱弱的了解了一点。
C++/Java 实现多态的方法(C++)
一、预先需要掌握的知识(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对象;
方法一:Class c=Class.forName("java.lang.String")
方法二:对于基本数据类型可以用形如Class c=int.class或Class c=Integer.TYPE的语句
方法三:Class c=MyClass.class
2、调用Class中的方法得到你想得到的信息集合,如调用getDeclaredFields()方法得到类的所有属性;
3、处理第2步中得到的信息,然后进行你想做的实际操作。
反射实例:
下面我将针对类的构造器、属性和方法分别举三个例子,向大家演示一下反射的应用过程。
1、构造器
步骤为:通过反射机制得到某个类的构造器,然后调用该构造器创建该类的一个实例
view plaincopy to clipboardprint?
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("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);
}
}
}
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("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、属性
步骤为:通过反射机制得到某个类的某个属性,然后改变对应于这个类的某个实例的该属性值
view plaincopy to clipboardprint?
import java.lang.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);
}
}
}
import java.lang.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、方法
步骤为:通过反射机制得到某个类的某个方法,然后调用对应于这个类的某个实例的该方法
view plaincopy to clipboardprint?
//通过使用方法的名字调用方法
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("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);
}
}
}
//通过使用方法的名字调用方法
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("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的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]的值,然后利用c构造对应该属性的set方法;
4.2、判断list[i]的类型XXX,调用PreparedStament语句中的getXXX(i),进而得到i处字段的值;
4.3、将4.2中得到的值作为4.1中得到的set方法的参数,这样就完成了一个字段向一个属性的赋值,如此循环即可;
看到了吧,这就是反射的功劳,如果没有反射很难想象如果完成同样的功能会有多么难!但是反射也有缺点,比如性能比较低、安全性比较复杂等,这里就不在讨论这些东西,感兴趣的读者可以在网上找到答案,有很多的!
发表评论
-
maven 在Mac OS下运行的问题总结
2014-05-16 17:24 834在maven下生成基本的项目结构。 生成eclipse项 ... -
【zz】 java函数参数类型后添加三点的用法
2012-07-02 09:48 1052今天看到一个没见过的函数参数列表test(int... a), ... -
【zz】Java编码的理解和Java加载器的理解
2012-06-08 15:59 757一,我对java中编码的理解1. 编码的产生 对电脑而言 ... -
类加载器入门级应用
2012-06-08 15:17 9311、类加载器负责加载 Ja ... -
ClassLoader详解
2012-06-08 14:23 1253Point One 将J2EE应用程序移植到W ... -
Java静态代理与动态代理
2012-05-29 10:32 945JAVA的静态代理与动态代 ... -
JDK的动态代理深入解析(Proxy,InvocationHandler)(转)
2012-05-29 10:31 5195调用处理器InvocationHandle ... -
zz 动态反射实现AOP的简单原理
2012-05-28 17:46 904其实AOP的意思就是面向切面编程. OO注重的是我们 ... -
理解Java枚举在单例模式的应用
2012-06-05 15:50 12825.3.9 单例和枚举 按照《高效Java 第二版》中的说 ... -
Java 枚举的介绍
2012-05-23 16:50 0一、使用简单程序完成枚举的功能 例:使用简单类完成枚举操作 ... -
枚举类型的用法
2012-06-05 15:50 1436DK1.5引入了新的类型——枚举。在 Java 中它虽然算 ... -
单例模式的七种写法 (包括1.5新特性)
2012-05-23 16:18 0第一种(懒汉,线程不安全): <!--<br / ... -
重写hashCode方法的意义
2012-05-23 16:01 1652Java中的很多对象都override了equ ... -
JDK Log的设计思想
2012-05-23 14:39 1316最近在看《Agile Java》,看到日志一节,收获颇多,所以 ... -
[zz] Synchronized和Static Synchronized区别
2012-05-23 14:07 790通过分析这两个用法的分析,我们可以理解java中锁的概念。一 ... -
双精度、单精度的有效位数
2012-05-22 17:25 5118浮点数7位有效数字。(应该是单精度数) 双精度数16位有效 ... -
DecimalFormat 使用方法
2012-05-22 16:44 1031我们经常要将数字进行格式化,比如取2位小数,这是最常见的。Ja ... -
Java Applet 无法运行的一个问题
2012-04-28 15:09 2541当你用JDK1.6开发出的新功能,在JDK1.6上re ... -
JDK1.5之中的Map相关的类
2012-04-26 10:14 1872java5的java.util包提供了大量集合类。其中最常用的 ... -
设计模式应用场景总结
2012-04-11 16:47 1276在J2EE的开发和测试中,其实不知不觉已经使用了许多设计模式。 ...
相关推荐
Java反射是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并操作类的对象。在Java中,反射机制提供了强大的能力,包括在运行时检查类的结构、创建对象实例、调用方法以及访问和修改字段值。...
Java反射是Java编程语言中的一个强大工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射主要用于在运行时分析类和对象,包括访问私有成员、调用私有方法、创建对象、获取类...
java反射机制java反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制...
### Java反射性能测试分析 #### 引言 Java反射机制是Java编程语言中一个强大的特性,它允许程序在运行时动态地访问、检测和修改类、接口、字段和方法等对象。然而,反射操作通常会引入额外的开销,这在性能敏感的...
Java反射机制是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这个特性使得Java具有了高度的灵活性和动态性,尤其是在处理元数据、创建对象、调用私有方法...
### Java反射机制详解 #### 一、引言 在Java面试中,经常会出现与反射机制相关的题目。这是因为Java反射机制不仅是Java语言的一项重要特性,也是理解Java动态特性的关键所在。通过本文,我们将深入探讨Java反射...
1.通过Java反射机制获取JavaBean对象。 2.通过JavaBean全路径字符串获取JavaBean对象。 3.获取JavaBean注解信息
"Java反射 JavaBean 对象自动生成插入、更新、删除、查询sql语句操作" Java反射JavaBean对象自动生成插入、更新、删除、查询sql语句操作是指通过Java反射机制,依据提供的表名、POJO类型、数据对象自动生成sql语句...
Java反射是Java编程语言中的一个强大特性,它允许运行时的程序访问并操作类、接口、字段和方法等信息,即使这些信息在编译时并未明确知晓。在Java中,反射通常通过`java.lang.Class`类和相关的API来实现。本实例将...
Java反射是Java语言提供的一种强大的动态类型特性,它允许程序在运行时检查类、接口、字段和方法的信息,并且能够动态地创建对象和调用方法。这个能力使得开发者可以突破静态类型的束缚,实现一些在编译时期无法完成...
Java反射是Java编程语言中的一个强大工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射主要用于在运行时分析类和对象,包括访问私有成员、调用私有方法、创建动态代理等。...
### Java反射机制详解 #### 一、什么是Java反射? Java反射是Java编程语言的一个特性,它允许运行时检查和操作程序结构(类、字段、方法等)。反射的主要用途包括但不限于:动态实例化对象、访问私有成员、调用...
### Java反射机制详解 #### 一、什么是Java反射机制? Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的...
Java反射是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制主要用到了java.lang.Class、java.lang.reflect.Method、java.lang.reflect....
Java反射机制是Java编程语言中的一个强大工具,它允许程序在运行时检查并操作类、接口、字段和方法等对象。在"北大青鸟java反射机制"的学习资料中,我们将会深入探讨这一核心特性。 首先,我们要理解反射的核心概念...
Java反射是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制的核心类集中在java.lang.reflect包下,包括Class、Constructor、Method和Field...
Java反射机制是Java编程语言中一个强大的特性,它允许运行时的程序动态地获取类的信息并操作类的对象。在Java中,反射主要涉及到`java.lang.Class`类、`java.lang.reflect`包下的类如`Constructor`、`Method`和`...
Java反射和动态代理是Java编程中的重要特性,它们在实现高度灵活和动态的代码执行上发挥着关键作用。本文将深入探讨这两个概念,以及如何在实际开发中利用它们。 首先,我们来理解Java反射(Reflection)。Java反射...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、字段和方法的信息,甚至动态地创建对象并调用其方法。通过反射,开发者可以实现高度灵活和动态的代码,这对于框架开发、元编程...