Annotation:注解 Java提供的一种源程序中关联信息或元素的方法。注解只能被动执行,永远不可能有主动行为。
元注解:注解注解的注解。中华文字的博大精深在此刻体现得无比的精妙了,哈哈。
元注解有以下:
@Retention:注解保留的作用范围。取值枚举RetentionPolicy
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
* 只在源码中保留
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
* 默认选择 保留到字节码class中 但运行时无法得到
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
* 不仅保留到class,在运行时也可得到
*/
RUNTIME
}
@Target 注解能修饰的元素 取值ElementType枚举
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}
public enum ElementType {
/*
* Class, interface (including annotation type), or enum declaration
* 能修饰类、接口、枚举类
*/
TYPE,
/*
* Field declaration (includes enum constants)
* 能修饰成员变量
*/
FIELD,
/*
* Method declaration
* 能修饰方法
*/
METHOD,
/*
* Formal parameter declaration
* 能修饰参数
*/
PARAMETER,
/*
* Constructor declaration
* 能修饰构造器
*/
CONSTRUCTOR,
/*
* Local variable declaration
* 能修饰局部变量
*/
LOCAL_VARIABLE,
/*
* Annotation type declaration
* 能修饰注解
*/
ANNOTATION_TYPE,
/*
* Package declaration
* 能修饰包
*/
PACKAGE
}
@Documented 可以在 javadoc中找到
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
@Inherited 注解类容可以被子类继承
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
注解其更多的使用是我们自定义我们自己的注解,方便我们编码的时候使用。
举个例子,我们自定义一个请求参数的注解,以注解的方式为参数赋值。
自定义注解如下:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface BindGet {
String param() default "";
}
注解保留到运行时,我们会用反射得到其值。作用域为方法。
使用注解的类如下:
public class TestGet {
private static final String TAG = TestGet.class.getSimpleName();
@BindGet(param = "Lily")
void getUser(String userName){
String url = "http://www.baidu.com/?username="+userName;
Log.e(TAG,url);
}
}
类里面定义一个获取用户信息的方法,使用注解赋值参数为Lily,然后用Log输出请求地址。
接下来,我们用反射的方法使用TestGet类。那么这里有个疑问,为什么以反射的方式使用?因为注解特性注解永远只能被动执行,不会有主动行为。如果对反射不熟悉的可以看下https://blog.csdn.net/calm1516/article/details/90902784这里面关于反射的。调用代码如下:
Class c = Class.forName("com.calm.calmstudy.TestGet");
TestGet testGet = (TestGet) c.newInstance();
Method[] methods = c.getDeclaredMethods();
for (Method method: methods){
if(method.isAnnotationPresent(BindGet.class)){
BindGet bindGet = method.getAnnotation(BindGet.class);
String param = bindGet.param();
method.invoke(testGet,param);
}
}
我们会得到输出地址http://www.baidu.com/?username=Lily
符合我们的预期。当然,注解的使用不会这么简单,其实我们在开发或者使用的一些开源工具等都会解除到很多的注解,如Retrift、GreenDao等等,我们想要更进一步的了解它们,这些知识储备必然是不可或缺的了。