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. .NET 开发快捷键大全

    序号 快捷键 说明 1 Ctrl + Tab 切换当前编辑视图 2 Ctrl + Shift + Tab 反向切换当前编辑视图 3 F7 将窗体设计视图转成其代码视图 4 Shift + F7 将代码 ...

  2. JVM之数据类型

    1.概述 Java虚拟机的数据类型可分为两大类:原始类型(Primitive Types,也称为基本类型)和引用类型(Reference Types).Java虚拟机用不同的字节码指令来操作不同的数据 ...

  3. 拥抱高效、拥抱 Bugtags 之来自用户的声音 2

    小编按:这是一篇 Bugtags 用户来稿,主要是介绍了使用 Bugtags 前后对测试及解决 Bug 所带来的变化,感谢单车娱乐 App 工程师 - 李斌同学对 Bugtags 的信赖和支持.小编在 ...

  4. Android Studio使用总结

    记录Android-Studio遇到的各种坑 http://blog.csdn.net/u012874222/article/details/50616698 Android Studio 权威教程  ...

  5. Vs2015智能提示英文?

    Vs2015智能提示英文? 装了vs2015代码的智能提示全部变成英文了   找到这个目录 C:\Program Files (x86)\Reference Assemblies\Microsoft\ ...

  6. MVC 访问IFrame页面Session过期后跳转到登录页面

    Web端开发时,用户登录后往往会通过Session来保存用户信息,Session存放在服务器,当用户长时间不操作的时候,我们会希望服务器保存的Session过期,这个时候,因为Session中的用户信 ...

  7. XE6 & IOS开发之免证书真机调试(2):连接真机并运行App(有图有真相)

    网上能找到的关于Delphi XE系列的移动开发的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 连接真机前,请先确保真机 ...

  8. 下载Tomcat时Tomcat网站上的core和deployer的区别

    下载Tomcat时Tomcat网站上的core和deployer的区别 做JavaEE开发的朋友,无论是学习者还是已经工作的朋友,总是会用到Tomcat这个Servlet容器,那么大家从Tomcat官 ...

  9. 关于计算机的ID和用户ID之间的关系

    关于计算机的ID和用户ID之间的关系 计算机安装完系统后就会生成计算机ID,然后系统会以计算机ID为前缀附加数字创建Administrator(500)和Guest(501)用户ID,其他用户的ID将 ...

  10. jquery文件上传控件 Uploadify

    (转自 http://www.cnblogs.com/mofish/archive/2012/11/30/2796698.html) 基于jquery的文件上传控件,支持ajax无刷新上传,多个文件同 ...