`
SunnyYoona
  • 浏览: 386601 次
社区版块
存档分类
最新评论

[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=setnameforstudentobject,author=sjf0115)
方法注解:@com.qunar.annotation.Annotation$Description(time=2016-01-11,desc=getnamefromstudentobject,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值。

















分享到:
评论

相关推荐

    java 自定义注解验证

    Java 自定义注解验证是Java开发中的一个重要特性,它允许开发者创建自己的元数据,以便在编译时或运行时对代码进行验证和处理。自定义注解为代码提供了额外的信息,使得程序更具可读性、可维护性和灵活性。在本案例...

    java和ssh注解

    总之,Java和SSH框架中的注解大大提升了开发效率,降低了维护成本。通过深入理解并熟练运用这些注解,开发者能够更好地构建和维护高质量的Java Web应用。在实际工作中,结合最佳实践,灵活运用注解,可以实现更加...

    Java自定义注解使用反射获取字段注解

    自定义注解的强大之处在于可以通过注解处理器生成额外的代码或者在运行时进行动态处理。例如,我们可以编写一个注解处理器来生成getter和setter方法,或者在运行时根据注解动态改变对象的行为。 总结一下,Java的...

    java 注解开发(包含详细注释,项目可以直接运行)

    在现代的Java开发中,注解被广泛应用于框架如Spring、Hibernate等,以实现依赖注入、数据验证、持久化等功能。 1. **注解的定义与分类** - **自定义注解**:Java允许我们创建自己的注解类型,通过`@interface`...

    Java自定义注解实例

    Java自定义注解是Java编程语言中的一个重要特性,它允许程序员在...自定义注解的灵活性和广泛用途使得它们成为现代Java开发不可或缺的一部分。在实际项目中,理解并熟练运用自定义注解能有效提高代码质量和可维护性。

    Java Bean 遍历和使用注解给Bean的属性添加属性值

    理解并熟练运用这两个概念,能让你在Java开发中更得心应手。 以上内容围绕Java Bean的遍历和注解进行了详细的解释,但具体实现可能需要结合实际的代码示例和应用场景。在给定的压缩包文件"TraversalBean"中,可能...

    java注解深入理解

    注解在现代Java开发中扮演了不可或缺的角色,尤其在依赖注入、代码生成、元编程以及验证等方面。 首先,我们需要了解注解的基本概念。Java注解是以`@`符号开头的特殊声明,后面跟着注解的名称。例如,`@Override`...

    Java Annotation注解技术

    Java Annotation注解技术是现代Java开发中不可或缺的一部分,它通过提供元数据增强了代码的表达能力,简化了代码的编写和维护,同时也促进了框架和工具的高效开发。了解和掌握注解技术对于提升Java开发的效率和质量...

    Java注解实现方式

    Java注解是Java编程语言中的一个重要特性,它允许程序员在代码中嵌入元数据,这些元数据可以被编译器或运行时环境用来执行各种任务,例如代码分析、验证、生成代码、部署等。注解提供了更加灵活和可扩展的方式来处理...

    注解javademo演示

    Java注解在现代Java开发中扮演着不可或缺的角色,尤其是在框架如Spring、Hibernate等中广泛使用。 注解的语法结构通常以`@`符号开始,后跟注解的名称。例如,`@Override`表示方法是重写父类的方法,`@Deprecated`...

    java自定义注解和通过反射获取注解

    Java自定义注解和通过反射获取注解是Java编程中重要的高级特性,它们极大地增强了代码的可读性和可维护性。注解(Annotation)是一种元数据,提供了在编译时和运行时对代码进行标记的方法,而反射(Reflection)则是...

    Java的注解包,在使用注解的时候导入的jjar包

    在Java开发中,除了JUnit,Spring框架也广泛使用注解。`@Autowired`用于自动装配依赖,使得无需显式使用setter方法或构造函数注入。`@Component`、`@Service`、`@Repository`和`@Controller`定义了不同的bean类型,...

    java注解webservice学习第一篇

    在Java Web服务(WebService)开发中,注解的应用极大地简化了服务的创建和配置。本文将深入探讨如何使用Java注解来构建Web服务,并结合给出的“lib”压缩包文件,推测可能包含了一些用于支持Web服务的库文件。 ...

    java通用注解API

    通过阅读《Java通用注解和API规范.pdf》这份文档,你可以更深入地理解Java注解的原理、使用方法以及最佳实践,从而在实际开发中更好地利用这一强大的工具。这份文档涵盖了从基础概念到高级特性的全面内容,对于Java...

    Java 注解技术视频详解

    总的来说,Java注解技术是现代Java开发中不可或缺的一部分,它简化了代码的编写,增强了代码的可读性和可维护性。通过学习和熟练掌握Java注解,开发者可以更好地利用Java平台提供的功能,提升开发效率和软件质量。在...

    java注解大全(非常全面)

    Java注解是Java编程语言中的一个重要特性,它们提供了一种元数据的方式,允许程序员在代码中插入信息,这些...这份"java注解大全"资料将引导你全面掌握这一强大的工具,无论是在日常开发还是面试准备中,都将大有裨益。

    java token验证和注解方式放行

    "java token验证和注解方式放行"的主题涉及了两个关键概念:Token验证和基于注解的权限管理。Token通常用于验证用户身份,防止未授权的访问。下面我们将深入探讨这两个主题。 首先,Token验证是一种常见的身份验证...

Global site tag (gtag.js) - Google Analytics