本文共 7577 字,大约阅读时间需要 25 分钟。
什么是反射?书上是这样定义的:“在Java中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制”。
要想了解反射,必须了解这四种API:
Class类:反射的核心类,可以获取类的Constructor,Method和Field属性。(注意:不要和class关键字搞混)
Constructor类:Java.lang.reflec包中的类,表示类中的构造方法。
Method类:Java.lang.reflec包中的类,表示类中的成员方法。
Field类:Java.lang.reflec包中的类,表示类中的成员变量。
下面我将根据API从四个方面讲一下反射的基本应用,先定义一个父子类:
package com.Jevin.blog;public class Person { /** * 成员变量: */ public String name; protected int age; String id; private String weight; /** * 成员方法: */ public void love(){ System.out.println("每个人都有追求爱的权利!"); } protected void makeLove(){ System.out.println("所以我们都喜欢做爱!"); } void romatic(){ System.out.println("爱情除了做,还需要浪漫!"); } private void life(){ System.out.println("我们同样都需要生活!"); }}
package com.Jevin.blog;public class Student extends Person { /** * 成员变量: */ public String stuNo; protected String className; int score; private String hobby; /** * 构造方法: */ public Student(){ System.out.println("共有的无参构造方法!"); } public Student(String stuNo){ System.out.println("共有的带参数的构造方法stuNo="+stuNo); } protected Student(int score){ System.out.println("受保护的有参构造方法score="+score); } Student(String hobby,int score){ System.out.println("默认的有参构造方法hobby="+hobby+",score="+score); } private Student(String stuNo,String className,int score){ System.out.println("私有的构造方法:stuNo="+stuNo+",className="+className+",score="+score); } /** * 成员方法: */ public void test(int a,boolean b){ System.out.println("作为学生,我们都需要考试!"); } void getScore(String str){ System.out.println("还需要拿高分数!"); } protected void hateScore(double d){ System.out.println("但是我们都讨厌分数!"); } private void CEE(String eng){ System.out.println("但是不得不面对高考!"); }}
一:创建反射的三种方式:
package com.Jevin.blog;/** * 创建反射类型的三种方式: */public class ReflectType { public static void main(String[] args) throws Exception { //方式一:".class" Class clazz1=Student.class; //方式二:"Class.forName(String args)" Class clazz2=Class.forName("com.Jevin.blog.Student"); //方式三:"引用.getClass()" Student student=new Student(); Class clazz3=student.getClass(); }}
二:利用反射获取类中的构造方法:
package com.Jevin.blog;import java.lang.reflect.Constructor;import java.lang.reflect.Modifier;/** * 利用反射获取类中的构造方法: */public class ConstructorTest { public static void main(String[] args) throws Exception { Class clazz=Class.forName("com.Jevin.blog.Student"); //1.通过"getConstructors()"获取当前类所有的public的构造方法: /*Constructor[] constructors1=clazz.getConstructors(); for(Constructor constructor:constructors1){ *//** * 结果: * public com.Jevin.blog.Student(java.lang.String) * public com.Jevin.blog.Student() *//* System.out.println(constructor); *//** * 结果: * public com.Jevin.blog.Student(String arg0) * public com.Jevin.blog.Student() * 这样写也可以,但是有点麻烦,所以不建议; *//* //获取权限修饰符: int mod=constructor.getModifiers(); String modifier=Modifier.toString(mod); System.out.print(modifier+" "); //获取方法名: String methodName=constructor.getName(); System.out.print(methodName+"("); //获得参数: Class[] cArgs=constructor.getParameterTypes(); for(int i=0;i
三:利用反射获取类中的成员变量:
package com.Jevin.blog;import java.lang.reflect.Field;/** * 利用反射获取类中的成员变量: * 四种:getFields(),getField(String arg),getDeclaredFields(),getDeclaredField(String arg); */public class VariableTest { public static void main(String[] args) throws Exception { Class clazz=Class.forName("com.Jevin.blog.Student"); /** * 1.利用getFeilds()获取本类及其父类中所有public修饰的成员方法: * * 结果:public java.lang.String com.Jevin.blog.Student.stuNo * public java.lang.String com.Jevin.blog.Person.name */ /*Field[] fields=clazz.getFields(); for(Field field:fields){ System.out.println(field); }*/ /** * 2.利用getField(String arg)获取本类中指定的public修饰的成员方法: * * 结果:public java.lang.String com.Jevin.blog.Student.stuNo */ /*Field field=clazz.getField("stuNo"); System.out.println(field);*/ /** * 3.利用getDeclaredFields()获取本类中所有的成员变量:包括public,protected,default,private修饰的: * * 结果: * public java.lang.String com.Jevin.blog.Student.stuNo * protected java.lang.String com.Jevin.blog.Student.className * int com.Jevin.blog.Student.score * private java.lang.String com.Jevin.blog.Student.hobby */ /*Field[] fields=clazz.getDeclaredFields(); for(Field field:fields){ System.out.println(field); }*/ /** * 4.利用getDeclaredField(String arg)获取本类中指定的成员变量,不论是public,protected,defaul,private中的哪一种。 * * 结果:private java.lang.String com.Jevin.blog.Student.hobby */ Field field=clazz.getDeclaredField("hobby"); System.out.println(field); }}
四:利用放射获取类中的成员方法:
package com.Jevin.blog;import java.lang.reflect.Method;/** *利用反射类型获取成员方法: * 四种:getMethods(),getMethod(String arg,Class... paramterType),getDeclaredMethods(),getDeclaredMethod(String arg,Class... paramterType) */public class MethodTest { public static void main(String[] args) throws Exception { Class clazz=Class.forName("com.Jevin.blog.Student"); /** * 1.利用getMethods()获取本类中及其父类中所有的public修饰的成员方法: * * 结果:public void com.Jevin.blog.Student.test(int,boolean) * public void com.Jevin.blog.Person.love() * 当然这里还有从Object父类中继承来的public方法,这里就不写了。 */ /*Method[] methods=clazz.getMethods(); for(Method method:methods){ System.out.println(method); }*/ /** * 2.利用getMethod(String arg,Class... paramterType)获取本类中public修饰的成员方法 * 第一个参数表示:方法名 * 第二个参数表示:方法中参数的反射类型 * * 结果:public void com.Jevin.blog.Student.test(int,boolean) */ /*Method method=clazz.getMethod("test",int.class,boolean.class); System.out.println(method);*/ /** * 3.利用getDeclaredMethods()获取本类中所有权限的成员方法,包括public,private,protected,default * * 结果: * public void com.Jevin.blog.Student.test(int,boolean) * void com.Jevin.blog.Student.getScore(java.lang.String) * private void com.Jevin.blog.Student.CEE(java.lang.String) * protected void com.Jevin.blog.Student.hateScore(double) */ /*Method[] methods=clazz.getDeclaredMethods(); for(Method method:methods){ System.out.println(method); }*/ /** * 4.利用getDeclaredMethod(String arg,Class... paramterType)货期本类中任意权限下的成员方法 * * 结果:private void com.Jevin.blog.Student.CEE(java.lang.String) */ Method method=clazz.getDeclaredMethod("CEE",String.class); System.out.println(method); }}
//如果我要利用放射调用Student类中的getScore(String str)方法@Testpublic void test(){ Class clazz = Student.class; Student student = (Student)clazz.newInstance(); //第一个参数是String类型,表示调用的方法名称。 //第二个参数是这个调用方法的参数的Class对象 Method method = clazz.getMethod("getScore", String.class); //invoke方法,第一个参数是该方法所在类的对象。 //第二个参数是该方法参数的对象 method.invoke(student, new String());}
好了,大致上最基本的就这些了。其他的更高深的等以后段位高了再发吧!
转载地址:http://jrtvb.baihongyu.com/