java中注解的使用

1.说再前面

使用注解开发的好处

1.使代码更加干净易读,易于维护修改。比如,以前使用spring的开发,都是基于xml文件实现了统一的配置管理,但是缺点也是显而易见的,就是随着项目的越来越大,xml文件会变得越来越复杂,维护成本也会越来越高。使用注解就可以提供更大的便捷性,易于维护修改。

2 可以实现代码的类型检查,特别是在编译器的角度实现一些类型检查,比如预检查(@Override)和抑制警告(@SuppressWarnings)等。

3 自定义注解,作为额外信息的载体,存储有关程序的额外信息

2 注解的分类以及使用

​ Java注解是附加在代码中的一些元信息,用于编译和运行时进行解析和使用,起到说明、配置的功能。

注解不会影响代码的实际逻辑,仅仅起到辅助性的作用。包含在java.lang.annotation包中。注解的定义类似于接口的定义,使用@interface来定义,定义一个方法即为注解类型定义了一个元素,方法的声明不允许有参数或throw语句,返回值类型被限定为原始数据类型、字符串String、Class、enums、注解类型,或前面这些的数组,方法可以有默认值。注解并不直接影响代码的语义,但是他可以被看做是程序的工具或者类库。它会反过来对正在运行的程序语义有所影响。注解可以从源文件、class文件或者在运行时通过反射机制多种方式被读取。

一般来说,注解一般分为三种类型: 元注解,标准注解,自定义注解

2.1 元注解

元注解是专职负责注解其他注解,主要是标明该注解的使用范围,生效范围。我们是不能改变它的,只能用它来定义我们自定义的注解。

包括 @Retention @Target @Document @Inherited四种。(java.lang.annotation中提供,为注释类型)。

注解

说明

@Target

定义注解的作用目标,也就是可以定义注解具体作用在类上,方法上,还是变量上

@Retention

定义注解的保留策略。RetentionPolicy.SOURCE:注解仅存在于源码中,在class字节码文件中不包含;RetentionPolicy.CLASS:默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得;RetentionPolicy.RUNTIME:注解会在class字节码文件中存在,在运行时可以通过反射获取到。

@Document

说明该注解将被包含在javadoc中

@Inherited

说明子类可以继承父类中的该注解

Target类型主要依赖于ElementType这个类型,具体的类型如下:

Target类型

说明

ElementType.TYPE

接口、类、枚举、注解

ElementType.FIELD

字段、枚举的常量

ElementType.METHOD

方法

ElementType.PARAMETER

方法参数

ElementType.CONSTRUCTOR

构造函数

ElementType.LOCAL_VARIABLE

局部变量

ElementType.ANNOTATION_TYPE

注解

ElementType.PACKAGE

2.2 标准注解

Java标准注解提供了三个,定义在java.lang中的注解,我认为这三个注解的作用更多的是一种注释

@Override 表示当前方法覆盖父类中的方法。

@Deprecated 标记一个元素为已过期,避免使用

支持的元素类型为:CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE

@SuppressWarnings 不输出对应的编译警告

一个简单的使用demo:

@SuppressWarnings(value = {"unused", "rawtypes"})

public class Children extends Parent{

@Override

public void work() {

System.out.println("我是一个被重写的方法");

}

@Deprecated

public void play(){

System.out.println("这个方法不推荐使用了");

}

}

2.3 自定义注解实现一个sql语句的拼接

需要注意的方面:注解的定义类似于接口的定义,使用@interface来定义,定义一个方法即为注解类型定义了一个元素,方法的声明不允许有参数或throw语句,返回值类型被限定为原始数据类型、字符串String、Class、enums、注解类型,或前面这些的数组,方法可以有默认值。

自定义注解一般可以分为三步: 定义注解,使用注解,读取注解

定义注解

@Target(ElementType.TYPE) //注解加载类上

@Retention(RetentionPolicy.RUNTIME) // 运行时读取注解

public @interface Table {

String value();

}

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

public@interface UserFiled {

String name();

String type();

int length();

}

使用注解

// 将自定义的注解加在用户上,实现一个表的映射

@Table(value = "user_table")

