首页 > 开发 > Java > 正文

举例讲解JDK注解的使用和自定义注解的方法

2024-07-14 08:43:45
字体:
来源:转载
供稿:网友

JDK中的三个基本注解

a、@Override:检查子类确实是覆盖了父类的方法。
b、@Deprecated:说明已经过时了。
c、@SuppressWarnings({ "unused", "deprecation" }):抑制程序中的警告。unused警告的类型。{}数组。all抑制所有警告。

简单使用:

public class Demo1 {  //@SuppressWarnings({ "deprecation", "unused" })  @SuppressWarnings("all")  public void fun()  {    int i = 5;    System.out.println("hello");    System.out.println(new Date().toLocaleString());  }}class Tests extends Demo1{  @Override  public void fun()  {    super.fun();  }   @Deprecated  public void tt()  {    System.out.println(new Date().toLocaleString());  }}

声明一个注解 @interface 注解名{}

public @interface MyAnnotation{}

注解它的本质就是一个接口,这个接口需要继承 Annotation接口。

public interface MyAnnotation extends java.lang.annotation.Annotation {}

注解的属性类型:

  •     1.基本类型
  •     2.String
  •     3.枚举类型
  •     4.注解类型
  •     5.Class类型
  •     6.以上类型的一维数组类型

具体是怎样定义的呢,我们看代码:

public @interface MyAnno1 {  //注解中定义的都是属性  int age() default 20;  String[] name() default "hehe";  String value() default "haha";  Love love();  //MyAnno2 anno();  //public static final int num = 5;//可以  //public abstract void fun();//error}

使用自定义注解:

public class Demo2 {  //@MyAnno1(age=25,name={"jack","lucy"},value="zhengzhi")  //@MyAnno1(value="zhengzhi")  @MyAnno1(value="zhengzhi",love=Love.eat)  public void tests()  {  }}

如果在没有默认值的情况下,使用自定义注解我们需要设置注解中属性的值。

注解的反射:(灵魂)

模拟Junit的@Testa、反射注解类java.lang.reflect.AnnotatedElement:<T extends Annotation> T getAnnotation(Class<T> annotationType):得到指定类型的注解引用。没有返回null。Annotation[] getAnnotations():得到所有的注解,包含从父类继承下来的。Annotation[] getDeclaredAnnotations():得到自己身上的注解。boolean isAnnotationPresent(Class<? extends Annotation> annotationType):判断指定的注解有没有。Class、Method、Field、Constructor等实现了AnnotatedElement接口.如果:Class.isAnnotationPresent(MyTest.class):判断类上面有没有@MyTest注解;Method.isAnnotationPresent(MyTest.class):判断方法上面有没有@MyTest注解。

下面通过代码实现一下。

我们模拟实现@Test注解的功能

首先这是我们的注解@MyTest

import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;//元注解: 用来注解注解的@Retention(RetentionPolicy.RUNTIME)public @interface MyTest {  long timeout() default Integer.MAX_VALUE;//设置超时时间的}

这是我们使用注解的类:

public class DBCRUD {  @MyTest(timeout=1000000)  public void addTest()  {    System.out.println("addTest方法执行了");  }  @MyTest  public void updateTest()  {    System.out.println("updateTest方法执行了");  }}

当我们使用了注解,我们就需要判该类是否使用了注解,我们通过反射来实现。

private static void method1() throws IllegalAccessException,    InvocationTargetException, InstantiationException {    Class claz = DBCRUD.class;//得到字节码文件对象    //得到该类及父类中的所有方法    Method[] methods = claz.getMethods();    for(Method m:methods){      //判断方法是否使用了@MyTest这个注解//     boolean boo = m.isAnnotationPresent(MyTest.class);//     System.out.println(m.getName()+"===="+boo);//都是false 默认注解存活到 CLASS,改变存活到RUNTIME      if(m.isAnnotationPresent(MyTest.class)){        m.invoke(claz.newInstance(), null);      }    }  }

这里我们需要注意的是,我们需要考虑到自定义注解的存活范围。

默认的自定义注解只存活到编译时期,class阶段。

可以注意到,我们上面的自定义注解应用了@Retention注解,这个注解就是改变自定义注解的存活范围。

这个注解也叫做元注解,只能用在注解上的注解叫做元注解。

上面的method方法没有考虑到超时的问题,下面我们再完善一下。

//method1();    //反射解析注解的属性    Class claz = DBCRUD.class;    Method[] methods = claz.getMethods();    for(Method m:methods){      //从该方法上获取MyTest注解      MyTest mt = m.getAnnotation(MyTest.class);      if(mt!=null){        //得到注解中的属性        long out = mt.timeout();        long start = System.nanoTime();        m.invoke(claz.newInstance(), null);        long end = System.nanoTime();        if((end-start)>out)        {          System.out.println("运行超时");        }      }    }

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对VeVb武林网的支持。


注:相关教程知识阅读请移步到JAVA教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表