JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。即为 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
功能清单1
1)获取对象包名称和类名称
2)所有类的对象其实都是Class的实例
3)通过Class实例化其他类的对象
4)获取类的所有实现接口
5)获取类的继承父类
6)获得其他类中的全部构造函数以及通过Class调用其他类中的构造函数
7)获取得其他类的全部属性,通过class取得一个类的全部框架
8)通过反射调用其他类中的方法
9)调用其他类的set和get方法
10)通过反射操作属性
11)获得类加载器,AppClassLoader 加载classpath指定的类,是最常用的加载器,也是java中默认的加载器。
为了方便运行,所有函数写在一个测试类中,具体代码注释以及运行结果都有包含(大家感觉有帮助帮忙转载一下,有什么问题文章下留言评论),具体代码如下文:
package com.yoodb; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class TestMain { public static void main(String[] args) { Demo demo = new Demo(); Class<?> demoAll = null; try { demoAll = Class.forName("com.yoodb.Demo"); } catch (ClassNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } /********** 获取对象包名称和类名称 **********/ System.out.println(demo.getClass().getName()); //输出结果: com.yoodb.Demo /********** 所有类的对象其实都是Class的实例 **********/ Class<?> demo1 = null; Class<?> demo2 = null; Class<?> demo3 = null; try { demo1 = new Demo().getClass(); demo2 = Demo.class; demo3 = Class.forName("com.yoodb.Demo"); System.out.println("demo1==>" + demo1); System.out.println("demo2==>" +demo2); System.out.println("demo3==>" +demo3); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } /* 输出结果: demo1==>class com.yoodb.Demo demo2==>class com.yoodb.Demo demo3==>class com.yoodb.Demo */ /********** 通过Class实例化其他类的对象 **********/ try { demo = (Demo) demoAll.newInstance(); demo.setId(1); demo.setName("www.yoodb.com"); System.out.println("DEMO 对象==>" + demo); } catch (InstantiationException | IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } //输出结果: DEMO 对象==>Demo [id=1, name=www.yoodb.com] /********** 获取类的所有实现接口 **********/ Class<?>[] tfs = demoAll.getInterfaces(); for (Class<?> cla : tfs) { System.out.println("DEMO 对象 实现接口==>" + cla.getName()); } //输出结果:DEMO 对象 实现接口==>com.yoodb.TFDemo /********** 获取类的继承父类 **********/ Class<?> sc = demoAll.getSuperclass(); System.out.println("DEMO 对象 继承父类==>" + sc.getName()); //输出结果:DEMO 对象 继承父类==>com.yoodb.FTDemo /********** 获得其他类中的全部构造函数以及通过Class调用其他类中的构造函数 **********/ Constructor<?>[] cts = demoAll.getConstructors(); try { for (Constructor<?> ctr : cts) { System.out.println("构造函数 ==>" + ctr); } demo = (Demo) cts[1].newInstance(1,"www.yoodb.com");//注意有参无参构造方法的先后顺序 System.out.println("调用其他类构造函数 ==>" + demo); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } /* 输出结果: 构造函数 ==>public com.yoodb.Demo() 构造函数 ==>public com.yoodb.Demo(java.lang.Integer,java.lang.String) 调用其他类构造函数 ==>Demo [id=1, name=www.yoodb.com] */ /********** 获取得其他类的全部属性,通过class取得一个类的全部框架 **********/ Field[] fields = demoAll.getDeclaredFields(); for (Field field : fields) { int mfs = field.getModifiers(); String priv = Modifier.toString(mfs); Class<?> type = field.getType(); System.out.println("权限修饰符==>" + priv); System.out.println("属性类型==>" + type); System.out.println("属性名称==>" + field.getName()); } /* 输出结果: 权限修饰符==>private 属性类型==>class java.lang.Integer 属性名称==>id 权限修饰符==>private 属性类型==>class java.lang.String 属性名称==>name */ /********** 通过反射调用其他类中的方法 **********/ try { Method method = demoAll.getMethod("execte",Integer.class,String.class); method.invoke(demoAll.newInstance(), 20 , "中国"); } catch (NoSuchMethodException | SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 输出结果:集合==>20---中国 /********** 调用其他类的set和get方法 **********/ try { Object obj = demoAll.newInstance(); setter(obj, "Id" ,20, Integer.class); getter(obj,"Id"); } catch (InstantiationException | IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } //输出结果==> get 方法输出==>20 /********** 通过反射操作属性 **********/ try { Object obj = demoAll.newInstance(); Field field = demoAll.getDeclaredField("name"); field.setAccessible(true); field.set(obj, "www.yoodb.com"); System.out.println(field.get(obj)); } catch (InstantiationException | IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchFieldException | SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } //输出结果:www.yoodb.com /********** 获得类加载器 **********/ System.out.println("类加载器==>"+ demo.getClass().getClassLoader().getClass().getName()); // 输出结果:类加载器==>sun.misc.Launcher$AppClassLoader } /** * @param obj 操作对象 * @param att 操作属性名称 */ private static void getter(Object obj,String att){ try { Method method = obj.getClass().getMethod("get" + att); System.out.println("get 方法输出==>" + method.invoke(obj)); } catch (NoSuchMethodException | SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * @param obj 操作对象 * @param att 操作属性名称 * @param value 设置值 * @param type 参数属性 */ private static void setter(Object obj, String att, Object value, Class<?> type){ try { Method method = obj.getClass().getMethod("set" + att, type); method.invoke(obj, value); } catch (NoSuchMethodException | SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
辅助测试类,包含继承类,接口以及数据类,具体代码如下:
package com.yoodb; //继承类 class FTDemo { } //实现接口 interface TFDemo { } public class Demo extends FTDemo implements TFDemo{ private Integer id; private String name; public Demo() { } public Demo(Integer id, String name) { this.id = id; this.name = name; } public void execte(Integer id,String name){ System.out.println( "集合==>" + id + "---" + name ); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Demo [id=" + id + ", name=" + name + "]"; } }
所有输出结果如下:
com.yoodb.Demo demo1==>class com.yoodb.Demo demo2==>class com.yoodb.Demo demo3==>class com.yoodb.Demo DEMO 对象==>Demo [id=1, name=www.yoodb.com] DEMO 对象 实现接口==>com.yoodb.TFDemo DEMO 对象 继承父类==>com.yoodb.FTDemo 构造函数 ==>public com.yoodb.Demo() 构造函数 ==>public com.yoodb.Demo(java.lang.Integer,java.lang.String) 调用其他类构造函数 ==>Demo [id=1, name=www.yoodb.com] 权限修饰符==>private 属性类型==>class java.lang.Integer 属性名称==>id 权限修饰符==>private 属性类型==>class java.lang.String 属性名称==>name 集合==>20---中国 get 方法输出==>20 www.yoodb.com 类加载器==>sun.misc.Launcher$AppClassLoader
功能清单2
将反射应用于工厂模式,方便于在添加每个子类的时候不用去修改工厂类
工厂模式不是很了解的话,建议看一下“ Java 设计模式之工厂模式 文章 ”,链接地址:http://blog.yoodb.com/yoodb/article/detail/309
将反射用于工厂模式,具体代码如下文:
package com.yoodb; public class FactoryMode { public static void main(String[] args) { Animal fy = Factory.getInstance("com.yoodb.Cat"); if(fy != null){ fy.eat(); } } } interface Animal{ public void eat(); } class Cat implements Animal{ public void eat(){ System.out.println("猫吃鱼!"); } } class Dog implements Animal{ public void eat(){ System.out.println("狗吃肉!"); } } class Factory { public static Animal getInstance(String className){ Animal al = null; try { al = (Animal) Class.forName(className).newInstance(); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return al; } }
功能清单3
利用反射机制将 JavaBean 复制给另一个JavaBean 对象,具体代码如下文:
package com.yoodb; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Reflect { public static void main(String[] args) { Deer deer = new Deer(); deer.setId(1); deer.setName("www.yoodb.com"); Deer et = (Deer) invoke(deer); System.out.println(et); // 输出结果:Deer [id=1, name=www.yoodb.com] } public static Object invoke(Object object){ Object newObj = null; try { Class<?> cla = object.getClass(); newObj = cla.getConstructor(new Class[]{}).newInstance(new Object[]{}); Field[] fields = object.getClass().getDeclaredFields(); for (Field field : fields) { String fieldName = field.getName(); String firstLetter = fieldName.substring(0,1).toUpperCase(); String getMethodName = "get" + firstLetter + fieldName.substring(1);//对象里所有get*函数 String setMethodName = "set" + firstLetter + fieldName.substring(1);//对象里所有set*函数 Method getMethod = cla.getMethod(getMethodName, new Class[]{}); Method setMethod = cla.getMethod(setMethodName, new Class[]{field.getType()}); //调用原对象中的get*函数 Object value = getMethod.invoke(object, new Object[]{}); //调用复制对象set*函数 setMethod.invoke(newObj, new Object[]{value}); } } catch (InstantiationException | IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException | SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException | InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } return newObj; } } class Deer{ private Integer id; private String name; public Deer() {} public Deer(Integer id, String name) { this.id = id; this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Deer [id=" + id + ", name=" + name + "]"; } }
复制一个类的对象,为newObj,程序中的 new Class[]{} 是一种快捷方式,获得方法的引用。[]中用来放参数,{}里面可以放置方法的返回类型。new Class[]{}相当于new class("构造函数参数").newinstance(),输出结果如下:
Deer [id=1, name=www.yoodb.com]