再叙Java反射
Java中的反射
本文为反射的基础知识部分。
能够分析类能力的程序被称为反射(reflective)。
反射机制允许程序在运行时取得任何一个已知名称的class的内部信息,容许程序在运行时加载、探知、使用编译期间未知的class。即Java的反射机制可以加载一个运行时才得知名称的class,获得其完整结构。
一.Class类
在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识。
这个信息保存着每个对象所属的类足迹。虚拟机利用运行时信息选择相应的方法执行。
然而,可以通过专门的Java类访问这些信息。保存这些信息的类称为Class.
(注:新版本为Class<T>,本文中经常为了方便只写Class)
API: java.lang.Class
(1.7)http://docs.oracle.com/javase/7/docs/api/index.html
获取类的Class对象的方法:
|
调用getClass() (Object类中的getClass()方法返回一个Class类型的实例) |
Boolean var1 = true;Class<?> classType2 = var1.getClass();System.out.println(classType2);输出:class java.lang.Boolean |
|
运用T.class 语法 (T是任意的Java类型) |
Class<?> classType4 = Boolean.class;System.out.println(classType4);输出:class java.lang.Boolean |
|
运用static method Class.forName() (使用时应该提供异常处理器) |
Class<?> classType5 = Class.forName("java.lang.Boolean");System.out.println(classType5);输出:class java.lang.Boolean |
|
运用primitive wrapper classes的TYPE 语法 (这里返回的是原生类型,和Boolean.class返回的不同) |
Class<?> classType3 = Boolean.TYPE;System.out.println(classType3);输出:boolean |
一个Class对象实际上表示的是一个类型,而这个类型未必一定是一种类。
例如,int不是类,但int.class是一个Class类型的对象。
虚拟机为每个类型管理一个Class对象。因此,可以用==运算符实现两个类对象比较的操作(不同的类加载器加载同一class文件得到的class肯定不同)。
最常用的Class方法:
|
方法 |
说明 |
例子 |
|
getName() |
返回类的名字 |
String.class.getName(); 返回: "java.lang.String" |
|
newInstance() |
快速地创建一个类的实例 (调用默认构造器,如果该类没有默认构造器,抛出异常) (如果要为构造器提供参数,使用java.lang.reflect.Constructor中的newInstance方法) |
String s = "java.util.Date"; Object m = Class.forName(s).newInstance(); |
|
getSuperclass() |
返回超类 |
|
|
getFields()getMethods()getConstructors()(还有带字符串参数,给定名称的形式) |
分别返回类支持的public域、方法和构造器数组,其中包括超类的公有成员 |
|
|
getDeclaredFields() getDeclaredMethods() getDeclaredConstructors() (还有给定名称的形式) |
分别返回类中声明的全部域、方法和构造器数组。其中包括私有和保护成员,但不包括超类的成员 |
二.java.lang.reflect包
上文中提到的Class类中的getFields()、getMethods()、getConstructors()方法的返回值都是特定类型(Field、Method、Constructor类)的数组类型。
Field、Method、Constructor类,分别用于描述类的域、方法和构造器,都在java.lang.reflect包中。
java.lang.reflect包提供反射相关的API,1.7.0的reflect包如下图:
(http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/package-frame.html)
2.1使用反射分析类
如前所述,Field、Method、Constructor类,分别用于描述类的域、方法和构造器。另外java.lang.reflect包中的Modifier类可以分析访问修饰符。那么用它们就可以分析类。
分析类常用的方法:
| 类 | 方法 | 作用 |
| FieldMethodConstructor | Class getDeclaringClass() | 返回一个用于描述类中定义的构造器、方法或域的Class对象 |
| String getName() | 返回相应条目的名称 | |
| int getModifiers() | 返回整型数值,用不同的位开关描述访问修饰符的使用状况 | |
|
Method Constructor |
Class[] getExceptionTypes() |
返回一个用于描述方法抛出的异常类型的Class对象数组 |
|
Class[] getParameterTypes() |
返回一个用于描述参数类型的Class对象数组 |
|
|
Field |
Class getType() |
用于返回描述域所属类型的Class类型对象 |
|
Modifier |
static String toString(int modifiers) |
返回对应modifiers位设置的修饰符的字符串表示 |
|
Static boolean isXXX(int modifiers) |
检测方法名中对应的修饰符在modifiers中的值 |
2.2使用反射分析对象
2.1节已经知道如何查看任意对象的数据域名称和类型,在本节中,将进一步查看数据域的实际内容。利用反射机制可以查看在编译时还不清楚的对象域。
查看对象域的关键方法是Field类中的get方法。
如果f是一个Field类型的对象(例如,通过getField(String name)得到的对象),obj是某个包含f域的类的对象,那么f.get(obj)将返回一个对象,其值为obj的f域的当前值。
可以获取就可以设置,调用f.set(obj,value)可以将obj对象的f域设置成新值。
访问权限问题
上面所说的例子中,如果该域为一个私有域,get方法将会抛出一个异常。
这是因为反射机制的默认行为受限于Java的访问控制,比如,除非拥有访问权限,否则Java安全机制允许查看任意对象有哪些域,而不允许读它们的值。
然而如果一个Java程序没有受到安全管理器的控制,就可以覆盖访问控制。为了达到这个目的,就需要调用Field、Method、Constructor对象的setAccessible方法。
Field、Method、Constructor类都派生自AccessibleObject.
AccessibleObject常用方法:
|
函数 |
作用 |
|
void setAccessible(boolean flag) |
为反射对象设置可访问标志,flag为true表明屏蔽Java语言的访问检查,使得对象的私有属性也可以被查询和设置 |
|
boolean isAccessible() |
返回反射对象的可访问标志的值 |
|
static void setAccessible(AccessibleObject[] array, boolean flag) |
一种设置对象数组可访问标志的快捷方法 |
原文请见http://www.cnblogs.com/mengdd/archive/2012/08/18/2645553.html
再叙Java反射的更多相关文章
- Android简易注解View(java反射实现)
一.引言 Android中通过findViewById在布局文件中找到需要的View,加入一个Activity里面有许多的View需要初始化,那将是一件很繁琐的事情.当然Google一下你会发现有很多 ...
- Java反射举例
本文參考:http://www.cnblogs.com/yydcdut/p/3845430.html 1.Java反射的基本介绍 Java的反射很强大,传递class. 能够动态的生成该类.取得这个类 ...
- java反射知识点总结
一.java反射基础 1.1 什么叫java反射? 答:程序运行期间,动态的获取类的基本信息.比如:创建对象,调用类的方法,获得类的基本结构.这样给程序设计提供了很大的灵活性.个人总结就是:根据动态需 ...
- 再回首,Java温故知新(十一):Java反射
最近继续回顾Java基础,进行到了Java反射这一部分,个人感觉这部分应该算是Java的高级特性了,在日常开发中使用的并不多,应用人员主要是工具构建人员,所以这次学习中以了解为主,Java反射主要应用 ...
- Java反射机制
Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射: 静态编译:在编译时确定类型,绑定对象,即通过 ...
- [转]Java反射之如何判断类或变量、方法的修饰符(Modifier解析)
Java针对类.成员变量.方法,有很多修饰符,例如public.private.static.final.synchronized.abstract等,这些修饰符用来控制访问权限或其他特性. 本文就用 ...
- java反射机制深入详解
java反射机制深入详解 转自:http://www.cnblogs.com/hxsyl/archive/2013/03/23/2977593.html 一.概念 反射就是把Java的各种成分映射成 ...
- java 反射的应用 以及通过反射 用到的工厂模式
java反射详解 本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案 ...
- [转]java反射机制
原文地址:http://www.cnblogs.com/jqyp/archive/2012/03/29/2423112.html 一.什么是反射机制 简单的来说,反射机制指的是程序在运 ...
随机推荐
- JavaScript 遍历多维数组
基于ECMAScript5提供遍历数组的forEach方法仅能遍历一维数组,没有提供循环遍历多维数组的方法,所以根据白鹤翔老师的讲解,实现如下遍历多维数组的each方法,以此遍历多维数组. <s ...
- 搭建LNMP;搭建WIKI
#!/bin/bash#lnmp搭建#搭建WIKI 1.系统检测,系统环境优化 搭建版本: nginx-1.8.1.tar.gzmysql-5.5.32-linux2.6-x86_64.tar.gzl ...
- 修改MySQL 5.7.9版本的root密码方法以及一些新变化整理
MySQL 5.7版本开始,增强密码验证机制,网上说安装的时候会在/root/.mysql_secret 文件中生成默认密码,这一点自 5.7.6版本以后也去掉了. 针对如果生成默认密码,网上有一个 ...
- 基于opencv和mfc的摄像头采集代码(GOMFCTemplate2)持续更新
编写带界面的图像处理程序,选择opencv+mfc是一种很好的选择:在读取摄像头数据方面,网上的方法很多,其中shiqiyu的camerads的方法是较好的. 基于现有资料 ...
- uImage和zImage的区别
1.各种文件的意义 vmlinux 编译出来的最原始的内核文件,未压缩. zImage 是vmlinux经过gzip压缩后的文件. bzImage bz表示“big zImage”,不是用bzi ...
- Zabbix实战-简易教程--动作(Actions)--自动发现
一.概述 Zabbix提供了有效和非常灵活的网络自动发现功能. 设置网络发现后你可以: 加快Zabbix部署(自动添加主机.添加模板) 简化管理(自动删除主机.删除模板.禁用主机) 无需过多管理就能在 ...
- virtio 简介
我的微信公众号 aCloudDeveloper 专注于云计算技术,互联网技术,生活感悟,打造干货分享平台,每周至少一更,欢迎小伙伴们多多关注! 什么是 virtio virtio 是一种 I/O 半虚 ...
- 前端基于react,后端基于.net core2.0的开发之路(番外篇) 后端使用T4模板,生成某些类
1.介绍 因为开发过程中,有部分类是你加一个模型,就需要去改动的,每次加非常的烦,或者有些类,你只用到了他基类的方法,但是你还必须建一个文件才能调用他基类的方法,也很烦. 这个时候,T4就非常有用了. ...
- 12、ABPZero系列教程之拼多多卖家工具 拼团提醒功能登录拼多多实现
上篇文章已经完成了整个拼多多拼团提醒功能,本篇继续完成拼多多帐号登录,拼多多帐号登录的目的是为了获取拼团商品的SKU和订单号,便于商家备货. 以下是拼多多官方的后台登录,要实现的功能并不是直接在这里登 ...
- c/s与b/s 动态网站与静态网站 (网站编码统一“UTF-8”)
1.c/s和b/s 第一张图是b/s 可以随时随地的浏览 (在服务器增加网页就能增加功能,只要改变网页就能使用户同步更新,共享性也强,开发也简单,在广域网和局域网都能建造b/s结构,然后通过int ...