举例讲解JDK注解的使用和自定义注解的方法
JDK中的三个基本注解
a、@Override:检查子类确实是覆盖了父类的方法。
b、@Deprecated:说明已经过时了。
c、@SuppressWarnings({"unused","deprecation"}):抑制程序中的警告。unused警告的类型。{}数组。all抑制所有警告。
简单使用:
publicclassDemo1{
//@SuppressWarnings({"deprecation","unused"})
@SuppressWarnings("all")
publicvoidfun()
{
inti=5;
System.out.println("hello");
System.out.println(newDate().toLocaleString());
}
}
classTestsextendsDemo1
{
@Override
publicvoidfun()
{
super.fun();
}
@Deprecated
publicvoidtt()
{
System.out.println(newDate().toLocaleString());
}
}
声明一个注解@interface注解名{}
public@interfaceMyAnnotation{}
注解它的本质就是一个接口,这个接口需要继承Annotation接口。
publicinterfaceMyAnnotationextendsjava.lang.annotation.Annotation{
}
注解的属性类型:
- 1.基本类型
- 2.String
- 3.枚举类型
- 4.注解类型
- 5.Class类型
- 6.以上类型的一维数组类型
具体是怎样定义的呢,我们看代码:
public@interfaceMyAnno1{
//注解中定义的都是属性
intage()default20;
String[]name()default"hehe";
Stringvalue()default"haha";
Lovelove();
//MyAnno2anno();
//publicstaticfinalintnum=5;//可以
//publicabstractvoidfun();//error
}
使用自定义注解:
publicclassDemo2{
//@MyAnno1(age=25,name={"jack","lucy"},value="zhengzhi")
//@MyAnno1(value="zhengzhi")
@MyAnno1(value="zhengzhi",love=Love.eat)
publicvoidtests()
{
}
}
如果在没有默认值的情况下,使用自定义注解我们需要设置注解中属性的值。
注解的反射:(灵魂)
模拟Junit的@Test a、反射注解类 java.lang.reflect.AnnotatedElement: TgetAnnotation(Class annotationType):得到指定类型的注解引用。没有返回null。 Annotation[]getAnnotations():得到所有的注解,包含从父类继承下来的。 Annotation[]getDeclaredAnnotations():得到自己身上的注解。 booleanisAnnotationPresent(ClassannotationType):判断指定的注解有没有。 Class、Method、Field、Constructor等实现了AnnotatedElement接口. 如果:Class.isAnnotationPresent(MyTest.class):判断类上面有没有@MyTest注解; Method.isAnnotationPresent(MyTest.class):判断方法上面有没有@MyTest注解。
下面通过代码实现一下。
我们模拟实现@Test注解的功能
首先这是我们的注解@MyTest
importjava.lang.annotation.Retention;
importjava.lang.annotation.RetentionPolicy;
//元注解:用来注解注解的
@Retention(RetentionPolicy.RUNTIME)
public@interfaceMyTest{
longtimeout()defaultInteger.MAX_VALUE;//设置超时时间的
}
这是我们使用注解的类:
publicclassDBCRUD{
@MyTest(timeout=1000000)
publicvoidaddTest()
{
System.out.println("addTest方法执行了");
}
@MyTest
publicvoidupdateTest()
{
System.out.println("updateTest方法执行了");
}
}
当我们使用了注解,我们就需要判该类是否使用了注解,我们通过反射来实现。
privatestaticvoidmethod1()throwsIllegalAccessException,
InvocationTargetException,InstantiationException{
Classclaz=DBCRUD.class;//得到字节码文件对象
//得到该类及父类中的所有方法
Method[]methods=claz.getMethods();
for(Methodm:methods){
//判断方法是否使用了@MyTest这个注解
//booleanboo=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();
//反射解析注解的属性
Classclaz=DBCRUD.class;
Method[]methods=claz.getMethods();
for(Methodm:methods){
//从该方法上获取MyTest注解
MyTestmt=m.getAnnotation(MyTest.class);
if(mt!=null){
//得到注解中的属性
longout=mt.timeout();
longstart=System.nanoTime();
m.invoke(claz.newInstance(),null);
longend=System.nanoTime();
if((end-start)>out)
{
System.out.println("运行超时");
}
}
}
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。如果你想了解更多相关内容请查看下面相关链接