Java 反射基础(上)
来源:互联网 发布:国际软件 编辑:程序博客网 时间:2024/06/06 03:40
【转载请注明出处】http://blog.csdn.net/my_truelove/article/details/51298218
在之前的文章中,有读者反馈我博客的内容有点长,如果要说长,可能是我习惯于思考,写博客的过程中会带着问题去写,解释我为什么这么想,我是怎么解决的,而不是上来直接说解决方案。可是,这样做无疑会增加篇幅,以后,我会在表达清楚的前提下尽可能减少文字描述(但不会省略代码),也算是对自己精简表达能力的锻炼。下面,直接进入正题。
本博文主要记录我学习 Java 反射(reflect)的一点心得,在了解反射之前,您应该先了解 Java 中的 Class 类,如果您不是很了解,可以查看我的另一篇博客《浅谈 Java 的 Class 类》。
我理解的 Java 反射机制
参考了许多博文,总结了以下个人观点,如您有更好的看法还望指导:
Java 反射机制在程序运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为 java 的反射机制。
反射机制很重要的一点就是“运行时”,其使得我们可以在程序运行时加载、探索以及使用编译期间完全未知的 .class
文件。换句话说,Java 程序可以加载一个运行时才得知名称的 .class
文件,然后获悉其完整构造,并生成其对象实体、或对其 fields(变量)设值、或调用其 methods(方法)。
不知道上面的理论您能否明白,反正刚接触反射时看的我一脸懵比,后来写了几个例子之后:哦~~原来是这个意思!如果您不明白理论没关系,建议您先往下看例子,之后再回来看相信您就能明白了。
实战演练
Step1. 编写测试类
为使得测试结果更加明显,我首先定义了一个 FatherClass
类(默认继承自 Object
类),然后定义一个继承自 FatherClass
类的 SonClass
类,如下所示。可以看到测试类中变量以及方法的访问权限不是很规范,是为了更明显得查看测试结果而故意设置的,实际项目中不提倡这么写。
FatherClass.java
public class FatherClass { public String mFatherName; public int mFatherAge; public void printFatherMsg(){}}
SonClass.java
public class SonClass extends FatherClass{ private String mSonName; protected int mSonAge; public String mSonBirthday; public void printSonMsg(){ System.out.println("Son Msg - name : " + mSonName + "; age : " + mSonAge); } private void setSonName(String name){ mSonName = name; } private void setSonAge(int age){ mSonAge = age; } private int getSonAge(){ return mSonAge; } private String getSonName(){ return mSonName; }}
Step2. 使用反射获取类的信息
获取类的所有变量
/** * 通过反射获取类的所有变量 */private static void printFields(){ //1.获取并输出类的名称 Class mClass = SonClass.class; System.out.println("类的名称:" + mClass.getName()); //2.1 获取所有 public 访问权限的变量 // 包括本类声明的和从父类继承的 Field[] fields = mClass.getFields(); //2.2 获取所有本类声明的变量(不问访问权限) //Field[] fields = mClass.getDeclaredFields(); //3. 遍历变量并输出变量信息 for (Field field : fields) { //获取访问权限并输出 int modifiers = field.getModifiers(); System.out.print(Modifier.toString(modifiers) + " "); //输出变量的类型及变量名 System.out.println(field.getType().getName() + " " + field.getName()); }}
以上代码注释很详细,就不再解释了。需要注意的是 2.1的 getFields()
与 2.2的 getDeclaredFields()
之间的区别(见注释),下面分别看一下两种情况下的输出。看之前强调一下 SonClass
extends FatherClass
extends Object
:
调用
getFields()
方法,输出SonClass
类以及其所继承的父类( 包括FatherClass
和Object
) 的public
方法。注:Object
类中没有成员变量,所以没有输出。类的名称:obj.SonClasspublic java.lang.String mSonBirthdaypublic java.lang.String mFatherNamepublic int mFatherAge
调用
getDeclaredFields()
, 输出SonClass
类的所有成员变量,不问访问权限。类的名称:obj.SonClassprivate java.lang.String mSonNameprotected int mSonAgepublic java.lang.String mSonBirthday
获取类的所有方法信息
/** * 通过反射获取类的所有方法 */private static void printMethods(){ //1.获取并输出类的名称 Class mClass = SonClass.class; System.out.println("类的名称:" + mClass.getName()); //2.1 获取所有 public 访问权限的方法 //包括自己声明和从父类继承的 Method[] mMethods = mClass.getMethods(); //2.2 获取所有本类的的方法(不问访问权限) //Method[] mMethods = mClass.getDeclaredMethods(); //3.遍历所有方法 for (Method method : mMethods) { //获取并输出方法的访问权限(Modifiers:修饰符) int modifiers = method.getModifiers(); System.out.print(Modifier.toString(modifiers) + " "); //获取并输出方法的返回值类型 Class returnType = method.getReturnType(); System.out.print(returnType.getName() + " " + method.getName() + "( "); //获取并输出方法的所有参数 Parameter[] parameters = method.getParameters(); for (Parameter parameter: parameters) { System.out.print(parameter.getType().getName() + " " + parameter.getName() + ","); } //获取并输出方法抛出的异常 Class[] exceptionTypes = method.getExceptionTypes(); if (exceptionTypes.length == 0){ System.out.println(" )"); } else { for (Class c : exceptionTypes) { System.out.println(" ) throws " + c.getName()); } } }}
同获取变量信息一样,需要注意2.1与2.2的区别,下面看一下打印输出:
调用
getMethods()
方法
获取SonClass
类所有public
访问权限的方法,包括从父类继承的。打印信息中,printSonMsg()
方法来自SonClass
类,printFatherMsg()
来自FatherClass
类,其余方法来自 Object 类。类的名称:obj.SonClasspublic void printSonMsg( )public void printFatherMsg( )public final void wait( ) throws java.lang.InterruptedExceptionpublic final void wait( long arg0,int arg1, ) throws java.lang.InterruptedExceptionpublic final native void wait( long arg0, ) throws java.lang.InterruptedExceptionpublic boolean equals( java.lang.Object arg0, )public java.lang.String toString( )public native int hashCode( )public final native java.lang.Class getClass( )public final native void notify( )public final native void notifyAll( )
调用
getDeclaredMethods()
方法打印信息中,输出的都是
SonClass
类的方法,不问访问权限。类的名称:obj.SonClassprivate int getSonAge( )private void setSonAge( int arg0, )public void printSonMsg( )private void setSonName( java.lang.String arg0, )private java.lang.String getSonName( )
结尾
这次的内容主要是代码,文字部分在能表达清楚意思的前提下已经压缩到最少了,希望您看的开心哈!如果文中有任何不妥或错误之处,还请不吝赐教,十分感谢!
本博文演示了如何借助反射获取类的所有变量和方法,当然还有其他许多获取类信息的API(比如得到类的包名、构造函数、接口等),我就不一一列举了,使用方法都差不多。下次将向大家分享如何利用反射在运行时刻修改类成员变量和方法的访问权限,一起期待吧 :)
Java 反射基础(下)
- Java 反射基础(上)
- AVA基础之反射(上)
- Java基础 泛型(反射)
- java 反射基础(1)
- Java基础---反射(Reflection)
- Java 反射基础(下)
- java基础(8)反射
- java基础--反射(1)
- java基础(1)--反射
- java反射(一):反射基础
- [ java ] java基础反射!
- Java基础(上)
- JAVA的反射机制简介(上)
- Java反射性能优化(上)
- Java 反射机制(上)
- Java基础之反射(一):反射入门
- Java基础之反射(二):反射应用
- JAVA基础 (二)反射 深入解析反射机制
- 简单的介绍一下C中申请的内存空间,free的使用
- ViewPager动画效果
- 第十一周上机实践项目——项目1-点-圆-圆柱类族的设计
- HDU 2034 人见人爱A-B
- 文章标题 改进的模式匹配算法
- Java 反射基础(上)
- c++ 找出一个整形数组中元素的最大值
- filter配置多个url-pattern和排除个别servlet
- DP 动态规划 Problem N 1014 折线分割平面
- python简单爬虫学习
- Lua安装及使用总结
- python 调用Google Translate API进行翻译
- HDU 2035 人见人爱A^B(快速幂取模 )
- 解决:Connections could not be acquired from the underlying database!