Java注解语法
1. 前置基础
学习java反射语法 JAVA通过反射使用公共构造方法和私有构造方法来创建对象
2. Java注解是什么?
Java注解是代码中的特殊标记,比如@Override
、@Test
等,作用是:让其他程序根据注解 信息决定怎么执行该程序。
比如:Junit
框架的@Test
注解可以用在方法上,用来标记这个方法是测试方法,被@Test
标记的方法能够被Junit框架执行。
再比如:@Override
注解可以用在方法上,用来标记这个方法是重写方法,被@Override
注解标记的方法能够被IDEA识别进行语法检查。
注解不光可以用在方法上,还可以用在类上、变量上、构造器上等位置。
3. 自定义注解
3.1 自定义注解格式
public @interface 注解名称 {public 属性类型 属性名() default 默认值;
}
3.2 自定义注解Test:
属性名称Test
, 包含属性String a
和int b
public @interface Test{String a();int b() default 3;
}
3.3 使用注解Test
@Test(a="ggg",b=5) //@Test即为对自定义注解的使用语法形式
public class demo{}
注意:注解的属性名如果是value
的话,并且只有value
没有默认值,使用注解时value
名称可以省略。
public @interface Test{String value();int b() default 3;int c() defaule 5;
}@Test("ggg") //@Test即为对自定义注解的使用语法形式
public class demo{}
4. 注解的本质
把注解的字节码进行反编译,使用XJad工具进行反编译。经过Test注解字节码反编译会发现:
1.Test注解本质上是接口,每一个注解接口都继承子Annotation接口
2.Test注解中的属性本质上是抽象方法
3.@Test实际上是作为MyTest接口的实现类对象
4.@Test(a="ggg",b=5) 里面的属性值,可以通过调用a()、b()方法获取到。
5. 元注解
元注解是修饰注解的注解,分别有注解@Retention
和@Target
.
@Target是用来声明注解只能用在那些位置,比如:类上、方法上、成员变量上等
@Retetion是用来声明注解保留周期,比如:源代码时期、字节码时期、运行时期
@Target注解可以标识多个位置
语法: @Target({ElementType.TYPE,ElementType.METHOD})
6. 解析注解
通过反射技术把类上、方法上、变量上的注解对象获取出来,然后通过调用方法就可以获取注解上的属性值了,该过程称为解析注解。
流程如下:
1.如果注解在类上,先获取类的字节码对象,再获取类上的注解
2.如果注解在方法上,先获取方法对象,再获取方法上的注解
3.如果注解在成员变量上,先获取成员变量对象,再获取变量上的注解
总之:注解在谁身上,就先获取谁,再用谁获取谁身上的注解
Class、Method、Filed、Constructor都实现了AnnotatedElement接口,都具有解析注解的能力。
示例:
1. 定义注解
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE, ElementType.METHOD})public @interface Test {String a();int b() default 3;boolean c();}
2. 定义Demo类并使用该注解。
@Test(a="first", b=5, c=false)
public class Demo {@Test(a="first", b=5, c=false)public void demoTest(){}
}
3. 编写测试类获取注解中的值。
import java.lang.reflect.Method;public class AnnotatedTest {public static void main(String[] args) throws Exception {// 获取类上注解属性// 1.获取Demo的class对象Class demoClass = Demo.class;// 2.获取类上的注解if(demoClass.isAnnotationPresent(Test.class)){Test test= (Test) demoClass.getDeclaredAnnotation(Test.class);System.out.println(test.a());System.out.println(test.b());System.out.println(test.c());System.out.println("-------------------");}// 获取方法上注解属性Method demoTest = demoClass.getDeclaredMethod("demoTest");// 2.获取类上的注解if(demoTest.isAnnotationPresent(Test.class)){Test test= (Test) demoTest.getDeclaredAnnotation(Test.class);System.out.println(test.a());System.out.println(test.b());System.out.println(test.c());System.out.println("-------------------");}}
}