干货系列之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. Java入门教程六(内置包装类)

    Java 是一种面向对象的编程语言,Java 中的类把方法与数据类型连接在一起,构成了自包含式的处理单元.但在 Java 中不能定义基本类型对象,为了能将基本类型视为对象处理,并能连接相关方法,Jav ...

  2. Java入门教程三(流程控制)

    概述 程序有 3 种结构:顺序结构.选择结构和循环结构.分别为:if elseswitch case,while与do while,for, foreach,return,break ,continu ...

  3. 软件工程实验一 Git代码版本管理

    实验一  GIT 代码版本管理 一.实验目的: 1)了解分布式分布式版本控制系统的核心机理: 2)熟练掌握git的基本指令和分支管理指令: 二.实验内容: 1)安装git: 2)初始配置git ,gi ...

  4. kali linux下运行.sh文件权限不够解决办法

    我要装一个生成免杀的神奇,系统提示权限不够 2 于是我想到了sudo,可还是不行 3 于是找到了方法 chmod   a+x   文件名 4 再运行一下,成功 5 有时有的方法很简答,只要你愿意找.

  5. Windows GDI 窗口与 Direct3D 屏幕截图

    前言 Windows 上,屏幕截图一般是调用 win32 api 完成的,如果 C# 想实现截图功能,就需要封装相关 api.在 Windows 上,主要图形接口有 GDI 和 DirectX.GDI ...

  6. MVC04

    1. 从页面到action 讲述controller与View之间的具体运作关系 在上次添加的名为Movie的Model内添加 下面我们尝试为该model内的属性添加attribute 具体修改如下: ...

  7. HTML常用标签的使用

    一.常见标签详解 1.<iframe>标签 HTML内联框架元素 <iframe> 表示嵌套的浏览上下文,有效地将另一个HTML页面嵌入到当前页面中.在HTML 4.01中,文 ...

  8. 总结:利用asp.net core日志进行生产环境下的错误排查(asp.net core version 2.2,用IIS做服务器)

    概述 调试asp.net core程序时,在输出窗口中,在输出来源选择“调试”或“xxx-ASP.NET Core Web服务器”时,可以看到类似“info:Microsoft.AspNetCore. ...

  9. Object-Oriented Programming Summary Ⅰ

    Part 0: 前言 令人闻风丧胆的OO还是来了.并没有像名字的外表一样可爱,简直就是恶魔. 疯狂压榨OS的时间,周末无法休息,互测狼人机制 虽然网上骂声很多,就算改进到9012年还是有很多不足的地方 ...

  10. flask 部署外部访问

    在 app.run(host='0.0.0.0',port=5000) 可以让外部客户端进行访问,访问地址是flask服务器的ip地址和你设置的端口(端口注意不要占用其他端口,如果是阿里云有可能要设置 ...