java的反射机制(第三篇)
本文转载自:http://c.biancheng.net/cpp/html/1782.html
Person p=new Person();
这是什么?当然是实例化一个对象了。可是这种实例化对象的方法存在一个问题,那就是必须要知道类名才可以实例化它的对象,这样我们在应用方面就会受到限制。那么有没有这样一种方式,让我们不知道这个类的类名就可以实例化它的对象呢?Thank Goodness!幸亏我们用的是java,java就提供了这样的机制。
- java程序在运行时可以获得任何一个类的字节码信息,包括类的修饰符(public、static等)、基类(超类、父类)、实现的接口、字段和方法等信息。
- java程序在运行时可以根据字节码信息来创建该类的实例对象,改变对象的字段内容和调用对象方法。
这样的机制就叫反射技术。可以想象光学中的反射,就像我们照镜子,镜子中又出现一个自己(比喻可能不太恰当,但是足以表达清楚意思了)。 。
Java的反射机制是通过反射API来实现的,它允许程序在运行过程中取得任何一个已知名称的类的内部信息。反射API位于java.lang.reflect包中。主要包括以下几类:
- Constructor类:用来描述一个类的构造方法。
- Field类:用来描述一个类的成员变量。
- Method类:用来描述一个类的方法。
- Modifer类:用来描述类内各元素的修饰符。
- Array:用来对数组进行操作。
Constructor,Field,Method这三个类都是JVM(虚拟机)在程序运行时创建的,用来表示加载类中相应的成员。这三个类都实现了java.lang.reflect.Member接口,Member接口定义了获取类成员或构造方法等信息的方法。要使用这些反射API,必须先得到要操作的对象或类的Class类的实例。通过调用Class类的newInstance方法(只能调用类的默认构造方法)可以创建类的实例。这样有局限性,我们可以先从类的Class实例获取类需要的构造方法,然后在利用反射来创建类的一个实例。
一. 获取类的构造方法的Constructor对象(数组)
- Constructor[] getDeclaredConstructors():返回已加载类声明的所有的构造方法的Constructor对象数组。
- Constructor getDeclaredConstructor(Class[] paramTypes):返回已加载类声明的指定构造方法的Constructor对象,paramTypes指定了参数类型。
- Constructor[] getConstructors():返回已加载类声明的所有的public类型的构造方法的Constructor对象数组。
- Constructor getConstructor(Class[] paramTypes):返回已加载类声明的指定的public类型的构造方法的Constructor对象,paramTypes指定了参数类型。
如果某个类中没有定义构造方法,第一个和第三个方法返回的数组中只有一个元素,就是缺省的构造方法;如果某个类中只定义了有参数的构造函数,而没有定义缺省构造函数,第一个和第三个方法返回的数组中不包含缺省的构造方法。
例子:
import java.lang.reflect.*;
public class DumpMethods {
public static void main(String[] args) {
try{
if(args.length<1){
System.out.println("请输入完整的类名:");
return;
}
Class strClass=Class.forName(args[0]);
//检索带有指定参数的构造方法
Class[] strArgsClass=new Class[]{ byte[].class,String.class};
Constructor constructor=strClass.getConstructor(strArgsClass);
System.out.println("Constructor:"+constructor.toString()); //调用带有参数的构造方法创建实例对象object
byte[] bytes="java就业培训".getBytes();
Object[] strArgs=new Object[]{bytes,"gb2312"};
Object object=constructor.newInstance(strArgs);
System.out.println("Object"+object.toString());
}catch(Exception e){
e.printStackTrace();
}
}
}
二. 获取类成员变量的Field对象(数组)
- Field[] getDeclaredFields():返回已加载类声明的所有成员变量的Field对象数组,不包括从父类继承的成员变量。
- Field getDeclaredField(String name):返回已加载类声明的所有成员变量的Field对象,不包括从父类继承的成员变量,参数name指定成员变量的名称。
- Field[] getFields():返回已加载类声明的所有public型的成员变量的Field对象数组,包括从父类继承的成员变量。
- Field getField(String name):返回已加载类声明的所有成员变量的Field对象,包括从父类继承的成员变量,参数name指定成员变量的名称。
例子:
import java.lang.reflect.*;
public class ReflectTest {
private String name;
private String age;
public ReflectTest(String name,String age){
this.name=name;
this.age=age;
} public static void main(String[] args) {
// TODO 自动生成方法存根
try{
ReflectTest rt=new ReflectTest("zhanghandong","shiba");
fun(rt);
}catch(Exception e){
e.printStackTrace();
}
}
public static void fun(Object obj) throws Exception{
Field[] fields=obj.getClass().getDeclaredFields();
System.out.println("替换之前的:");
for(Field field:fields){
System.out.println(field.getName()+"="+field.get(obj));
if(field.getType().equals(java.lang.String.class)){
field.setAccessible(true); //必须设置为true才可以修改成员变量
String org=(String)field.get(obj);
field.set(obj,org.replaceAll("a","b"));
} }
System.out.println("替换之后的:");
for(Field field:fields){
System.out.println(field.getName()+"="+field.get(obj));
}
}
}
三. 获取类的方法的Method对象(数组)
- Method[] getDeclaredMethods():返回已加载类声明的所有方法的Method对象数组,不包括从父类继承的方法。
- Method getDeclaredMethod(String name,Class[] paramTypes):返回已加载类声明的所有方法的Method对象,不包括从父类继承的方法,参数name指定方法的名称,参数paramTypes指定方法的参数类型。
- Method[] getMethods():返回已加载类声明的所有方法的Method对象数组,包括从父类继承的方法。
- Method getMethod(String name,Class[] paramTypes):返回已加载类声明的所有方法的Method对象,包括从父类继承的方法,参数name指定方法的名称,参数paramTypes指定方法的参数类型。
四. 检索类的其他信息
- int getModifiers():返回已加载类的修饰符的整形标识值。
- Package getPackage():返回已加载类的包名。
- Class getSuperclass():返回已加载类的父类的Class实例。
- Class [] getInterfaces():返回已加载类实现的接口的Class对象数组。
- boolean isInterface():返回已加载类是否是接口。
反射的功能很强大,但是使用不当可能会缺点大于优点,反射使代码逻辑混乱,会带来维护的问题。
java的反射机制(第三篇)的更多相关文章
- Java高级特性——反射机制(第三篇)
获取类运行时的结构 通过反射获取运行时类的完整结构 Field.Method.Constructor.Superclass.Interface.Annotation >实现的全部接口 >所 ...
- Java的反射机制(应用篇)
Java的的反射机制,是一个很难但却比较有用的概念.反射机制经常出现在框架设计中,大神说:反射是框架设计的灵魂,也就是说要想看懂框架的源代码,必须得掌握反射机制. 作为初学者的我,觉得至少应该掌握它日 ...
- 深入浅出学习hibernate框架(三):java的反射机制
上篇博客写到了JDBC的基本操作,今天准备写一篇关于JAVA反射机制的文章,因为java的反射机制和上一篇JDBC都是Hibernate框架的基本要素.在Hibernate的运行机制中,这两块的内容正 ...
- Java 类反射机制分析
Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...
- Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别
一.Java的反射机制 每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图: 其中
- 014 Java的反射机制
作者:nnngu GitHub:https://github.com/nnngu 博客园:http://www.cnblogs.com/nnngu 简书:https://www.jianshu.com ...
- java笔记--反射机制之基础总结与详解
一.反射之实例化Class类的5种方式: java的数据类型可以分为两类,即引用类型和原始类型(即基本数据类型). 对于每种类型的对象,java虚拟机会实例化不可变的java.lang.Class对象 ...
- Java高新技术 反射机制
Java高新技术 反射机制 知识概要: (1)反射的基石 (2)反射 (3)Constructor类 (4)Field类 (5)Method类 (6)用反射方 ...
- 【转】Java利用反射机制访问私有化构造器
Java利用反射机制访问私有化构造器 博客分类: java 我们都知道,当一个类的构造方法被设为私有的时候(private),在其他类中是无法用new来实例化一个对象的. 但是有一种方法可以把带有 ...
随机推荐
- container_of分析【转】
转自:http://blog.csdn.net/tigerjibo/article/details/8299589 1.container_of宏 1> Container_of在Linux内核 ...
- 利用github pages五分钟建好个人网站+个人博客
笔者自己在建个人网站/个人博客的时候其实遇到了不少麻烦,但是都一一解决了,这里教给大家最简单的方式. 首先你需要一个GitHub账号,访问https://github.com创建新账号即可. 然后访问 ...
- Genymotion上不能安装APK软件的问题
Genymotion模拟器不能安装APK的原因 官网给出的解释:Genymotion模拟器使用的是x86架构,在第三方市场上的应用有部分不采用x86这么一种架构,所以在编译的时候不通过,报“APP n ...
- Mac上删除不了的文件,Windows上也粉碎不了怎么办?
推荐一个Mac上的软件:Tuxera Disk Manager 用法很简单:选择删除文件原来所在的文件进行维护就可以了. 维护之后,在废纸篓中清除,成功.
- 【小程序开发】上拉加载更多demo
wxml: <scroll-view class='swiper-scroll' scroll-y="{{true}}" bindscrolltolower="lo ...
- 使用Jsoup解析出html中的img元素
jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据. 博客项目 ...
- Java事务管理之Hibernate
环境与版本 Hibernate 版本:Hibernate 4.2.2 (下载后的文件名为hibernate-release-4.2.2.Final.zip,解压目录hibernate-release- ...
- 消息 8101,级别 16,状态 1,第 1 行仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表'CUSTOMER_TBL'中的标识列指定显式值。
像这样的问题怎么解决呢? 问题分析: 意思是你的主键是自动编号类型的,所以不能向该列插入数据. 解决办法: 执行 语句 :SET IDENTITY_INSERT CUSTOMER_TBL ON 然后在 ...
- MySQL学习笔记:upper、lower、ucase、lacase——字符串函数
在MySQL中,通过利用upper.lower.ucase.lacase几个函数对字符串进行大小写转换. upper(str)——根据当前字符集映射返回字符串str,并将所有字符更改为大写.默认值是l ...
- SSIS 学习之旅 FTP文件传输-脚本任务
这一章主要讲解一下用脚本怎么把CSV文件抛送到FTP服务器上 设计: 通过Demon库的Users表数据生成CSV文件. 生成后的CSV文件抛送到FTP指定目录下. 控件的使用这里就不做详细讲 ...