通过Java反射,可以实现以下功能:
> 在运行时判断任意一个对象所属的类
> 在运行时构造任意一个类的对象
> 在运行时判断任意一个类所具有的方法和属性
> 在运行时调用任意一个对象的方法
反射常用API:
> Class类:反射的核心类,反射所有的操作都是围绕该类来生成的,通过Class类,可以获取类的属性,方法等内容信息。
> Field类:表示该类的属性(字段),可以获取和设置类中属性的值。
> Method类:表示类的方法,它可以用来获取类中方法的信息,或者执行方法。
> Constructor类:表示该类的构造方法。
使用反射的基本步骤:
> 导入java.lang.reflect.*;包;
> 获得需要操作的类的java.lang.Class对象;
> 调用Class的方法获取Field、Method等对象;
> 使用反射API进行操作。
获取Class对象的三种方式:
> 调用对象的getClass()方法
Student s = new Student();
Class c = s.getClass();
> 调用类的class属性
Class c = Student.class;
> 使用Class类的forName()静态方法
Class c = Class.forName("com.arvin.bean.Student");
括号中的类名称必须是带完整包名的类名称!!! 否则将抛出ClassNotFoundException
Constructor的使用:
> 通过Class对象的getConstructor(Class<T>... parameterTypes)来获得一个Constructor对象
> parameterTypes:需要被获取的构造方法的参数列表类型对象的Class对象
> 调用Constructor对象的newInstance(Object... initArgs)方法创建一个对应的对象
> initArgs:对象初始化时需要传入的参数
Field的使用:
> 通过Class对象的getDeclaredField(String fieldName)可以获取任何访问级别的属性,得到Field对象
Field field = c.getDeclaredField("name");
> 若第一步获取的属性在当前类中无访问权限,则需要设置通过反射访问时取消权限检查
field.setAccessible(true);
> true:表示运行时不检查权限
> false:表示运行时要检查权限
> 对filed对象进行赋值或者取值。setXxx(Object obj, Object value), getXxx(Object obj);
> 参数obj:应该修改其字段的对象
> value:要修改的值
Method的使用:
> 通过Class对象的getMethod(String methodName, Class<T>... parameterType)方法类获取一个Method对象
> methodName:需要获取的方法的方法名字符串
> parameterType:需要获取的方法的参数列表类型的Class对象
> 调用方法,通过Method对象的invoke(Object obj, Object... args)方法来执行
> obj:从中调用底层方法的对象
> args:被调用的方法的参数列表
!!!!!!!
注意:
使用反射虽然会很大程度上提高代码的灵活性,但是不能滥用反射,因为通过反射创建对象时性能要稍微低一些。
实际上,只有当程序需要动态创建某个类的对象时才会考虑使用反射,通常在开发通用性比较广的框架,基础平台是肯能会大量使用反射,
因为在很多Java框架中都需要根据配置文件信息来创建Java对象,从配置文件读取的只是某个类的字符串类名,程序需要根据字符串来创建
对应的实例,就必须使用反射。
在实际开发中,没有必要使用反射来访问已知类的方法和属性,只有当程序需要动态创建某个类的对象的时候才会考虑使用