举例讲解JDK注解的使用和自定义注解的方法
程序员文章站
2023-12-22 10:56:40
jdk中的三个基本注解
a、@override:检查子类确实是覆盖了父类的方法。
b、@deprecated:说明已经过时了。
c、@suppresswarnin...
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("运行超时"); } } }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接