元注解

@Target :标识注解的目标,默认为所有

  • ElementType.TYPE(用于类)
  • ElementType.FIELD(用于域,包括enum)
  • ElementType.METHOD(用于方法)
  • ElementType.PARAMETER(用于正式参数)
  • ElementType.CONSTRUCTOR(类型构造方法)
  • ElementType.LOCAL_VARIABLE(用于本地变量)
  • ElementType.ANNOTATION_TYPE(用于注解)
  • ElementType.PACKAGE(用于包)
  • ElementType.TYPE_PARAMETER(java8,用于输入参数)
  • ElementType.TYPE_USE (java8,用于类型)

@Retention:注解保留到哪

  • RetentionPolicy.SOURCE (只保留到源码,编译为.class文件时忽略)
  • RetentionPolicy.CLASS (只保留到.class文件,运行时忽略,default默认)
  • RetentionPolicy.RUNTIME (运行时保留,可以通过反射机制读取注解的信息。)

@Documented:将此注解保存在 Javadoc 中

@Inherited:允许子类继承父类的注解

@Repeatable:用于重复使用注解(Java8新增)

常用注解

一、@Override

常用于重写父类的方法,或实现接口的方法,若不满足则报错。

package java.lang;

import java.lang.annotation.*;

/**
* 使用在方法上,只存在在源码上
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

二、@Deprecated

常用于标注一个方法被弃用。

package java.lang;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*; /**
* 记录JavaDoc,保留至运行时,可使用在构造方法,属性(包括枚举),本地变量,方法,包,公共参数和类
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

三、@SuppressWarnings

常用于忽略特定警告,@SuppressWarnings("unchecked", "deprecation")可以同时忽略多个警告。

package java.lang;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*; /**
* 在类型、域、方法、正是参数、构造方法、本地变量上使用,只存在于源码
*/
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
/**
* 一般取 unchecked/deprecation,表示忽略 unchecked/deprecation 警告信息
*/
String[] value();
}

四、@SafeVarargs (Java7)

常用于抑制varargs相关的未检查警告,一般只能用于static、final方法

package java.lang;

import java.lang.annotation.*;

/**
* 能记录JavaDoc,保留至运行时,使用在构造方法和方法上
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SafeVarargs {}

五、@FunctionalInterface (Java8)

编译器检测接口是否符合函数式接口定义

package java.lang;

import java.lang.annotation.*;

/**
* 能记录JavaDoc,存在于运行时,只能使用在类上
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

自定义注解

首先定义一个注解

package com.example.demo.util.annotation;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
@Inherited
public @interface MyAnnotation {
String value() default "001";
}

可以看到,在Student的sNo属性上使用了该注解

package com.example.demo.util.annotation;

import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor; @Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
@MyAnnotation
private String sNo; private String sName;
}

处理注解

package com.example.demo.util.annotation;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Objects; public class AnnotationTest { public static void main(String[] args) {
//创建一个学号为 002 的学生 kw
Student student = new Student("002", "kw"); //获取学生对象对应的类
Class<? extends Student> clazz = student.getClass();
//获取学生类的属性
Field[] declaredFields = clazz.getDeclaredFields();
/** 循环判断是否存在注解@MyAnnotation
* 若存在则获取该属性的set方法
* 并使用该方法将值改为@MyAnnotation的value值
*/
@MyAnnotation的value
for (Field field: declaredFields) {
if (field.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = field.getAnnotation(MyAnnotation.class);
if (Objects.nonNull(annotation)) {
String name = field.getName();
try {
Method setMethod = clazz.getDeclaredMethod(
"set" + name.substring(0, 1).toUpperCase() + name.substring(1), String.class);
String annotationValue = annotation.value();
setMethod.invoke(student, annotationValue);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} }
}
//打印
System.out.println(student);
}
} /** 输出
Student(sNo=001, sName=kw)
*/

