- 浏览: 188548 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
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 1120序列化的必要性 Java中,一切都是对象,在分布式环境中经 ... -
JAVA反射机制的应用(2)
2010-12-07 16:28 1232JAVA反射机制的应用(2 ... -
JAVA反射机制的简单应用(1)
2010-12-06 13:15 1422JAVA反射机制的简单应用(1) Spring中的IOC ... -
Java反射笔记(2)
2010-12-02 09:46 1724java.lang.array提供了动态 ... -
Java反射笔记(1)
2010-12-01 10:54 1135感谢张龙老师的视频:http://www.verycd.com ... -
连接池的基本工作原理及简单实现
2010-11-24 21:25 913连接池的基本工 ... -
Java 继承与组合的区别
2010-11-22 10:36 7985根据网络上大家对 ... -
蛇形矩阵的java实现
2010-11-10 22:22 7868题目: 计算并输出 nXn ... -
两个矩阵的乘积的java实现
2010-11-10 16:23 8330题目: 计算两个矩阵 A、B 的乘积矩阵 C。 ... -
螺旋数组的java实现
2010-11-10 15:26 2091螺旋数组 要求:存储和输出nXm的螺旋数组,其中n和m为 ... -
统计一个整数中出现次数最多最大的数字
2010-11-10 09:31 6539要求: 统计一个整数中出现最多的数字。如果数字个数 ... -
“百元买百鸡问题”之一重循环实现
2010-11-09 10:06 3706问题描述: 每只母鸡 3 元,每只公鸡 4 元,每只小鸡 0 ... -
[转]欧几里得算法(辗转相除法)求最大公约数
2010-11-08 22:52 2867欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数 ... -
[转]深入理解自增自减运算符a=a++和a=++a
2010-11-07 23:04 3227更深入地理解自增自减运算符 首先贴一个非常简洁却 ... -
[转]java中char,byte,short的移位操作
2010-11-07 22:38 4738在Think in Java中有这么一段话“对c ... -
笔试题之以单词为最小单位翻转字符串
2010-11-06 15:39 2390最近做了几个公司 ... -
java解惑之无穷大和NaN
2010-11-01 10:12 17801、i == i + 1 一个数字永远不会等于它自己加1 ... -
java 死锁及解决
2010-10-31 21:28 1122Java线程死锁如何避免 ... -
深入Java关键字null
2010-10-31 14:20 835深入Java关键字null ... -
对java中equals和hashCode函数的一些理解2(转)
2010-10-31 11:24 1048一致性 即如果两个对象相等的话,那么它们必须始终保持相等,除非 ...
相关推荐
本学习笔记主要涵盖了Java的基础知识,包括面向对象、集合、IO流、多线程、反射与动态代理以及Java 8的新特性等方面,旨在帮助初学者或有经验的开发者巩固和提升Java编程技能。 1. 面向对象(OOP):Java的核心是...
java注解和反射的个人学习笔记
Java反射是Java编程语言中的一个强大特性,允许程序在运行时动态地获取类的信息并操作类的对象。在Java中,反射主要用于以下场景:动态加载类、访问私有成员、调用私有方法以及处理泛型等。以下是关于Java反射的一些...
8. **反射机制**:探讨Java反射API的使用,包括动态获取类信息、创建对象、调用方法等功能,这对于理解和调试程序有很大的帮助。 9. **JVM内部机制**:简述Java虚拟机的工作原理,包括类加载、内存管理、垃圾回收...
"Java入门第三季学习笔记"可能涵盖了更多高级话题,如反射、注解、设计模式和Java库的使用。反射允许程序在运行时检查类、接口、字段和方法的信息,提供了更大的灵活性。注解是一种元数据,可以用来提供编译器或运行...
java学习笔记java反射机制
### Java李兴华学习笔记之Java常用类库 #### 一、课程介绍及知识点概览 根据提供的资料,“Java李兴华学习笔记之Java常用类库”这份文档来源于北京MLDN软件实训中心的教学资料,主要涵盖了Java编程语言中常用类库...
本篇笔记将深入探讨Java反射的概念、重要性以及如何使用。 一、反射基础 1. 类加载:当Java虚拟机(JVM)加载一个类时,它会创建该类的Class对象。这个对象包含了关于类的所有信息,包括方法、字段、构造器等。...
本笔记主要涵盖了四个核心知识点:Java反射机制、流(I/O流)、内存管理和Java学习的基础。以下是对这些主题的详细阐述: 一、Java反射机制 Java反射机制是Java语言的一个强大特性,允许程序在运行时检查类、接口、...
《JAVA学习笔记》是林信良先生的一部深入浅出的Java编程教程,旨在帮助初学者和有一定经验的开发者巩固和提升Java编程技能。这本书涵盖了Java语言的基础到高级概念,是一份宝贵的自学资料。 首先,从基础部分开始,...
在“java反射笔记”这个主题中,我们将深入探讨反射的基础知识和常见用法。 首先,我们需要了解什么是反射。在Java中,反射是指在运行时获取类的信息(如类名、方法名、参数类型等)并动态调用对象的方法或访问其...
8. **反射机制**:Java反射API允许在运行时动态访问类的信息,包括类名、方法、字段等。学习笔记会讲解如何使用反射进行元编程,以及其在插件系统、序列化和动态代理中的应用。 9. **Java API和库**:Java标准库...
Java反射机制是Java编程语言的一项重要特性,它允许程序在运行时动态地获取类的信息,并且能够对类的属性和方法进行操作。反射机制的核心在于Java的`java.lang.reflect`包,其中包含了`Class`、`Constructor`、`...
1. **反射**:Java反射机制允许在运行时检查类的信息(如类名、方法、字段等),并能动态调用方法和修改字段值,增强了代码的灵活性。 2. **泛型**:泛型提供了一种在编译时检查类型安全的方法,允许在类、接口和...
"java校招学习笔记"显然是针对应届毕业生或求职者准备的,旨在帮助他们掌握Java的基础知识和校招面试中常见的技术问题。这份笔记可能包含了从基础概念到进阶主题的全面概述,以提高求职者的竞争力。 首先,Java的...
"Java超强学习笔记"显然是一份全面且深入的Java学习资料,由一位极具洞察力和组织能力的作者精心编纂。这份笔记可能包含了从基础知识到高级特性的全方位讲解,旨在帮助学习者构建坚实的Java编程基础,并提升他们的...
这份“Java学习笔记(必看经典).doc”文档将涵盖Java的核心概念和重要知识点,对于初学者和有经验的开发者来说都是宝贵的参考资料。 首先,Java的基础部分通常包括以下几个方面: 1. **Java语法基础**:这是所有...
基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip 基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip 基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码....