Java反射机制实战——字段篇
首先,我们来认识几个类。
Class(java.lang.Class)
Class对象是一个特殊对象,每一个类都有一个Class对象,用来创建该类的“常规”对象。可以通过对象的getClass()方法获取。
比如我们运行这一行代码:
System.out.println("测试".getClass().toString());
得到的结果就是:
class java.lang.String
Field(java.lang.reflect.Field)
这个类表示一个字段,可以使用这个字段来访问类
下面,我们来创建测试类:
class Book {
public String title;
public int length = 0;
public ArrayList<Page> pages = null; @Override
public String toString() {
String sb = "Book:\n";
sb += "title="+title+"\n";
sb += "length=" + length + "\n";
sb += "pages=" + pages + "\n";
if (pages != null) {
for (Page page : pages) {
sb += page.toString();
}
}
return sb.toString();
}
} class Page {
@Override
public String toString() {
return "page\n";
} }
调用以下方法来测试上面的类:
Book book = new Book();
System.out.println(book);
它的结果是这样:
Book:
title=null
length=0
pages=null
这是book对象的初始状态
我们下面通过反射机制,获取book对象中的length字段并进行修改,查看结果:
Book book = new Book();
Class<?> aClass = book.getClass();
Field field = aClass.getField("length");
field.setInt(book, 9);
System.out.println(book);
可以看到运行结果是:
Book:
title=null
length=9
pages=null
可以看出,length字段的值已经被修改了。
上面修改的是int型的简单字段,事实上像title字段这样的对象字段也是可以修改的,下面是示例:
Book book = new Book();
Class<?> aClass = book.getClass();
Field[] fields = aClass.getFields();
for (Field field : fields) {
field.setAccessible(true);
if(field.getType().equals(String.class)){
field.set(book, "格林童话");
}else if(field.getType().equals(int.class)){
field.set(book, 199);
}
}
System.out.println(book);
上面的代码输出结果是:
Book:
title=格林童话
length=199
pages=null
事实上,是将所有String类型的字段都修改成“格林童话”,将所有int类型字段都修改成199 。我们甚至根本不知道这个字段代表什么意思。
下面,我们对pages这个字段进行修改。这个字段是个ArrayList,我们将创建一个ArrayList对象,并向其中插入一个对象。
Book book = new Book();
Class<?> aClass = book.getClass();
Field[] fields = aClass.getFields();
for (Field field : fields) {
field.setAccessible(true);
if(field.getType().equals(ArrayList.class)){
String genric = field.getGenericType().toString();
String genricClass = genric.substring(
genric.indexOf('<') + 1,
genric.indexOf('>'));
Class<?> entityClass = Class.forName(genricClass);
Object obj = entityClass.newInstance();
ArrayList list = new ArrayList();
list.add(obj);
field.set(book, list);
}
}
System.out.println(book);
输出结果如下:
Book:
title=null
length=0
pages=[page
]
Page
可以看出,尽管我们根本没有直接使用Page类,但还是创建出了一个Page对象。
Page对象的创建语句在:entityClass.newInstance()这一句。newInstance语句是Class对象的重要方法,用来创建这个类对应的对象。当然,需要类的构造方法支持。另外,通过genGenericType方法,我们可以获取到字段的类型修饰符。放在这里,获取到的就是ArrayList<Page>。有了这一个字符串,我们就可以通过类加载器Class.forName来加载Page类并创建一个Page对象了。
Java反射机制实战——字段篇的更多相关文章
- 文末送书四本 | 这篇Java反射机制太经典!不看后悔!
先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索[程序职场]关注这个执着的职场程序员. 价值:Java技能,面试经验指导,简历优化,职场规划指导,技能提升方法,讲不完的职场故事,个人成长经 ...
- 11.Java反射机制 哦对了,前面的序号来自随笔关于编程之路的思索第一篇
基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象的方法的功能来自于J ...
- Java反射机制的浅显理解(这篇文章还没写好,留个草稿给自己看的)
目前只是有一个大概的理解,先把自己感觉容易立即的概念放这里,等以后结合实际工作理解深刻了再来补充. 一.什么是Java反射机制?(多种定义) 1. JAVA反射机制是在运行状态中,对于任意一个类,都能 ...
- Java 反射机制[Method反射]
Java 反射机制[Method反射] 接着上一篇Java 反射机制[Field反射],通过调用Person类的setName方法将obj的name字段的Value设置为"callPerso ...
- 详解Java反射机制
反射是程序在运行状态下,动态的获取某个类的内部信息的一种操作.例如:类名,包名,所有属性的集合,所有方法的集合,构造方法的集合等.该操作发生在程序的运行时状态,所以编译器管不着有关反射的一些代码,通常 ...
- 菜鸟学Java(十四)——Java反射机制(一)
说到反射,相信有过编程经验的人都不会陌生.反射机制让Java变得更加的灵活.反射机制在Java的众多特性中是非常重要的一个.下面就让我们一点一点了解它是怎么一回事. 什么是反射 在运行状态中,对于任意 ...
- Java反射机制Reflection
Java反射机制 1 .class文件 2 Class类 3 Class类与反射机制 4 Java反射机制的类库支持及简介 5 反射机制的定义与应用 6 反射机制Demo Java反射机制demo(一 ...
- java反射机制的进一步理解
承上一篇. JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语 ...
- Java技术——Java反射机制分析
)生成动态代理. 2. Java反射API 反射API用来生成在当前Java虚拟机中的类.接口或者对象的信息. Class类:反射的核心类,可以获取类的属性,方法等内容信息. Field类:Java. ...
随机推荐
- ImportError: No module named MySQLdb解决办法
http://blog.slogra.com/post-429.html http://blog.sina.com.cn/s/blog_74a7e56e0101a7qy.html 今天突发奇想在服务器 ...
- linux系统的开机流程
开机流程: 1)BIOS:开机主动运行的韧体.会认识第一个可开机设备. 2)MBR:第一个可开机设备的第一个扇区内的主引导分区块.当中包括引导载入程序. 3)引导载入程序:一支可读取内核文件来运行的软 ...
- 分析Linux内核的启动过程
第一章 环境 Ubuntu 14.10 Linux Kernel 3.18.6 第二章 代码及调试过程 环境搭建与内核准备: cd ~/LinuxKernel/ wget https://www.ke ...
- 特征列 属性值 获取 vowpal wabbit 生成DNN 的训练测试数据
用户特征文件 userFeature.data 每 行 代 表 一 个 用 户 的 特 征 数 据, 格 式 为: “uid|features”,uid 和 features 用竖线“|”分隔.其中 ...
- mybatis多表关联配置
首先需要的jar包 mybatis-3.4.1 配置文件(mybatis.cfg.xml) <?xml version="1.0" encoding="UTF-8& ...
- 在MAC端查看win7
在MAC端查看win7,在finder中打开网络,输入win7地址,填入用户名和密码,就可以了
- [国家集训队2]Tree I
https://www.zybuluo.com/ysner/note/1294263 题面 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解 ...
- android View页面布局总结 最全总结(转)
下面是我在工作中总结的内容,希望对大家有帮助. 一.布局 View的几种布局显示方式有下面几种:线性布局(LinearLayout).相对布局(RelativeLayout).表格布局(TableLa ...
- 频繁项集------->产生强关联规则的过程
频繁项集------->产生强关联规则的过程 1.由Apriori算法(当然别的也可以)产生频繁项集 2.根据选定的频繁项集,找到它所有的非空子集 3.强关联规则需要满足最小支持度和最小置性度 ...
- Spring通过注解注入有参
1.通过注解方式注入有参的构造函数 把@Autowired注解放在构造函数上方,在构造函数里写上需要注入的形参即可 2.通过XML配置文件方式定义有参构造函数