干货系列之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. 事务以及Spring的事务管理

    一.什么是事务? 事务是逻辑上的一组操作,要么都执行,要么都不执行 二.事务的特性(ACID) 原子性: 事务是最小的执行单位,不允许分割.事务的原子性确保动作要么全部完成,要么完全不起作用: 一致性 ...

  2. APPium+Python+iOS屏幕滑动方法对比

    最近在学习appium自动化,对iOS手机进行滑动操作进行总结: 1.mobile:scroll;该方法在实际使用调用时,会滚动2次.执行时间很长. 向下滚动整个屏幕driver.execute_sc ...

  3. IDEA中Git的使用详解

    原文链接:https://www.cnblogs.com/javabg/p/8567790.html 工作中多人使用版本控制软件协作开发,常见的应用场景归纳如下: 假设小组中有两个人,组长小张,组员小 ...

  4. Safari配置WebApp----添加启动图和桌面图标让你的WebApp在ios设备上体验如原生一样

    现在很多开发者的Web应用程序的设计样式和交互类似本机应用程序,例如,它的缩放比例适合iOS上的整个屏幕.当用户将其添加到主屏幕时,您可以通过使其看起来像本机应用程序一样,在iOS上为您的Web应用程 ...

  5. Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics)

    A. Even Subset Sum Problem 题意 给出一串数,找到其中的一些数使得他们的和为偶数 题解 水题,找到一个偶数或者两个奇数就好了 代码 #include<iostream& ...

  6. SpringBoot图文教程12—SpringData Jpa的基本使用

    有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...

  7. 开源网站云查杀方案,搭建自己的云杀毒-搭建ClamAV服务器

    开源网站云查杀方案,搭建自己的云杀毒 搭建ClamAV服务器 1        前言: 在上一篇我们已经演示了整个方案,传送门<开源网站云查杀方案,搭建自己的云杀毒>:https://ww ...

  8. SpringBoot1.5.10.RELEASE整合druid时,在druid monitor界面出现(*) property for user to setup

    接上篇随笔,配置druid之后出现的错误,解决方法如下: @Bean(destroyMethod = "close",initMethod = "init") ...

  9. 大型Java进阶专题(三) 软件架构设计原则(下)

    前言 ​ 今天开始我们专题的第二课了,本章节继续分享软件架构设计原则的下篇,将介绍:接口隔离原则.迪米特原则.里氏替换原则和合成复用原则.本章节参考资料书籍<Spring 5核心原理>中的 ...

  10. Redis系列四 - 分布式锁的实现方式

    前言 分布式锁一般有3中实现方式: 数据库乐观锁: 基于Redis的分布式锁: 基于ZooKeeper的分布式锁. 以下将详细介绍如何正确地实现Redis分布式锁. 可靠性 首先,为了确保分布式锁的可 ...