人的一生就像一篇文章,只有经过多次精心修改,才能不断完善

Java注解概念理解:

  Java注解又称为Java标注,是JDK5引入的一中注释机制,Java中大家熟悉的五种注解分别是:@Override,@Deprecated,@SuppressWarnings,@SafeVarargs,@FunctionalInterface,看到这些注解大家应该都不陌生,这是Java中基本的五个注解。

  Java注解可以通俗理解为打标签,我可以给一个年轻人打一个标签为年轻,活力,激情,理想主义等,这些就可以看作是年轻人的注解。可以理解标签是事物某些方面的特点和解释。

如何定义注解:

  定义注解通过@interface关键字来实现    

public @interface Fruit {
}

  如上代码,即创建了Fruit注解,可以理解一个名字为Fruit的标签。

  使用注解:使用注解的方法很简单,可以将注解放在类上或者方法上,看你需要这个注解实现什么作用了,例如将注解注释类

@Fruit
public class Annotest {
}

  这样就将@Fruit标签打到了Annotest这个类上。

  看到这,你可能就明白了,注解就是将标签打到某个方法,类,包上,标识这个类,使这个方法,类具有这个注解所具有的标识呗,是的,没错

  使用自定义注解仅仅做到这样是不够的,还需要用到Java中的元注解

元注解:

  元注解是一种基本的注解,可以运用到注解上边(可以理解为元注解也是一种标签,只不过他是特殊的标签,可以打在注解身上的一种注解)

  Java中的注解有以下五种,@Retention,@Documented,@Target,@Inherited,@Repeatable

  @Retention:保留,维持,保留的意思,该注解提供了注解的生命周期

       取值有如下几种:

       RetentionPolicy.SOURCE: 标识该注解只保留源码阶段,编译器即忽视丢弃 

       RetentionPolicy.CLASS:  高注解保留到编译阶段,不回加载到jvm

      RetentionPolicy.RUNTIME: 注解保留到运行时候
  @Documented:标识该注解属于文档类型,他的作用是将注解中的元素包含到javac中去
  @Target:标识该注解运用的地方,限制注解的使用场景,target的取值如下: 
      ElementType.ANNOTATION_TYPE:可以给一个注解类进行注解
      ElementType.CONSTRUCTOR:给一个构造方法进行注解
      ElementType.FIELD:给属性方法进行注解
      ElementType.LOCAL_VARIABLE:给局部方法进行注解
      ElementType.METHOD:给方法进行注解
      ElementType.PACKAGE:给包进行注解
      ElementType.PARAMETER:给一个方法内的参数进行注解
      ElementType.TYPE:给一个类型进行注解,类型包括:类,接口,枚举类
  @Inherited:继承注解,如果一个超类使用该注解,其子类没有被任何注解标注的话,那么这个子类就继承了该超类的注解
  @Repeatable:jdk1.8加进来的一个注解,意思是可重复的意思,使用该注解意味着注解的值可以取多个(这个注解我用到的很少,需要深入了解请百度)   注解属性:
  注解只有成员变量,没有方法,成员变量就是属性,例如:
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
public @interface Fruit {
int id();
String msg();
}

  该注解定义了两个成员:id和msg,在使用的时候,我们应该给它进行赋值

@Fruit(id = 1, msg = "anno")
public class TestAno {
}

  在注解中定义的成员类型时候必须是8中基本数据类型+类,接口,注解,以及注解数组

  注解中的成员属性还可以指定默认值

  

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
public @interface Fruit {
int id() default 0;
String msg() default "apple";
}

获取注解:

  我们使用注解的初衷就是对代码中的类,方法等打标签,那它的作用是什么,当然是在获取类或者方法的时候,判断这个类或者方法是不是该注解类型,进行特殊的操作和处理,那么如何检查和提取注解呢,相信你们已经想到,那就是使用Java中的反射机制

  反射获取注解:Class类中的方法判断类中isAnnotationPresent()方法判断是否运用注解,getAnnotation()方法获取注解对象,getAnnotations()获取所有的注解

public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
return GenericDeclaration.super.isAnnotationPresent(annotationClass);
}
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
Objects.requireNonNull(annotationClass); return (A) annotationData().annotations.get(annotationClass);
}

  public Annotation[] getAnnotations() {} 

  如下利用反射获取注解的例子:

  

@Fruit
public class Test { public static void main(String[] args) {
boolean isAnno = Test.class.isAnnotationPresent(Fruit.class);
if(isAnno) {
Fruit annotation = Test.class.getAnnotation(Fruit.class);
System.out.println(annotation.id());
System.out.println(annotation.msg());
}
}
}

  运行的结果当然是:0 apple

  接下来看注解在方法的注解如何提取

  1. 先定义一个属性注解:MyParamAnno

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyParamAnno { String value();
}

  2. 定义一个方法类型注解:MyMethodAnno

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.METHOD)
public @interface MyMethodAnno {
}

  3. 解析方法属性上注解示例:

@Fruit(msg = "skyline")
public class MethodAnnoTest { @MyParamAnno("hello")
String param; @MyMethodAnno
public void method(){} public static void main(String[] args) {
boolean isAnno = MethodAnnoTest.class.isAnnotationPresent(Fruit.class);
if (isAnno) {
Fruit annotation = MethodAnnoTest.class.getAnnotation(Fruit.class);
System.out.println(annotation.msg());
}
//解析属性方法注解
try {
Field param = MethodAnnoTest.class.getDeclaredField("param");
param.setAccessible(true);
//获取该变量的注解
MyParamAnno paramAnno = param.getAnnotation(MyParamAnno.class);
if(paramAnno != null) {
System.out.println("成员属性的注解值为:" + paramAnno.value());
} //获取方法的注解
Method method = MethodAnnoTest.class.getDeclaredMethod("method");
if (method != null) {
MyMethodAnno methodAnno = method.getAnnotation(MyMethodAnno.class);
System.out.println("方法注解:" + methodAnno.annotationType().getSimpleName());
} } catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} }
}
 输出的结果值为:
skyline
成员属性的注解值为:hello
方法注解:MyMethodAnno

总结:

  注释是为了标注和解释代码,但是由于用到反射机制,所以会对性能方面有所影响,所以不要滥用。

 

Java的注解浅析的更多相关文章

  1. java自定义注解类

    一.前言 今天阅读帆哥代码的时候,看到了之前没有见过的新东西, 比如java自定义注解类,如何获取注解,如何反射内部类,this$0是什么意思? 于是乎,学习并整理了一下. 二.代码示例 import ...

  2. lombok 简化java代码注解

    lombok 简化java代码注解 安装lombok插件 以intellij ide为例 File-->Setting-->Plugins-->搜索"lombok plug ...

  3. JAVA自定义注解

    在学习使用Spring和MyBatis框架的时候,使用了很多的注解来标注Bean或者数据访问层参数,那么JAVA的注解到底是个东西,作用是什么,又怎样自定义注解呢?这篇文章,即将作出简单易懂的解释. ...

  4. 深入理解Java:注解

    注解作用:每当你创建描述符性质的类或者接口时,一旦其中包含重复性的工作,就可以考虑使用注解来简化与自动化该过程. Java提供了四种元注解,专门负责新注解的创建工作. 元注解 元注解的作用就是负责注解 ...

  5. Java Annotation 注解

    java_notation.html div.oembedall-githubrepos { border: 1px solid #DDD; list-style-type: none; margin ...

  6. java自定义注解实现前后台参数校验

    2016.07.26 qq:992591601,欢迎交流 首先介绍些基本概念: Annotations(also known as metadata)provide a formalized way ...

  7. JAVA Socket超时浅析

    JAVA Socket超时浅析 套接字或插座(socket)是一种软件形式的抽象,用于表达两台机器间一个连接的"终端".针对一个特定的连接,每台机器上都有一个"套接字&q ...

  8. Java Android 注解(Annotation) 及几个常用开源项目注解原理简析

    不少开源库(ButterKnife.Retrofit.ActiveAndroid等等)都用到了注解的方式来简化代码提高开发效率. 本文简单介绍下 Annotation 示例.概念及作用.分类.自定义. ...

  9. paip.Java Annotation注解的作用and 使用

    paip.Java Annotation注解的作用and 使用 作者Attilax 艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog. ...

随机推荐

  1. Shell基本语法---处理海量数据的awk命令

    awk命令 其实是一门编程语言,支持条件判断,数组,循环等功能,与grep,sed被称为linux三剑客 之所以叫AWK是因为取其三位创始人 Alfred Aho,Peter Weinberger, ...

  2. 带你快速了解 MongoDB 分布式集群

    在分布式应用系统中,mongodb 已经成为 NoSQL 经典数据库.要想很好的使用 mongodb,仅仅知道如何使用它是不够的.只有对其架构原理等有了充分认识,才能在实际运用中使其更好地服务于应用, ...

  3. 题解 洛谷 P5331 【[SNOI2019]通信】

    考虑用费用流解决本题. 每个哨站看作一个点,并将其拆为两个点,建图方式为: \(S \longrightarrow x_i\) 容量为\(1\),费用为\(0\) \(x_i \longrightar ...

  4. 为什么在SpringBoot+maven的项目中,所引入的依赖包可以不指定依赖的版本号?

    当在Springboot项目中引入了spring-boot-starter-parent,则可以不用引入依赖包版本号,比如: <parent> <groupId>org.spr ...

  5. 附002.Nginx全系列大总结

    Nginx全系列总结如下,后期不定期更新. 欢迎基于学习.交流目的的转载和分享,禁止任何商业盗用,同时希望能带上原文出处,尊重ITer的成果,也是尊重知识. 若发现任何错误或纰漏,留言反馈或右侧添加本 ...

  6. Arrays.sort() ----- DualPivotQuicksort

    Arrays.sort() ----- DualPivotQuicksort DualPivotQuicksort是Arrays.sort()对基本类型的排序算法,它不止使用了双轴快速排序,还使用了T ...

  7. Monster Audio 使用教程(二)效果参数的保存

    点击左上角主菜单按钮,点击[保存]菜单,即可保存当前的所有效果参数. [另存为]菜单,则是把当前参数另存一个名称,然后通过[切换效果]菜单,实现效果的切换.  独立保存单个音轨的效果 点击音轨对应的[ ...

  8. python-闭包和装饰器-01-闭包(closure)

    闭包(closure) 闭包就是在一个函数定义的内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包,如: def line(a, b): def cal( ...

  9. ES数据库重建索引——Reindex(数据迁移)

    应用背景: 1.当你的数据量过大,而你的索引最初创建的分片数量不足,导致数据入库较慢的情况,此时需要扩大分片的数量,此时可以尝试使用Reindex. 2.当数据的mapping需要修改,但是大量的数据 ...

  10. IDEA 修改快捷键和Myeclipse 快捷键一致

    介绍 我们知道IDEA这款开发工具功能很强大,为了简化开发步骤,提高开发效率,使用快捷键很显然是必不可少的,那么怎么才能使得IDEA快捷键和MyEclipse快捷键 保持相同呢? 第一种方法,一个快捷 ...