[Java开发之路](15)注解

简介:
1. 简介

注解(也被称为元数据),为我们在代码中添加信息提供了一种形式化的方法。注解在一定程度上是把 元数据与源代码文件结合在一起,而不是保存在外部文档中这一大趋势之下所催生的。

它可以提供用来 完整的描述程序所需的信息,而这些信息是无法使用Java来表达的。因此,注解使得我们能够以将 编译器来测试和验证的格式,存储有关程序的额外信息。注解可以用来生成描述符文件,甚至是新的类定义。通过使用注解,我们可以将这些 元数据保存在Java源代码中,并利用 Annotation API为自己的注解构造处理工具

注解可以生成更加干净易读的代码以及编译器类型检查等等。

注解(annotation)实在实际的源代码级别保存所有的信息,而不是某种注释性文字(comment),这使得代码更加简洁,便于维护。

2. 注解分类

按照运行机制分类 描述
源码注解 注解只在源码中存在,编译成.class文件就不存在了
编译时注解 注解只在源码和.class文件中都存在(例如:@override)
运行时注解 在运行阶段还起作用,甚至影响运行逻辑的注解(例如:@Autowired)


3. 内置注解:

(1)@override

表示当前的方法定义将覆盖超类中的方法。如果你不小心拼写错误,或者方法签名对不上被覆盖的方法,编译器就会发出错误提示。

(2)@Deprecated

如果程序员使用了注解为它的元素,那么编译器会发出警告信息。

(3)@SuppressWarnings

关闭不当的编译器警告信息(在java SE5 之前,也可以使用这个注解,不过被忽略不起作用)

4. 基本语法

4.1 定义注解

可以看到注解的定义很像接口的定义。事实上,与其他任何Java接口一样,注解也会被编译成class文件。
 
  
package com.qunar.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;
 
public class Annotation {
// 定义Description注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
// 使用@interface 关键字定义注解
public @interface Description{
// 成员以无参无异常方式声明
String desc();
String author();
// 可以使用default关键字为成员指定一个默认值
int age() default 18;
}
}

除了@符号以外,@Description的定义很像一个接口。定义注解的时候会需要一些元注解,如@Target和@Retention。 @Target用来定义你的注解将用于什么地方(是一个方法上还是一个类上), @Retention用来定义该注解在哪一个级别上可用(在源代码上或者是类文件上或者是运行时),具体下面讲解。

4.2 注解元素

注解@Description中包含int元素age,以及String元素desc和author。注解元素可以使用的类型如下:
  • 所有基本数据类型(int,float,boolean等)
  • String
  • Class
  • enum
  • Annotation
  • 以上类型的数组
如果你使用了其他类型,那么编译器就会报错。注意,也不允许使用任何包装类型,不过由于自动打包的存在,这算不上什么限制。注解也可以作为元素的类型,也就是注解可以嵌套。

4.3 默认值限制

编译器对元素的默认值有些过分的挑剔。
首先,元素不能有不确定的值,也就是说元素必须要么有默认值,要么使用注解时提供元素的值。
其次,对于非基本类型的元素,无论是在源代码中声明时,或者是在注解接口中定义默认值时,都不能以null作为其值。为了这个约束,我们只能自己定义一些特殊的值,例如空字符串或者负数,来表示某个元素不存在。

4.4 元注解

元注解只负责注解其他的注解。

元注解 参数 描述



@Taget


CONSTRUCTOR 构造器的声明

           表示注解可以用于什么地方


FIELD 域声明
METHOD 方法声明
PACKAGE 包声明
PARAMETER 参数声明
TYPE 类,接口或enum声明
LOCAL_VARIABLE 局部变量声明  

@Retention
SOURCE 注解只在源码中存在,编译成.class文件就不存在了
        表示需要在什么级别保存该注解信息
CLASS 注解只会在.class文件存在,会被VM丢弃
RUNTIME VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息
@Document     将此注解包含在Javadoc中
@Inherited     允许子类继承父类中的注解


4.5 使用注解

语法:@<注解名称>(<成员名1> = <成员值1>, <成员名2> = <成员值2>,... )

 
  
package com.qunar.annotation;
 
import com.qunar.annotation.Annotation.Description;
 
public class Student {
private String name;
@Description(desc = "set name for student object" , author = "sjf0115")
public String getName() {
return name;
}
@Description(desc = "get name from student object" , author = "sjf0115", time = "2016-01-11")
public void setName(String name) {
this.name = name;
}
}


5. 解析注解

通过反射机制获取类,函数或者成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。

 
  
package com.qunar.annotation;
 
import java.lang.reflect.Method;
 
import com.qunar.annotation.Annotation.Description;
 
