一、注解入门
1、什么是注解
- Annotation是从JDK1.5开始引入的新技术
- Annotation的作用
- 不是程序本身,可以对程序做出解释.(这一点和注释(comment)没什么区别)
- 可以被其他程序(比如:编译器等)读取
- Annotatiton的格式
- 注解是已"@注解名"在代码中存在的,还可以添加一些参数值
@SuppressWarnings(value = "all")
- Annotation在哪里使用
- 可以附加在package,class,method,field等上面,相当于给他们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问
二、内置注解
1、@Override:定义在java.lang.Override,此注解只使用修辞方法,表示一个方法声明打算重写超类中的另一个方法
//重写注解
@Override
public String toString() {
return super.toString();
}
2、@Deprecated:定义在java.lang.Deprecated中,此注解可以用于修辞方法,属性,类,标识不鼓励程序员使用这样的元素,通常是因为它很危险或者存在更好的选择
@Deprecated
public void test1(){};
//当调用被@Deprecated注解修饰的方法时会出现一条删除线
3、@SuppressWarnings:定义在java.lang.SuppressWarnings中,此注解用来抑制编译中的警告信息
-
与前两个注解不相同,你需要添加一个参数才能正确使用,这些参数都是已经定义好的了,我们选择性使用就行
- @SuppressWarnings(value = “all”)
- @ SuppressWarnings(value = “unchecked”)
- @ SuppressWarnings(value = {“unchecked”,“deprecation”})
- 等等…
三、元注解
- 元注解的作用就是负责注解其他注解的,Java定义了4个标准的meta-annotation类型,他们被用来提供对其他annotation类型做说明
//这是@Deprecated注解的元注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
//以上的注解使用来注解当前注解的
-
这些类型和他们所支持的类在java.lang.annotation包中可以找到(@Target,@Retention,@Documented,@Inherited)
- @Target:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
//我们进入@Target注解的源码进查看 @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target { ElementType[] value(); } //我们发现在元注解中也有元注解在修饰,因此我们得出结论:元注解可以修饰其他注解,也可以自注解 //我们在进入到它的ElementType[]参数中进行查看 public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ //类,接口 TYPE, /** Field declaration (includes enum constants) */ //字段 FIELD, /** Method declaration */ //方法 METHOD, /** Formal parameter declaration */ //参数 PARAMETER, /** Constructor declaration */ //构造器 CONSTRUCTOR, /** Local variable declaration */ //局部变量 LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE, /** * Type parameter declaration * * @since 1.8 */ TYPE_PARAMETER, /** * Use of a type * * @since 1.8 */ TYPE_USE } //我们发现该参数使用的枚举类型,已经为我们列举好了参数类型
- @Retention:表示需要在什么级别保存该注解信息,用于描述注解的声明周期 ,它也需要一个参数,它的参数类型也是枚举形,(source < class < runtime)感兴趣的可以去它的源码自己看一下这里我就不再赘述了。
- @Documet:说明该注解是否将被包含在JavaDoc中
- @Inherited:说明子类可以继承父类中的注解
四、自定义注解
- 我们先来看下自定义注解注解
//这就是一个最基础的自定义注解
public @interface MyAnnotation {
//TODO
}
- 我们也可以给我们的自定义注解添加元注解
//Target 表示我们的注解可以用在哪些地方
@Target(value = {ElementType.TYPE, ElementType.METHOD})
public @interface MyAnnotation {
//TODO
}
//Retention 表示该注释在什么地方生效
// source > class > runtime
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
//TODO
}
//Documented 表示是否将我们的注解生成在JavaDoc中
@Documented
public @interface MyAnnotation {
//TODO
}
//Inherited 子类可以继承父类的注解
@Inherited
public @interface MyAnnotation {
//TODO
}
//当然,这些元注解可以同时存在
- 也可以给我们的注解添加参数信息
public @interface MyAnnotation {
//注解的参数 : 参数类型 + 参数名 ();
String name();
int age() ;
String[] hobby();
}
//那么在使用该注解时要填入相同的数据类型的参数,顺序必须也相同
@MyAnnotation(name= "李垚", age= 1, hobby= {"弹吉他", "打球"})
public void test(){};
- 还可以给参数添加默认值
public @interface MyAnnotation {
//注解的参数 : 参数类型 + 参数名 ();
String name() default "";
int age() default -1;
String[] hobby() default {""};
}
//这样在使用该注解的时候不写参数也不会报错
@MyAnnotation()
public void test(){};
- 如果只有一个参数的时候,在使用该注解时可以省略参数名直接写值,但必须声明参数的时候参数名称是value
public @interface MyAnnotation {
//参数名称必须为value才可以省略
String value();
}
//只有一个参数,在调用的时候可以省略参数名称
@MyAnnotation("李垚")
public void test(){};
-
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口
-
分析:
- @interface用来声明一个注解,格式:public @Interface 注解名{}
- 其中的每一个方法实际上就是声明的一个配置参数
- 方法的名称就是参数的名称
- 可以通过default来声明参数的默认值
- 如果只有一个参数成员,一般命名为value
- 注解参数必须要有值,我们定义直接元素时,经常使用空字符串,0作为默认值