官方描述
注解是一种能被添加到java代码中的元数据,类、方法、变量、参数和包都可以用注解来修饰。注解对于它所修饰的代码并没有直接的影响。
注解的作用
注解其实就是一种标记,可以在程序代码中的关键节点(类、方法、变量、参数、包)上打上这些标记,然后程序在编译时或运行时可以检测到这些标记从而执行一些特殊操作。
注解运行流程图
新建注解
选中包鼠标右键—》点击Annotation
基本语法
元注解:专门修饰注解的注解。它们都是为了更好的设计自定义注解的细节而专门设计的。我们为大家一个个来做介绍。
@Target
自定义注解的使用范围
ElementType.METHOD:方法声明
ElementType.TYPE:类、接口(包括注解类型)或enum声明
ElementType.CONSTRUCTOR:构造器的声明
ElementType.FIELD:域声明(包括enum实例)
ElementType.LOCAL_VARIABLE:局部变量声明
ElementType.PACKAGE:包声明
ElementType.PARAMETER:参数声明
@Retention
注解级别信息
RetentionPolicy.RUNTIME:VM运行期间保留注解,可以通过反射机制读取注解信息
RetentionPolicy.SOURCE:注解将被编译器丢弃
RetentionPolicy.CLASS:注解在class文件中可用,但会被VM丢弃
@Documented
@Documented注解,是被用来指定自定义注解是否能随着被定义的java文件生成到JavaDoc文档当中。
@Inherited
@Inherited注解,是指定某个自定义注解如果写在了父类的声明部分,那么子类的声明部分也能自动拥有该注解。@Inherited注解只对那些@Target被定义为ElementType.TYPE的自定义注解起作用。
注意项
定义注解类型元素时需要注意如下几点:
- 访问修饰符必须为public,不写默认为public;
- 该元素的类型只能是基本数据类型、String、Class、枚举类型、注解类型(体现了注解的嵌套效果)以及上述类型的一位数组;
- 该元素的名称一般定义为名词,如果注解中只有一个元素,请把名字起为value(后面使用会带来便利操作);
- ()不是定义方法参数的地方,也不能在括号中定义任何参数,仅仅只是一个特殊的语法;
- default代表默认值,值必须和第2点定义的类型一致;
- 如果没有默认值,代表后续使用注解时必须给该类型元素赋值。
在java类上使用注解
定义一个注解、和一个供注解修饰的简单Java类
package com.test;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation2 {
String name();
int age() default 18;
int [] score();
}
public class Student{
public void study(int times){
for(int i = 0; i < times; i++){
System.out.println("Good Good Study, Day Day Up!");
}
}
}
最终书写
package com.test;
public class Student {
@MyAnnotation2(name="window",age=23,score= {22,99})
public void study(int times){
for(int i = 0; i < times; i++){
System.out.println("Good Good Study, Day Day Up!");
}
}
}
反射获取注解
创建一个注解
package com.test;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义注解
* @author liuchunming
*
*/
@Target({ElementType.METHOD,ElementType.TYPE})
@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String msg() default "这是我的自定义注解";//default 默认值
}
定义一个接口
package com.test;
@MyAnnotation //使用自定义注解
public interface Message {
@MyAnnotation
public void msg();
}
实现接口类
package com.test;
@MyAnnotation
public class MessageImpl implements Message {
@Override
@MyAnnotation(msg = "我是自定义注解信息...")
public void msg() {
// TODO Auto-generated method stub
}
}
测试
package com.test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class Mytest {
Annotation [] annotation =null;
public static void main(String[] args) throws ClassNotFoundException {
new Mytest().getAnnotation();
}
private void getAnnotation() throws ClassNotFoundException {
Class<?> clazz = Class.forName("com.test.MessageImpl");
boolean isEmpty = clazz.isAnnotationPresent(com.test.MyAnnotation.class);
if(isEmpty) {
annotation= clazz.getAnnotations();//获取注解接口
for (Annotation a : annotation) {
MyAnnotation my = (MyAnnotation) a;//强制转换成MyAnnotation类型
System.out.println(clazz + "--" + my.msg());
}
}
Method[] method = clazz.getMethods();
for (Method m : method) {
boolean ismEmpty = clazz.isAnnotationPresent(com.test.MyAnnotation.class);
if(ismEmpty) {
Annotation[] aa =m.getAnnotations();
for (Annotation a : aa) {
MyAnnotation my =(MyAnnotation) a;
System.out.println(m+"--"+my.msg());
}
}
}
}
}
测试结果
总结
今天就到这里了如果有什么不对的地方欢迎大家在评论区留言交流改进!!