概述

在JDK5之后提供了一个新特性,和类、接口同级。定义时使用的关键字是@interface。注解主要有三个作用,分别是编译检查、替代配置文件、定义注解(元注解)、分析代码(用到反射)。注解的本质就是接口,可通过反编译注解的字节码文件。

Java中的3个常用注解

@Override

@Override注解主要是用于编译检查,子类重写父类的方法,重写的方法上面有该注解,一旦我们修改重写方法名就会报错。当我们删除@Override,再修改就不会报错了,这样编译器会认为这个方法是开发者自定义的方法

@Override
public String toString() {
return super.toString();
}

@SuppressWarnings

@SuppressWarnings注解作用是用于消除警告。比如我们定义一个变量,当变量未使用时,编译器会提示警告信息。对于这些警告如果你不想被提示,可以在方法名添加该注解。注解属性有很多取值,一般我们赋值"all",就意味着消除所有⚠️。

@SuppressWarnings("all")
public static void main(String[] args) {
int a = 10;
}

@Deprecated

@Deprecated注解适用于提示方法不建议使用,可能改方法有bug或者有新的方法替代了。如果我们调用该注解表明的方法会有中划线提示。

如果我们写一个框架对外提供的接口想要告诉调用者该方法已经过期。也可以使用该注解声明。

@Deprecated
public static void test(){ }

自定义注解

注解的定义与基本使用

自定义一个注解跟类、接口格式一样,只是修饰的关键字是@interface。概述中说过注解的本质就是接口,那么跟接口一样,接口中可以有常量和抽象方法。抽象方法在注解中就称之为注解属性

public @interface MyAnnotation {

    // 定义一个注解属性age
public int age();
public String[] names();
}

在MyAnnotation注解定义了一个test属性,该注解属性类型为int。 注意:注解属性类型只支持基本数据类型、Class、String、Annotation、Enum枚举

定义了MyAnnotation注解后,我们就可以在其它类中使用注解。

package com.coderhong.annotation;

// 给注解属性test赋值10
@MyAnnotation(age =10, names="{jake, rose}")
public class MyAnnotationExample { }

一旦注解中声明了属性,使用注解是必须对所有属性赋值,否者报错。 当注解只有一个属性,且该属性名为value,在给注解属性赋值是可以省略属性名。

public @interface MyAnnotation {

	public String value();
} // 省略属性名
@MyAnnotation("rose")
public class MyAnnotationExample { }

元注解

上面的自定义注解我们将注解作用在类上,其实它还可以作用在接口、方法、字段等上面。那么这个通过什么机制去控制呢,这就需要了解元注解。元注解就是作用在注解上的注解。我们常见的元注解@Retention@Target

@Retention

定义注解保留到什么阶段

@Retention取值 注解保留到什么阶段
RetentionPolicy.SOURCE 只在代码中保留,在字节码文件中就删除了
RetentionPolicy.CLASS 只在代码和字节码文件中都保留
RetentionPolicy.CLASS 只在代码和字节码文件中都保留
RetentionPolicy.RUNTIME 所有阶段都保留

@Retention使用示例:

//@Retention(RetentionPolicy.RUNTIME)
//@Retention(RetentionPolicy.SOURCE)
//@Retention(RetentionPolicy.CLASS)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation { public String value();
}

@Target

@Target规定注解作用在什么上面。

@Target取值 作用目标
ElementType.TYPE 作用在类、接口等上面
ElementType.METHOD 作用在方法上面
ElementType.FIELD 作用在字段上面
//@Target(ElementType.TYPE)
//@Target(ElementType.METHOD)
@Target(ElementType.FIELD)
public @interface MyAnnotation { public String value();
}

注解的使用示例

通过注解模拟JUint实现

自定义一个注解MyAnnotation跟两个Java类Test、MainClass。 通过执行MainClass类中的main方法调用Test类中所有被MyAnnotation修饰的方法。

这里主要运用到的技术就是注解+反射。通过反射获取Test类中所有方法,遍历方法数组拿到每一个Method对象,通过isAnnotationPresent();判断方法是否被某个注解修饰。

Boolean flag = method.isAnnotationPresent(MyAnnotation.class);

然后调用。

这里主要看下MainClass类中的实现

// 执行main 执行TestClass中有MyAnnotation注解声明的方法
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException { // 获取TestClass的字节码文件
Class clazz = TestClass.class; // 获取所有方法
Method[] methods = clazz.getMethods(); // 遍历所有方法
for (Method method : methods) {
// 判断方法时候有指定注解
Boolean flag = method.isAnnotationPresent(MyAnnotation.class);
// 判断是否包含MyAnnotation注解 如果包含就执行方法
if(flag){
method.invoke(clazz.newInstance());
}
}
}

注解替代JDBC的配置文件

定义一个注解JDBCAnnotation,声明属性对应了JDBC获取连接所需的参数信息。在工具类JDBCUtils的getConnection方法声明注解并对注解属性进行赋值。在调用getConnection方法获取连接时,通过映射技术获取getConnection的Method,载通过Method的getAnnotation获取该方法的注解,从而获取注解属性值。

JDBCAnnotation

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface JDBCAnnotation { // default 给注解属性设置默认值
public String DriverClass() default "com.mysql.jdbc.Driver";
public String url() default "jdbc:mysql://localhost:3306/myDB";
public String user() default "root";
public String password();
}

