首页 > 编程知识 正文

java注解在框架中的应用,jdk注解原理

时间:2023-05-04 15:51:27 阅读:134514 作者:3524

创建第一个评论

package com.tmser.annotation;

public @interface TestA {

//这里定义了空注释,可以做什么呢? 我也不知道,他能用。

}

在以下步骤中使用。

package com.tmser.annotation;

import java.util.HashMap;

import java.util.Map;

使用了@TestA //类注释

公共类用户身份验证{

@TestA //使用了类成员的注释

私有整合者;

@TestA //使用了构建方法注释

公共用户身份验证

}

使用了@TestA //类方法的注释

公共void a () {

@TestA //使用了局部变量注释

mapm=newHashmap(0;

}

使用了公共void b (@ testaintegera )//方法参数注释

}

}

编译没有错误,ok,注释实验完成。 这个注释也太简单了吧。 好像传达不了任何信息。 不要着急。 接下来一步一步完善它,4位注释也开始按顺序出现。

4个meta评论分别为@Target,@Retention,@Documented,@Inherited,meta评论由java API提供,再次强调是专门用于评论定义的评论

@Target表示使用注释的位置。 枚举类ElemenetType中提供了可能的值,其中包括:

elemenettype.constructor------构造函数声明

包括elemenettype.field------域声明----- enum实例

elemenettype.local _ variable------局部变量声明

elemenettype.method----方法声明

elemenettype.package---- -包声明

elemenettype.parameter---- -参数声明

elemenettype.type------类、接口-----包含注释类型-----或enum声明

@Retention表示在哪个级别保存此注释信息。 枚举类型RetentionPolicy具有以下可选参数值:

retentionpolicy.source---------注释将被编译器丢弃

retention policy.class-------- -注释可以在class文件中使用,但在VM中会被丢弃

retentionpolicy.runtimevm----为了在运行时也保留注释,反射机制可以读取注释信息。

@Documented将此注释包含在javadoc中。 这表示javadoc工具将此注释提取到文档中。 doc文档的内容取决于此注释的内容。 相当于@see,@param等。

@Inherited允许子类从父类继承注释。

学习高骥远是最重要的。 最重要的是实践。 一个一个地实验一下吧。

第一个是@Target,给之前我们写的评论加元评论。

package com.tmser.annotation;

import Java.lang.annotation.element type;

import Java.lang.annotation.target;

@Target(elementtype.package ) /与前面定义的评论的不同之处在于,这里使用了元评论target

public @interface TestA {

}

ctrl s保存,今天的电脑比较给力,我们测试班很快出现了很多错误。 班级注释除外。 想到这个,聪明的你马上就理解了这个元评论的意思。 是不是理所当然地懈怠了? 有事故吗? 细心的朋友应该注意到,我们的测试类少了一个ElemenetType.PACKAGE属性,没有用。 在我们的评论中添加了这个属性的元评论后,我们测试程序的元评论都战死了。 不,我没有再加一个。 请追加。 package包,想成为

然是加载 package 前面。即

@TestA package com.tmser.annotation;

什么也报错。这就搞不明白了,不加在这加哪去呢。我也不知道了,不过这是编译错误,我们的eclipse 将错误给我们指出了,就是Package annotations must be in file package-info.java ,e 文虽然不好,但这个简单的还是难不倒几个人的,package 注解必须定义在 package-info.java 中。package-info 又是什么东西,好了为节省你们的时间帮你百度好了(在另一篇我的另一篇博文里面,自己找吧,咔咔)。ok,到此 target 元注解就全部完成了。

第二个元注解: @Retention 参数 RetentionPolicy。有了前面的经验这个注解理解起来就简单多了,并且幸运的是这个注解还没有特殊的属性值。 简单演示下如何使用:

package com.tmser.annotation;

import java.lang.annotation.ElementType;

import java.lang.annotation.Target;

@Target(ElementType.PACKAGE)

@Retention(RetentionPolicy.RUNTIME)

public @interface TestA {

}

第三和第四个元注解就不再举例了。比较简单,也没有值,相信看过上面的解释也就清楚了。下面我们还是继续来深入的探讨下注解的使用。上面的例子都非常简单,注解连属性都没有。ok,下面我们就来定义一个有属性的注解,并在例子程序中获取都注解中定义的值。

