1.什么是反射?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
通俗来说,反射机制就是可以把一个类,类的成员(函数,属性),当成一个对象来操作,也就是说,类,类的成员,我们在运行的时候还可以动态地去操作他们。
2.为什么需要反射?
反射能够让我们:
(1)在运行时检测对象的类型;
(2)动态构造某个类的对象;
(3)检测类的属性和方法;
(4)任意调用对象的方法;
(5)修改构造函数、方法、属性的可见性;
反射是框架中常用的方法。
3.demo
(1)反射获取field
package reflection; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class GetFieldsFromReflection { /**通过反射去获取类的私有属性和访问私有方法 * @param args * @throws NoSuchFieldException * @throws SecurityException */ public static void main(String[] args) throws SecurityException, NoSuchFieldException { try { Class<?> clazz = Class.forName("reflection.Person");//jvm加载类 Object obj = clazz.newInstance();//实例化 Person person = (Person)obj; //获取字段值,第一种:通过构造getter方法,然后使用method.invoke(object instance)获取 Field[] fields = clazz.getDeclaredFields();//for all fields for (Field field : fields) { System.out.print(field.getName() + ":"); //System.out.println(p.getName()); String getter = "get" + field.getName().substring(0,1).toUpperCase() + field.getName().toString().substring(1);//构造getter方法名称 Method m = clazz.getMethod(getter, new Class[0]);//获取字段值 System.out.println(m.invoke(person)); System.out.println(m.getReturnType()); System.out.println(m.getReturnType().getSimpleName()); System.out.println("-------------------------"); } //获取字段值,第二种:通过类field获取,field.get(object instance),若是静态变量,则field.get(object)或者field.get(object instance) Field fil0 = clazz.getField("sex"); System.out.println("第二种获取field方法:" + fil0.get( person));//非static变量通过类实例获取 Field fil1 = clazz.getField("staticSex"); System.out.println("第二种获取field方法(static变量):" + fil1.get( clazz));//static变量直接通过类获取 //获取字段类型 Field fil2 = clazz.getField("sex"); System.out.println("字段类型是:" + fil2.getType()); //getFields for accessible public fields Field[] fils = clazz.getFields(); for(Field field : fils){ System.out.println("-------------" + field + "------------------"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } class Person{ private String name = "lopez"; private String age = "23"; public String sex="male"; public static String staticSex = "fmale"; public static String getStaticSex() { return staticSex; } public static void setStaticSex(String staticSex) { Person.staticSex = staticSex; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public void getMessage(){ System.out.println("name:" + name + "age:" + age); } private void getPrivateData(){ System.out.println("name:lopez,passWord:123456"); } }
(2).反射获取method
package reflection; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class GetMethodFromReflection { /** * @param args */ public static void main(String[] args) { try { Class<?> clazz = Class.forName("reflection.HiWord"); Object o = clazz.newInstance(); //无参方法调用 Method m = clazz.getMethod("getWord", null); m.invoke(o, null); //有参方法调用 Method m1 = clazz.getMethod("getBook", String.class); m1.invoke(o, "MyParameter"); //多参方法 Method m2 = clazz.getMethod("getWatch", String.class,String.class,int.class); m2.invoke(o, "MyParameter1","MyParameter2",3); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } class HiWord{ public HiWord(){//构造方法 } public void getWord(){//无参方法 System.out.println("这是一个无参方法!"); } public void getBook(String str){//有参方法 System.out.println("这是一个有参方法,参数为:" + str); } public void getWatch(String str,String str1,int str2){//有参方法 System.out.println("这是一个有参方法,参数分别为:" + str + "," + str1 +"," +str2 + ""); } }
(3)反射获取构造器
package reflection; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class GetConstructorAndCreateInstance { /**reflection constructor * @author lilewen * @param args */ public static void main(String[] args) { try { Class<?> clazz = Class.forName("reflection.HelloWord2");//jvm加载类(Class<?>为未知类) Constructor<?>[] constructor = clazz.getConstructors(); //获取构造器参数类型 Class<?>[] paraeterType0s = constructor[0].getParameterTypes();//null Class<?>[] paraeterType1s = constructor[1].getParameterTypes();//class java.lang.String for (Class<?> class1 : paraeterType1s) { if(class1 != null){ System.out.println(class1.getSimpleName()); } } //调用构造器生成实例 HelloWord2 helloWord2 = (HelloWord2) constructor[0].newInstance(); HelloWord2 helloWord21 = (HelloWord2) constructor[1].newInstance("abc"); helloWord2.print(); helloWord21.print(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } class HelloWord2{ String s = null; public HelloWord2(){}; public HelloWord2(String s){ this.s = s; } public void print(){ System.out.println(s); } }
(4)反射访问私有属性
package reflection; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class AccessPrivateFromReflection { /** * @param args */ public static void main(String[] args) { try { Class<?> clazz = Class.forName("reflection.Person1"); Object o = clazz.newInstance(); //访问私有变量 Field[] fields = clazz.getDeclaredFields();//获取私有变量getDeclaredFields //Field[] fils = o.getClass().getFields();只能获取public变量 for(Field field : fields){ field.setAccessible(true);//必须设置为可访问 System.out.println(field.get(o)); } //访问私有方法 Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { method.setAccessible(true); method.invoke(o,null); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } class Person1{ private String name = "lopez"; private String password = "123456"; public String age = "23"; private String Method1(){ System.out.println("私有方法能够被访问!"); return "OK"; } }