前言:
反射作为一个高级技术,应该是必须掌握的,之前虽然一直都懂,也会用,但是真正做需求的时候总感觉容易忘记,而且很多细节和一些实用的用法不太懂,看了别人的博客,也写的不太详细,现在打算从初级到高级,写的尽量详细和易懂,也方便之后自己翻看.
注解类关键字:@interface
每个注解,都需要添加该关键字才能作为一个注解.
元注解:
@Target:java的原始注解,用于声明注解类型
ElementType:枚举类,其中包含了多种注解声明的字段:
TYPE,类,接口(包括注释类型)或枚举声明
FIELD,成员属性声明
METHOD,方法声明
PARAMETER,正式参数声明
CONSTRUCTOR,构造函数声明
LOCAL_VARIABLE,局部变量声明
ANNOTATION_TYPE,注解类型声明
PACKAGE,包装声明
TYPE_PARAMETER,键入参数声明
TYPE_USE;使用类型
@Retention :注解策略,说明注解的保留时间,分3种策略
RetentionPolicy.RUNTIME:注释将由编译器记录在类文件中,并由VM在运行时保留,因此可以反射读取,运行时调用。
RetentionPolicy.CLASS:注释将由编译器记录在类文件中,但VM不需要在运行时保留,即在编写代码时执行
RetentionPolicy.SOURCE:注释将被编译器丢弃。(这种情况没用过,具体如何定义后面再给出结论)
上面是最基本的介绍,去看看文档,大家应该都懂。其中常用的是方法,类,成员属性加上运行时注解。另外一些注解声明用到的较少,我自己也没怎么用过,有兴趣的可以自己写个demo去研究下。
反射
关于反射的官方解释:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
我自己的理解:
反射是用来修改和调用对象的方法的一种方式,简单点,从实用角度来说,就是让你对于某些API中无法修改和调用的对象,通过反射的方式去使用.
接下来介绍下反射的简单用法:
View view = new View();
//反射修改属性
view.show = 10;
Field member = view.getClass().getDeclaredField("show");
member.setAccessible(true);
member.set(view, 78);
System.out.println(view.show);
//反射调用方法
Method method = view.getClass().getDeclaredMethod("modify");
method.setAccessible(true);
method.invoke(view, null);
上面是最基本的用法了,不过有一个方法需要注意,setAccessible(),这个方法的作用是让你能够拿到私有方法和私有属性并进行修改,如果方式和属性是private的,你直接set或invoke,这个时候是会抛异常的,如果设置的是private final,则说明这个属性,即使通过反射也是无法修改的,因为设置了final,是不允许对对象进行修改的.不过方法的话设置了private final依然可以调用.
然后举个例子,android中通过反射的方式修改光标的值,代码如下:
Field f = TextView.class.getDeclaredField("mCursorDrawableRes");
f.setAccessible(true);
f.set(et, R.drawable.editext_cursor);