我对java的理解(一)——注解就是贴标签
在现实生活中,贴标签这种现象比比皆是。去超市,去商场,每个或者每类物品都会有它的标签,甚至在我们自己身上也会有标签,比如,程序猿、逗逼、单身狗、80/90后、屌丝……呵呵,太多了。有时候,我们也会戏谑朋友同事,给他们贴个标签逗逗乐。但是这篇的正题是注解,下面我会说说为什么我理解的注解就是贴标签,虽然有时候也会称它为“扣帽子”。
元注解
在java提供了四个元注解,元注解就是注解的注解。它们是:
1.@Target, 2.@Retention, 3.@Documented, 4.@Inherited
在我们刚出生的时候,就已经被贴上标签了,我们的户籍按照地域划分,会被贴上河南河北、山东山西、湖南湖北等等23个省和四个直辖市中的其中一个。另外在我们的生命过程中也会经历标签的变换,小孩、未成年人、成年人、丈夫、妻子、父亲、母亲、爷爷奶奶等等。国家还会给我们贴上一个最普通的标签“公民”以及我们的继承的身份,农民或者城里人。为什么要说这些呢,因为JAVA中提供的四个元注解要表达的东西和提到的有共通之处。
@Target
@Target说明了注解修饰的范围,就好像我们有地域划分,而Java中也会有包、接口、类、枚举、属性、方法、构造函数等。那么为了表示不同的区别,注解是这么写的:
1、包
@Target(ElementType.PACKAGE)
2、接口、类、枚举、注解
@Target(ElementType.TYPE)
3、注解
@Target(ElementType.ANNOTATION_TYPE)
4、构造函数
@Target(ElementType.CONSTRUCTOR)
5、局部变量
@Target(ElementType.LOCAL_VARIABLE)
6、方法
@Target(ElementType.METHOD)
7、方法的参数
@Target(ElementType.PARAMETER)
@Retention
@Retention表示了注解的生命周期。我们在生命过程中会随着时间的变化而引起标签的变化,那么我们的标签本身也就说明了它有一定的生命周期,当我们未满18周岁的时候叫未成年人,在我们满18周岁的时候叫做成年人,等头发白了,走不动就被叫做老年人,而有的标签会伴随一生,例如男人或者女人。在JAVA中,注解也有它的生命周期,从源代码到编译后的Class文件,再到被JDK加载后的运行时就是整个周期。@Retention指定了它所要注解的注解的生命周期是什么,它会存在多长时间。JAVA中我们最常见的两个注解@SuppressWarnings和@Override,他们就只会存在于源代码中。下面是@Retention的取值:
1、在源代码中保留
@Retention( RetentionPolicy.SOURCE)
2、在Class文件中保留
@Retention( RetentionPolicy.CLASS)
3、在运行时保留
@Retention( RetentionPolicy.RUNTIME)
@SuppressWarnings注解的源代码如下:
package java.lang; import java.lang.annotation.*;
import java.lang.annotation.ElementType;
import static java.lang.annotation.ElementType.*; @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
@Documented
默认情况下javadoc是不包括注解信息的,但是当某一个注解被贴上@Documented标签的时候,那么当某个类或者方法的使用了被贴上@Documented这个标签的注解的时候,javadoc就会把注解信息也包含在生成的文档中。这个注解就不过度解读了,如果有兴趣的可以从网上自行查找相关资料。
@Inherited
@Inherited注解主要说明了一种继承性,意思是子类可以继承父类中的该注解(注意:只有当被贴上@Inherited标签的注解被用在类上的时候子类才能获得这个注解)。就像之前提到的,如果父母是农村户口,那么他们的孩子也默认就是农村户口了。Spring中的@Qualifier注解,代码如下:
package org.springframework.beans.factory.annotation; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier { String value() default ""; }
@Qualifier注解可以被用在字段、方法、方法参数、类、接口、注解、枚举上,但是只有@Qualifier被用在类上的时候才能被它的子类继承,子类才可以获取到这个注解。
自定义注解
除了一些我们生来就被贴上的标签意外,我们在日常生活中不管是主动的还是被动都会去主动的给别人贴一些标签以及被别人贴一些标签。当我们在公司,按照职能划分,会被贴上不同的岗位标签,便于安排工作;迟到,早退,全勤这些标签用于考勤;优秀员工,技术达人,管理精英等标签用来树立标杆,有助于提高积极性和向心力。那么这些标签被创造出来有没有用处呢,对于公司来说自然是有用处的。但是呢,逗逼这个标签对公司来说有没有用处呢,我想,除非公司愿意因为员工逗逼颁发逗逼奖这才有点用处,否则的话谁关心呢!贴个标签大多数时候并不会影响正常的生活,除了个人或者组织关注了你身上的标签的时候才会有影响,就像现在很多人一看到河南人三个字就开骂了一样……。其实这也是为了说明,注解并不会影响程序的正常运行,有或者没有并不影响什么,只有关注了这些注解的程序获得并且解析了注解进行处理以后才会更改程序本身的行为。
我们知道JAVA的JDK中很多地方都用了注解,到我们使用Spring的时候,注解就被使用的更广泛了,Spring用注解来对bean进行分类,注册,注入以及管理,这些事情是Spring在扫描Bean的时候通过反射来获取Bean的注解信息,配合完成Bean的自动装配,进而进行管理,给我们提供了丰富多彩的功能。下面写一个利用反射来处理自定义注解的例子,这个例子就是简单生成一个建表语句,代码如下:
1、创建@Table注解
package person.lb.annotation; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* 表名
* @author nobounds
*
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String value() default "";
}
2、创建@Column注解:
package person.lb.annotation; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* 字段
* @author nobounds
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String name() default "";
String dataType() default "varchar(20)";
String comment() default "";
}
3、创建实体类Users:
package person.lb.annotation; @Table("users")
public class Users {
@Column(name="ID", dataType="int")
private int id; @Column(comment="用户名")
private String userName; @Column(name="pwd", comment="密码")
private String password; @Column(dataType="varchar(25)", comment="邮箱")
private String email; public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public String getEmail() {
return email;
} public void setEmail(String email) {
this.email = email;
}
}
4、创建注解处理器AnnotationHandler:
package person.lb.annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Field; public class AnnotationHandler { public static void main(String[] args) {
StringBuilder sql = new StringBuilder("CREATE TABLE ");
try {
Class clazz = Class.forName("person.lb.annotation.Users");
//获取Users类上的Table注解
Table tableAnnotation = (Table) clazz.getAnnotation(Table.class);
//获取表名
String tableName = tableAnnotation.value().toUpperCase();
if("".equals(tableName)) {
tableName = clazz.getName().toUpperCase();
}
sql.append(tableName);
sql.append(" ( \n");
//获取类中的所有字段
Field[] fields = clazz.getDeclaredFields();
for(Field field : fields) {
//获取字段上的所有注解
Annotation[] fieldAnnotations = field.getAnnotations();
if(fieldAnnotations.length > 0) {
//遍历注解
for(Annotation fieldAnnotation : fieldAnnotations) {
//如果是@Field注解,那么进行处理
if(fieldAnnotation instanceof Column) {
//获取字段名
String columnName = ((Column) fieldAnnotation).name().toUpperCase();
if("".equals(columnName)) {
columnName = field.getName().toUpperCase();
}
//获取数据类型
String dataType = ((Column) fieldAnnotation).dataType().toUpperCase();
//获取注释
String comment = ((Column) fieldAnnotation).comment();
if("".equals(comment)) {
sql.append(columnName + "\t" + dataType + ",\n");
} else {
sql.append(columnName + "\t" + dataType + " COMMENT '" + comment + "',\n");
}
}
}
}
}
sql.append(" ) ");
System.out.println("生成的sql语句为:\n" + sql.toString()); } catch (ClassNotFoundException e) {
e.printStackTrace();
} } }
执行结果如下:
生成的sql语句为:
CREATE TABLE USERS (
ID INT,
USERNAME VARCHAR(20) COMMENT '用户名',
PWD VARCHAR(20) COMMENT '密码',
EMAIL VARCHAR(25) COMMENT '邮箱',
)
上面是一个简单的生成sql的例子,例子中忽略了某些非空判断,逻辑并不严谨,仅作为参考使用。如果大家觉得有问题请留言!
我对java的理解(一)——注解就是贴标签的更多相关文章
- Java学习记录-注解
注解 一.org.springframework.web.bind.annotation ControllerAdviceCookieValue : 可以把Request header中关于cooki ...
- Effective Java通俗理解(持续更新)
这篇博客是Java经典书籍<Effective Java(第二版)>的读书笔记,此书共有78条关于编写高质量Java代码的建议,我会试着逐一对其进行更为通俗易懂地讲解,故此篇博客的更新大约 ...
- Effective Java通俗理解(下)
Effective Java通俗理解(上) 第31条:用实例域代替序数 枚举类型有一个ordinal方法,它范围该常量的序数从0开始,不建议使用这个方法,因为这不能很好地对枚举进行维护,正确应该是利用 ...
- JAVA提高五:注解Annotation
今天我们学习JDK5.0中一个非常重要的特性,叫做注解.是现在非常流行的一种方式,可以说因为配置XML 比较麻烦或者比容易查找出错误,现在越来越多的框架开始支持注解方式,比如注明的Spring 框架, ...
- Effective Java通俗理解(上)
这篇博客是Java经典书籍<Effective Java(第二版)>的读书笔记,此书共有78条关于编写高质量Java代码的建议,我会试着逐一对其进行更为通俗易懂地讲解,故此篇博客的更新大约 ...
- Java基础教程:注解
Java基础教程:注解 本篇文章参考的相关资料链接: 维基百科:https://zh.wikipedia.org/wiki/Java%E6%B3%A8%E8%A7%A3 注解基础与高级应用:http: ...
- Java深度理解——Java字节代码的操纵
导读:Java作为业界应用最为广泛的语言之一,深得众多软件厂商和开发者的推崇,更是被包括Oracle在内的众多JCP成员积极地推动发展.但是对于 Java语言的深度理解和运用,毕竟是很少会有人涉及的话 ...
- Java枚举类与注解详解——一篇文章读懂枚举类与注解详
目录 一.枚举类 ① 自定义枚举类 ② enum关键字定义枚举类 ③ enum 枚举类的方法 ④ enum 枚举类实现接口 二.注解 ① 生成文档相关注解 ②注解在编译时进行格式检查 ③注解跟踪代码的 ...
- 深入理解Spring注解机制(一):注解的搜索与处理机制
前言 众所周知,spring 从 2.5 版本以后开始支持使用注解代替繁琐的 xml 配置,到了 springboot 更是全面拥抱了注解式配置.平时在使用的时候,点开一些常见的等注解,会发现往往在一 ...
随机推荐
- 使用JMeter测试Java项目
一. Apache JMeter工具 1)简介 JMeter——一个100%的纯Java桌面应用,它是Apache组织的开放源代码项目,它是功能和性能测试的工具.JMeter可以用于测试静态或者动态资 ...
- 七. PHP模式设计----运行及描写叙述任务
1. 解析器模式 //解析器内容类 //用于存放表达式的运算结果,并且能依据传入的表达式返回当初记录的结果 class InterpreterContext{ private $expressions ...
- html5中form表单新增属性以及改良的input标签元素的种类
在HTML5中,表单新增了一些属性,input标签也有了更多的type类型,有些实现了js才能实现的特效,但目前有些浏览器不能全部支持.下面是一些h5在表单和input标签上的一些改动. <!D ...
- "活在未来" VS “活在当下”(通向财富自由学习笔记六)
之前读过一些灵修类的书籍,<遇见未知的自己>.<当下的力量>等都在告诉我们活在当下很重要,这里笑来老师提出了一个问题,是活在当下重要呢?还是活在未来?,笑来老师给出了很好的答案 ...
- [原创]将本地代码共享到github的操作步骤
将本地代码共享到github的操作步骤 本地代码目录执行如下命令,初始化为git仓库. git init 到github上新建一个仓库,假设为https://github.com/sky0014/sk ...
- POJ 2187 Beauty Contest【凸包周长】
题目: http://poj.org/problem?id=1113 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...
- 1.设计模式-------Iterator
本文主要是参考<图解设计模式>写的读书笔记: 开发中我用到遍历集合时候,无非我常用的就是简单的for循环,foreach,iterator 这三种方式进行遍历! 当然这三种的效率: 学习I ...
- 我的Android进阶之旅------>Android关于TextWatcher的初步了解
首先来看一下TextWatcher的源代码 package android.text; /** * When an object of a type is attached to an Editabl ...
- ubuntu13.04中把ibus中的中文拼音输入设为默认
全新的ubuntu ,先选择 下载服务器 首选项->软件和更新 选择 最佳服务器 准备工作:卸载Ubuntu默认的ibus输入法: sudo apt-get remove ibus 然后添加Fc ...
- Python OOP(3) staticmethod和classmethod统计实例
staticmethod 统计实例 #!python2 #-*- coding:utf-8 -*- class c1: amount_instance=0 def __init__(self): c1 ...