- 浏览: 185897 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
netwelfare:
这篇文章关于jsessionid讲解的不错。关于jsessio ...
关于JSessionID【转】 -
ITcms:
Activity直接执行了onCreate方法的那部分,我觉得 ...
Android之Activity学习 -
tinygroup:
Sorry发错了。
蛇形矩阵的java实现 -
tinygroup:
public static int[][] spira ...
蛇形矩阵的java实现 -
laitao:
[*]引用pulic djs
Servlet的生命周期
java反射作用:
1、自省:通过对象自身获得类结构,继而获取并修改字段值,调用方法,构造实例。
2、String->Object:通过类字符串构造类实例
传统创建一个对象 或者是调用对象的一个方法 ,需要在程序里将创建对象的语句,即new一个对象,都需要在程序里面写死,即在程序中硬编码。众所周知,硬编码是一种不好的编程方式,最好的方法是在程序中通过配置信息(String字符串)动态创建对象或是动态调用对象的方法。
Class对象 :类对象,它是JAVA自省机制的起点 , 一个对象要知道自己有什么,首先肯定需要知道自己是什么,即首先获知它是哪个类的对象,那么怎么获知这个对象呢?
这里不得不提到类加载 ,类经过编译后会生成一个Class字节码文件 , 当生成某个类的实例时,首先需要JVM将对应类的Class文件加载 进来,JVM会在类路径下(ClassPath)下根据包名去相应路径下搜索目标类的Class文件,找到后将其读到虚拟机中,这就是所谓的 类加载 ,这样JVM便获知了类的信息。读到JVM中后,更进一步地说,JVM需要将类存起来,即 封装 ,这样JVM便会把类信息封装在一个对象中,这个记录了类信息的对象就是 类对象 ,即Class对象,类对象是JVM加载类的一个产物,只要类对象没有消失,就不需要再加载类对象,这样JVM通过类对象就知道了类的组成结构,继而也就能创建类的实例了。当我们 首次使用某个类的时候才会发生类加载 ,什么才算使用呢?创建一个类的对象,访问一个类的静态属性或者方法,注意声明一个类的引用时不会产生类加载,JVM不需要知道这个类是什么,它只在栈空间中为这个引用分配四个字节就行了,在真正使用类的时候才会加载类。
大家都知道面向对象的一个重要特征便是
封装
,JVM会把类对象中的每个字段封装成一个Field对象,把每个构造方法封装成一个Constructor对象,把每个方法封装成一个Method对象,这些对象再一同封装为类对象,我们可以理解为封装的封装。
程序中如何获取类对象呢?三种方法:
- 类名.class: 八种基本数据类型也通过.class获得类对象,需要注意,int.class和Integer.class是不一样的 , 它们是两个不同的类对象。
- 对象.getClass(): 来获取对象所属类的类对象,这个方法是继承于Object的,因此所有类都拥有这个方法。
- Class.forName(类名字符串): 通过Class的静态方法forName得到类字符串代表的类对象
获 取了类对象之后,我们继而可以获得该类中的Field对象,Constructor对象,Method对象,再通过上面这些对象获得字段,构造方法,方法 的详细信息。这里需要注意的是getFileds()与getDeclaredFields()的区别,其实大家看API也能看到,这里简述一下:
- getDeclaredFields () 返回类中的所有字段对象,甚至包括私有的字段,但是需要注意的是它不会返回父类中的字段。
-
getFields () 返回该类及其父类的公有字段,即public修饰的字段。
获取Method[]以及Constructor[]同样的道理。
另外,获得指定的Method时, 除了传递方法的名字外,还需要传递参数类对象数组 ,以此参数类对象数组来判断调用的是哪个方法,因为方法可以重载嘛,而参数的类型,顺序,个数决定了不同的重载方法。
通过反射,我们 还可以对对象进行一些操作 。上面已经讲到我们可以通过反射获得类成员变量本身的一些信息,这里我们不仅仅是想获得类的结构信息,我们还想获取和修改字段的值,另外可能还要调用某个方法,构造一个对象实例等等。即对此类进行 动态操作 ,我们可以把获取类结构看做对类的 静态操作 。但是要注意,如果类的字段 是private的而且没有提供get和set接口 ,我们还可以操作该字段吗?答案是可以的。
那么我们 怎么获取和修改另外一个类的私有字段呢?
- 首先通过对象获得类对象(调用对象的getClass());
- 接着需要得到私有成员字段包装的Field对象(调用类对象的getDeclaredFields());
- 接下来下面大家可以查看一下Field对象的API,其中有一个get方法:
public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException
参数object指的是针对哪个对象获取相应字段的值,如果你直接通过调用get()并传入对象去获取私有字段的值,会得到 IllegalAccessException 异常。这里我们需要用到另外一个关键的方法: setAccessible(boolean flag) ,该方法来自于Field,Constructor,Method的父类 AccessibleObject ,大致浏览该类的API大家可以发现,该类主要用来对 Field, Constructor,Method的访问控制检测进行压制( It provides the ability to flag a reflected object as suppressing default Java language access control checks when it is used ), 访问控制检测大家应该都知道是什么意思,这里调用setAccessible(true),顾名思义,表示设置可访问性,其是对当前Filed或者 Constructor或者Method对象进行访问控制检测压制,这样我们便可以通过get(Object obj)来获得私有字段的值了。
- 我们还可以设置该字段的值,调用set方法:
public void set(Object obj, Object value) throws IllegalArgumentException, illegalAccessException
进行赋值。
调用私有方法怎么做呢?
- 首先调用类对象的
getDeclaredMethod
(
String
name,
Class
<?>... parameterTypes)
throws
NoSuchMethodException
,
SecurityException
传递两个参数,一个是参数的名字,另外一个是方法的参数类对象数组,用来确定调用的是哪个方法。
- 接着查看Method类的API可以看到invoke方法:
invoke ( Object obj, Object ... args) Invokes the underlying method represented by this Method object, on the specified object with the specified parameters.
这里需要传递两个参数,第一个参数表示对哪个对象调用invoke方法,第二参数是一个Object数组,即参数值 。返回一个Object对象,即调用方法的返回值。如果调用的是一个void方法,那么调用invoke方法返回的是null。
如何通过类对象创建实例呢? 第一种方法:直接调用类对象的newInstance()来构造一个实例。不知道大家注意到没有,创建实例的时候并没有传递参数,也就是说原来的类中必须有一个无参数的构造方法,否则该方法不能调用,那么带参数的构造方法怎么调用呢?
第二种方法:通过类对象调用:
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
传递的参数大家应该都清楚了,和上面获取指定Method一样,传递一个参数类对象数组,用于确认到底获取那个构造方法。接下来,再调用Constructor的
public T newInstance(Object... initargs) throws InstantiationException,
LegalAccessException,IllegalArgumentException, InvocationTargetException
并传递参数就可以创建对象了。
大家 现在应该知道JAVABean中为什么要必须包含一个无参的构造方法以及包含一系列public的get,set方法了,这样 工具便可以通过反射使用类对象的newInstance直接创建对象了,同时由于方法名都是有规律的,只要知道字段名,便可以通过构造get/set+字段名(首字母大写)字符串得到对应字段的Method对象,继而调用它们来获取和设置值了 ,这一切都可以由工具自动来完成。
发表评论
-
Java序列化机制和原理【转】
2011-05-18 09:14 1075序列化的必要性 Java中,一切都是对象,在分布式环境中经 ... -
JAVA反射机制的应用(2)
2010-12-07 16:28 1186JAVA反射机制的应用(2 ... -
JAVA反射机制的简单应用(1)
2010-12-06 13:15 1372JAVA反射机制的简单应用(1) Spring中的IOC ... -
Java反射笔记(2)
2010-12-02 09:46 1685java.lang.array提供了动态 ... -
Java反射笔记(1)
2010-12-01 10:54 1095感谢张龙老师的视频:http://www.verycd.com ... -
连接池的基本工作原理及简单实现
2010-11-24 21:25 870连接池的基本工 ... -
Java 继承与组合的区别
2010-11-22 10:36 7938根据网络上大家对 ... -
蛇形矩阵的java实现
2010-11-10 22:22 7809题目: 计算并输出 nXn ... -
两个矩阵的乘积的java实现
2010-11-10 16:23 8289题目: 计算两个矩阵 A、B 的乘积矩阵 C。 ... -
螺旋数组的java实现
2010-11-10 15:26 2044螺旋数组 要求:存储和输出nXm的螺旋数组,其中n和m为 ... -
统计一个整数中出现次数最多最大的数字
2010-11-10 09:31 6493要求: 统计一个整数中出现最多的数字。如果数字个数 ... -
“百元买百鸡问题”之一重循环实现
2010-11-09 10:06 3669问题描述: 每只母鸡 3 元,每只公鸡 4 元,每只小鸡 0 ... -
[转]欧几里得算法(辗转相除法)求最大公约数
2010-11-08 22:52 2812欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数 ... -
[转]深入理解自增自减运算符a=a++和a=++a
2010-11-07 23:04 3185更深入地理解自增自减运算符 首先贴一个非常简洁却 ... -
[转]java中char,byte,short的移位操作
2010-11-07 22:38 4706在Think in Java中有这么一段话“对c ... -
笔试题之以单词为最小单位翻转字符串
2010-11-06 15:39 2347最近做了几个公司 ... -
java解惑之无穷大和NaN
2010-11-01 10:12 17431、i == i + 1 一个数字永远不会等于它自己加1 ... -
java 死锁及解决
2010-10-31 21:28 1094Java线程死锁如何避免 ... -
深入Java关键字null
2010-10-31 14:20 805深入Java关键字null ... -
对java中equals和hashCode函数的一些理解2(转)
2010-10-31 11:24 1021一致性 即如果两个对象相等的话,那么它们必须始终保持相等,除非 ...
相关推荐
java注解和反射的个人学习笔记
java学习——java中的反射学习笔记
目录1. 获取类类型2. 获取类内部信息2.1 构造函数2.1.1 获取构造函数2.1.2 使用构造函数构造实例2.2 Field 对象2.2.1 获取 Field 对象2.2.2 Field 的 set,get 操作2.3 Method 对象2.2.1 获取 Method 对象2.2.2 ...
java学习笔记java反射机制
这是一年多以来学习java和在项目中遇到问题之后总结出的一系列资料。包含:java 反射机制 流 内存管理等信息。
java反射学习的一些基础代码,简单使用反射的案例,为eclipse中的工作空间,编码GBK
基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip 基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip 基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码....
java反射机制
java学习笔记 [Java学习笔记doc]之反射机制
轻松掌握java反射技术,虽然讲得比较简单,但是通俗易懂。
Java反射机制总结(实例分析) Java反射机制学习笔记
java语言反射与动态代理学习笔记
注解与反射—狂神说Java学习笔记
7.13. 反射 7-37 8. 七•异常 8-37 8.1. 异常的基本概念 8-37 8.2. 捕获异常 8-38 8.3. 处理异常 8-38 8.4. 捕捉多个异常 8-38 8.5. finally 声明 8-38 8.6. 异常调用栈 8-39 8.7. 异常层次 8-39 8.8. 一些未检查的...
《java jdk 7学习笔记》适合java的初中级读者,以及广大java应用开发人员。 作译者 林信良(网名:良葛格) 学历:台湾大学电机工程学系 经历:台湾升阳教育训练技术顾问、专业讲师,oracle授权训练中心讲师 ...
JAVAWEB反射学习笔记中使用的java文件,用于演示反射的各种效果
关于Java反射的笔记,在学习java者可以看看
Java 基础学习笔记,主要包括: 10_Java常见对象.md 10_Java常见对象_2.md 1_数据类型.md 3_运算.md 4_Object通用方法.md 5_关键字.md 6_反射.md 8_泛型.md JDK8新特性.md 正则表达式.md Java是一种面向对象的编程...