首先,我们来认识几个类。

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反射机制实战——字段篇的更多相关文章

  1. 文末送书四本 | 这篇Java反射机制太经典!不看后悔!

    先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索[程序职场]关注这个执着的职场程序员. 价值:Java技能,面试经验指导,简历优化,职场规划指导,技能提升方法,讲不完的职场故事,个人成长经 ...

  2. 11.Java反射机制 哦对了,前面的序号来自随笔关于编程之路的思索第一篇

    基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象的方法的功能来自于J ...

  3. Java反射机制的浅显理解(这篇文章还没写好,留个草稿给自己看的)

    目前只是有一个大概的理解,先把自己感觉容易立即的概念放这里,等以后结合实际工作理解深刻了再来补充. 一.什么是Java反射机制?(多种定义) 1. JAVA反射机制是在运行状态中,对于任意一个类,都能 ...

  4. Java 反射机制[Method反射]

    Java 反射机制[Method反射] 接着上一篇Java 反射机制[Field反射],通过调用Person类的setName方法将obj的name字段的Value设置为"callPerso ...

  5. 详解Java反射机制

    反射是程序在运行状态下,动态的获取某个类的内部信息的一种操作.例如:类名,包名,所有属性的集合,所有方法的集合,构造方法的集合等.该操作发生在程序的运行时状态,所以编译器管不着有关反射的一些代码,通常 ...

  6. 菜鸟学Java(十四)——Java反射机制(一)

    说到反射,相信有过编程经验的人都不会陌生.反射机制让Java变得更加的灵活.反射机制在Java的众多特性中是非常重要的一个.下面就让我们一点一点了解它是怎么一回事. 什么是反射 在运行状态中,对于任意 ...

  7. Java反射机制Reflection

    Java反射机制 1 .class文件 2 Class类 3 Class类与反射机制 4 Java反射机制的类库支持及简介 5 反射机制的定义与应用 6 反射机制Demo Java反射机制demo(一 ...

  8. java反射机制的进一步理解

    承上一篇. JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语 ...

  9. Java技术——Java反射机制分析

    )生成动态代理. 2. Java反射API 反射API用来生成在当前Java虚拟机中的类.接口或者对象的信息. Class类:反射的核心类,可以获取类的属性,方法等内容信息. Field类:Java. ...

随机推荐

  1. top命令查看线程信息和jstack使用介绍

    top -Hp pid可以查看某个进程的线程信息 -H 显示线程信息,-p指定pid jstack 线程ID 可以查看某个线程的堆栈情况,特别对于hung挂死的线程,可以使用选项-F强制打印dump信 ...

  2. 【c++】【转】如何只在heap上创建对象,如何只在stack上建立对象?

    http://www.cnblogs.com/chio/archive/2007/10/23/934335.html http://blog.csdn.net/szchtx/article/detai ...

  3. NYOJ 55 懒省事的小明(哈弗曼树)

    懒省事的小明 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描写叙述       小明非常想吃果子,正好果园果子熟了. 在果园里,小明已经将全部的果子打了下来,并且按果子的不 ...

  4. Memento - 备忘录模式

    定义 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 案例 比方如今有一个画图系统,我们在Viewer里面画了一些图形,可是在绘 ...

  5. mongodb的备忘录

    https://www.cnblogs.com/best/p/6212807.html

  6. php与国付宝对接过程吐槽

    最近.我们在打造全国第一家互联网+风险管理平台(避险谷)时.须要与第三方支付平台"国付宝"进行在线交易对接. 之前对接过支付宝 .感觉还非常easy,拿到国付宝的接口文档.我晕啊. ...

  7. 湖南省第九届大学生计算机程序设计竞赛 Interesting Calculator

    Interesting Calculator Time Limit: 2 Sec  Memory Limit: 128 MB Submit: 163  Solved: 49 Description T ...

  8. Codeforces Round #362 (Div. 2) D. Puzzles

    D. Puzzles time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  9. HDU 5783Divide the Sequence

    Divide the Sequence Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  10. 同一个站点下,兼容不同版本的JQuery

    https://stackoverflow.com/questions/1566595/can-i-use-multiple-versions-of-jquery-on-the-same-page Y ...