经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
JAVA 注解
来源:cnblogs  作者:不该相遇在秋天  时间:2018/10/23 9:28:37  对本文有异议

一、注解是什么?

官方概念:java支持在源文件中嵌入补充信息,这类信息被称为注解,也被称为元数据。
个人理解:注解,就是标记。

二、注解有什么用?

1.用过spring的人我想天天都在用@Controller、@Autowrite、@Service 等等注解,这些注解的作用实际上只是标记而已。
如:框架启动时,main方法中跑一套初始化动作,遍历一遍所有的类,取出带有@Service注解的类,进行实例化,将实例化后的对象装入容器中,再遍历出所有带有@Autowrite注释的属性,将该属性的类型所对应的对象赋值给该属性,这就实现了依赖注入的特性,一切都是反射的功劳。

 

2.还有,很多人都用过一个叫lombok的工具,以@Getter @Setter 注解自动生成getter/setter 方法,这可不是程序能干的活,生成源代码的事情只有编译器才能做,这就是注解的第二种用法,在编译中使用,而不是在运行中使用。

 

三、内置注解

注解接口 应用场合 作用
@Deprecated 全部 将注解内容标记为过时
@Override 方法 方法重写
@Resource 类、接口 标记为要在其他地方要用到的资源
@Resource 属性、方法 注入
@FunctionalInterface 接口 标记为函数式接口
@Target 注解(只能在注解上使用的注解叫做 元注解) 表示该注解可以在哪里使用  详细枚举有点多 不细说 点进源码一目了然
@Retention 注解 保留策略 

 

 

 

 

 

 

 

 

 

保留策略 :3个枚举(SOURCE 、CLASS 、RUNTIME)   SOURCE在编译期间丢弃   CLASS编译时保存在.class文件中 但是会被JVM丢弃   RUNTIME在运行中依旧保留可以被反射机制发现

还有一些@Documented、@Inherited、@PostConstruct、@PreDestroy等等冷门注解,个人认为没必要特别关注。

 

四、注解声明

官方概念分了好几个类型 说的词一套一套的高深莫测,但实际上就下面这几种声明  

  1. public @ interface Controller {
  2. }

//裸注解  直接@Controller使用

 

  1. public @ interface Annot {
  2. String name();
       int sex() default 1;//默认值
  3. }

//带参数的注解需要传参数  @Annot(name="aaaaa")      @Annot(name="aaaaa",sex="2")

 

  1. public @ interface Mapper {
  2. String value();//value是特殊名字
  3. }

//之所以value()是特殊名字,是因为它既可以@Mapper(value = "aaaaa") 用 也可以 @Mapper("aaaaa")用

 

以上只是示例声明的写法  而正常的注解都会在头上加两个元注解

  1. @Target(ElementType.METHOD)//只能在方法上应用
  2. @Retention(RetentionPolicy.RUNTIME)//保留策略选择运行中
  3. public @ interface Mapper {
  4. String value();//value是特殊名字
  5. }

 

五、注解使用(反射使用)

因为注解可以用在类头上,属性头上,方法头上,参数头上,写法都是用反射,非常相似,写出来不免有点多又重复,我自己看的时候也会觉得无趣

所以为避免拉低博客水准,这里只示例两个,全部示例请查看源码分享

 

  1. try {
  2. Class cla = Class.forName("TestController");
  3. if (cla.isAnnotationPresent(Controller.class)) {
  4. System.out.println("TestController类含有Controller注解");
  5. }
  6. } catch (Exception e) {
  7. e.printStackTrace();
  8. }

 

  1. try {
  2. Class cla = Class.forName("TestController");
  3. Method[] methods = cla.getDeclaredMethods();
  4. Arrays.stream(methods).forEach((v) -> {
  5. Parameter[] parameters = v.getParameters();
  6. Arrays.stream(parameters).filter((a)->a.isAnnotationPresent(Param.class)).forEach((aa)->{
  7. Annotation annotation = aa.getAnnotation(Param.class);
  8. System.out.println(v.getName() + "方法的" + aa.getName() + "参数有Param注解 值是" + ((Param) annotation).value());
  9. //注明一点 aa.getName() 所得到的名称实际上是arg0、arg1一类的 原因是编译器在编译的时候将参数名称替换成了arg+index格式
  10. });
  11. });
  12. } catch (Exception e) {
  13. e.printStackTrace();
  14. }

 

 

六、注解使用(编译使用)

研究中 待补充

 

七、源码分享

Fork me on Gitee

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号