标签:阶段 reflect tco meta 项目 相关 源码 comm interface
反射:是一种机制,利用该机制可以在程序运行过程中对类进行解剖并操作类中的方法,属性,构造方法等成员。
是另外一种调用构造方法、普通方法、属性的方式。
对比普通方式:
功能更强
但是更麻烦
反射操作的统一步骤:
获取Class字节码对象
要操作什么,就获取什么:getxxx(), getDeclaredXXX()
要操作构造方法,就获取Constructor对象
要操作普通方法,就获取Method对象
要操作属性字段,就获取Field对象
如果操作是private类型,就提前设置允许暴力反射:setAccessible(true)
反射调用
反射调用Constructor:newInstance()
反射调用Method:invoke()
反射调用Filed: set(), get()
//1. 类名.class
Class clazz = Student.class;
?
//2. 对象.getClass()
Class clazz = student.getClass();
?
//3. 静态方法Class.forName("全限定类名")
Class clazz = Class.forName("com.itheima._01reflect.Student");
//获取简单类名:不包含包的类名
String simpleName = clazz.getSimpleName();
?
//获取全限定类名
String name = clazz.getName();
?
//生成类的实例对象
Object object = clazz.newInstance();
clazz.getConstructor(Class... parameterTypes)
:获取public类型的Constructor对象
参数parameterTypes:构造方法的参数类型
clazz.getDeclaredConstructor(Class... parameterTypes)
:获取任意类型的Constructor对象
clazz.getConstructors()
:获取所有的public类型Constructor数组
clazz.getDeclaredConstructors()
:获取所有任意类型的Constructor数组
//1. 获取public类型的构造方法
Constructor constructor = clazz.getConstructor(String.class, Integer.class);
//2. 获取private类型的构造方法
Constructor constructor = clazz.getDeclaredConstructor();
constructor.newInstance(Object... parameterValues)
:反射调用构造方法,生成类实例对象
参数parameterValues:构造方法需要的实参值
注意:只能操作public类型的构造方法,如果要操作private类型的,需要提前设置暴力反射
setAccessible(true)
:设置允许暴力反射
clazz.getMethod(String methodName, Class... parameterTypes)
:获取public类型的方法
clazz.getDeclaredMethod(String methodName, Class... parameterTypes)
:获取任意类型的方法
clazz.getMethods()
:获取所有的public类型方法(自己的,和父类 的)
clazz.getDeclaredMethods()
:获取所有的任意类型方法(自己的)
Class<Student> clazz = Student.class;
?
//获取student里的study方法:public, 无参
Method method = clazz.getMethod("study");
//获取student里的eat方法:private,无参
method = clazz.getDeclaredMethod("eat");
//获取student里的sleep方法:public,有参:String
method = clazz.getMethod("sleep", String.class);
method.invoke(Object target, Object... parameterValues)
:反射调用方法
参数:
target:调用哪个对象的方法
parameterValues:方法的实参
返回值:方法执行的返回值
只能调用public类型的方法。如果要调用private类型的,需要提前设置:允许暴力反射
setAccessible(true)
:设置允许暴力反射
clazz.getField(String fieldName)
:获取public类型的属性
clazz.getDeclaredField(String fieldName)
:获取任意类型的属性
clazz.getFields()
:获取所有public类型的属性数组
clazz.getDeclaredFields()
:获取所有任意类型的属性数组
//获取Class对象
Class<Student> clazz = Student.class;
//获取属性的Field对象:name,private
Field field = clazz.getDeclaredField("name");
//获取属性的Field对象:sex,public
field = clazz.getField("sex");
field.set(Object target, Object value)
:设置属性值
参数:
target:设置哪个对象的属性值
value:要设置的属性值
field.get(Object target)
:获取属性值
参数:
target:获取哪个对象的属性值
返回值:
属性值,Object
Student student1 = new Student("老王");
Student student2 = new Student("老李");
?
?
//获取Class对象
Class<Student> clazz = Student.class;
//获取name的Field对象
Field field = clazz.getDeclaredField("name");
?
field.setAccessible(true);
?
//1. 设置student1的name的属性值
field.set(student1, "老赵");
System.out.println(student1);
?
//2. 获取student2的name属性值
Object fieldValue = field.get(student2);
System.out.println(fieldValue);
BeanUtils:Apache的commons项目提供的一个工具包,简化了JavaBean的封装。
相关概念:
字段:类里的成员变量名
属性:get/set方法,去年前缀,首字母小写是属性
注意:创建的字段,建议使用idea的快捷键生成get/set方法==>保证了字段名和属性名一致
相关jar包:
BeanUtils.setProperty(Object bean, String fieldName, Object fieldValue)
:设置属性值
BeanUtils.getProperty(Object bean, String fieldName)
:获取属性值
BeanUtils.populate(Object bean, Map<String, Object> map)
:把map里的数据封装成JavaBean
注解:Annotation,是JDK1.5提供的新特性。
注解:是一种和class、interface同一等级的语法说明,是一种记号(标记)。本身没有功能,其它程序、工具根据记号提供不同的功能。
作用:
辅助生成文档的:
@Documented
@author:作者
@version:版本(代码的版本,而不是jdk的版本)
编译检查:
@Override:方法是重写的方法。添加之后,idea/eclipse会检查语法是否正确
@Deprecated:标记方法已过时。标记之后,idea/eclipse会给这些方法的使用加上删除线
@SupressWarning:压制警告。标记之后,idea/eclipse不再显示警告信息
代替xml配置文件:
@WebServlet:(Tomcat提供的注解)配置一个Servlet的信息的,早期是使用web.xml配置
注意:
注解本身没有功能;其它软件、其它程序、其它框架会根据注解,设置功能
元注解:JDK提供的,用来限制自定义注解的注解。
常见的有2个:
@Target:用来限制自定义注解可以用在什么地方。从ElementType里取值,常用值有:
ElementType.TYPE:可以用在类、接口上
ElementType.METHOD:可以用在方法上
ElementType.FIELD:可以用在成员变量上
@Retention:用来限制自定义注解的生命周期(保留到什么阶段)。从RetentionPolicy里取值,常用的有:
RetentionPolicy.SOURCE:自定义注解保留到源码阶段。 字节码和运行阶段不存在的
RetentionPolicy.CLASS:自定义注解保留到字节码阶段。在运行阶段是不存在原
RetentionPolicy.RUNTIME:自定义注解保留到运行阶段。所有阶段都存在
注解的属性,并非任意属性都可以。支持的属性有:
8种基本数据类型
String
Class
枚举
注解
以上类型的数组形式
@注解名(属性名=值, 属性名=值, ...)
注意:
如果属性有默认值,使用属性时可以不设置值
如果只有一个属性要设置值,并且属性名称是value,使用注解时可以简写成:@注解名(值)
自定义注解必须要保留到运行阶段,才可以解析
method.isAnnotationPresent(Class annotationClass)
:判断方法上是否有指定的注解
反射:掌握反射的统一步骤
1. 获取Class对象
2. 要操作什么,就获取什么:clazz.getXXX(), clazz.getDeclaredXXX()
构造方法:Constructor对象
普通方法:Method对象
字段属性:Field对象
3. 如果是private类型的,反射之前,要允许暴力反射:xxx.setAccessible(true)
4. 反射操作
构造方法的反射调用:constructor.newInstance(Object... parameterValues)
普通方法的反射调用:method.invoke(Object target, Object... paramaterValues)
字段属性的反射调用:
field.set(Object target, Object value),
field.get(Object target)
BeanUtils的使用:
BeanUtils.setProperty(bean, fieldName, fieldValue)
BeanUtils.getProperty(bean, fieldName)
BeanUtils.populate(bean, map)
注解:
能说出一些JDK提供的注解:@author, @version, @Override, @Deprecated, @SupressWarning
了解元注解及其作用:
@Target:限制自定义 注解用在什么地方,从ElementType里取值
@Retention:限制自定义注解保留到什么阶段(生命周期),从RetentionPolicy里取值
掌握注解的使用:
@注解名(属性名=值, 属性名=值,....)
如果属性有默认值,可以不设置值
如果只有一个属性要设置值,并且属性名称是value,可以简写成:@注解名(value的值)
了解注解的解析:
method.isAnnotationPresent(Class annotationClass)
:判断方法上是否有指定注解
标签:阶段 reflect tco meta 项目 相关 源码 comm interface
原文地址:https://www.cnblogs.com/penghuake/p/10886322.html