前言
在你立足处深挖下去,就会有泉水涌出!别管蒙昧者们叫嚷:“下边永远是地狱!”
博客主页:KC老衲爱尼姑的博客主页
博主的github,平常所写代码皆在于此
共勉:talk is cheap, show me the code
作者是爪哇岛的新手,水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!
注解
概述
Java注解是Java5引入的一种注释解释,又称之为标注。Java中的类,构造器,方法,成员变量,参数等都可以被注解进行标注。我们可以将注解理解为标签,标签可以上的内容可以自由的定义,它是对人和事物属性的评价。这就如商品上的价格标签,图书馆中的书本编码标签,B站上游戏分区标签等。
注解的作用
对Java中类,方法,成员变量做标记,然后进行特殊处理,至于到底进行何种处理由具体业务决定。比如说:JUnit框架中,标注了注解为@Test的方法就可以被当成测试方法执行,而没有标记的就不能打算当初当成测试方法执行。
特殊属性
- value属性,如果只有一个value属性的情况下,使用value属性的时候可以省略value名称不写。
- 但是如果有多个属性,并且属性没有默认值,那么value名称不能省略。
自定义注解格式
public @interface 注解名称 {
public 属性类型 属性名() default 默认值;
}
代码示例
public @interface MyDemo {
String value();
String name();
boolean flag() default true;
String [] str();
}
元注解
元注解就是注解的注解,注解的标签。
常用的元注解
- @Target: 约束自定义注解只能在哪些地方使用
- @Retention:申明注解的生命周期
@Target中可使用的值定义在枚举类ElementType中,常用值如下:
- TYPE,类
- 接口 FIELD,
- 成员变量METHOD,
- 成员方法PARAMETER,
- 方法参数CONSTRUCTOR,
- 构造器LOCAL_VARIABLE
- 局部变量
@Retention中可使用的值定义在枚举类ElementType中,常用值如下:
- SOURCE: 注解只作用在源码阶段,生成的字节码文件中不存在
- CLASS: 注解作用在源码阶段,字节码文件阶段,运行阶段不存在,默认值.
- RUNTIME:注解作用在源码阶段,字节码文件阶段,运行阶段(开发常用)
注解的解析
示例代码
@Target({ElementType.TYPE,ElementType.METHOD})// 当前被修饰的注解只能用在类上,方法上。
@Retention(RetentionPolicy.RUNTIME)// 控制下面的注解一直保留到运行时
public @interface MyTest {
}
MyTest的使用
@MyTest
public class AnnotationTest {
// @MyTest
// private String name;
@MyTest
@MyDemo(value = "Annotation",name="张三",str={"java","C++"})
public static void test() {
System.out.println("Hello World");
}
public static void main(String[] args) {
test();
}
}
如果把@MyTest修饰在成员变量上就会报错—>java: 注释类型不适用于该类型的声明
注解的解析
注解的操作中经常需要解析,注解的解析就是判断是否存下注解,存在注解就解析出内容。
与注解解析相关的接口
- Annotation: 注解的顶级接口,注解都是Annotation类型的对象
- AnnotatedElement:该接口定义了与注解解析相关的解析方法
相关API如下
方法 | 说明 |
---|---|
Annotation[] getDeclaredAnnotations() | 获得当前对象上使用的所有注解,返回注解数组。 |
T getDeclaredAnnotation(Class annotationClass) | 根据注解类型获得对应注解对象 |
boolean isAnnotationPresent(Class annotationClass) | 判断当前对象是否使用了指定的注解,如果使用了则返回true,否则false |
所有的类成分Class, Method , Field , Constructor,都实现了AnnotatedElement接口他们都拥有解析注解的能力。
注解解析案例
首先定义一个MyTest2注解
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest2 {
String value();
String name();
boolean flag() default true;
String [] str();
}
在Demo类和方法上使用
@MyTest2(value = "大小姐",name ="林黛玉",str={"java","C++"})
public class Demo {
@MyTest2(value = "小小姐",name ="薛宝钗",str={"java","Python"})
public void test() {
}
}
解析类上的注解
public class AnnotationTest2 {
public static void main(String[] args) {
//1.得到class对象
Class<Demo> demoClass = Demo.class;
//2.判断类上是否包含注解
if (demoClass.isAnnotationPresent(MyTest2.class)) {
MyTest2 myTest2 = demoClass.getDeclaredAnnotation(MyTest2.class);
System.out.println(myTest2.value());
System.out.println(myTest2.name());
System.out.println(myTest2.flag());
System.out.println(Arrays.toString(myTest2.str()));
}
}
}
运行结果:
解析方法上的注解
public class AnnotationTest3 {
public static void main(String[] args) throws NoSuchMethodException {
//1.得到class对象
Class<Demo> demoClass = Demo.class;
Method test = demoClass.getDeclaredMethod("test");
//2.判断方法对象上是否包含注解
if (test.isAnnotationPresent(MyTest2.class)) {
MyTest2 myTest2 = test.getDeclaredAnnotation(MyTest2.class);
System.out.println(myTest2.value());
System.out.println(myTest2.name());
System.out.println(myTest2.flag());
System.out.println(Arrays.toString(myTest2.str()));
}
}
}
运行结果:
模拟Junit中的@Test
我们定义若干个方法,只要加了MyTest注解,就可以在启动时被触发执行
分析
- 定义一个自定义注解MyTest,只能注解方法,存活范围是一直都在。
- 定义若干个方法。只要有@MyTest注解的方法就能在启动时被触发执行,没有这个注解的方法不能执行。
示例代码
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestDemo {
@MyTest
public void test1() {
System.out.println("test1");
}
@MyTest
public void test2() {
System.out.println("test2");
}
@MyTest
public void test3() {
System.out.println("test3");
}
@MyTest
public void test4() {
System.out.println("test4");
}
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
TestDemo t = new TestDemo();
//启动程序
//1.得到TestDemo对象
Class<TestDemo> testDemoClass = TestDemo.class;
//提取类中的方法
Method[] declaredMethods = testDemoClass.getDeclaredMethods();
//触发方法
for (Method method : declaredMethods) {
if (method.isAnnotationPresent(MyTest.class)) {
method.invoke(t);
}
}
}
}
运行结果:
各位看官如果觉得文章写得不错,点赞评论关注走一波!谢谢啦!。文章来源:https://www.toymoban.com/news/detail-650459.html
文章来源地址https://www.toymoban.com/news/detail-650459.html
到了这里,关于《Java-SE-第三十八章》之注解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!