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

作者:Melissa_hexiu 时间:2022-06-29 17:34:52 

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的@Test
a、反射注解类
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("运行超时");
       }
     }
   }

来源:https://blog.csdn.net/melissa_heixiu/article/details/52768816

标签:jdk,注解,自定义注解
0
投稿

猜你喜欢

  • Springboot整合支付宝支付功能

    2023-07-02 17:38:09
  • Java SpringBoot集成ChatGPT实现AI聊天

    2021-08-21 21:55:23
  • Java SpringSecurity+JWT实现登录认证

    2022-12-13 16:44:18
  • Java语言一元运算符实例解析

    2023-01-14 15:31:22
  • Java 使用IO流实现大文件的分割与合并实例详解

    2023-08-23 09:33:33
  • C#中动态显示当前系统时间的实例方法

    2023-06-20 14:46:02
  • Java毕业设计实战之平行志愿管理系统的实现

    2023-09-12 14:34:23
  • 聊一聊jdk1.8中的ArrayList 底层数组是如何扩容的

    2023-11-16 08:55:50
  • C#使用foreach语句遍历堆栈(Stack)的方法

    2021-11-03 08:03:38
  • 浅谈Java对象禁止使用基本类型

    2022-11-07 19:59:04
  • Maven打包jar包没有主属性问题解决方案

    2023-11-25 06:56:32
  • flutter 路由跳转的实现示例

    2023-08-23 14:55:26
  • Java Collections.shuffle()方法案例详解

    2023-11-24 15:53:16
  • IDEA入门级使用教程你居然还在用eclipse?

    2022-03-27 07:35:19
  • SpringMVC请求参数的使用总结

    2022-11-30 22:23:18
  • Java Spring详解如何配置数据源注解开发以及整合Junit

    2021-10-31 11:03:25
  • 详解C#面相对象编程中的继承特性

    2022-06-09 09:15:24
  • Spring MVC请求参数接收的全面总结教程

    2023-11-28 19:44:47
  • Maven学习----Maven安装与环境变量配置教程

    2021-12-04 08:20:25
  • java 装饰模式(Decorator Pattern)详解及实例代码

    2023-09-07 03:13:08
  • asp之家 软件编程 m.aspxhome.com