Java源码赏析(四)Java常见注解的更多相关文章

  1. Java源码赏析(三)初识 String 类

    由于String类比较复杂,现在采用多篇幅来讲述 这一期主要从String使用的关键字,实现的接口,属性以及覆盖的方法入手.省略了大部分的字符串操作,比如split().trim().replace( ...

  2. Java源码赏析(六)Class<T> 类

    目的 Class 类是每一个程序员都必须了解的,也是使用反射机制的基础. 这篇文章将Class 类的公共方法大致介绍了一遍(省略了安全.枚举.断言.注解相关代码). 代码 package java.l ...

  3. Java源码赏析(五)再识 String 类

    在 Java源码赏析(三)初识 String 类   中,我们已经大概理解了String的接口,接下来我们描述一下String的常用工具方法. /** * 为了精简的String结构,之前提到的方法省 ...

  4. 【java集合框架源码剖析系列】java源码剖析之java集合中的折半插入排序算法

    注:关于排序算法,博主写过[数据结构排序算法系列]数据结构八大排序算法,基本上把所有的排序算法都详细的讲解过,而之所以单独将java集合中的排序算法拿出来讲解,是因为在阿里巴巴内推面试的时候面试官问过 ...

  5. Java源码赏析(二)Java常见接口

    一.Comparable接口 package java.lang; import java.util.*; public interface Comparable<T> { /** * i ...

  6. Java 源码赏析 - java.lang - Void

    被人鄙视了,于是也来读读源码... package java.lang; /** * The Void class is an uninstantiable placeholder class to ...

  7. Java源码赏析(一)Object 类

    写这个系列的原因,其实网上已经有无数源码分析的文章了,多一篇不多,少一篇不少,但为什么还要写这部分文章呢?于私,其一,上班族已经很久没有打过完整的一整段有意义的话,算是锻炼个人的书写.总结能力,其二, ...

  8. Java源码赏析(六)Java String 三顾

    在大致了解了String之后,可能有的读者发现了,我们并没有谈到CharSequence接口. 原因是在这一节,CharSequence要和StringBuilder(Java1.5).StringB ...

  9. 24点扑克牌游戏——(含java源码)(GUI实现)

    给出四个数字,要求,在其间添加运算符和括号,使得计算结果等于24. 括号的放置即为决定哪几个数先进行计算.所以,我们先确定首先进行计算的两个相邻的数,计算完成后,就相当于剩下三个数字,仍需要在它们之间 ...

随机推荐

  1. Open MPI 4.0 编译安装

    电脑上目前使用的mpi环境是2.1.1版本的openmpi,是我之前直接使用系统的包管理工具安装的.但是系统包版本一般都比较老旧,现在openmpi最新版已经出到了4.0,即将出4.1了,所以我打算升 ...

  2. 如何加速github下载速度

    第一步 魔法 第二步 git config --global http.proxy http://127.0.0.1:1080 git config --global https.proxy http ...

  3. python numpy常用的数学和统计函数

    numpy模块的核心就是基于数组的运算,相比于列表和其他数据结构,数组的运算效率是最高的.在统计分析和挖掘过程中,经常会使用到numpy模块的函数,以下是常用的数学函数和统计函数: 常数p就是圆周率  ...

  4. Mac上如果看不到.git目录的解决方法

    Mac OS X上,如果需要查看.git目录下的隐藏文件,操作很简单: 做法是:打开一个Terminal终端窗口,输入: defaults write com.apple.finder AppleSh ...

  5. python爬虫之多线程、多进程+代码示例

    python爬虫之多线程.多进程 使用多进程.多线程编写爬虫的代码能有效的提高爬虫爬取目标网站的效率. 一.什么是进程和线程 引用廖雪峰的官方网站关于进程和线程的讲解: 进程:对于操作系统来说,一个任 ...

  6. 从零开始的SpringBoot项目 ( 二 ) 使用IDEA创建一个SpringBoot项目

    工欲善其事 , 必先利其器 . IntelliJ IDEA 2019.3.3 x64的安装与破解 下面详细说明下如何使用idea创建我们的第一个springboot项目: 首先打开idea主界面选择 ...

  7. 如何利用微博客进行seo赚钱营销

    http://www.wocaoseo.com/thread-130-1-1.html       我们知道做SEO就是用人的思维来模仿搜索引擎的习惯,尽量适应seo的规则,并按照搜索引擎的规则和习惯 ...

  8. PyTorch入门-CIFAR10图像分类

    CIFAR10数据集下载 CIFAR10数据集包含10个类别,图像尺寸为 3×32×32 官方下载地址很慢,这里给一个百度云: https://pan.baidu.com/s/1oTvW8wNa-VO ...

  9. Linux安装Rabbitmq3.8.5

    安装环境: 操作系统为:centOS-7 erlang版本为22.3,软件包:otp_src_22.3.tar.gz rabbitMQ版本为3.8.5,软件包:rabbitmq-server-gene ...

  10. C#还原对图像做的修改

    在C#程序中对图像进行处理,有的时候需要将处理后的图像还原,便于观察两者之间的区别,避免重新运行程序造成的麻烦.我是将之前写的Tab页中打开的图像进行还原,将原始图像数据保存在数据流中,然后从数据流中 ...