java 注解的基础详细介绍

前言
注解是Java引入的一项非常受欢迎的补充,它提供了一种结构化的,并且具有类型检查能力的新途径,从而使得程序员能够为代码加入元数据,而不会导致代码杂乱且难以阅读。使用注解能够帮助我们避免编写累赘的部署描述文件,以及其他生成的文件。
注解的语法比较简单,除了@符号的使用之外,它基本与java固有的语法一致。但由于java源码中提供的内置注解很少,所以大部分同学对注解都不是很了解,虽然我们都接触过,比如java内置的几种注解:
@Override,表示当前的方法定义将覆盖超类中的方法。 @Deprecated,表示当前方法即将废弃,不推荐使用。 @SuppressWarnings,表示忽略编译器的警告信息。
但这并不能让我们体会到注解的强大和便利,其实Java还另外提供了四种注解,专门负责新注解的创建。今天我们就来学习下怎么创建和使用注解。
注解类的定义
首先看看一个注解类的定义:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraints {
boolean primaryKey() default false;
boolean allowNull() default true;
boolean unique() default false;
}
除了@符号以外,注解类的定义很像一个空的接口。定义注解时,会需要一些元注解,如@Target和@Retention,java提供了四种元注解,定义如下:
@Target:表示该注解可以用于什么地方。
取值(ElementType)包括:
CONSTRUCTOR:用于描述构造器
FIELD:用于描述域
LOCAL_VARIABLE:用于描述局部变量
METHOD:用于描述方法
PACKAGE:用于描述包
PARAMETER:用于描述参数
TYPE:用于描述类、接口(包括注解类型) 或enum声明
@Retention:表示需要在什么级别保存该注解信息。
取值(RetentionPolicy)包括:
SOURCE:在源文件中有效(即源文件保留)
CLASS:在class文件中有效(即class保留)
RUNTIME:在运行时有效(即运行时保留),因此可以通过反射机制读取注解的信息。
@Documented:表示将此注解包含在javadoc中。
@Inherited:表示允许子类继承父类中的注解。
可以看出 定义注解格式为:
public @interface 注解名 {定义体}
注解类中定义的元素称为注解元素,注解元素可用的类型如下:
所有基本数据类型(int,float,boolean,byte,double,char,long,short) String类型 Class类型 enum类型 Annotation类型 以上所有类型的数组
如果你使用了其它类型,那编译器就会报错。注意,也不允许使用任何包装类型,但由于自动打包的存在,这算不上什么限制。注解也可以作为元素的类型,比如我们再定义一个注解类:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLString {
int value() default 0;
String name() default "";
Constraints constraints() default @Constraints;
//@Constraints后没有括号表明使用默认值,可以加括号,在里面定义初始值,比如@Constraints(unique=true)
}
可以看出,所有的注解元素都有一个默认值。编译器对元素的默认值有些过分挑剔,首先,元素必须具有默认值;其次不能以null作为默认值。所以我们只能自己定义一些特殊的值,例如空字符串或负数,来表示某个元素不存在。
注解类的使用
注解类定义好了,怎么使用呢?
为了体现注解的便利和强大,在这里我们写一个demo,使用注解来自动生成一个建数据库表的SQL命令。
另外我们再提供两个注解类:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
public String name() default "";
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLInteger {
String name() default "";
Constraints constraints() default @Constraints;
}
好,现在我们一共有4个注解类。
@DBTable 代表数据库表,注解元素name表示表名;
@Constraints 代表对数据表每一列的条件补充,有primaryKey是不是主键,默认false,allowNull是否允许为空,默认true,unique数据是否唯一,默认false;
@SQLString 代表表中的String列,注解元素value表示列长度,name表示列名,constraints表示对列的一些约束条件;
@SQLInteger 代表表中的int列,name表示列名,constraints表示对列的一些约束条件;
下面我们定义一个简单的Bean类,在其中应用以上4个注解类:
@DBTable(name = "MEMBER")
public class Member {
@SQLString(30) String firstName;
@SQLString(50) String lastName;
@SQLInteger int age;
@SQLString(value = 30, constraints = @Constraints(primaryKey = true)) String handle;
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public String getHandle() {
return handle;
}
public String toString() {
return handle;
}
}
注解的元素在使用时表现为名-值对的形式,并需要置于 @注解类名 声明之后的括号内。如果没有使用括号,代表全部使用默认值。
1、类的注解@DBTable给定了值MEMBER,它将会用来作为表的名字;
2、Bean的属性firstName和lastName,都被注解为@SQLString类型,这些注解有两个有趣的地方:第一,他们都使用了嵌入的@Constraints注解的默认值;第二,它们都使用了快捷方式。何谓快捷方式?如果程序员的注解中定义了名为value的元素,并且在应用该注解的时候,如果该元素是唯一需要赋值的一个元素,那么此时无需使用名-值对的这种语法,而只需在括号内给出value元素所需的值即可。这可以应用于任何合法类型的元素。当然了,这也限制了程序员必须将此元素命名为value。
Bean属性age全部使用默认值,handle为主键。
3、Bean属性age全部使用默认值,handle为主键。
实现注解处理器
注解类使用上了,我们还需要一个注解处理器来解析我们定义的Bean,这样才能将注解转换成我们需要的操作。
以下定义解析Bean的注解处理器,我们的目的是要输出一条SQL语句。主要用到了反射技术。
public class TableCreator {
public static void main(String[] args) throws Exception{
//传入我们定义好的Bean类名,带上包名
Class<?> cl = Class.forName("annotation.Member");
//检查我们传入的类是否带有@DBTable注解
DBTable dbTable = cl.getAnnotation(DBTable.class);
List<String> columnDefs = new ArrayList<String>();
//得到类中的所有定义的属性
for(Field filed : cl.getDeclaredFields()){
String columnName = null;
//得到属性的注解,对一个目标可以使用多个注解
Annotation[] anns = filed.getAnnotations();
if(anns.length < 1){
continue;
}
//SQLString注解走着
if(anns[0] instanceof SQLString){
SQLString sString = (SQLString)anns[0];
//name()使用的是默认值,所以这里取属性名
if(sString.name().length() < 1){
columnName = filed.getName().toUpperCase();
}else{
columnName = sString.name();
}
//构建SQL语句
columnDefs.add(columnName + " VARCHAR(" + sString.value() + ")" + getConstraints(sString.constraints()));
}
//SQLInteger注解走着
if(anns[0] instanceof SQLInteger){
SQLInteger sInt = (SQLInteger)anns[0];
if(sInt.name().length() < 1){
columnName = filed.getName().toUpperCase();
}else{
columnName = sInt.name();
}
columnDefs.add(columnName + " INT" + getConstraints(sInt.constraints()));
}
}
StringBuilder creator = new StringBuilder("CREATE TABLE " + dbTable.name() + "( ");
for(String c : columnDefs){
creator.append("\n" + c + ",");
}
creator.deleteCharAt(creator.length()-1);
creator.append(")");
System.out.println(creator.toString());
}
private static String getConstraints(Constraints con) {
String constraints = "";
if(!con.allowNull()){
constraints += " NOT NULL";
}
if(con.primaryKey()){
constraints += " PRIMARY KEY";
}
if(con.unique()){
constraints += " UNIQUE";
}
return constraints;
}
}
最后的输出:
CREATE TABLE MEMBER( FIRSTNAME VARCHAR(30), LASTNAME VARCHAR(50), AGE INT, HANDLE VARCHAR(30) PRIMARY KEY)
总结
最后,通过这篇文章,我们要学到一下几点:
1、了解Java 4种元注解的说明与使用;
2、会自定义注解类;
3、了解注解元素的定义和规则;
4、会使用注解类;
5、能写一个简单的注解处理器解析注解。
如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# java
# 注解
# 注解的使用方法
# 注解详解
# mybatis自动生成@Table、@Column、@Id注解的方法
# JAVA注解相关知识总结
# 解决springboot jpa @Column columnDefinition等属性失效问题
# 默认值
# 类中
# 主键
# 可以看出
# 使用了
# 将此
# 四种
# 走着
# 快捷方式
# 的是
# 括号内
# 但由于
# 就会
# 如果你
# 也不
# 都有
# 在这里
# 好了
# 让我们
# 多个
相关文章:
如何快速辨别茅台真假?关键步骤解析
广州顶尖建站服务:企业官网建设与SEO优化一体化方案
制作农业网站的软件,比较好的农业网站推荐一下?
建站OpenVZ教程与优化策略:配置指南与性能提升
如何通过虚拟主机快速搭建个人网站?
建站主机如何安装配置?新手必看操作指南
高端智能建站公司优选:品牌定制与SEO优化一站式服务
如何快速选择适合个人网站的云服务器配置?
购物网站制作公司有哪些,哪个购物网站比较好?
东莞专业制作网站的公司,东莞大学生网的网址是什么?
怎么将XML数据可视化 D3.js加载XML
如何快速搭建个人网站并优化SEO?
Android自定义listview布局实现上拉加载下拉刷新功能
专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?
在线ppt制作网站有哪些,请推荐几个好的课件下载的网站?
网站制作公司广州有几家,广州尚艺美发学校网站是多少?
西安制作网站公司有哪些,西安货运司机用的最多的app或者网站是什么?
rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted
Avalonia如何实现跨窗口通信 Avalonia窗口间数据传递
广东企业建站网站优化与SEO营销核心策略指南
零服务器AI建站解决方案:快速部署与云端平台低成本实践
建站之星3.0如何解决常见操作问题?
建站主机CVM配置优化、SEO策略与性能提升指南
北京企业网站设计制作公司,北京铁路集团官方网站?
如何通过二级域名建站提升品牌影响力?
建站之星安装模板失败:服务器环境不兼容?
建站主机空间推荐 高性价比配置与快速部署方案解析
如何配置支付宝与微信支付功能?
杭州银行网站设计制作流程,杭州银行怎么开通认证方式?
动图在线制作网站有哪些,滑动动图图集怎么做?
建站主机选虚拟主机还是云服务器更好?
,柠檬视频怎样兑换vip?
php json中文编码为null的解决办法
如何批量查询域名的建站时间记录?
如何快速搭建高效服务器建站系统?
如何通过商城自助建站源码实现零基础高效建站?
想学网站制作怎么学,建立一个网站要花费多少?
建站之星代理商如何保障技术支持与售后服务?
网站插件制作软件免费下载,网页视频怎么下到本地插件?
济南网站制作的价格,历城一职专官方网站?
网站建设制作、微信公众号,公明人民医院怎么在网上预约?
广州美橙建站如何快速搭建多端合一网站?
建站之星logo尺寸如何设置最合适?
韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南
如何通过虚拟主机快速完成网站搭建?
Swift中switch语句区间和元组模式匹配
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
正规网站制作公司有哪些,目前国内哪家网页网站制作设计公司比较专业靠谱?口碑好?
制作宣传网站的软件,小红书可以宣传网站吗?
建站之星如何实现五合一智能建站与营销推广?
*请认真填写需求信息,我们会在24小时内与您取得联系。