有用的Java注解
好处:
能够读懂别人的代码,特别是框架相关的代码;
让编程更加简洁,代码更加清晰。
使用自定义注解解决问题!!
Java1.5版本引入。
Java中的常见注解
- @Override:告诉使用者及编译器,该方法覆盖了父类或接口中的同名方法
- @Deprecated:表示该方法已经过时了。
- @Suppvisewarnings:忽略deprecated给出的警告。
- 常见第三方注解:
- Spring: @Autowired, @Service, @Repository
- Mybatis: @InsertProvider, @UpdateProvider, @Options
注解分类
- 按照运行机制分:
- 源码注解:注解只在源码中存在,编译成class文件就不存在了
- 编译时注解:注解在源码和.class文件中都存在
- 运行时注解 :在运行阶段还起作用,甚至会影响运行逻辑的注解 如@Autowired注解
- 按照来源分:
- 来自JDK的注解
- 来自第三方的注解
- 自己定义的注解
- 元注解:注解的注解
自定义注解
- 语法要求

- 成员类型是受限的,合法的类型包括原始类型及String,Class,Annotation,Enumeration;
- 如果注解只有一个成员,则成员们必须取名为value(),在使用时可以忽略成员名和赋值号(=);
- 注解类可以没有成员,没有成员的注解类成为标识注解;
- 元注解(注解的注解)
- @Target(……)
- @Retention:生命周期(SOURCE:只在源码显示编译时丢弃;CLASS:编译时会记录到class中,运行时忽略;RUNTIME:运行时存在,可以通过反射读取)
- @Inherited:允许子类继承,只能在类或者抽象类间继承,接口是不会继承的。而且继承时只是类的继承,类中的方法并不会继承。
- @Documented:生成javadoc时会包含信息。
- 到处一个Javadoc:在工程上点击Export->javadoc->设置路径,通过index.html即可查看你导出的Javadoc
- 使用自定义注解
解析注解
- 概念:通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。
//实例:拿到类名字的解释
public class ParseAnn {
public static void main(String[] args) {
//1.使用类加载器加载类
try {
Class c = Class.forName("com.ann.test.Child");
//2.找到类上面的注解
boolean isExist = c.isAnnotationPresent(Description.class);
if(isExist) {
//3.拿到注解实例
Description d = (Description) c.getAnnotation(Description.class);
System.out.println(d.value());
}
//4.找到方法上的注解
Method[] ms = c.getMethods();
for(Method m : ms) {
boolean isMExist = m.isAnnotationPresent(Description.class);
if(isMExist) {
Description d = (Description) m.getAnnotation(Description.class);
System.out.println(d.value());
}
} //另外一种解析方法
for(Method m : ms) {
Annotation[] as = m.getAnnotations();
for(Annotation a : as) {
if(a instanceof Description) {
Description d = (Description)a;
System.out.println(d.value());
}
}
} } catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}//Child.java信息
@Description("I am class annotation")
public class Child implements Person { @Override
@Description("I am method annotation")
public String name() {
// TODO Auto-generated method stub
return null;
} @Override
public int age() {
// TODO Auto-generated method stub
return 0;
} @Override
public void sing() {
// TODO Auto-generated method stub } }
实践
- 项目取自一个公司的持久层框架,用来代替Hibernate的解决方案,核心代码就是通过注解来实现的。
- 需求:
- 1.有一张用户表,字段包括用户ID、用户名、昵称、年龄、性别、所在城市、邮箱、手机号。
- 2.方便的对每个子弹或字段的组合条件进行检索,并打印出SQL。
- 使用方式要足够简单。
private static String query(Object f) {
StringBuilder sb = new StringBuilder();
//1.获取到class
Class c = f.getClass();
//2.获取到table的名字
boolean exist = c.isAnnotationPresent(Table.class);
if(!exist)
return null;
Table t = (Table) c.getAnnotation(Table.class);
String tableName = t.value();
sb.append("select * from ").append(tableName).append(" where 1=1 ");
//3.遍历所有的字段
Field[] fArray = c.getDeclaredFields();
for(Field field : fArray) {
//4. 处理每个字段对应的SQL
//4.1 拿到字段名
boolean fe = field.isAnnotationPresent(Column.class);
if(!fe)
continue;
// Column column = field.getAnnotation(Column.class);
// String columnName = column.value();
//4.2拿到字段值
String fieldName = field.getName();
String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() +
fieldName.substring(1);
Object fieldValue = null;
try {
Method getMethod = c.getMethod(getMethodName);
fieldValue = getMethod.invoke(f);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//4.3拼装SQL
if(fieldValue == null ||
(fieldValue instanceof Integer && (Integer)fieldValue == 0))
continue;
if(fieldValue instanceof String) {
if(((String) fieldValue).contains(",")) {
String[] values = ((String) fieldValue).split(",");
sb.append("and ").append(fieldName).append(" in(");
for(String v : values) {
sb.append("'").append(v).append("',");
}
sb.deleteCharAt(sb.length()-1);
sb.append(")");
}
else
sb.append("and ").append(fieldName).append("='")
.append(fieldValue).append("'");
}
else
sb.append("and ").append(fieldName).append("=").append(fieldValue);
} return sb.toString();
}
总结
- 注解的作用范围@Target和生命周期@Retention
- 作用范围包括:包、类、字段、方法、方法的参数和局部变量
- 生命周期:源文件SOURCE、编译CLASS、运行RUNTIME
- 等读懂注解
- 在实际项目中用注解解决问题,并能自定义注解
有用的Java注解的更多相关文章
- Java 注解 入门
这几天在学习Spring3.x,发觉现在许多框架都用上了java注解功能,然后自己就对java注解这方面初步学习了一下. 首先,注解跟注释不是一个意思,也根本不是同一个事物. 注释就是我们平常平常中对 ...
- Java注解(2)-注解处理器(运行时|RetentionPolicy.RUNTIME)
如果没有用来读取注解的工具,那注解将基本没有任何作用,它也不会比注释更有用.读取注解的工具叫作注解处理器.Java提供了两种方式来处理注解:第一种是利用运行时反射机制:另一种是使用Java提供的API ...
- Java 注解指导手册 – 终极向导
原文链接 原文作者:Dani Buiza 译者:Toien Liu 校对:深海 编者的话:注解是java的一个主要特性且每个java开发者都应该知道如何使用它. 我们已经在Java Code Gee ...
- Java注解处理器
Java注解处理器 2015/03/03 | 分类: 基础技术 | 0 条评论 | 标签: 注解 分享到:1 译文出处: race604.com 原文出处:Hannes Dorfmann Java ...
- Java注解解析-搭建自己的注解处理器(CLASS注解使用篇)
该文章是继Java注解解析-基础+运行时注解(RUNTIME)之后,使用注解处理器处理CLASS注解的文章.通过完整的Demo例子介绍整个注解处理器的搭建流程以及注意事项,你将知道如何去搭建自己的注解 ...
- java注解使用总结
2005年,sun公司推出了jdk1.5,同时推出的注解功能吸引了很多人的目光,使用注解编写代码,能够减轻java程序员繁琐配置的痛苦. 使用注解可以编写出更加易于维护,bug更少的代码. 注解是什么 ...
- 夯实Java基础系列15:Java注解简介和最佳实践
Java注解简介 注解如同标签 Java 注解概述 什么是注解? 注解的用处 注解的原理 元注解 JDK里的注解 注解处理器实战 不同类型的注解 类注解 方法注解 参数注解 变量注解 Java注解相关 ...
- Java注解简单学习
注解(也被称作元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们在稍后某个时刻可以很方便的使用这些数据,其在一定程度上将元数据与源代码文件结合在一起,而不是保存在外部文档中. 注解使我们可以 ...
- Java 注解指导手册(下)
9. 自定义注解 正如我们之前多次提及的,可以定义和实现自定义注解.本章我们即将探讨. 首先,定义一个注解: public @interface CustomAnnotationClass ...
随机推荐
- 在Closing事件中,将e.Cancle设置成true,则Windows无法关机和重启系统的解决办法
最近在设计一个WinForm程序的时候遇到一个bug,就是From1窗体的关闭事件中设置了e.Cancle设置成true,导致系统无法关机重启,windows7 和windows xp都是这样. 我这 ...
- sql sever 基础 建表
---恢复内容开始--- SQL Sever 基础以创建银行数据库bankDB为案例 1.创建数据库 1-1 创建文件夹用以存放数据库 1-2 创建建库bankDB 2.创建数据库 2-1.创建用户信 ...
- javascript--自定义弹出登陆窗口(弹出窗)
web开发中浏览器对象封装了诸如prompt.alert.confirm等弹出框,但是有的弹出框并不能满足开发需要,需要我们自己定义弹出框,诸如用户登陆框.消息提示框等.本文利用弹出用户登陆框示例,对 ...
- 汇编:模拟C语言实现break与continue
;=============================== ;循环程序设计 ;模拟C语言实现break 与continue DATAS SEGMENT i dw sum dw DATAS end ...
- 学习新框架laravel 5.6 (第二天)-DB,控制器及模型使用
DB类使用,控制器使用及模型使用 链接数据库: /config/database.php /.env DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=330 ...
- python 函数 练习
# 2.写函数,接收n个数字,求这些参数数字的和. def sum_func(*args): total = 0 for i in args: total += i return total prin ...
- 多线程编程以及socket编程_Linux程序设计4chapter15
看了Linux程序设计4中文版,学习了多线程编程和socket编程.本文的程序参考自Linux程序设计4的第15章. 设计了一个客户端程序,一个服务端程序.使用TCP协议进行数据传输. 客户端进程创建 ...
- Linux C语言结构体-学习笔记
Linux C语言结构体简介 前面学习了c语言的基本语法特性,本节进行更深入的学习. 预处理程序. 编译指令: 预处理, 宏定义, 建立自己的数据类型:结构体,联合体,动态数据结构 c语言表达式工具 ...
- Python tips(
(此文是在实际工程中遇到的一些小问题,给予解决和整理.解决方法大多来自网上零散的文章.有一个系统化的Python问题解决方案,来自<Python 3 学习笔记>雨痕著,其中对Python的 ...
- Mac OS下搭建Hadoop + Spark集群
首先注意版本兼容问题!!!本文采用的是Scala 2.11.8 + Hadoop 2.7.5 + Spark 2.2.0 请在下载Spark时务必看清对应的Scala和Hadoop版本! 一.配置JD ...