Java反射机制在我的理解当中就是下面几点:

1. 对一个给定的类名(以字符串形式提供)能动态构建一个对象实例

2. 对于任意一个类,都能够知道这个类的所有属性和方法

    3. 对于任意一个对象,都能够调用它的任意一个方法和属性;
 
这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制,这种反射机制在Java当中给我们带来了极大的方便,被大量地应用于JavaBean中
 
在Java的反射中我们主要用到以下几个类,下面将逐个说明
  1. java.lang.Class;

  2. java.lang.reflect.Constructor;

  3. java.lang.reflect.Field;

  4. java.lang.reflect.Method;

  5. java.lang.reflect.Modifier;

1.java.lang.Class类:用于保存每个对象所属类的相关信息,在Java中,Object类中的getClass()方法将会返回一个Class类型的实例,(注意:记住这是一个类,和关键字class完全是两码事)
2.java.lang.reflect.Constructor:提供关于类的单个构造方法的信息以及对它的访问权限。
3.java.lang.reflect.Field:提供有关类或接口的单个字段的信息,以及对它的动态访问权限
4.java.lang.reflect.Method:提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。
5.java.lang.reflect.Modifier:提供了类、类的成员、static方法、常量的修饰符。
 
public class Person {
// Field
private String person_name;
protected int person_age;
public boolean person_sex; // Construct
public Person() {
super();
} public Person(String name, int age, boolean sex) {
super();
this.setPerson_name(name);
this.person_age = age;
this.person_sex = sex;
} // Method
public void AddAge(int year) {
this.person_age += this.person_age + year;
} public String getPerson_name() {
return person_name;
} public void setPerson_name(String person_name) {
this.person_name = person_name;
}
}
 
public class Employee extends Person{
private double saray;
protected String gangwei; public Employee() {
super();
} public Employee(double saray, String gangwei) {
super();
this.saray = saray;
this.gangwei = gangwei;
} public double getSaray() {
return saray;
} public void setSaray(double saray) {
this.saray = saray;
} public String getGangwei() {
return gangwei;
} public void setGangwei(String gangwei) {
this.gangwei = gangwei;
} public void addSaray(double money){
this.saray+=money;
} }

 
以下按照我们常用的方法介绍下使用方法:

1.根据类名构造一个实例

		// 根据类名获取Class对象
Class c = Class.forName("Employee");
System.out.println(c.getName()); // 此处打印:Employee
// 获取父类Class对象
Class cp = c.getSuperclass();
System.out.println(cp.getName());// 此处打印:Person
// 获取类的访问修饰符
String modifiers = Modifier.toString(c.getModifiers());
System.out.println(modifiers); // 此处打印:public
// 实例化
Object obj = c.newInstance(); //通过无参的构造函数进行实例化
 
 
2.获取类的Field,主要有以下四个方法
 

Class c = Class.forName("Employee");

  • c.getField(name) ;
  • c.getFields()
  • c.getDeclaredFields()
  • c.getDeclaredField(name)
getField()方法返回这个类或其超类的公有字段(不包括private和protect修饰的字段)
getDeclaredField方法返回这个类的全部字段(包括private和protect修饰的字段)
 
 
<span style="white-space:pre">		</span>/*
* 获取类Employee的所有Field
*
* c.getField(name) c.getFields() c.getDeclaredFields()
* c.getDeclaredField(name)
*/
Field[] fields = c.getDeclaredFields();
for (Field f : fields) {
// 获取该Field的类型
Class type = f.getType();
// 获取该Field的名称
String name = f.getName();
// 获取该Field的访问修饰符
String sFieldModifiers = Modifier.toString(f.getModifiers());
System.out.println(sFieldModifiers + " " + type.getName() + " " + name + ";");
}


3.获取类的构造函数
同Field一样,获取构造函数也有4个方法
  • * c.getDeclaredConstructors()
  • * c.getConstructors()
  • * c.getDeclaredConstructor(parameterTypes)
  • * c.getDeclaredConstructor(parameterTypes)
 
