JAVA中反射机制的研究

来源:互联网 发布:vb编程题及答案 编辑:程序博客网 时间:2024/05/17 23:13

   Java的反射机制是Java特性之一,反射机制是构建框架技术的基础所在。灵活掌握Java反射机制,对大家以后学习框架技术有很大的帮助。

 

那么什么是Java的反射呢?

     JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
     Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

 

Class类

       要正确使用Java反射机制就得使用java.lang.Class这个类。它是Java反射机制的起源。当一个类被加载以后,Java虚拟机就会自动产生一个Class对象。通过这个Class对象我们就能获得加载到虚拟机当中这个Class对象对应的方法、成员以及构造方法的声明和定义等信息。

 

       利用Java反射机制我们可以很灵活的对已经加载到Java虚拟机当中的类信息进行检测。当然这种检测在对运行的性能上会有些减弱,所以什么时候使用反射,就要靠业务的需求、大小,以及经验的积累来决定。


代码示例:

/** 内容 : Java的反射机制的学习* 备注 :* 1、通过Class类的三种实例化对象* 2、通过class类中的newInstance()实例化对象* 3、获取所有接口*  printAllInterfaces( myclass );*4、获得父类*printSuperClass( myclass );*5、获取所有的构造函数*printConstructors( myclass );*6、输出类中所有方法,包括父类的方法*printAllMethods( myclass );*7、输出类中所有属性,不包括父类的属性*printDeclaredFields( myclass );*8、通过反射调用函数*reflectInvoke( myclass );** 作者 : UIT-ESPACE XXX* 日期 :2012-10-28 */// 编译时则为 javac -d . ReflectionDemo.java, 运行时要输入完整路径: java uit.demo.reflection.ReflectionDemopackage uit.demo.reflection;import java.util.*;import java.lang.reflect.*;// Person实现了Comparable的接口,可以排序class Person implements Comparable<Person>{private String name;private int age;// 无参构造public Person(){}// 带参构造public Person(String name, int age){this.name = name;this.age = age;}// 设置名字public void setName(String name){this.name = name;}// 设置年龄public void setAge(int age){this.age = age;}// 获取名字public String getName(){return this.name;}// 获取年龄public int getAge(){return this.age;}// 转换成字符串public String toString(){return "姓名: " + this.name + ", 年龄: " + this.age;}// 覆写equals函数,判断对象是否是同一对象public boolean equals(Object obj){if ( obj == this ){return  true;}if ( !(obj instanceof Person)){return false;}Person per = (Person)obj;if ( per.name.equals(this.name) && per.age == this.age){return true;}else{return false;}}// 覆写hashCode(),hashCode表示对象的唯一编码public int hashCode(){return  this.name.hashCode() * this.age;}// 排序接口的函数实现,使用此函数实现排序public int compareTo(Person per){if (this.age > per.age){return 1;}else if(this.age < per.age) {return -1;}else {// 调用String中的compareTo()方法return this.name.compareTo(per.name) ;}}}// mainpublic class ReflectionDemo{public static void main(String args[]) throws Exception{Person per = new Person();println("per的类为 : " + per.getClass().getName());// 三种方法实例化Class对象Class<?> c1 = null;Class<?> c2 = null;Class<?> c3 = null;// 1、最常用的方式是forName的形式c1 = Class.forName("uit.demo.reflection.Person");c2 = new Person().getClass();c3 = Person.class;println("per的类为 : " + c1.getName());println("per的类为 : " + c2.getName());println("per的类为 : " + c3.getName());// 2、通过反射机制实现对象的实例化,前提是自定义的类必须有无参构造函数Person per2 = (Person)c1.newInstance();per2.setName("反射");println(per2 + ",名字为: " + per2.getName() + "\n");// 3、通过获取构造方法,然后传参数的形式实例化对象Person per3 = null;// 获取所有的构造函数Constructor<?> con[] = c1.getConstructors();for ( Constructor<?> pers : con){println( "构造函数 : " + pers.toString() );}println("\n");// 4、通过带参数的构造函数传参来实例化per3 = (Person)con[1].newInstance("某某人", 21);println( "通过反射机制和带参构造函数实例化: " + per3.toString() + "\n");// 5、获得类的所有结构,包括属性、方法、实现的接口、父类等getClassAll();}// 通过反射机制取得类的结构,包括属性、方法、接口、父类等public static void getClassAll() throws Exception{println("*****************************类的结构****************************");// 1、实例化Class对象Class<?> myclass = Class.forName("uit.demo.reflection.Person");// 2、获取所有接口printAllInterfaces( myclass );// 3、获得父类printSuperClass( myclass );// 4、获取所有的构造函数printConstructors( myclass );// 输出类中所有方法,包括父类的方法printAllMethods( myclass );// 输出类中所有属性,不包括父类的属性printDeclaredFields( myclass );// 通过反射调用函数reflectInvoke( myclass );println("*************************** FINAL END ******************************\n");}// 输出所有接口public static void printAllInterfaces( Class<?> myclass ){// 获取所有接口Class<?> iterfaceAll[] = myclass.getInterfaces();for ( Class<?> temp : iterfaceAll){println("实现了接口: " + temp);}}// 输出父类public static void printSuperClass( Class<?> myclass ){// 获取父类Class<?> supercs = myclass.getSuperclass();println("父类: " + supercs + "\n");}// 输出所有构造函数public static void printConstructors( Class<?> myclass ){// 获取所有构造函数Constructor<?> cons[] = myclass.getConstructors();for ( Constructor<?> pConstructor : cons){println( "构造函数 : " );// 获得修饰符,比如public 、private等int me = pConstructor.getModifiers();print(Modifier.toString( me ) + " ");// 获得构造函数的名字print( pConstructor.getName() + "(");// 获取所有参数Class<?> params[] = pConstructor.getParameterTypes();for (int i=0; i<params.length; i++){print( params[i].getName() + " arg" + i);// 后面还有参数,则使用逗号分开if ( i < params.length - 1 ){print( ", " );}}println( ")" );}println("\n");}// 输出所有类中定义的方法public static void printAllMethods( Class<?> myclass){println("***************类的所有方法,包括父类的方法****************");// getDeclaredMethods为得到本类中的所有方法,getMethods为获得所有方法,包括父类中的方法Method methods[] = myclass.getMethods();for (int i=0; i<methods.length; i++){// 获得返回值类型Class<?> returnType = methods[i].getReturnType();// 获得参数列表Class<?> params[] = methods[i].getParameterTypes();// 获得修饰符,public等int md = methods[i].getModifiers();// 1、输出修饰符print( Modifier.toString( md ) + " ");// 2、输出返回值类型print( returnType + " ");// 3、输出函数名print( methods[i].getName() + "(");// 4、挨个输出参数for(int j=0; j<params.length; j++){print( params[j].getName() + " arg" + j);if ( j < params.length -1 ){print( "," );}}print( ")" );// 获取抛出的异常名称Class<?> expt[] = methods[i].getExceptionTypes();// 如果含有异常参数则输出if (expt.length > 0){print( " throws " );for (int k=0; k<expt.length; k++){print( expt[k].getName());if ( k < expt.length - 1 ){print( "," );}}}// end ifprint(";\n");} // end forprintln("***************类的所有方法,包括父类的方法  END ****************\n\n");}// 输出类中的方法public static void printDeclaredFields(Class<?> myclass){println("********************类的属性*******************");// 获取类中的属性,不包括父类的属性Field decField[] = myclass.getDeclaredFields();for (int i=0; i<decField.length; i++){// 获取修饰符String md = Modifier.toString( decField[i].getModifiers() );// 属性的类型Class<?> type = decField[i].getType();print(md + " " + type.getName() + " " + decField[i].getName() + " ;\n");}println("********************类的属性*******************\n");}// 通过反射调用成员函数public static void reflectInvoke(Class<?> myclass) throws Exception{// 1、获得setName函数, 参数为String 类型的Method mt = myclass.getMethod( "setName", String.class);// 2、通过myclass.newInstance()构造对象Person per = (Person)myclass.newInstance();// 3、通过反射调用setName方法, 有参函数mt.invoke( per, "名字:反射调用");// 调用无参函数, 输出返回的信息Method mt2 = myclass.getMethod( "getName" );// 调用getName函数返回Person对象的名字String name = (String)mt2.invoke( per );print(  name + "\n");}// 输出信息public static void print(String msg){System.out.print( msg );}// 输出信息,换行public static void println(String msg){System.out.println( msg );}}



原创粉丝点击