JDBCUtils

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException; public class JDBCUtils { @JDBCAnnotation(password="123456", user="root")
public static Connection getConnection() throws NoSuchMethodException, SecurityException, ClassNotFoundException, SQLException{ Class clazz = JDBCUtils.class; // 获取getConnection对应的Method
Method method = clazz.getMethod("getConnection"); // 判断是否包含@JDBCAnnotation注解
if(method.isAnnotationPresent(JDBCAnnotation.class)){
// 通过Method获取注解
JDBCAnnotation annotation = method.getAnnotation(JDBCAnnotation.class); // 通过注解获取属性value
String driverClass = annotation.DriverClass();
String url = annotation.url();
String user = annotation.user();
String password = annotation.password(); // 注册驱动
Class.forName(driverClass); // 获取连接
Connection connection = DriverManager.getConnection(url, user, password);
return connection;
} return null; }
}

Java开发系列-注解的更多相关文章

  1. [转帖]Java高级系列——注解(Annotations)

    Java高级系列——注解(Annotations) 2018年01月13日 :: RonTech 阅读数 3405更多 所属专栏: Java高级系列文章 版权声明:转载请注明出处,谢谢配合. http ...

  2. Java开发系列-文件上传

    概述 Java开发中文件上传的方式有很多,常见的有servlet3.0.common-fileUpload.框架.不管哪种方式,对于文件上传的本质是不变的. 文件上传的准备 文件上传需要客户端跟服务都 ...

  3. 【java开发系列】—— JDK安装

    前言 作为一个java开发者,安装JDK是不可避免的,但是配置路径却总是记不住,百度也有很多参考例子.这里仅仅当做以后参考的笔记记录. 说到JDK,就不得不提JRE.他们到底是什么呢? 通常我们进行j ...

  4. 【java开发系列】—— 自定义注解

    之前在开发中,就总纳闷,为什么继承接口时,会出现@Override注解,有时候还会提示写注解@SuppressWarnings? 原来这是java特有的特性,注解! 那么什么是注解呢? 注解就是某种注 ...

  5. 【java开发系列】—— struts2简单入门示例

    前言 最近正好有时间总结一下,过去的知识历程,虽说东西都是入门级的,高手肯定是不屑一顾了,但是对于初次涉猎的小白们,还是可以提供点参考的. struts2其实就是为我们封装了servlet,简化了js ...

  6. 【java开发系列】—— Tomcat编译报错

    由于之前Eclipse里面有一个可移植性的web工程,但是在我很久没用后,再次登录这个IDE的时候就发现了问题. 首先,我的电脑里面有两个版本的JDK,1.6和1.7.两个版本的Tomcat6和7以及 ...

  7. Java开发系列-JSP

    概述 JSP是java 服务器页面,它运行在服务器端,本质上就是一个serlvet,产生的java文件和class保留在tomcat的word目录下. JSP主要作用是将内容的生成与页面相分离. JS ...

  8. Java开发系列-JDBC

    概述 JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和 ...

  9. 【java开发系列】—— spring简单入门示例

    1 JDK安装 2 Struts2简单入门示例 前言 作为入门级的记录帖,没有过多的技术含量,简单的搭建配置框架而已.这次讲到spring,这个应该是SSH中的重量级框架,它主要包含两个内容:控制反转 ...

随机推荐

  1. inobounce.js : 禁止IOS H5的滑动回弹

    IOS的移动端/H5/webapp 页面如果滚动到底部或者在页面顶部再往上拉,都会出现一个回弹的效果. 想取消这个效果可以引入一个简单的库就行,不用再写繁琐的样式. github地址 直接引入就行 & ...

  2. 牛客多校第八场 B Beauty Values 水题

    题意: 给定一个序列,问你子区间中不同数字数量,在所有子区间中之和为多少. 题解: 统计每个数字在多少个区间中出现即可.对于每个数字,直接枚举左右端点. 注意去重,因此要记录每个数字上一次出现在哪里, ...

  3. Python-爬虫-HTTP协议请求之GET请求

    我们在百度搜索时,输入关键词,比如“hello”,URL发生变化,如下: https://www.baidu.com/s?wd=hello&rsv_spt=1&rsv_iqid=0xf ...

  4. jQuery 表单域选中选择器

    复选框.单选按钮.下拉列表 /***********************************************/ <script type="text/javascrip ...

  5. 2019 牛客多校第五场 B generator 1

    题目链接:https://ac.nowcoder.com/acm/contest/885/B 题目大意 略. 分析 十进制矩阵快速幂. 代码如下 #include <bits/stdc++.h& ...

  6. this 关键字的使用及说明

    this 是Java 中常见的一个关键字,它的主要作用是引用类的当前实例,本篇文章主要介绍 this 关键字的几种使用情况. 1. this 调用当前类的变量,也就是类中的成员变量. 代码示例: pu ...

  7. springDataJpa的官方API

    一 .  Core concepts(核心概念) 1.springdata中的中心接口是——Repository.这个接口没有什么重要的功能(原句称没什么惊喜的一个接口).主要的作用就是标记和管理.其 ...

  8. Django 前后端数据传输、ajax、分页器

    返回ORM目录 Django ORM 内容目录: 一.MTV与MVC模式 二.多对多表三种创建方式 三.前后端传输数据 四.Ajax ​ 五.批量插入数据 六.自定义分页器 一.MTV与MVC模式 M ...

  9. JS事件 失焦事件(onblur)onblur事件与onfocus是相对事件,当光标离开当前获得聚焦对象的时候,触发onblur事件,同时执行被调用的程序。

    失焦事件(onblur) onblur事件与onfocus是相对事件,当光标离开当前获得聚焦对象的时候,触发onblur事件,同时执行被调用的程序. 如下代码, 网页中有用户和密码两个文本框.当前光标 ...

  10. CSS动画库——animate.css的使用

    Animate.css是一款强大的CSS3动画库 官网地址:https://daneden.github.io/animate.css/ 使用方法如下所示: (1)下载animate.css 下载地址 ...