反射学习整理
【摘要】
本文主要通过自己对反射机制的总结编写的文档,主要目的就是为了自己以后能可以参考温习也可以方便刚刚入门的同仁们学习指导,通过doc的编写相信可以在帮助别人的同时提高自己。
反射机制;
Reflection API;
如何使用反射机制;
反射机制的应用举例;
第一节 反射机制
什么是反射机制,说的通俗一些就是在java运行期间动态加载一些不确定的类对象,那么我
们如何使用一个类的呢?当然大多数情况下我们是使用一个确定的类,然后通过在内存中的加载再使用之。
其实在一个project中会有很多类,虚拟机并不是在每一次运行时都将所有的类都进行加载然后解析的,是在我们使用的过程中才会被加载,这个大家可以看一下ClassLoader(在后期中我也会编写ClassLoader相关的文章总结)
反射机制提供的功能:
加载运行时才能确定的数据类型;
解析类的结构,获取其内部的信息;
能够操作的类型或者实例;
1. 访问属性;
2. 调用方法;
3. 创建新的对象;
以上的功能我会在接下来的文字中都进行阐述,然后每一个功能点都会通过代码的形式进行逐一的说明举例;
1.1动态加载类
Java虚拟机在运行是能加载的类型有如下几种:
类接口;
数组;
枚举;
注解(Annotation,可以参见我的另一篇文档,《java Annotation学习文档》);
基本数据类型;
在类加载的时候,JVM会自动加载上述类型对应的Class对象。
package com.wangwenjun.demo;
import java.util.ArrayList;
public class ReflectionDemo1 {
private final static String LIST_STRING="java.util.ArrayList"; //动态加载java.util.ArrayList的类路径
@SuppressWarnings("unchecked")
public static void main(String[] args) {
try {
Class<?> clazz=Class.forName(LIST_STRING); //通过反射获取运行时的Class
ArrayList<Object> list=(ArrayList<Object>) wInstance(); //通过newInstance方法获取Object
list.add("hello");
System.out.println(list.size()+":"+(0));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
执行结果为:1:hello
通过上面的代码我们可以总结出来使用Reflection大致需要如下的几步:
获取目标对象的Class对象;
调用Class对象内省方法获取目标对类成员信息;
访问目标类的成员属性;
1.2解析类的结构
通过第一步的操作,我们获取了目标对象的class之后就可以解析出来class对应的内部结构;别不多说直接上代码,来看看如何解析出来目标对象;
我们定义一个Teacher类
package com.wangwenjun.demo;
public class Teacher {
private String username;
private int age;
private static int total;
public Teacher(){
super();
total++;
}
public Teacher(String username,int age){
super();
this.username = username;
this.age = age;
total++;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public static int getTotal() {
return total;
}
public static void setTotal(int total) {
Teacher.total = total;
}
@Override
public String toString(){
return "UserName:"+this.username+",age:"+this.age;
}
}
假如说上述的Teacher类是在我们运行时才知道的一个类,也就是说是我们运行时才能确定的一个类,那么我们就可以通过反射的形式将它解析出来,包括它的属性,方法,以及构造函数等等。好了,下面有一个专门的类针对Teacher进行解析,通过观察打印的语句我们就可以看出来效果
package com.wangwenjun.demo;
import flect.Constructor;
import flect.Field;
import flect.Method;
import flect.Modifier;
public class ReflectionTeacher {
private final static String TEACHER_CLASS="com.wangwenjun.demo.Teacher";
@SuppressWarnings("unchecked")
public static void main(String[] args) {
try {
Class<?> clazz = Class.forName(TEACHER_CLASS);
Field[] fields = DeclaredFields(); //获取该类中的属性成员
Method[] methods = DeclaredMethods(); //获取该类中的成员方法
Constructor[] constructors = Constructors();//获取该类的所有构造方法
System.out.println("***********打印成员属性***********");
for(Field field:fields){
System.out.println("属性:"+field);
System.out.println("名称:"+Name());
System.out.println("修饰符:"+Modifier.toString(Modifiers()));
System.out.println("数据类型:"+Type());
System.out.println("=====================================");
}
System.out.println("***********打印成员方法***********");
for(Method method:methods){
System.out.println("方法:"+String());
System.out.println("方法名称:"+Name());
System.out.println("方法修饰符:"+Modifier.toString(Modifiers()));
System.out.println("方法参数列表");
Class[] ParameterTypes();
System.out.print(mClass.length!=0?"有参数:":"无参数:");
for(Class c:mClass){
System.out.Name()+"类型\t");
}
System.out.println("\n方法返回类型:"+ReturnType().getName());
System.out.println("=====================================");
}
System.out.println("***************打印构造方法***************");
for(Constructor constructor:constructors){
System.out.println("构造方法:"+String());
System.out.println("构造方法名:"+Name());
System.out.println("构造方法修饰符:"+Modifier.toString(Modifiers()));
Class[] ParameterTypes();
System.out.print(mClass.lengthjava的tostring方法!=0?"有参数:":"无参数:");
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论