干货系列之java注解

前言

java反射和注解在java里面很重要,但是很多人对这方面的知识理解不是很好,我来说说我自己对java反射和注解的理解,这两块内容本来应该出在一个博客文章里面讲解,但是由于我的java反射说的内容有点小多,然后我就分开将讲解一下。

目录

  1. 注解的概念
  2. 注解的类别
  3. 注解用法
  4. 通过反射获取注解
  5. 反射注解一起使用拼写SQL语句实战演练

注解的概念

java注解:

比较官方的说法:

从JDK5开始,Java增加对元数据的支持,也就是注解,注解与注释是有一定区别的,可以把注解理解为代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过注解开发人员可以在不改变原有代码和逻辑的情况下在源代码中嵌入补充信息。

注解,可以看作是对 一个 类/方法 的一个扩展的模版,每个 类/方法 按照注解类中的规则,来为 类/方法 注解不同的参数,在用到的地方可以得到不同的 类/方法 中注解的各种参数与值。

说说我的理解

注解就是Annotation,相信不少人也和我之前一样以为和注释一样,是一段辅助性的文字,其实注解不是这样的。注解与注释的区别在于,注解可以实现程序的某些功能。

注解是不会影响java程序的运行,不会干扰程序代码的运行。通俗来讲,注解就像一个标签,初学者需要知道他就像一个功能标签,能实现一些功能就行了!入门了再慢慢深入理解。

看下面的例子你就能更好的理解注解了。

注解的类别

  1. java语言提供的注解
  2. 元注解
  3. 其他注解

java语言提供的注解

1.Override

学过java你就知道,你肯定见过这种

@Override
public Object clone() throws CloneNotSupportedException {}

没错,@Override就是一个java提供的注解。当你要重写父类的方法是需要用到这个注解。

2.@Deprecated

这个注解你能看到的时间比较少,但是你应该见过类似的,编译一个java程序时,编译器可能会提示你你使用了一个过时的方法(idea会),或者过时的类,过时的成员变量。

3.@SuppressWarnings

这个注解的意思是:阻止编译器的警告,上一个注解说到@Deprecated会提示你使用过时方法等的一个警告,当你使用了这个注解之后就不会有这种提示了!这个注解需要一个参数,参数都是提前设计好了的。

参数如下

  • deprecation 使用了过时的类或方法的警告
  • unchecked 执行了未检查的转换时的警告,如使用集合时未指定泛型
  • fallthrough :当在switch语句使用时发生case穿透
  • path 在类路径,源文件路径等中有不存在路径的警告
  • serial 当在可序列化的类上缺少serialVersionUID定义时的警告
  • finally 任何finally子句不能完成时的警告
  • all 关于以上所有情况的警告

元注解

所谓元注解就是注解的注解,虽然说这些注解也是java语言提供的,但是他不同于上面说的哪几种注解,上面的几种注解也是由元注解组成的。他们的源代码里面包含了元注解。

元注解有哪些呢?

- @Target:注解的作用目标
- @Retention:注解的生命周期
- @Documented:注解是否应当被包含在 JavaDoc 文档中
- @Inherited:是否允许子类继承该注解

这4个值java8之前的元注解,在java8又新增了一个

@Repeatable 元注解,表示被修饰的注解可以用在同一个声明式或者类型加上多个相同的注解(包含不同的属性值)

我们详细说一下这些注解都是什么意思

1.@Target 注解的作用目标

具体的作用目标有以下几个

- ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上

- ElementType.FIELD:允许作用在属性字段上

- ElementType.METHOD:允许作用在方法上

- ElementType.PARAMETER:允许作用在方法参数上

- ElementType.CONSTRUCTOR:允许作用在构造器上

- ElementType.LOCAL_VARIABLE:允许作用在局部变量上

- ElementType.ANNOTATION_TYPE:允许作用在注解上

- ElementType.PACKAGE:允许作用在包上

以上都是这个注解的参数

可能有人会问作用目标是什么?就是说我声明的这个注解可以用在那个地方,比如说@Override,是不是只能用在重写的方法上面。如果你学了springboot的话,里面的很多注解都是可以使用在类上面也可以使用在方法上面。

2.@Retention 注解的生命周期

什么意思?注解本身是不会影响正常逻辑程序的运行的,然后这个注解的生命周期指的是我声明的这个注解会保留到什么阶段,具体的参数如下:

- RetentionPolicy.SOURCE:当前注解编译期可见,不会写入 class 文件,会被编译器丢弃
- RetentionPolicy.CLASS:类加载阶段丢弃,会写入 class 文件,会被java虚拟机丢弃
- RetentionPolicy.RUNTIME:永久保存,可以反射获取到对应的注解

3.@Documented 注解是否应当被包含在 JavaDoc 文档中

