注解和反射
1、JDK中提供的三个基本的注解
@Deprecated:标注XX过时的。
@SuppressWarnings:抑制警告
unused:抑制的警告类型
{ "unused", "rawtypes", "unchecked" }:数组,抑制的多个警告类型
all:抑制所有警告
@Override:保证用户确实是覆盖了父类的某个方法。
2、自定义注解
使用@interface关键字来声明注解:public @interface MyAnn1{}
声明注解的属性字段:类型 字段名() [defalut 默认值];
注解属性的类型只能下面的几种:
String Class 八个基本类型 注解类型 枚举类型 及以上类型的1维数组。
特殊属性:String value;或String[] value();
使用时,直接给定取值,而不用加属性名称
//定义注解
public @interface MyAnn1 {
String name() default "";
int age() default -1;
String city();
MyAnn2[] ann(); //注解中使用注解类型
}
public @interface MyAnn2 {
String name() default "";
String[] value() default ""; //使用是直接使用即可,不需要写属性名
}
public class UserMyAnn1 {
// @MyAnn1(name="wf",age=98,city="山沟沟")//没有指定属性
// public void m1(){
//
// }
@MyAnn2("abc")
// 如果省略属性名,就是给value赋值
public void m2() {
}
@MyAnn2(value = "abc", name = "def")
public void m3() {
}
//数组形式
@MyAnn2(name = "def", value = { "a", "b", "c" })
public void m4() {
}
//注解中使用注解类型
@MyAnn1(name = "abc", city = "BJ", ann = {
@MyAnn2(name = "a", value = "b"), @MyAnn2(name = "c", value = "d") })
public void m5() {
}
}
3、元注解
服务于注解的注解就是元注解
*@Retention:指定注解的存活范围。默认是CLASS
RetentionPolicy:SOURCE|CLASS|RUNTIME
*@Target:指定注解可以用在什么元素上
ElementType:TYPE|METHOD|。。。
@Documented: 用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档.
@Inherited: 被它修饰的 Annotation 将具有继承性.如果某个类使用了被
@Inherited 修饰的 Annotation, 则其子类将自动具有该注解
//注解和反射一起使用:
public class MyJunitTest {
@MyTest(time=100000000)
public void testAdd(){
System.out.println("执行了add方法的测试");
}
@MyTest
public void testUpdate(){
System.out.println("执行了update方法的测试");
}
}
//反射实现单元测试:
//反射注解:所有注解类型都是Annotation类型的子类
/*
java.lang.reflect.AnnotatedElement:
<T extends Annotation> getAnnotation(Class<T> annotationType):
获取指定类型的注解
Annotation[] getAnnotations():获取所有的注解
Annotation[] getDeclareAnnotations():返回直接存在于此元素上的所有注释,包含继承
boolean isAnnotationPresend(Class<? extends Annotation>):有木有指定的注解
Class, Constructor, Field, Method, Package都实现了该接口
*/
public class MyTestRunner {
//执行测试:
/*
* 获取要测试的java类:MyJunitTest
* 取到其中的所有方法:Method
* 看看谁的方法前面有@MyTest的注解,谁有就执行谁
*/
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {
test2();
}
//反射带有属性的注解
private static void test2() throws IllegalAccessException,
InvocationTargetException, InstantiationException {
Class clazz = MyJunitTest.class; //获取要测试的类
Method ms[] = clazz.getMethods();
for(Method m:ms){
MyTest myTest = m.getAnnotation(MyTest.class); //从方法上获取指定类型的注解 @MyTest
if(myTest!=null){
//得到注解的属性
long timeLimit = myTest.time(); //获取指定类型的注解的属性上面的值 @MyTest(time=100000000)
if(timeLimit>-1){
//有性能测试需求
long startTime = System.nanoTime();
m.invoke(clazz.newInstance(), null); //执行每个方法
long useTime = System.nanoTime()-startTime;
if(useTime>timeLimit){
System.out.println(m.getName()+"执行效率没有测试通过");
}
}else{
//没有性能测试需求
m.invoke(clazz.newInstance(), null);
}
}
}
}
//注解的基本反射
private static void test1() throws IllegalAccessException,
InvocationTargetException, InstantiationException {
Class clazz = MyJunitTest.class;
Method ms[] = clazz.getMethods();
for(Method m:ms){
boolean b = m.isAnnotationPresent(MyTest.class); //判断有木有指定的注解
// System.out.println(m.getName()+"方法上有木有MyTest注解:"+b);
if(b){
m.invoke(clazz.newInstance(), null);//
}
}
}
}
版权声明:本文为qq_20261343原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。