开始之前将下定义属性的规则:

@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。

代码:

@Target({TYPE,METHOD,FIELD,CONSTRUCTOR})

@Retention(RetentionPolicy.RUNTIME)

public @interface TestA {

String name();

int id() default 0;

Class gid();

}

下面改下我们的测试类:

package com.tmser.annotation;

import java.util.HashMap;

import java.util.Map;

@TestA(name="type",gid=Long.class) //类成员注解

public class UserAnnotation {

@TestA(name="param",id=1,gid=Long.class) //类成员注解

private Integer age;

@TestA (name="construct",id=2,gid=Long.class)//构造方法注解

public UserAnnotation(){

}

@TestA(name="public method",id=3,gid=Long.class) //类方法注解

public void a(){

Map m = new HashMap(0);

}

@TestA(name="protected method",id=4,gid=Long.class) //类方法注解

protected void b(){

Map m = new HashMap(0);

}

@TestA(name="private method",id=5,gid=Long.class) //类方法注解

private void c(){

Map m = new HashMap(0);

}

public void b(Integer a){

}

}

下面到了最重要的一步了,就是如何读取我们在类中定义的注解。只要读取出来了使用的话就简单了。

package com.tmser.annotation;

import java.lang.annotation.Annotation;

import java.lang.reflect.Constructor;

import java.lang.reflect.Method;

public class ParseAnnotation {

public static void parseTypeAnnotation() throws ClassNotFoundException {

Class clazz = Class.forName("com.tmser.annotation.UserAnnotation");

Annotation[] annotations = clazz.getAnnotations();

for (Annotation annotation : annotations) {

TestA testA = (TestA)annotation;

System.out.println("id= ""+testA.id()+""; name= ""+testA.name()+""; gid = "+testA.gid());

}

}

public static void parseMethodAnnotation(){

Method[] methods = UserAnnotation.class.getDeclaredMethods();

for (Method method : methods) {

boolean hasAnnotation = method.isAnnotationPresent(TestA.class);

if (hasAnnotation) {

TestA annotation = method.getAnnotation(TestA.class);

System.out.println("method = " + method.getName()

+ " ; id = " + annotation.id() + " ; description = "

+ annotation.name() + "; gid= "+annotation.gid());

}

}

}

public static void parseConstructAnnotation(){

Constructor[] constructors = UserAnnotation.class.getConstructors();

for (Constructor constructor : constructors) {

boolean hasAnnotation = constructor.isAnnotationPresent(TestA.class);

if (hasAnnotation) {

TestA annotation =(TestA) constructor.getAnnotation(TestA.class);

System.out.println("constructor = " + constructor.getName()

+ " ; id = " + annotation.id() + " ; description = "

+ annotation.name() + "; gid= "+annotation.gid());

}

}

}

public static void main(String[] args) throws ClassNotFoundException {

parseTypeAnnotation();

parseMethodAnnotation();

parseConstructAnnotation();

}

}

先别说话,运行:

id= "0"; name= "type"; gid = class java.lang.Long

method = c ; id = 5 ; description = private method; gid= class java.lang.Long

method = a ; id = 3 ; description = public method; gid= class java.lang.Long

method = b ; id = 4 ; description = protected method; gid= class java.lang.Long

constructor = com.tmser.annotation.UserAnnotation ; id = 2 ; description = construct; gid= class java.lang.Long

看到了吧,我们定义的注解都完整的输出了,你要使用哪个,直接拿去用就好了。

为了不让这篇文章打开太慢,我省略了类属性注解,及参数注解的解析。其实都大同小异。

另外,我也没有举使用例子。因为我认为好的教程是讲的详细的同时,还会留有扩展。如果我全部写出来,而你只是学习的话,那基本不会自己去动脑了,而是复制粘贴运行一遍完事。

最后提醒下:

1. 要用好注解,必须熟悉java 的反射机制,从上面的例子可以看出,注解的解析完全依赖于反射。

2. 不要滥用注解。平常我们编程过程很少接触和使用注解,只有做设计,且不想让设计有过多的配置时

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。