<span style="white-space:pre">		</span>/*
* 获取类的构造函数
* c.getDeclaredConstructors()
* c.getConstructors()
* c.getDeclaredConstructor(parameterTypes)
* c.getDeclaredConstructor(parameterTypes)
*/
Constructor[] constructors = c.getDeclaredConstructors();
for (Constructor cr : constructors) {
// 构造函数名称
String name = cr.getName();
// 构造函数修饰符
String sConstructorModifiers = Modifier.toString(cr.getModifiers());
// 构造函数参数
Class[] paramTypes = cr.getParameterTypes();
String sParam = "";
for (int j = 0; j < paramTypes.length; j++) {
if (j > 0)
sParam += ", ";
sParam += paramTypes[j].getName();
}
System.out.println(sConstructorModifiers + " " + name + "(" + sParam + ");");
}
4.获取类的Method
同Field一样,有4个获取方法的方法,另外多了一个方法,用于获取返回类型
 
<span style="white-space:pre">		Method[] methods = c.getDeclaredMethods();
<span style="white-space:pre"> </span>for (Method m : methods) {
<span style="white-space:pre"> </span>// 方法返回类型
<span style="white-space:pre"> </span>Class returnType = m.getReturnType();
<span style="white-space:pre"> </span>String sReturnType = returnType.toString();
<span style="white-space:pre"> </span>// 方法名称
<span style="white-space:pre"> </span>String name = m.getName();
<span style="white-space:pre"> </span>// 方法修饰符
<span style="white-space:pre"> </span>String sMethodModifiers = Modifier.toString(m.getModifiers());
<span style="white-space:pre"> </span>// 方法参数
<span style="white-space:pre"> </span>Class[] paramTypes = m.getParameterTypes();
<span style="white-space:pre"> </span>String sParam = "";
<span style="white-space:pre"> </span>for (int j = 0; j < paramTypes.length; j++) {
<span style="white-space:pre"> </span>if (j > 0)
<span style="white-space:pre"> </span>sParam += ", ";
<span style="white-space:pre"> </span>sParam += paramTypes[j].getName();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>System.out.println(sMethodModifiers + " " + sReturnType + " " + name + "(" + sParam + ");");
<span style="white-space:pre"> </span>}</span>

5.利用反射动态给对象属性赋值,比如我们需要从配置文件中读取某个员工的信息,并赋值给某个对象,我们可以这样写:

<span style="white-space:pre">		</span>/*
<span style="white-space:pre"> </span> * 动态给类的属性赋值
<span style="white-space:pre"> </span> */
<span style="white-space:pre"> </span>Class c2 = Class.forName("Employee");
<span style="white-space:pre"> </span>Object e = c2.newInstance();
<span style="white-space:pre"> </span>Field f = c2.getDeclaredField("saray");
<span style="white-space:pre"> </span>// 因为属性saray是private的,所有需要调用setAccessible方法才能给该属性赋值,否则报错
<span style="white-space:pre"> </span>f.setAccessible(true);
<span style="white-space:pre"> </span>f.set(e, 10000);
<span style="white-space:pre"> </span>Field f2 = c2.getDeclaredField("gangwei");
<span style="white-space:pre"> </span>f2.set(e, "高级软件工程师");
<span style="white-space:pre"> </span>System.out.println(((Employee) e).getGangwei() + " " + ((Employee) e).getSaray());
<span style="white-space:pre"> </span>// 取值
<span style="white-space:pre"> </span>Field f3 = c2.getDeclaredField("saray");
<span style="white-space:pre"> </span>Field f4 = c2.getDeclaredField("gangwei");
<span style="white-space:pre"> </span>f3.setAccessible(true);
<span style="white-space:pre"> </span>System.out.println(f3.get(e));
<span style="white-space:pre"> </span>System.out.println(f4.get(e));
输出结果如下:
高级软件工程师 10000.0
10000.0
高级软件工程师
 
6.利用反射动态地调用对象的方法,比如Employee类中有个addsaray的方法,我们看下要怎么调用:
		Class c3 = Class.forName("Employee");
Object e3 = c3.newInstance();
Field fSaray = c3.getDeclaredField("saray");
fSaray.setAccessible(true);
fSaray.set(e3, 10000);
System.out.println(fSaray.get(e3)); //输出10000
// 获取Method
Method m = c3.getDeclaredMethod("addSaray", double.class);
/*
* Method m = c3.getDeclaredMethod("addSaray"); Method m2 =
* c3.getDeclaredMethod("addSaray", double.class);
* 如果有多个重名的方法,要添加参数让编译器知道应该调用哪个方法,这里只有一个参数,所以上面两种写法都可以
*/
// 调用方法
m.invoke(e3, 5000);
System.out.println(fSaray.get(e3)); //输出15000,因此证明方法调用成功

输出结果如下:

10000.0
15000.0

JAVA反射实践的更多相关文章

  1. java 反射实践

    /** * * @author yuxg */ import coreJava.javaFile; import javaClassStudy.Student; import javaClassStu ...

  2. java反射基础知识(五)反射应用实践

    详解Java反射各种应用   Java除了给我们提供在编译期得到类的各种信息之外,还通过反射让我们可以在运行期间得到类的各种信息.通过反射获取类的信息,得到类的信息之后,就可以获取以下相关内容: Cl ...

  3. java反射-- Field 用法实践

    java 反射是一种常用的技术手段, 通过加载类的字节码的方式来获取相关类的一些信息 比如成员变量, 成员方法等. Field 是什么呢? field 是一个类, 位于java.lang.reflec ...

  4. Java反射(六)纯面向接口编程的简单框架实践

    我们知道在使用MyBatis开发时,只需要添加DAO接口和对应的映射XML文件,不需要写DAO的实现类,其实底层是通过动态代理实现. 本文将使用前几篇文章的知识点实现一个纯面向接口编程的简单框架,与M ...

  5. 大型网站系统与Java中间件实践

    大型网站系统与Java中间件实践(贯通分布式高并发高数据高访问量网站架构与实现之权威著作,九大一线互联网公司CTO联合推荐) 曾宪杰 著   ISBN 978-7-121-22761-5 2014年4 ...

  6. java 反射(reflect)总结,附对象打印工具类

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

  7. Java 反射机制详解

    动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化.比如众所周知的ECMAScript(JavaScript)便是一个动态语言.除此之外如Ru ...

  8. 一个例子让你了解Java反射机制

    本文来自:blog.csdn.net/ljphhj JAVA反射机制: 通俗地说,反射机制就是可以把一个类,类的成员(函数,属性),当成一个对象来操作,希望读者能理解,也就是说,类,类的成员,我们在运 ...

  9. (转)个例子让你了解Java反射机制

    个例子让你了解Java反射机制   原文地址:http://blog.csdn.net/ljphhj/article/details/12858767 JAVA反射机制:   通俗地说,反射机制就是可 ...

随机推荐

  1. PHP购物车类

    <?php /** * 购物车类 */ session_start(); class Cart{ private static $ins = null; private $items = arr ...

  2. Unity UI on the HoloLens

    Following the steps under "Required configuration" will allow Unity UI to continue to work ...

  3. 【转】PL/SQL Developer各个窗口的功能

    源地址:http://www.codeweblog.com/pl-sql-developer%E5%90%84%E4%B8%AA%E7%AA%97%E5%8F%A3%E7%9A%84%E5%8A%9F ...

  4. oracle ||,

    || oracle数据库中的 ||称为 "字符串连接符" 用于连接查询结果,如下: select trade_id,accept_date from A; ------------ ...

  5. PHP常用函数总结(不定期更新)

    array_merge函数和两个数组相加的区别 array_merge函数,在出现相同的索引数组,会把两个数组中的索引数组,进行融合,以第一个数组的索引最大值往后相加,如果是关联数组,后面数组的值覆盖 ...

  6. [转]理解HTTP幂等性

    基于HTTP协议的Web API是时下最为流行的一种分布式服务提供方式.无论是在大型互联网应用还是企业级架构中,我们都见到了越来越多的SOA或RESTful的Web API.为什么Web API如此流 ...

  7. 安利一个MVC的好东西,RazorGenerator.MsBuild,可以自动编译cshtml文件

    在传统的asp.net webForm 开发里,在发布时,如果选择预编译,就会自动将所有的aspx 文件编译,在发布后的目录里,就看不到aspx的源代码了,同时因为是预编译的,所以每个页面打开速度都挺 ...

  8. 【转】HTML5 jQuery图片上传前预览

    hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images,本例子主要是使用HTML5 的File API,建立一個可存取到该 file的url,一个空的img标签,ID为img0,把选 ...

  9. MyEclipse10建立Maven Webapp项目并通过git传到GitHub

    先创建Maven Webapp项目 图文详解MyEclipse中新建Maven webapp项目的步骤(很详细) 在web项目的路径中右键(前提是你机器已经装了git)“Git Init Here”, ...

  10. 如何为datagridview加上序号

    最简单的方法是在Datagridview的事件RowPostPaint事件下面添加如下代码即可 private void dataGridView1_RowPostPaint(object sende ...