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

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. Java常用开源库

    Java的经久不衰,很大程度上得益于Java的生态好.在日常开发中,我们也会经常使用到各种开源库和工具类,为了避免重复造轮子,本文将贴出工作及学习中会用到的部分开源库和工具类.Java的生态实在太大, ...

  2. 感知机算法(PLA)代码实现

    目录 1. 引言 2. 载入库和数据处理 3. 感知机的原始形式 4. 感知机的对偶形式 5. 多分类情况-one vs. rest 6. 多分类情况-one vs. one 7. sklearn实现 ...

  3. DJANGO-天天生鲜项目从0到1-001-环境框架搭建

    本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...

  4. python 结合redis 队列 做一个例子

    结合redis 队列 做了一个例子 #!/usr/bin/env python # coding: utf-8 # @Time : 2018/12/21 0021 13:57 # @Site : # ...

  5. Ansible部署zabbix-agent

    playbook目录 zabbix/ ├── hosts ##定义的主机列表 ├── install_zabbix_agent.yml ##安装入口文件 └── roles ├── install_z ...

  6. pandas之cut

    cut( )用来把一组数据分割成离散的区间. cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_low ...

  7. Android中Activity的启动模式和使用场景

    一.为什么需要启动模式 在Android开发中,我们都知道,在默认的情况下,如果我们启动的是同一个Activity的话,系统会创建多个实例并把它们一一放入任务栈中.当我们点击返回(back)键,这些A ...

  8. JAVA基础(jdk安装和环境变量的配置)

    JAVA 1.何为JAVA Java的发展可以归纳如下的几个阶段. (1)第一阶段(完善期):JDK 1.0 ( 1995年推出)一JDK 1.2 (1998年推出,Java更名为Java 2): ( ...

  9. IO流——转换流、缓冲流

    一.转换流 1. OutputStreamWriter类 属于字符输出流,OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字节. 它的作 ...

  10. Django学习路4_数据库添加元素,读取及显示到网页上

    在 views 中实现对数据库的添加和读取数据库 添加数据 对象 = models 中创建的类名() 对象.列名 = '字段值' 对象.save() 进行保存 return HttpResponse( ...