为什么需要反射?
需求:我公司定义了一组接口,然后第三方公司按照我公司的接口实现了一套功能,然后交给我们,但是我们公司的项目已经结束,如何实现动态加载第三方公司提供的功能。(类似于热拔插效果)
什么是反射?
反射就是八类中的各种成分映射成各种对象。等同于解刨,可以拿到类中任何成分。
反射常用类:
- Class:获取类和类的成员信息
- Filed:可访问的类的属性
- Method:类的方法
- Constructor:类的构造方法
使用反射基本步骤:
- 1.导入java.lang.reflect.*
- 2.获得需要操作的类的Java.lang.Class对象
- 3.调用Class的方法获取Field、Method等对象
Field[] declaredFields = clazz.getDeclaredFields();
2.获取单个属性用的类是Field, ----------- Field name = clazz.getDeclaredField("name");
注:Declared这个关键字获取私有的必须要带上,如果想修改private属性,必须先修改权限可以访问 如:name.setAccessible(true);
public static void getField() throws Exception{ //1获取类对象 Class<?> clazz = Class.forName("com.qf.Person"); //2获取 Field[] declaredFields = clazz.getDeclaredFields(); for (Field declaredField : declaredFields) { System.out.println(declaredField); } //获取单个 System.out.println("--------------------------"); Field name = clazz.getDeclaredField("name"); // // Person wangwu=new Person(); // wangwu.name="王五"; Object wangwu = clazz.newInstance(); //赋值 name.setAccessible(true); name.set(wangwu, "王五");// wangwu.name="王五"; //获取 Object object=name.get(wangwu);// wangwu.name System.out.println(object); }
Constructor<?>[] constructors = clazz.getConstructors();
Constructor<?> constructor = clazz.getConstructor();
Constructor<?> constructor1 = clazz.getConstructor(String.class, int.class, String.class);
public static void getConstructor() throws Exception{ Class<?> clazz=Class.forName("com.qf.Person"); //1获取构造方法 Constructor<?>[] constructors = clazz.getConstructors(); for (Constructor<?> constructor : constructors) { System.out.println(constructor); } System.out.println("--------------------------"); //2获取单个构造方法 //2.1获取无参构造方法 Constructor<?> constructor = clazz.getConstructor(); //2.2获取带参 Constructor<?> constructor1 = clazz.getConstructor(String.class, int.class, String.class); System.out.println(constructor); System.out.println(constructor1); //3利用构造方法创建对象 System.out.println("---------利用构造方法创建对象------------"); Person zhangsan=new Person(); Object lisi = constructor.newInstance(); System.out.println(zhangsan); System.out.println(lisi); Object wangwu = constructor1.newInstance("王五", 20, "男"); System.out.println(wangwu); //简单创建对象的方法 Object o = clazz.newInstance(); System.out.println(o.toString()); }
Method[] methods = clazz.getMethods();
2.获取公类自己所有的方法,包括非公开的方法
Method[] methods = clazz.getDeclaredMethods();
3 获取单个方法(无参)
Method show = clazz.getMethod("show");show.invoke(zhangsan);// zhangsan.show();注:必须要指定对象 invoke(obj p)
public static void getMethod() throws Exception{ //1获取无参的方法 Class<?> clazz=Class.forName("com.qf.Person"); //Method[] methods = clazz.getMethods();//获取公类自己公开的方法,继承的公开方法 // Method[] methods = clazz.getDeclaredMethods();//获取公类自己所有的方法,包括非公开的方法 // System.out.println("-----------getMethods();----------"); // for (Method method : methods) { // System.out.println(method); // } // Person p=new Person(); // p.show(); Object zhangsan = clazz.newInstance(); Method show = clazz.getMethod("show"); show.invoke(zhangsan);// zhangsan.show(); //2获取有参 Method show2=clazz.getMethod("show",String.class); show2.invoke(zhangsan, "北京"); //3获取带返回值的方法 Method getInfo = clazz.getMethod("getInfo"); Object value=getInfo.invoke(zhangsan); System.out.println(value); //4获取静态方法 Method print = clazz.getMethod("print"); print.invoke(null);// Person.print(); //5私有方法 Method show3 = clazz.getDeclaredMethod("show", String.class, String.class); //设置访问权限无效 show3.setAccessible(true); show3.invoke(zhangsan, "上海","zhangsan@qq.com"); }
注:Java ,内省机制,是一种使用反射获取或设置对象属性的一种方式
- Introspector 内省类
- BeanInfo 类的信息
- PropertyDescriptor 属性描述符
public class Demo { public static void main(String[] args) throws Exception{ CarManager carManager=new CarManager(); //car Field car = CarManager.class.getDeclaredField("car"); Class<?> carClass = car.getType(); //获取注解 CarAnnotation annotation = car.getAnnotation(CarAnnotation.class); Object o = carClass.newInstance(); //Java ,内省机制,是一种使用反射获取或设置对象属性的一种方式 // Introspector 内省类 // BeanInfo 类的信息 // PropertyDescriptor 属性描述符 Class<?> clazz3=CarAnnotation.class; //1使用内省类Introspector获取类信息对象 BeanInfo beanInfo = Introspector.getBeanInfo(carClass); //2调用类信息的getPropertyDescriptors()获取属性描述符 PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); //3遍历 for (PropertyDescriptor pd : propertyDescriptors) { //System.out.println(pd.getName()); //System.out.println(pd.getName()); String name=pd.getName();//属性 try { Method method = clazz3.getMethod(name); if(method!=null){ Object value = method.invoke(annotation); Method writeMethod = pd.getWriteMethod(); writeMethod.invoke(o,value); } } catch (Exception e) { continue; } } System.out.println(o.toString()); } }