java自定义注解实例_Java的自定义注解使用实例

概念

Java有五个元注解,自动继承java.lang.annotation.Annotation。

什么是元注解,可以理解为其他普通注解进行解释说明

@Target 该注解的使用范围,限定应用场景。枚举类 ElemenetType 中

TYPE:类,接口

FIELD:字段,枚举的常量

METHOD:函数(方法)

PARAMETER:参数

CONSTRUCTOR:构造函数

ANNOTATION_TYPE:注解类型

LOCAL_VARIABLE:局部变量

PACKAGE:包

@Retention该注解的生存周期,相当于时间戳。枚举类型 RetentionPolicy 中

SOURCE:在源文件中有效,编译后会被丢弃(如@Override,@Deprecated)

CLASS:在class文件中有效,在jvm丢弃

RUNTIME:在运行时有效,class文件保留,jvm运行时保留(很多框架运用反射调用)

@Documented

javadoc文档生成工具的使用

@Inherited

允许子类继承父类中的注解。

@Repeatable

同一种注解可多次使用

作用

注释,解释,通过代码的标识元数据生成doc文档;

使用反射,通过代码标识的元数据对代码进行分析;

编译检查,通过代码标识的元数据让编译器进行基本检查。

实例

定义一个普通的注解,

public @interfaceTest

{

}

使用我们自定义的注解

@Testpublic classPerson

{

@TestprivateString name;

@Testprivate intage;

@Testpublic voidsay()

{

System.out.println("Hello,Java Annotation");

}

}

@Target(ElementType.PACKAGE) 注解作用的目标>包

这个注解要理解什么是友好声明类和包常量,包中有很多的内部访问的类或常量,就可以统一的放到友好声明类中,这样就方便,而且集中管理,减少friendly类到处游走的情况。

importjava.lang.annotation.ElementType;@Target(ElementType.PACKAGE)public @interfaceTest

{

}

@Testpackagetest;classPerson

{privateString name;private intage;public voidsay()

{

System.out.println("Hello,Java Annotation");

}

}

@Target(ElementType.CONSTRUCTOR) 注解作用的目标>构造函数

packagetest;importjava.lang.annotation.ElementType;importjava.lang.annotation.Target;

@Target(ElementType.CONSTRUCTOR)public @interfaceTest

{

}

packagetest;public classPerson

{privateString name;private intage;

@TestpublicPerson()

{

}public voidsay()

{

System.out.println("Hello,Java Annotation");

}

}

其他范围就不一一列举,都是相同的。

@Retention(RetentionPolicy.RUNTIME)   生存周期

代码运行时动态获取注解的信息

packagetest;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;

@Target(ElementType.CONSTRUCTOR)

@Retention(RetentionPolicy.RUNTIME)public @interfaceTest

{

}

packagetest;public classPerson

{privateString name;private intage;

@TestpublicPerson()

{

}public voidsay()

{

System.out.println("Hello,Java Annotation");

}

}

注解的属性-->成员变量

方法名是成员变量的的名字,变量的类型是他的返回值。

package test;

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 Test

{public int age() default 20;public String name() default "";publicString className();

}

packagetest;importjava.lang.annotation.Annotation;importjava.lang.reflect.Field;importjava.lang.reflect.Method;

@Test(age= 15,name = "zhangsan",className = "高三(3)班")public classPerson

{privateString name;private intage;publicPerson()

{

}private voidsay()

{

System.out.println("Hello,Java Annotation");

}

}

既然给了注解,我们要做的工作必然是要提取注解上面的内容,要拿到这些注解就要用到反射。

packagetest;importjava.lang.annotation.Annotation;importjava.lang.reflect.Field;importjava.lang.reflect.Method;

@Test(age= 15,name = "zhangsan",className = "高三(3)班")public classPerson

{privateString name;private intage;publicPerson()

{

}private voidsay()

{

System.out.println("Hello,Java Annotation");

}public static voidmain(String[] args)

{boolean hasAnnotation = Person.class.isAnnotationPresent(Test.class);if(hasAnnotation)

{

Test test= Person.class.getAnnotation(Test.class);

System.out.println("age:" +test.age());

System.out.println("name:" +test.name());

System.out.println("className:" +test.className());

}

}

}

输出结果

age:15name:zhangsan

className:高三(3)班

对于类的属性和方法,都是同样的道理。

成员注解

packagetest;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)public @interfaceField

{publicString name();

}

函数注解

packagetest;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)public @interfaceMethod

{publicString say();

}

Person类

packagetest;importjava.lang.annotation.Annotation;

@Test(age= 15,name = "zhangsan",className = "高三(3)班")public classPerson

{

@Field(name= "lisi")privateString name;private intage;publicPerson()

{

}

@Method(say= "hello")private voidsay()

{

System.out.println("Hello,Java Annotation");

}public static voidmain(String[] args)

{boolean hasAnnotation = Person.class.isAnnotationPresent(Test.class);if(hasAnnotation)

{

Test test= Person.class.getAnnotation(Test.class);

System.out.println("age:" +test.age());

System.out.println("name:" +test.name());

System.out.println("className:" +test.className());

}try{

java.lang.reflect.Field field= Person.class.getDeclaredField("name");

field.setAccessible(true);

Field check= field.getAnnotation(Field.class);if (check != null)

{

System.out.println("check value:" +check.name());

}

java.lang.reflect.Method method= Person.class.getDeclaredMethod("say");if (method != null)

{

Annotation[] ans=method.getAnnotations();for (int i = 0; i < ans.length; i++)

{

System.out.println("method annotation:" +ans[i].annotationType().getSimpleName());

}

}

}catch(NoSuchFieldException e)

{

e.printStackTrace();

}catch(Exception e){

e.printStackTrace();

}

}

}

输出

age:15name:zhangsan

className:高三(3)班

check value:lisi

method annotation:Method

可以看出我们获取了注解上的值,现在都没有实际意义,我们可以用注解来做些什么?

这些我没办法给出确切答案,只能说根据各人需求去合理利用注解。

实例

注解参数赋值

@Test注解

packagetest;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.FIELD})public @interfaceTest

{

String value();

}

Person类属性赋值

packagetest;importorg.apache.poi.ss.formula.functions.T;importjava.lang.annotation.Annotation;importjava.lang.reflect.Field;importjava.lang.reflect.Method;public classPerson

{

@Test("zhangsan")privateString name;

@Test("15")private intage;publicPerson()

{

}private voidsay()

{

System.out.println("Hello,Java Annotation");

}

@OverridepublicString toString()

{return "name = " + name + "\n" + "age = " +age;

}public static voidmain(String[] args)

{

Person person= newPerson();try{//取得成员变量的值

Field field = Person.class.getDeclaredField("name");//打开权限

field.setAccessible(true);//判断属性是否有注解

if (field.isAnnotationPresent(Test.class))

{//获取属性上的注解值

Test test = field.getAnnotation(Test.class);

String name=test.value();//赋值

field.set(person,name);

}

Field field1= Person.class.getDeclaredField("age");

field1.setAccessible(true);if (field1.isAnnotationPresent(Test.class))

{

Test test= field1.getAnnotation(Test.class);int age =Integer.valueOf(test.value());

field1.set(person,age);

}

System.out.println(person);

}catch(Exception e)

{

e.printStackTrace();

}

}

}

输出

name =zhangsan

age= 15

用注解去检查函数等等。。

lz不善于用语言表达,所以可能有很多人没看懂,可以看下

一个大佬讲解的注解说明(简单易懂)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值