反射机制+注解

反射是一种机制,利用该机制可以在程序运行过程中对类进行解剖并操作类中的方法,属性,构造方法等成员。

前提:使用反射机制的前提条件是获取字节码文件对象,即Class类型对象.

获取Class对象的三种方式:

1:通过 类名.class 获取

eg:Class c = Student.class;

2:通过Object类的getClass()方法获取

eg:Student stu = new Student(); Class c = stu.getClass();

3:通过Class.forName(“权限定类型”)获取

eg: String className = "com.yxx.bean.Student"; Class clazz = Class.forName(className);

Class对象相关方法 :

String getSimpleName(); 获得简单类名,只是类名,没有包
String getName(); 获取完整类名,包含包名+类名
T newInstance() ;

创建此 Class 对象所表示的类的一个新实例。

要求:类必须有public的无参数构造方法

反射获取Class对象的Constructor方法:

Constructor getConstructor(Class... parameterTypes)

根据参数类型获取构造方法对象,只能获得public修饰的构造方法。

如果不存在对应的构造方法,则会抛出 java.lang.NoSuchMethodException 异常。

Constructor getDeclaredConstructor(Class... parameterTypes)

根据参数类型获取构造方法对象,包括private修饰的构造方法。

如果不存在对应的构造方法,则会抛出 java.lang.NoSuchMethodException 异常。

Constructor[] getConstructors() 获取所有的public修饰的构造方法
Constructor[] getDeclaredConstructors() 获取所有构造方法,包括privat修饰的
T newInstance(Object... initargs) 根据指定参数创建对象。
void setAccessible(true) 暴力反射,设置为可以直接访问私有类型的构造方法。

反射获取Class对象的Method方法:

Method getMethod("方法名", 方法的参数类型... 类型) 根据方法名和参数类型获得一个方法对象,只能是获取public修饰的
Method getDeclaredMethod("方法名", 方法的参数类型... 类型) 根据方法名和参数类型获得一个方法对象,包括private修饰的
Method[] getMethods() 获取所有的public修饰的成员方法,包括父类中。
Method[] getDeclaredMethods() 获取当前类中所有的方法,包含私有的,不包括父类中。
Object invoke(Object obj, Object... args)

根据参数args调用对象obj的该成员方法

如果obj=null,则表示该方法是静态方法

void setAccessible(boolean flag) 暴力反射,设置为可以直接调用私有修饰的成员方法

反射获取Class对象的Field方法:

Field getDeclaredField(String name) 根据属性名获得属性对象,包括private修饰的
Field getField(String name) 根据属性名获得属性对象,只能获取public修饰的
Field[] getFields() 获取所有的public修饰的属性对象,返回数组。
Field[] getDeclaredFields() 获取所有的属性对象,包括private修饰的,返回数组。

注解

  1. 属性的作用 可以让用户在使用注解时传递参数,让注解的功能更加强大。

  2. 属性的格式

         格式1:数据类型 属性名();

         格式2:数据类型 属性名() default  默认值;

     3.属性适用的数据类型

              八种基本数据类型(int,flfloat,boolean,byte,double,char,long,short)

              String类型,Class类型,枚举类型,注解类型

               以上所有类型的一维数组

元注解

@Target  
作用: 指明此注解用在哪个位置,如果不写默认是任何地方都可以使用。
可选的参数值在枚举类ElemenetType中包括:

TYPE: 用在类,接口上

FIELD:用在成员变量上

METHOD: 用在方法上

PARAMETER:用在参数上

CONSTRUCTOR:用在构造方法上

LOCAL_VARIABLE:用在局部变量上

@Retention  
作用: 定义该注解的生命周期(有效范围)。
可选的参数值在枚举类型RetentionPolicy中包括

SOURCE:注解只存在于Java源代码中,编译生成的字节码文件中就不存在了

CLASS:注解存在于Java源代码、编译以后的字节码文件中,运行的时候内存中没有,默认值。 RUNTIME:注解存在于Java源代码中、编译以后的字节码文件中、运行时内存中,程序可以通过反射获取该 注解。

注解的接口

1.Anontation:所有注解类型的公共接口,类似所有类的父类是Object。

2.AnnotatedElement:定义了与注解解析相关的方法,常用方法以下几个

boolean isAnnotationPresent(Class annotationClass); 判断当前对象是否有指定的注解,有则返回true,否则返回false。
T getAnnotation(Class<T> annotationClass); 获得当前对象上指定的注解对象。
Annotation[] getAnnotations(); 获得当前对象及其从父类上继承的所有的注解对象。

我们使用反射的时候 , 都需要先获取类的字节码对象 ,最常用的方式就是 Class.forName("类的全限定名") .我们可以通过字节码对象就可以获取类的构造器 , 从而创建对象 ,最常用的方式是通过字节码对象获取无参构造器getConstructor , 就可以调用构造器对象的 newInstance() 方法创建对象 , 当然这种方式简化为:字节码对象直接调用 newInstance() 方法创建对象 .也可以通过字节码对象获取指定的方法 , 然后调用方法对象的 invoke(Object obj, Object... args) 来执行此方法.也可以通过字节码对象获取类中的所有字段 , 从而给字段赋值和获取字段的值 .有了以上的基础 , 我们就可以通过一个指定全限定名 , 就可以创建该类对象的实例对象 , 执行里面的方法 , 给其字段进行赋值或者获取值.

发布了15 篇原创文章 · 获赞 2 · 访问量 4226

猜你喜欢

转载自blog.csdn.net/weixin_41858337/article/details/102523535