首先了解一下什么是注解:
所谓的注解就是当我们编写代码时,常常见到的@Override、@Deprecated、@SuppressWarnings等,可以查看帮助文档中:java.lang.annotation接口,所有的注解都必须实现该接口。
接下来了解一下注解的作用:
1、 当我们在编写代码时用到一些不建议使用的方法时,就会出现一些黄色的警告,那么这些警告是怎么产生的呢,这就是注解的作用。下面我们通过一个实际的例子来分析一下其情况和过程。
还是先进行了解一下@Deprecated这个注解:
@Documented
@Retention(value=RUNTIME)
public @interface Deprecated用 @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。
知道了这个注解的作用,那么我们就看一下java.util.Date这个包下的一些方法:
@Deprecated
public int getSeconds() {
return normalize().getSeconds();
}
当注解用在这个方法上时,编译器就知道这个方法是个不建议被使用的方法,当然如果我们用了,那么如果出现意外后果,也只有我们自己承担了。那么我们在编写代码时,如果用到该方法,编译器就会提醒我们不建议我们使用。
2、 了解一下@Override这个注解
表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。
当我们继承父类的某一个方法时,可以在方法的上面添加这个注解,如果不加,也不会有什么影响,但是如果我们加了,但是我们写的方法父类中不存在该方法,则当我们编译的时候,就会报错。
…………
还有其他的注解作用自己看java帮助文档
接下来,就学习一下如果写自己的注解
注解有两个常用的特征:
1、 注解的生命长度:即这个注解用到什么时候会被编译器抛弃,总共有三个选项,一个注解只能为下列的一种情况。
a) SOURCE:编译器要丢弃的注释。
b) CLASS:编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。
c) RUNTIME:编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。
2、 注解的使用范围:即注解是在方法上还是类上、抑或是变量上,这类注解的取值可以为多个:
a) ANNOTATION_TYPE:注解类型声明
b) CONSTRUCTOR:构造方法声明
c) FIELD:字段声明(包括枚举常量)
d) LOCAL_VARIABLE:局部变量声明
e) METHOD:方法声明
f) PACKAGE:包声明
g) PARAMETER:参数声明
h) TYPE:类、接口(包括注释类型)或者枚举声明
那么根据这些情况我们就可以写一些自己的注解:这个示例是圣思园编程竞赛中的一道题
packagedong.application.shengsiyuan;
importjava.lang.annotation.ElementType;
importjava.lang.annotation.Retention;
importjava.lang.annotation.RetentionPolicy;
importjava.lang.annotation.Target;
//这个注解是用于标示要进行测试的方法
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public@interface Test
{
}
下面我们使用一下这个注解:
packagedong.application.shengsiyuan;
publicclass MyClass
{
public void method1()
{
System.out.println("method1");
}
@Test
public void method2()
{
System.out.println("method2");
}
@Test
public int add(int a, int b)
{
return a + b;
}
@Test
public void doSomething(String str)
{
System.out.println(str);
}
@Test
public void doSomething2()
{
System.out.println("doSomething2");
}
@Test
protected void doSomething3()
{
System.out.println("doSomething3");
}
@Test
private void doSomething4()
{
System.out.println("doSomething4");
}
@Test
void doSomething5()
{
System.out.println("doSomething5");
}
}
下面我们通过反射来获取注解信息,然后根据注解内容进行相应的操作:
packagedong.application.shengsiyuan;
importjava.lang.reflect.Method;
/**
* 一个小型框架,用于执行用户的@Test注解的方法
*
* @author HS
*
*/
publicclass ApplicationRun
{
/**
* 执行用户@Test注解的方法
*@param className
* 要执行的类
*@throws Exception
*/
public void run(String className) throwsException
{
// 获取类的Class对象
Class<?> clazz =Class.forName(className);
// 获取类中的所有public方法
Method[] methods =clazz.getMethods();
for (Method method : methods)
{
// 获取每一个方法的@Test注解
Test test =method.getAnnotation(Test.class);
// 如果获取的注解不为空则,进行返回值类型判断
if (test != null)
{
// 如果返回值类型为void,则进行参数个数判断
if(method.getReturnType() == void.class)
{
// 如果参数个数为0,则执行该方法
if(method.getParameterTypes().length == 0)
{
method.invoke(clazz.newInstance(),new Object[]{});
}
}
}
}
}
}
测试类:
packagedong.application.shengsiyuan;
publicclass TestMyClass
{
public static void main(String[] args)
{
ApplicationRun app = newApplicationRun();
try
{
app.run("dong.application.shengsiyuan.MyClass");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
======================================================================
这个就是传说中的测试框架的简易模型,注解在以后的框架学习中作用很大,当然如果我们仅仅是框架的使用者、一个机器人,那么没有必要学习框架,只需要按照框架的条条框框去编代码即可。
下面通过反射去获取注解的内容信息:
注解的定义:
packagedong.application.annotation;
importjava.lang.annotation.Retention;
importjava.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public@interface FirstAnnotation
{
//为注解的参数设置默认值的方法就是在后面加上一个default
//当然也可以为数组,其类型也可以根据情况设定
String value() default "lovexiaojing";//李晓静是我的女朋友哦。。。嘻嘻
}
注解的使用:
packagedong.application.annotation;
@FirstAnnotation("xiaojing")
publicclass BaseAnnotationTest
{
@FirstAnnotation("xiaojing")
public String toString()
{
return "LOVE XIAOJING";
}
@FirstAnnotation
public String action()
{
return "FOREVER";
}
}
通过反射去获取注解信息:
packagedong.application.annotation;
importjava.lang.annotation.Annotation;
publicclass TestMyAnnotation
{
@SuppressWarnings("unchecked")
public static void main(String[] args)
{
BaseAnnotationTest bat = newBaseAnnotationTest();
Class<?> clazz =bat.getClass();
FirstAnnotation f =clazz.getAnnotation(FirstAnnotation.class);
System.out.println(f.annotationType().isAnnotation());
System.out.println(f.value());
// Annotation[] annotation =clazz.getAnnotations();
// for(Annotation a : annotation)
// {
// System.out.println(a.annotationType());
// Class<FirstAnnotation>ano = (Class<FirstAnnotation>) a.annotationType();
// System.out.println(ano.getName());
// }
}
}
联系客服