public class ParseAnnotation {
public static void main(String[] args){
Class<?> class1 = null;
try {
// 使用类加载器加载类
class1 = Class.forName("com.qunar.annotation.Student");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 判断Student类上是否有Description注解
boolean isExits = class1.isAnnotationPresent(Description.class);
if(isExits){
// 注解实例
Description desc = class1.getAnnotation(Description.class);
System.out.println("注解:" + desc.toString());
}//if
// 获取Student类上的所有方法
Method[] methods = class1.getMethods();
// 遍历所有方法
for (Method method : methods) {
// 判断方法上是否有Description注解
isExits = method.isAnnotationPresent(Description.class);
if(isExits){
Description description = method.getAnnotation(Description.class);
System.out.println("方法注解:" + description.toString());
}//if
}//for
}
}
运行结果:

方法注解:@com.qunar.annotation.Annotation$Description(time=2016-01-12, desc=set name for student object, author=sjf0115)
方法注解:@com.qunar.annotation.Annotation$Description(time=2016-01-11, desc=get name from student object, author=sjf0115)

 
  
package com.qunar.annotation;
 
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
 
import com.qunar.annotation.Annotation.Description;
 
public class ParseAnnotation {
public static void main(String[] args){
Class<?> class1 = null;
try {
// 使用类加载器加载类
class1 = Class.forName("com.qunar.annotation.Student");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 判断Student类上是否有Description注解
boolean isExits = class1.isAnnotationPresent(Description.class);
if(isExits){
// 注解实例
Description desc = class1.getAnnotation(Description.class);
System.out.println("注解:" + desc.toString());
}//if
// 获取Student类上的所有方法
Method[] methods = class1.getMethods();
// 遍历所有方法
for (Method method : methods) {
// 方法上获取所有的注解
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
if(annotation instanceof Description){
System.out.println("Description注解:" + annotation.toString());
}//if
}//for
}//for
}
}

这两个程序都用到了反射的方法:getMethods()和getAnnotation(),它们都属于AnnotatedElement接口(Class,Method与Field等类都实现了该接口)。 getAnnotation()方法返回指定类型的注解对象,在这里就是Description。如果被注解的方法上没有该类型的注解,则返回null值。

















目录
相关文章
|
25天前
|
消息中间件 人工智能 Java
抖音微信爆款小游戏大全:免费休闲/竞技/益智/PHP+Java全筏开源开发
本文基于2025年最新行业数据,深入解析抖音/微信爆款小游戏的开发逻辑,重点讲解PHP+Java双引擎架构实战,涵盖技术选型、架构设计、性能优化与开源生态,提供完整开源工具链,助力开发者从理论到落地打造高留存、高并发的小游戏产品。
|
25天前
|
存储 Java 关系型数据库
Java 项目实战基于面向对象思想的汽车租赁系统开发实例 汽车租赁系统 Java 面向对象项目实战
本文介绍基于Java面向对象编程的汽车租赁系统技术方案与应用实例,涵盖系统功能需求分析、类设计、数据库设计及具体代码实现,帮助开发者掌握Java在实际项目中的应用。
43 0
|
2月前
|
安全 Java 数据库
Java 项目实战病人挂号系统网站设计开发步骤及核心功能实现指南
本文介绍了基于Java的病人挂号系统网站的技术方案与应用实例,涵盖SSM与Spring Boot框架选型、数据库设计、功能模块划分及安全机制实现。系统支持患者在线注册、登录、挂号与预约,管理员可进行医院信息与排班管理。通过实际案例展示系统开发流程与核心代码实现,为Java Web医疗项目开发提供参考。
113 2
|
2月前
|
JavaScript 安全 前端开发
Java开发:最新技术驱动的病人挂号系统实操指南与全流程操作技巧汇总
本文介绍基于Spring Boot 3.x、Vue 3等最新技术构建现代化病人挂号系统,涵盖技术选型、核心功能实现与部署方案,助力开发者快速搭建高效、安全的医疗挂号平台。
150 3
|
2月前
|
安全 Oracle Java
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
206 0
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
|
3月前
|
并行计算 Java API
Java List 集合结合 Java 17 新特性与现代开发实践的深度解析及实战指南 Java List 集合
本文深入解析Java 17中List集合的现代用法,结合函数式编程、Stream API、密封类、模式匹配等新特性,通过实操案例讲解数据处理、并行计算、响应式编程等场景下的高级应用,帮助开发者提升集合操作效率与代码质量。
148 1
|
3月前
|
安全 Java API
Java 17 及以上版本核心特性在现代开发实践中的深度应用与高效实践方法 Java 开发实践
本项目以“学生成绩管理系统”为例,深入实践Java 17+核心特性与现代开发技术。采用Spring Boot 3.1、WebFlux、R2DBC等构建响应式应用,结合Record类、模式匹配、Stream优化等新特性提升代码质量。涵盖容器化部署(Docker)、自动化测试、性能优化及安全加固,全面展示Java最新技术在实际项目中的应用,助力开发者掌握现代化Java开发方法。
138 1
|
3月前
|
IDE Java API
Java 17 新特性与微服务开发的实操指南
本内容涵盖Java 11至Java 17最新特性实战,包括var关键字、字符串增强、模块化系统、Stream API、异步编程、密封类等,并提供图书管理系统实战项目,帮助开发者掌握现代Java开发技巧与工具。
183 1
|
2月前
|
移动开发 Cloud Native 安全
Java:跨平台之魂,企业级开发的磐石
Java:跨平台之魂,企业级开发的磐石

热门文章

最新文章

下一篇
日志分析软件