java提高(16)---java注解

注解含义注解是JDK1.5之后才有的新特性,它相当于一种标记,在程序中加入注解就等于为程序打上某种标记,之后又通过类的反射机制来解析注解。

一、JDK自带注解

JDK1.5之后内部提供的三个注解

 @Deprecated       #废弃,过时。
@Override #重写、覆盖。
@SuppressWarnings #压缩警告。

示例

@SuppressWarnings("deprecation")
public class AnnotationTest {
//4、这里称为压缩警告注解,可以在类上也可以放在方法上,因为该方法用了个已经过期的方法.getYear(),所以会发出警告
//加上这个注解表明取消对deprecation的警告,那么该方法里有过时方法也不会发出预警。同时getYear()的那条横线也消失了。
@SuppressWarnings("deprecation")
public static void main(String[] args) { //1、这里的.getYear()方法画了一条横线表示此方法已经过时了,里面方法加上了@Deprecated注解
new Date().getYear();
} //2、这里我通过@Deprecated注解自定义一个已经过时不建议使用的方法。
@Deprecated
public String getName() {
return "小小"; }
//3、重写(覆盖)父类Object的toString()方法
@Override
public String toString() {
return "小小";
}
}

注解示意图

二、自定义注解

示例

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface AnCode {//使用@interface关键字定义注解 //如果只有一个属性 强烈建议取名为value
String value() default "";
}

在自定义注解上面有四个注解,我们称为元注解,下面一个一个解释。

1、@Target 用于描述注解的使用范围

取值(ElementType)有:
    1、CONSTRUCTOR: 用于描述构造器
    2、FIELD: 用于描述域(字段申明)
    3、LOCAL_VARIABLE:用于描述局部变量
    4、METHOD: 用于描述方法
    5、PACKAGE: 用于描述包
    6、PARAMETER: 用于描述参数
    7、TYPE: 用于描述类、接口(包括注解类型) 或enum声明
    8、TYPE_PARAMETER:输入参数申明(JDK1.8)
    9、TYPE_USE: 使用类型(JDK1.8)

2、@Retention 定义了该注解生命周期

取值(RetentionPoicy)有:
    1、SOURCE: 在源文件中有效(即源文件保留)
    2、CLASS: 在class文件中有效(即class保留)
    3、RUNTIME: 注解永久保留,可以被VM加载时加载到内存中

一般框架注解和我们自定义注解采用的几乎都是RUNTIME,因为只有这个才能运行时通过反射来获取注解中的数据。

3、@Inherited

概念: @Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

注意:@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation

解释: 比如A继承B,B类的上面有一个注解@A带有元注解@Inherited 那么A也可以拥有B父类的这个注解@A,但接口实现是不可以的。同时需要指出@A注解是需要元注解@Retention(RetentionPolicy.RUNTIME)。

参考文章:java @Inherited注解的作用

4、@Documented

概念:描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。

5、自定义注解参数

  1、只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型; 
2、参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和
String,Enum,Class,annotations等数据类型,以及这一些类型的数组;
  3、如果只有一个参数成员,最好把参数名称设为"value",后加小括号(也可以不加小括号)

三、自定义注解案例

目标 实现一个简单的通过注解生成SQL查询语句。

先创建两个注解

@Table表名注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table { //数据库表名属性
String value() default "";
}

@Column字段名注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
//数据库表字段名称和实体属性映射
String value() default "";
}

User实体

@Table("t_user")
public class User {
/**
* 用户Id
*/
@Column("user_id")
private Integer userId;
/**
* 用户年龄
*/
@Column("age")
private Integer age; public User(Integer userId, Integer age) {
this.userId = userId;
this.age = age;
}
//添加get和set方法
}

解析注解类

public class Query {
public static String query(Object object) throws Exception{
StringBuilder sql = new StringBuilder();
//1.利用反射获取Class
Class c = object.getClass();
//2.获取Table的名字
boolean isExist = c.isAnnotationPresent(Table.class);
if (!isExist) {
return null;
}
Table t = (Table) c.getAnnotation(Table.class);
//3、获取注解上的value值
String tableName = t.value();
sql.append("select * form ").append(tableName).append(" where 1 = 1 ");
//4.遍历所有的属性字段
Field[] fArray = c.getDeclaredFields();
for (Field field : fArray) {
//处理每个字段对应的sql
boolean fExist = field.isAnnotationPresent(Column.class);
if (!fExist) {
continue;
}
Column column = field.getAnnotation(Column.class);
//数据库字段名
String columnName = column.value();
//5、将user_id 变成 userId
String[] columns = columnName.split("_");
StringBuilder columnBuilder = new StringBuilder();
for (int i = 0; i < columns.length; i++) {
String s = columns[i];
columnBuilder.append(s.substring(0, 1).toUpperCase()).append(s.substring(1));
}
//6、活动属性值
String getMethodName = "get" + columnBuilder.toString(); //get方法名
Method getMethod = c.getMethod(getMethodName);
Object fieldValue = getMethod.invoke(object);//类字段值
//7、拼装sql
sql.append(" and ").append(columnName).append(" = ").append(fieldValue);
}
return sql.toString();
}
}

测试类

public static void main(String[] args) throws Exception {
User user = new User(001, 4);
String query = Query.query(user);
System.out.println("query = " + query);
}

