Java 内置注解简单理解
感谢原文作者:yejg1212
原文链接
https://www.cnblogs.com/yejg1212/p/3187362.html
https://www.cnblogs.com/yejg1212/p/3188751.html
https://www.cnblogs.com/yejg1212/p/3188791.html
超通俗易懂的注解入门文章:https://blog.csdn.net/shengzhu1/article/details/81271409
Bilibili:https://www.bilibili.com/video/av55440782
Ⅰ. 简单介绍Jave的内置注解(7个:4个元注解)
Java从JDK 5开始引入注解(annotation)。
注解使得Java源代码中不但可以包含功能性的实现代码,还可以添加元数据。
注解的功能类似于代码中的注释,所不同的是注解不是提供代码功能的说明,而是实现程序功能的重要组成部分。
Java注解已经在很多框架中得到了广泛的使用,用来简化程序中的配置。
下面先来看看java中常用的注解。
一、常用注解
① @Override注解
package java.lang;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@Override注解表示子类要重写父类的对应方法。
如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。
顺便说一句:@override注解在JDK 5环境下只能用于对继承的类的方法的重写,实现接口中的方法不能用@override注解。但是JDK1.6可以。
② @Deprecated注解
package java.lang;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Deprecated {
}
@Deprecated注解表示方法是不被建议使用的。
③ @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();
}
@SuppressWarnings注解表示抑制警告。
例如下面的代码,声明了2个未使用的变量,加上2个@SuppressWarnings来抑制警告。
@SuppressWarnings("unused")
int a=10;
@SuppressWarnings({ "rawtypes", "unused" })
List list =new ArrayList();
上面给出了Java自带的几个常用的注解,下面先来了解下代码中出现的诸如@Target,@Retention,@Documented(这些也叫元注解)的意义。
二、元注解
① @Target
@Target 表示该注解用于什么地方,可取的值包括:
ElemenetType.CONSTRUCTOR 构造器声明
ElemenetType.FIELD 域声明(包括 enum 实例)
ElemenetType.LOCAL_VARIABLE 局部变量声明
ElemenetType.METHOD 方法声明
ElemenetType.PACKAGE 包声明
ElemenetType.PARAMETER 参数声明
ElemenetType.TYPE 类,接口(包括注解类型)或enum声明
ElementType.ANNOTATION_TYPE 注解
② @Retention
@Retention 表示在什么级别保存该注解信息。可选的 RetentionPolicy 参数包括:
- RetentionPolicy.SOURCE 注解将被编译器丢弃
- RetentionPolicy.CLASS 注解在class文件中可用,但会被VM丢弃
- RetentionPolicy.RUNTIME JVM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。
③ @Documented
@Documented 将此注解包含在 javadoc 中
④ @Inherited
@Inherited 允许子类继承父类中的注解
Ⅱ. 自定义注解及注射提取的简单介绍
自定义注解其实很简单,直接上代码:
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
/*
1. 定义注解 Test
2. 注解中含有两个元素 id 和 description
3. description 元素 有默认值 "hello anntation"
*/
public @interface Test {
public int id();
public String description() default "hello annotation";
}
根据上一篇对元注解的解释,我们知道:
- 这个注解可以用于方法
- JVM运行期间该注解都有效
- 该注解包含在 javadoc 中
- 该注解允许子类继承
下面看下通过注解我们能取到什么
public class TestMain {
/*
* 被注解的三个方法
*/
@Test(id = 1, description = "hello methodA")
public void methodA() {
}
@Test(id = 2)
public void methodB() {
}
@Test(id = 3, description = "last method")
public void methodC() {
}
/*
* 解析注解,将类被注解方法 的信息打印出来
*/
public static void main(String[] args) {
Method[] methods = TestMain.class.getDeclaredMethods();
for (Method method : methods) {
/*
* 判断方法中是否有指定注解类型的注解
*/
boolean hasAnnotation = method.isAnnotationPresent(Test.class);
if (hasAnnotation) {
/*
* 根据注解类型返回方法的指定类型注解
*/
Test annotation = method.getAnnotation(Test.class);
System.out.println("Test( method = " + method.getName() + " , id = " + annotation.id()
+ " , description = " + annotation.description() + " )");
}
}
}
}
上面的Demo打印的结果如下:
Test( method = methodA , id = 1 , description = hello methodA )
Test( method = methodB , id = 2 , description = hello annotation )
Test( method = methodC , id = 3 , description = last method )
例其实也说明了,我们一般通过反射来取RUNTIME保留策略的注解信息。
Ⅲ. 简单实例
目标:将实体bean保存到数据库
先来定义一个实体注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Entity {
String getTableName();
}
这个注解可用在类上,它有一个变量参数getTableName。
其实意义很明显,就是一个实体类对应一张数据库的表,通过Entity注解将类和数据库表名关联起来
那么,通过什么将类的参数和数据库表中的列关联起来呢?再来定义一个注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String getName();
}
有了Column注解,类里面的属性就和表中的列关联起来了。
POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。
EJB是的Enterprise Java Beans技术的简称, 又被称为企业Java Beans。这种技术最早是由美国计算公司研发出来的。
下面来看看POJO中怎么用这两个注解:
@Entity(getTableName = "user")
public class User {
@Column(getName = "user_id")
private String id;
@Column(getName = "user_name")
private String name;
@Column(getName = "user_age")
private int age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
通过Entity和Column注解,就将一个实体bean和一张数据库表连接起来了。很多ORM映射就是采取这种方式实现的。
最后,来感受一下注解给我们带来的便利,来个方法见证下~~
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
public class Session {
public static void main(String[] args) {
Session session = new Session();
System.out.println(session.getInsertSql(new User()));
}
//在实际项目中,你可以save(obj)方法来保存一个bean
public void save(Object obj) {
// get a connection
//PreparedStatement pstmt = getStatement(con, obj);
//pstmt.execute();
}
//得到PreparedStatement
public PreparedStatement getStatement(Connection con, Object obj)
throws Exception {
PreparedStatement pstmt = con.prepareStatement(getInsertSql(obj));
Class<?> c = obj.getClass();
Field[] fs = c.getDeclaredFields();
for (int i = 0; i < fs.length; i++) {
fs[i].setAccessible(true);
pstmt.setObject(i + 1, fs[i].get(obj));
}
return pstmt;
}
//insert into tableName(ziduan1,ziduan2...) values(?,?...)
public String getInsertSql(Object obj) {
StringBuilder s = new StringBuilder();
s.append("insert into ");
Class<?> c = obj.getClass();
String tableName = c.getSimpleName();//类名,不包含包名 User
Entity entity = (Entity) c.getAnnotation(Entity.class);
if (entity != null) {
tableName = entity.getTableName();
}
s.append(tableName).append("(");
Field[] fs = c.getDeclaredFields();
for (int i = 0; i < fs.length; i++) {
String fieldName = fs[i].getName();
Column column = fs[i].getAnnotation(Column.class);
if (column != null) {
fieldName = column.getName();
}
s = i == 0 ? s.append(fieldName) : s.append(",").append(fieldName);
}
s.append(") values").append(getString(fs.length));
return s.toString();
}
//得到(?,?,?,...?,?)
private String getString(int length) {
StringBuilder s = new StringBuilder();
s.append("(");
for (int i = 0; i < length; i++) {
s = i == 0 ? s.append("?") : s.append(",?");
}
s.append(")");
return s.toString();
}
}
OK,That’s all!
Java 内置注解简单理解的更多相关文章
- java注解学习(1)注解的作用和三个常用java内置注解
今天,记录一下自己学习的关于注解方面的知识. Annotation是从JDK5.0开始引入的新技术 Annotation的作用: -不是程序本身,可以对程序做出解释(这一点和注释没什么区别) -可以被 ...
- JAVA内置注解 基本注解
温故而知新,可以为师矣! 每天复习,或者学习一点小东西,也能水滴石穿! 今天复习5个JAVA内置基本注解(贴代码胜过千言万语): package com.lf.test; import java.ut ...
- java内置注解、元注解和自定义注解
注解的作用: 1.生成文档 2.跟踪代码依赖性 3.编译时进行格式检查 ---------------------------------------------------------------- ...
- java注解——内置注解和四种元注解
java内置注解: @Override(重写方法):被用于标注方法,用于说明所标注的方法是重写父类的方法 @Deprecated(过时方法):用于说明所标注元素,因存在安全问题或有更好选择而不鼓励使用 ...
- Java内置锁和简单用法
一.简单的锁知识 关于内置锁 Java具有通过synchronized关键字实现的内置锁,内置锁获得锁和释放锁是隐式的,进入synchronized修饰的代码就获得锁,走出相应的代码就释放锁. jav ...
- Java注解-元数据、注解分类、内置注解和自定义注解|乐字节
大家好,我是乐字节的小乐,上次说过了Java多态的6大特性|乐字节,接下来我们来看看Java编程里的注解. Java注解有以下几个知识点: 元数据 注解的分类 内置注解 自定义注解 注解处理器 Ser ...
- 深入理解Java内置锁和显式锁
synchronized and Reentrantlock 多线程编程中,当代码需要同步时我们会用到锁.Java为我们提供了内置锁(synchronized)和显式锁(ReentrantLock)两 ...
- Java 性能分析工具 , 第 2 部分:Java 内置监控工具
引言 本文为 Java 性能分析工具系列文章第二篇,第一篇:操作系统工具.在本文中将介绍如何使用 Java 内置监控工具更加深入的了解 Java 应用程序和 JVM 本身.在 JDK 中有许多内置的工 ...
- 使用Java内置的Http Server构建Web应用
一.概述 使用Java技术构建Web应用时, 我们通常离不开tomcat和jetty之类的servlet容器,这些Web服务器功能强大,性能强劲,深受欢迎,是运行大型Web应用的必备神器. 虽然Jav ...
随机推荐
- Linux的基本目录结构
- javascript实现base64格式转码与解码
最近碰到一个需求,后端返回base64格式的数据,前端需要进行base64格式解码,好了,前端采用内部提供的atob函数进行解码,开完成,交付测试,然后测试小哥哥小姐姐反馈说中文乱码! 然后查了一下, ...
- 1.HTML基本结构、头部、注释
基本结构 1.HTML基本结构 <html> <head> <meta charset="utf-8"> ...
- JS 数组的基本使用和案例
知识点汇总: 数组:就是一组数据的集合,存储在单个变量的方式 自变量创建数组 var 数组名字 = ['a','b'] // []里面的是数据的元素,可为任意字符类型 利用new创建数组 var 数组 ...
- XPTH定位总结
xpath定位总结:nodename 选取此节点的所有子节点. / :从根节点选取.绝对定位 //:从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置. 相对定位(推荐使用相对定位) . :选取 ...
- 利用pyinstaller给工程打包生成python可执行文件
step1.下载pyinstaller: step2.将pyinstaller的路径加入系统环境变量PATH中:(关键) step3.进入工程的根目录下(即可执行文件.py)所在目录下,cmd,输入命 ...
- CAP原理详解
转载 https://blog.csdn.net/u013332124/article/details/82874178 文章目录 一.CAP原理介绍 对CAP原理的一些常见的理解误区 二.CAP原理 ...
- Vue下路由History mode 出现404,无法正常刷新
在History mode下,如果直接通过地址栏访问路径,那么会出现404错误,这是因为这是单页应用(废话)-其实是因为调用了history.pushState API 所以所有的跳转之类的操作都是通 ...
- Jmeter中用例禁用
1.在线程组下创建2个http请求(blogs和baidu),并且在Thread Group 添加[View Results Tree]和[View Results in Table] 2.选择[ba ...
- 基于rabbitmq延迟插件实现分布式延迟任务
承接上文基于redis,redisson的延迟队列实践,今天介绍下基于rabbitmq延迟插件rabbitmq_delayed_message_exchange实现延迟任务. 一.延迟任务的使用场景 ...