絮絮叨叨
以前学注解的时候,绑定了泛型一起学的,最后泛型和注解都没学好,今天打算深入学习下Spring的时候,到处都是注解,感觉不会注解啥都不会了,所以看了会儿博客,又翻出同事的java编程思想进行学习。
注解是干嘛的?
注解这个东西就是一种标记,配合注解的处理器,你就能对加有这个注解的方法或者类做点什么。注解里面也可以有一种长得像方法的属性,必须设置值,没有设置默认的必须加在括号里。
案例
一、 定义自己的注解类:
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.ANNOTATION_TYPE})
public @interface MyAnnotation {
long time();
}
@Retention、@Target是元注解,前者是定义这个注解什么级别可用(具体看RetentionPolicy枚举),后者是定义注释用在什么地方上(具体看ElementType枚举)。
二、 使用我自己的注解类:
public class MyAnnotationUse {
@MyAnnotation(time = 1)
public void testAdd(){
System.out.println("新增");
}
@MyAnnotation (time = 2)
public void testUpdate(){
System.out.println("更新");
}
}
这里可以看到,注解级别在方法上,里面的参数time因为没有默认值,所以必须写上。
三、 扫描自己的注解
// 反射,注解扫描器
public class MyTestRunner {
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
Class clazz = SomeDaoImplTest.class;
Method[] ms = clazz.getMethods();
for (Method method : ms) {
MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
if (myAnnotation!= null) {
System.out.println("time:"+myAnnotation.time());
method.invoke(clazz.newInstance(), null);
}
}
}
}
在反射注解这一步,我们可以讨论下注解级别的这三个意思了:
public enum RetentionPolicy {
// 在原文件中有效,被编译器丢弃
SOURCE,
// 在编译的过程中保留并且会写入Class文件中
CLASS,
// 在运行时有效
RUNTIME
}
- 刚刚的TestRunner类上,只有MyAnnotation是RUNTIME级别才能有输出,其它的时候是没有输出的。所以,虽然CLASS是class文件有效,但是,是反射不可见的。
- SOURCE类的标致性是@Override这种类似的,可以用于类型检查之类的,主要作用于编译器,见是常见,不常用。
- CLASS类型的注解在编译的过程中保留并且会写入Class文件中,但是JVM在加载类的时候不需要将其加载为运行时可见的(反射可见)的注解。
关于第3点:
在知乎看到这样一段话,“要编译A.java源码文件和B.class文件,其中A类依赖B类,并且B类上有些注解希望让A.java编译时能看到,那么B.class里就必须要持有这些注解信息才行。”然并卵,我愚蠢的脑袋并不能想到具体的证明案例。然后我又翻博客翻到了把这个证明得极好的案例,放链接:
自定义注解之源码注解(RetentionPolicy.SOURCE)
自定义注解之编译时注解(RetentionPolicy.CLASS)(一)
自定义注解之编译时注解(RetentionPolicy.CLASS)(二)——JavaPoet
自定义注解之编译时注解(RetentionPolicy.CLASS)(三)—— 常用接口介绍
结束
我的笔记到这里就结束了,这一个学习的过程还是挺长的,越学习越发现后面深不见底。然后这次意外似乎发现了大牛一枚:
[CSDN Rukey7]http://blog.csdn.net/github_35180164?viewmode=contents)
反射这一系列相当全面,值得学习。