运行结果

通过这个小案例实现了通过注解的方式,生成sql语句。

只要自己变优秀了,其他的事情才会跟着好起来(少将20)

【java提高】(16)---java注解(Annotation)的更多相关文章

  1. JAVA提高五:注解Annotation

    今天我们学习JDK5.0中一个非常重要的特性,叫做注解.是现在非常流行的一种方式,可以说因为配置XML 比较麻烦或者比容易查找出错误,现在越来越多的框架开始支持注解方式,比如注明的Spring 框架, ...

  2. Java自定义数据验证注解Annotation

    本文转载自:https://www.jianshu.com/p/616924cd07e6 Java注解Annotation用起来很方便,也越来越流行,由于其简单.简练且易于使用等特点,很多开发工具都提 ...

  3. Java学习笔记:注解Annotation

    annotation的概念 In the Java computer programming language, an annotation is a form of syntactic metada ...

  4. Java反射reflection与注解annotation的应用(自动测试机)

    一.关于自动测试机 1.什么是自动测试机? 对类中的指定方法进行批量测试的工具 2.自动测试机有什么用? a.避免了冗长的测试代码 当类中的成员方法很多时,对应的测试代码可能会很长,使用测试能够让测试 ...

  5. Java提高篇——Java实现多重继承

    多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承.有些时候我们会认为如果系统中需要使用多重继承往往都是糟糕的设计,这个时候我们往往需 ...

  6. Java提高篇——Java 异常处理

    异常的概念 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的. 比如说,你的代码少了一个分号,那么运行出来结果是提示是错误java.lang.Error:如果你用Syst ...

  7. java 编程基础:注解(Annotation Processing Tool)注解处理器 利用注解解读类属性生成XML文件

    APT的介绍: APT(Annotation Processing Tool)是一种注解处理工具,它对源代码文件进行检测,并找出源文件所包含的注解信息,然后针对注解信息进行额外的处理. 使用APT工具 ...

  8. 【java提高】---java反射机制

    java反射机制 一.概述 1.什么是反射机制 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态 ...

  9. Java提高合集(转载)

    转载自:http://www.cnblogs.com/pony1223/p/7643842.html Java提高十五:容器元素比较Comparable&Comparator深入分析 JAVA ...

  10. Java总结——常见Java集合实现细节(1)

    Java提高——常见Java集合实现细节(1) 2018年04月18日 15:07:35 阅读数:25 集合关系图 Set和Map set代表一种集合元素无序.集合元素不可重复的集合 map代表一种由 ...

随机推荐

  1. Java之Collection接口(单列集合根接口)

    集合概述 集合到底是什么呢?集合:集合是java中提供的一种容器,可以用来存储多个数据 集合和数组既然都是容器,它们有啥区别呢? 区别1: 数组的长度是固定的. 集合的长度是可变的. 区别2:  数组 ...

  2. File Zilla server安装完报错could not load TLS libraries. aborting start of administration interface

    问题描述: 系统:Windows2008R2x64 安装完filezillaserver以后出现这个问题 解决方法: 需要安装个系统补丁:Windows6.1-KB2533623-x64 安装完重启服 ...

  3. tensorflow中卷积、转置卷积具体实现方式

    卷积和转置卷积,都涉及到padding, 那么添加padding 的具体方式,就会影响到计算结果,所以搞清除tensorflow中卷积和转置卷积的具体实现有助于模型的灵活部署应用. 一.卷积 举例说明 ...

  4. sql server判断表存在

    在创建表.更改表结构.删除表或对表进行什么操作之前,一个比较严谨的做法是先判断该表是否已经存在. 在SQL Server中判断一个表是否存在,有两个方法,下面以diso表为例. 方法1 from sy ...

  5. RK3399安装Qt

    更新软件源.升级软件 sudo apt-get update sudo apt-get upgrade 安装Qt sudo apt-get install qt5-default sudo apt-g ...

  6. C++ 课程设计——电梯调度系统

    这是我在本学期C++课程最后的课程设计报告,源代码将会上传到GitHub上. 一.背景 随着经济的不断发展,越来越多的摩天大楼拔地而起,而电梯作为高层建筑物种的运送人员货物的设备也越来越被广泛使用.电 ...

  7. 如何解决eclipse远程服务器上面的Rabbitmq连接超时问题?

    1.嗯,问题呢,就是一开始安装好RabbitMQ,练习了一下RabbitMQ的使用,但是呢,过了一段时间,我来复习的时候,发现运行出现下面的错误了.后来想想,是自己学习微服务的时候,修改了/etc/h ...

  8. PHP+Mysql统计文件下载次数实例

    PHP+Mysql统计文件下载次数实例,实现的原理也很简单,是通过前台点击链接download.php传参id,来更新点击次数. 获取文件列表: <?php require 'conn.php' ...

  9. Access Grid Control Properties 访问网格控件属性

    In this lesson, you will learn how to access the properties of a list form's Grid Control in WinForm ...

  10. 关于如何获取项目所部署的本机IP和端口的问题

    关于如何获取项目所部署的本机IP和端口的问题 今天在写一个需求的时候碰到一个不常见的问题,在没有继承或者实现服务器提供的接口或者实现类的时候,比如说部署在tomacat上,某个类不去继承servelt ...