这个倒没有什么好说的,就是标注被修饰这个注解包含在JavaDoc文档中。

4.@Inherited 是否允许子类继承该注解

简单点说,子类继承父类时,如果父类的注解有@Inherited标识的注解,子类继承过来的时候也会自动继承@Inherited标识的注解。

但是在接口继承的时候,子类不会继承任何@Inherited标识的注解。

5.@Repeatable

在需要对同一种注解多次使用时,往往需要借助@Repeatable。比如说,现在有一篇文章,这篇文章需要添加多个标签,这些标签就相当于注解,但是这个标签只是内容不同,这时候就需要使用到这个注解了。

其他注解

所谓的其他注解就是第三方注解,比如说很火的springboot,它提供了很多的注解,可以替代一些配置文件,告诉这个框架有这个注解是需要提供哪些功能。比如说@Controller,@RequestMapping,@Service等。

注解用法

讲了半天,可能你还是一脸懵逼,你只讲概念,怎么用?

下面就来介绍这个注解怎么用,主要是讲解注解的声明用法。

1.注解声明

public @interface Entity {

}

这个和声明接口很类似,只是在前面多了一个@

具体怎么用,我们用一个例子来讲解

@Target(ElementType.TYPE)//允许声明的注解修饰在接口,类,枚举上面
@Retention(RetentionPolicy.RUNTIME)//代码运行期间一直保存注解,可以通过反射获取
public @interface Entity {
//表名,注解的参数,默认为空
public String tableName() default "";
//中文名称
public String cnName() default ""; }

解释一下注解的参数声明

第一个参数定义参数为String类型,设置default 默认值,表示这个不是必须的,在使用注解的时候没有填写这个参数不会报错,他会使用默认值。

声明好注解之后,我们将这些注解运用到一个实体类上面。

再来一个声明的作用在属性上面的注解。

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
//属性的名称
public String fieldName() default "";
//属性的属性中文名称
public String fieldCnName() default "";
//属性的类型
public String Type() default "String";
}

然后我们将这两个注解运用到实体类Student上面。

@Entity(tableName = "student",cnName = "学生表")
public class Student {
@Column(fieldCnName = "姓名",fieldName ="name")
private String name;
@Column(fieldCnName = "年龄",fieldName = "age",Type = "Integer")
private Integer age;
@Column(fieldCnName = "性别",fieldName = "sex")
private String sex;
}

set,get方法没有贴上来。

具体的用法就是这样了。然后我们说说注解与反射的关系,怎么用反射获取注解。

通过反射获取注解

不会反射的请看上一篇文章,8000字为你讲懂反射,然后再回来看这篇注解的文章。

上代码直接

	//获取Class类
Class clazz = Student.class; //获取类上面的注解
Entity entity = (Entity) clazz.getAnnotation(Entity.class);
System.out.println(entity.cnName()+entity.tableName()); //获取所有该类声明的属性
Field fields[] = clazz.getDeclaredFields(); for (Field field:fields){
//获取对应属性上面的注解
Column column = field.getAnnotation(Column.class);
System.out.println(column.fieldCnName());
}

这个运行结果是

学生表student
姓名
年龄
性别

很简单是不是。懂了吗?懂了的话关注走一波?精彩美文每天为你推送,喜欢手机看文章的还可以(wx search 全栈学习笔记)!

反射注解一起使用拼写SQL语句实战演练

其实这一部分你懂反射和注解就会了,通过反射和注解你可以实现一个简单的万能的增删改查。贴个新增的SQL语句代码吧!

//insert into student_test(student_id,student_name,student_sex) values (1,"Jack","男")
StringBuilder sql = new StringBuilder();
Class clazz = object.getClass();
sql.append("insert into ");
//获取类上面的注解
Entity entity = (Entity) clazz.getAnnotation(Entity.class);
sql.append(entity.tableName()); sql.append("(");
Field[] fields = clazz.getDeclaredFields();
for(Field field:fields){
sql.append(field.getAnnotation(Column.class).fieldName()).append(",");
}
sql.deleteCharAt(sql.length()-1);
sql.append(")");
sql.append(" values (");
for(Field field:fields){
field.setAccessible(true);
Object value = field.get(object);
if(value.getClass().equals(String.class)){
sql.append("\"").append(value).append("\"").append(",");
}else {
sql.append(value).append(",");
}
}
sql.deleteCharAt(sql.length()-1);
sql.append(")");
System.out.println(sql.toString());
return sql.toString();

结语:觉得文章不错的,带上原文链接,欢迎转发,如果你发现文章中有错误可以评论或者私信我,及时修改!(wx search 全栈学习笔记)精彩美文每天为你推送!

