注解是一系列元数据,它提供数据用来解释程序代码,但是注解并非是所解释的代码本身的一部分。注解对于代码的运行效果没有直接影响。
注解有许多用处,主要如下:
- 提供信息给编译器: 编译器可以利用注解来探测错误和警告信息
- 编译阶段时的处理: 软件工具可以用来利用注解信息来生成代码、Html文档或者做其它相应处理。
- 运行时的处理: 某些注解可以在程序运行的时候接受代码的提取
// 所以在程序运行时可以获取到它们
//必须加上元注解 才可以使用注解
//@Inherited//继承父类的注解 注解 Test 被 @Inherited 修饰,之后类 A 被 Test 注解,类 B 继承 A,类 B 也拥有 Test 这个注解。
//@Documented//它的作用是能够将注解中的元素包含到 Javadoc 中去。
//@Deprecated//废弃
//@SuppressWarnings()//java 预置 忽略警告
//@Target(ElementType.METHOD)//限制注解的运用场景 ,可以不限制
//@Repeatable//java1.8新特性
@Retention(RetentionPolicy.RUNTIME)
//- RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
// RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
// RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,
public @interface Test {
}
一,自定义一个注解类
/**
* @author: zjl on 2017-7-3.
* Class:
*/
//@Target(ElementType.METHOD)//可以不限制注解使用范围
@Retention(RetentionPolicy.RUNTIME)//必须加上元注解
public @interface TestAnimotion {
//注解的属性也叫做成员变量。注解只有成员变量,没有方法。
// 注解的成员变量在注解的定义中以“无形参的方法”形式来声明,
// 其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型。
String msg();
int id();
}
二,使用注解
/**
* @author: zjl on 2017-7-3.
* Class:可以作用于类,方法,成员变量,构造方法等等
*/
@TestAnimotion(msg = "类注解", id = 8)//可以在类上加注解
public class Dog {
@TestAnimotion(msg = "gg", id = 9)
private String name;//成员变量上加注解
@TestAnimotion(msg = "xiaohuang", id = 9)//方法上使用
private void getname(String str) {
System.out.print(str);
}
@TestAnimotion(msg = "nan", id = 9)
private void getsax() {
System.out.print("hh");
}
@TestAnimotion(msg = "xian", id = 9)
private void getadderss() {
System.out.print("hh");
}
三,测试注解
当开发者使用了Annotation 修饰了类、方法、Field 等成员之后,这些 Annotation 不会自己生效,必须由开发者提供相应的代码来提取并处理 Annotation 信息。这些处理提取和处理 Annotation 的代码统称为 APT(Annotation Processing Tool)。
/**
* @author: zjl on 2017-7-3.
* Class:
*/
public class TestTool3 {
public static void main(String[] arg) throws InvocationTargetException, IllegalAccessException {
Dog dog = new Dog();//类可以直接构造对象
Class<? extends Dog> aClass = dog.getClass();
Dog dog1 = null;
try {
dog1 = aClass.newInstance();//不能直接构造用反射 默认无参构造,可以指定有参的构造
} catch (InstantiationException e) {
e.printStackTrace();
}
//类是否被注解
boolean annotationPresent = aClass.isAnnotationPresent(TestAnimotion.class);
TestAnimotion annotation1 = aClass.getAnnotation(TestAnimotion.class);
String msg = annotation1.msg();//得到注解的属性
int id1 = annotation1.id();
try {
//获取方法
Method method = aClass.getDeclaredMethod("getname", String.class);
method.setAccessible(true);
//获取方法的注解
TestAnimotion annotation = method.getAnnotation(TestAnimotion.class);
String value = annotation.msg();//获取属性值
int id = annotation.id();
method.invoke(dog1, value);//获取的属性值传递过来,反射执行方法
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
参考scdn博客链接http://blog.youkuaiyun.com/briblue/article/details/73824058