public class User {

@UserFiled(name = "user_id",type = "int",length = 8)

private int userId;

@UserFiled(name = "user_name",type = "varchar",length = 16)

private String userName;

@UserFiled(name = "password",type = "varchar",length = 16)

private String password;

public int getUserId() {

return userId;

}

public void setUserId(int userId) {

this.userId = userId;

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

}

读取注解的内容

/**

* 读取注解中的值

*/

public class GetUser {

public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {

Class userClass = Class.forName("annocation.blog.User");

// 读取类上的注解

Table table = (Table) userClass.getAnnotation(Table.class);

System.out.println(table.value());

// 读取属性上注解

Field userId = userClass.getDeclaredField("userId");

UserFiled userFiledId = userId.getAnnotation(UserFiled.class);

System.out.println(userFiledId.length() + "----" + userFiledId.type() + "-----" + userFiledId.name());

Field userName = userClass.getDeclaredField("userName");

UserFiled userFiledName = userName.getAnnotation(UserFiled.class);

System.out.println(userFiledName.length()+"----"+userFiledName.type()+"----"+userFiledName.name());

Field password = userClass.getDeclaredField("password");

UserFiled userFiledPassword = password.getAnnotation(UserFiled.class);

System.out.println(userFiledPassword.name() + "-----" + userFiledPassword.type() + "-----" + userFiledPassword.length());

// 拼接一个sql语句

String name = "chenwei";

String sql ="select * from" + table.value()+"where"+userFiledName.name()+"="+name;

}

}

结果:

user_table

user_id----int-----8

user_name----varchar----16

password-----varchar-----16

自定义注解的实现过程:

1,定义注解

2,使用注解,根据自己定义的注解来达到一些目的,本例中,就是使用注解来完成数据库表和实体类的映射关系

3 读取注解的内容,也是比较重要的一部分,核心还是利用了反射的思想,得到使用注解的这个类,根据类中的getAnnotion的方法得到定义的注解,获得注解上的值。

3 注解的实现的原理

注解的实现的原理很大的一部分是基于反射实现。

​ 反射可以获取到Class对象,进而获取到Constructor、Field、Method等实例,点开源码结构发现Class、Constructor、Field、Method等均实现了AnnotatedElement接口,AnnotatedElement接口的方法如下

// 判断该元素是否包含指定注解,包含则返回true

boolean isAnnotationPresent(Class extends Annotation> annotationClass)

// 返回该元素上对应的注解,如果没有返回null

T getAnnotation(Class annotationClass);

// 返回该元素上的所有注解,如果没有任何注解则返回一个空数组

Annotation[] getAnnotations();

// 返回指定类型的注解,如果没有返回空数组

T[] getAnnotationsByType(Class annotationClass)

// 返回指定类型的注解,如果没有返回空数组,只包含直接标注的注解,不包含inherited的注解

T getDeclaredAnnotation(Class annotationClass)

// 返回指定类型的注解,如果没有返回空数组,只包含直接标注的注解,不包含inherited的注解

T[] getDeclaredAnnotationsByType

// 返回该元素上的所有注解,如果没有任何注解则返回一个空数组,只包含直接标注的注解,不包含inherited的注解

Annotation[] getDeclaredAnnotations();

通过一个实例再次说明一下注解的使用过程:

定义注解

@Documented

@Target({ElementType.TYPE, ElementType.FIELD,ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

public @interface MyAnnotaion {

String getValue() default "this is myAnntaion";

int order() default 0;

}

使用注解

@MyAnnotaion(getValue = "annotation on class")

public class Demo {

@MyAnnotaion(getValue = "annotation on filed")

public String name;

@MyAnnotaion(getValue = "annotation on method")

public void hello(){

}

@MyAnnotaion

public void defaultMethod(){

}

}

利用反射读取注解中的值。

public class TestDemo {

public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {

/**

* 获取类上的注解

*/

Class demoClass = Demo.class;

Annotation[] annotaion = demoClass.getAnnotations();

printAnnotation(annotaion);

/**

* 读取成员变量上的注解

*/

Field name = demoClass.getField("name");

Annotation[] getOnFiled = name.getAnnotations();

printAnnotation(getOnFiled);

/**

* 读取方法上的注解

*/

Method hello = demoClass.getMethod("hello", null);

MyAnnotaion onMethod = hello.getAnnotation(MyAnnotaion.class);

System.out.println(onMethod.getValue());

/**

* 获取默认方法上的注解

*/

Method defaultMethod = demoClass.getMethod("defaultMethod", null);

MyAnnotaion onDefaultMethod = defaultMethod.getAnnotation(MyAnnotaion.class);

System.out.println(onDefaultMethod.getValue());

}

public static void printAnnotation(Annotation... annotations) {

for (Annotation annotation : annotations) {

System.out.println(annotation);

}

}

}

运行结果

@annocation.MyAnnotaion(getValue=annotation on class, order=0)

@annocation.MyAnnotaion(getValue=annotation on filed, order=0)

annotation on method

this is myAnntaion

参考资料:

《java编程思想》

java注解使用变量_java注解的使用相关推荐

  1. java注解详解_Java注解详解

    Annotation是从JDK5.0开始引入的新技术. Annotation的作用:–不是程序本身,可以对程序作出解释.(这一点,跟注释没什么区别)–可以被其他程序(比如:编译器等)读取.(注解信息处 ...

  2. java注解的反射_Java注解与反射

    概要 本文主要是总结Java注解与反射的相关知识,加深自己对Java类动态语言的理解,同时为日后学习Spring打下基础. 注解: 什么是注解 Annotation的作用 不是程序本身,但是可以对程序 ...

  3. java 注解与反射_Java注解与反射直接上手

    什么是注解(Annotation) 注解顾名思义为注释.讲解,可以理解为一种标签或标记,可以用在类.方法或者域上.向类.方法等添加注解,相当于给他们贴上了一层标签. 注解使用 在使用注解时,在类名.方 ...

  4. java注解怎么写_java注解

    写在前面 现在的java主流框架中,注解无处不在,因此我们完全有必要搞明白注解到底是什么.如何理解注解,它到底是怎么起作用的. 注解的定义 java是这样定义注解的:Java 注解用于为 Java 代 ...

  5. java annotation详解_Java注解Annotation详解

    从JDK5开始,Java增加了Annotation(注解),Annotation是代码里的特殊标记,这些标记可以在编译.类加载.运行时被读取,并执行相应的处理.通过使用Annotation,开发人员可 ...

  6. java 注解报错_java注解验证接收参数 返回注解字段的错误

    1.在controller接口方法接收参数加上 @Valid注解 并且在实体类参数后紧跟 BindingResult bindingresul BindingResultMsgUtil工具类: pub ...

  7. java语言环境变量_JAVA语言环境变量的设置教程

    本文主要向大家介绍了JAVA语言环境变量的设置教程,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 安装JDK到目录,我这里是C:\Java 右键点击计算机属性 在系统变量里面建 JA ...

  8. java的环境变量_java学习册|JDK|环境变量

    每一个学java的小伙伴遇到的第一个拦路虎就是配置环境变量,而且关于环境变量,已经写过了不少文章,今天,我们不炒冷饭,我们来深入探讨下 往期文章 首先还是把什么是环境变量,如何配置环境变量讲一下,参考 ...

  9. 怎样配置java的环境变量_java配置环境变量步骤

    在完成了JDK的安装后,环境变量设置是其安装后的首要操作,有人会问为什么要设置这个,要理解这个你首先要明白环境变量的涵义,它可以简单的理解为路径导向. . JAVA_HOMEC:\Usr\Java\j ...

最新文章

  1. SAP HUM嵌套HU场景下WM报表LS26里SU号码是外层HU号码
  2. POJ 1279 Art Gallery 半平面交 多边形的核
  3. hashmap containsvalue时间复杂度_面试宝典:数据结构HashMap
  4. request设置请求头_收藏 Scrapy框架各组件详细设置
  5. SpringSecurity remeber功能源码跟踪
  6. Java中可怕的双重检查锁定成语
  7. JavaFX中将FXML文件自动转换为Java代码
  8. Linux常用的基本命令14
  9. SystemVerilog中package(包)的基本使用
  10. Ubuntu 13.10 安装后配置
  11. 前端第一天,第六十五天
  12. SaaS到底是什么东西
  13. 【离散数学】偏序集Hasse图的画法和重要元素
  14. 品牌的成功取决于质量的好坏
  15. 学习Android启动初始化 App StartUp
  16. GatewayWorker 与 Workerman的关系
  17. 深圳各区对企业制定行业标准和国家标准的补贴,奖励5-200万
  18. 3D建模师的工作环境到底是怎么样的?10年建模师:没有艺术天分,建模是我最好的选择
  19. 小视频app源码,邻接矩阵实现图的相关代码
  20. Leetcode算法——537、复数乘法

热门文章

  1. wps/word如何打印指数字符?
  2. 来自灵魂深处的拷问:人为什么要活着?(转载)
  3. 遥控器的键位功能的实现
  4. Latex插入图表目录后,参考文献排序乱序问题
  5. 【金猿产品展】易观千帆——国内权威的数字经济洞察平台
  6. php数字验证码代码,php实现的数字验证码及数字运算验证码
  7. php变量简写_PHP 三元运算符简写
  8. Excel·VBA自定义函数筛选单元格区域重复值
  9. 最出色的吉他贝斯效果器:IK Multimedia AmpliTube 5 Mac
  10. 【推免攻略】一.北交计算机学院夏令营、预推免攻略