干货系列之java注解的更多相关文章

  1. 夯实Java基础系列15:Java注解简介和最佳实践

    Java注解简介 注解如同标签 Java 注解概述 什么是注解? 注解的用处 注解的原理 元注解 JDK里的注解 注解处理器实战 不同类型的注解 类注解 方法注解 参数注解 变量注解 Java注解相关 ...

  2. [转]Java多线程干货系列—(一)Java多线程基础

    Java多线程干货系列—(一)Java多线程基础 字数7618 阅读1875 评论21 喜欢86 前言 多线程并发编程是Java编程中重要的一块内容,也是面试重点覆盖区域,所以学好多线程并发编程对我们 ...

  3. Java多线程干货系列—(四)volatile关键字

    原文地址:http://tengj.top/2016/05/06/threadvolatile4/ <h1 id="前言"><a href="#前言&q ...

  4. 【转】Spring Boot干货系列:(一)优雅的入门篇

    转自Spring Boot干货系列:(一)优雅的入门篇 前言 Spring一直是很火的一个开源框架,在过去的一段时间里,Spring Boot在社区中热度一直很高,所以决定花时间来了解和学习,为自己做 ...

  5. 【转】Spring Boot干货系列:(二)配置文件解析

    转自:Spring Boot干货系列:(二)配置文件解析 前言 上一篇介绍了Spring Boot的入门,知道了Spring Boot使用"习惯优于配置"(项目中存在大量的配置,此 ...

  6. 【转】Spring Boot干货系列:(三)启动原理解析

    前言 前面几章我们见识了SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏.所以这次博主就跟你们一起一步步揭开Sprin ...

  7. Spring Boot干货系列:(六)静态资源和拦截器处理

    Spring Boot干货系列:(六)静态资源和拦截器处理 原创 2017-04-05 嘟嘟MD 嘟爷java超神学堂 前言 本章我们来介绍下SpringBoot对静态资源的支持以及很重要的一个类We ...

  8. Spring Boot干货系列:(四)Thymeleaf篇

    Spring Boot干货系列:(四)Thymeleaf篇 原创 2017-04-05 嘟嘟MD 嘟爷java超神学堂 前言 Web开发是我们平时开发中至关重要的,这里就来介绍一下Spring Boo ...

  9. Spring Boot干货系列:(二)配置文件解析

    Spring Boot干货系列:(二)配置文件解析 2017-02-28 嘟嘟MD 嘟爷java超神学堂   前言 上一篇介绍了Spring Boot的入门,知道了Spring Boot使用“习惯优于 ...

随机推荐

  1. [python每日一练]--0012:敏感词过滤 type2

    题目链接:https://github.com/Show-Me-the-Code/show-me-the-code代码github链接:https://github.com/wjsaya/python ...

  2. Object.defineProperty注意事项

    Object.defineProperty() 方法设置属性时,属性不能同时声明访问器属性( set 和 get )和 writable 或者 value 属性. 意思就是,某个属性设置了 writa ...

  3. 康威定律(Conway's law)

    系统是设计该系统的组织结构的映射. Conway's law 最初是Conway在1967年发表的论文<How Do Committees Invent?>,然后 Fred Brooks ...

  4. C++扬帆远航——7(年月日)

    /* * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:charizi.cpp * 作者:常轩 * 完成日期:2016年 ...

  5. paddlepaddle目标检测之水果检测(yolov3_mobilenet_v1)

    一.创建项目 (1)进入到https://aistudio.baidu.com/aistudio/projectoverview/public (2)创建项目 点击添加数据集:找到这两个 然后创建即可 ...

  6. C#可空类型知多少

    在项目中我们经常会遇到可为空类型,那么到底什么是可为空类型呢?下面我们将从4个方面为大家剖析. 1.可空类型基础知识 顾名思义,可空类型指的就是某个对象类型可以为空,同时也是System.Nullab ...

  7. Java中如何更优雅的处理空值

    经常看到项目中存在到处空值判断的情况,这些判断,会让人觉得摸不着头绪,它的出现很有可能和当前的业务逻辑并没有关系.但它会让你很头疼.有时候,更可怕的是系统因为这些空值的情况,会抛出空指针异常,导致业务 ...

  8. handlebar.js模板引擎(轻页面小工程可用)

    介绍 Handlebars 让你能够有能力高效地容易地创立语义化的模版.Handlebars兼容Mustache语法,在大多数情况下它可以读取Mustache的语法并在你当前模板中使用.具体点击这里 ...

  9. layer打开弹窗时传递参数(content:)

    在使用layer打开弹窗时,我希望带一些参数过去,进行某些判断.直接就可以用链接+参数的方式即可. js var userGrade=Mrant layer.open({ title: '权限管理', ...

  10. vue.js 中使用(...)运算符报错

    今天在起别人项目的时候, 发现报错. 这个错误是,项目中不识别es6的扩展运算符, 解决方式很简单. // 第一步 cnpm install babel-plugin-transform-object ...