Java的注解浅析
人的一生就像一篇文章,只有经过多次精心修改,才能不断完善
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的注解浅析的更多相关文章
- java自定义注解类
一.前言 今天阅读帆哥代码的时候,看到了之前没有见过的新东西, 比如java自定义注解类,如何获取注解,如何反射内部类,this$0是什么意思? 于是乎,学习并整理了一下. 二.代码示例 import ...
- lombok 简化java代码注解
lombok 简化java代码注解 安装lombok插件 以intellij ide为例 File-->Setting-->Plugins-->搜索"lombok plug ...
- JAVA自定义注解
在学习使用Spring和MyBatis框架的时候,使用了很多的注解来标注Bean或者数据访问层参数,那么JAVA的注解到底是个东西,作用是什么,又怎样自定义注解呢?这篇文章,即将作出简单易懂的解释. ...
- 深入理解Java:注解
注解作用:每当你创建描述符性质的类或者接口时,一旦其中包含重复性的工作,就可以考虑使用注解来简化与自动化该过程. Java提供了四种元注解,专门负责新注解的创建工作. 元注解 元注解的作用就是负责注解 ...
- Java Annotation 注解
java_notation.html div.oembedall-githubrepos { border: 1px solid #DDD; list-style-type: none; margin ...
- java自定义注解实现前后台参数校验
2016.07.26 qq:992591601,欢迎交流 首先介绍些基本概念: Annotations(also known as metadata)provide a formalized way ...
- JAVA Socket超时浅析
JAVA Socket超时浅析 套接字或插座(socket)是一种软件形式的抽象,用于表达两台机器间一个连接的"终端".针对一个特定的连接,每台机器上都有一个"套接字&q ...
- Java Android 注解(Annotation) 及几个常用开源项目注解原理简析
不少开源库(ButterKnife.Retrofit.ActiveAndroid等等)都用到了注解的方式来简化代码提高开发效率. 本文简单介绍下 Annotation 示例.概念及作用.分类.自定义. ...
- paip.Java Annotation注解的作用and 使用
paip.Java Annotation注解的作用and 使用 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog. ...
随机推荐
- Java常用开源库
Java的经久不衰,很大程度上得益于Java的生态好.在日常开发中,我们也会经常使用到各种开源库和工具类,为了避免重复造轮子,本文将贴出工作及学习中会用到的部分开源库和工具类.Java的生态实在太大, ...
- 感知机算法(PLA)代码实现
目录 1. 引言 2. 载入库和数据处理 3. 感知机的原始形式 4. 感知机的对偶形式 5. 多分类情况-one vs. rest 6. 多分类情况-one vs. one 7. sklearn实现 ...
- DJANGO-天天生鲜项目从0到1-001-环境框架搭建
本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...
- python 结合redis 队列 做一个例子
结合redis 队列 做了一个例子 #!/usr/bin/env python # coding: utf-8 # @Time : 2018/12/21 0021 13:57 # @Site : # ...
- Ansible部署zabbix-agent
playbook目录 zabbix/ ├── hosts ##定义的主机列表 ├── install_zabbix_agent.yml ##安装入口文件 └── roles ├── install_z ...
- pandas之cut
cut( )用来把一组数据分割成离散的区间. cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_low ...
- Android中Activity的启动模式和使用场景
一.为什么需要启动模式 在Android开发中,我们都知道,在默认的情况下,如果我们启动的是同一个Activity的话,系统会创建多个实例并把它们一一放入任务栈中.当我们点击返回(back)键,这些A ...
- JAVA基础(jdk安装和环境变量的配置)
JAVA 1.何为JAVA Java的发展可以归纳如下的几个阶段. (1)第一阶段(完善期):JDK 1.0 ( 1995年推出)一JDK 1.2 (1998年推出,Java更名为Java 2): ( ...
- IO流——转换流、缓冲流
一.转换流 1. OutputStreamWriter类 属于字符输出流,OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字节. 它的作 ...
- Django学习路4_数据库添加元素,读取及显示到网页上
在 views 中实现对数据库的添加和读取数据库 添加数据 对象 = models 中创建的类名() 对象.列名 = '字段值' 对象.save() 进行保存 return HttpResponse( ...