注解

注解学习笔记

2019/10/24 周四
程序员节快乐!


一、什么是注解

  • 注解就是符合一定格式的语法 @xxxx

  • 与注释(//xxx、/* */)的区别:注释是给程序员看的,使程序在阅读时清楚;而注解是给JVM虚拟机看的

  • 注解在目前而言最主流的应用:代替配置文件

  • 优点:开发效率高、成本低,在一定程序上取代配置文件
    缺点:耦合性大 并且不利于后期维护

二、jdk1.5提供的三种注解

  1. @Override:标注重写,告知编译器此方法是覆盖父类的;JDK1.6还可以表示实现接口的方法
  2. @Deprecated:标注过时。过时的方法不建议使用,但仍可以使用
  3. @SuppressWarnings:压制警告,被修饰的类或方法如果存在编译警告,将被编译器忽略

其中,使用压制警告注解时,把要忽略哪种警告作为注解的属性,格式为

@SuppressWarnings("unused")

共有下面几种警告可以忽略:

(1)deprecation,忽略过时
(2)rawtypes,忽略类型安全(如使用集合时没有指定泛型)
(3)unused,忽略不使用(最常见)
(4)unchecked,忽略安全检查
(5)null,忽略空指针
(6)all,忽略所有

注:注解的使用位置有限制(下文介绍),压制警告注解是使用在类上面,但由于在同一个位置注解不能重复使用,因此如果有多个警告要忽略,属性以数组的形式标注,如

@SuppressWarnings({"unused","rawtypes"})

三、自定义注解

注解可以自己定义,使用关键字 @interface (与接口没有任何关系,只是因为Java关键字不够用了)

  1. 注解有属性,定义注解属性的语法为“ 返回值 名称(); ”(括号与方法没有关系),如
public @interface MyAnnotation {
	String[] value(); // 给注解定义属性,类型为String的数组
	int age() default 18; // 可以给用default关键字属性设置默认值
}

注解的属性类型只能是以下几种:
(1) 基本数据类型
(2) String
(3) 枚举类型
(4) 注解类型
(5) Class类型
(6) 以上类型的一维数组类型(如果数组的元素只有一个,使用时可以省略花括号)

  1. 使用注解:在类/方法/字段上使用,以在类上使用为例:
@MyAnnotation(value="zhangsan",age=18)
public class Test{

}

注:(1)属性的顺序没有关系
(2)有默认值的属性(如这个例子中的age)可以不再赋值,可忽略
(3)如果属性的名字是value,并且需要赋值的属性值有且只有一个,那么在使用注解时可以省略value,如:

@MyAnnotation("zhangsan")
public class Test{

}

由此可见,上文中@SuppressWarnings压制警告的注解,它的属性名就是value,使用时省略了

四、元注解

元注解是修饰注解的注解,作用是限制定义的注解的特性

常用元注解有两个:

  1. @Target 限制注解修饰的范围(位置),即限制该注解是在类上使用、方法上使用、还是字段上使用,它的常用属性有三个:
    (1)ElementType.FIELD:字段上可用此注解
    (2)ElementType.METHOD:方法上可以用此注解
    (3)ElementType.TYPE:类/接口上可以使用此注解
    其他位置还有:CONSTRUCTOR(构造方法)、PACKAGE(包)、LOCAL_VARIABLE(局部变量)、PARAMETER(方法内的参数)、ANNOTATION_TYPE(可以给一个注解进行注解)

  2. @Retention 限制注解的可见范围,它的属性有:
    (1)SOURCE(默认):注解在源码级别可见,在编译器进行编译时它将被忽视
    (2)CLASS:注解在字节码文件级别可见,不会被加载到 JVM 中
    (3)RUNTIME:注解在整个运行阶段都可见,因此在程序运行时可以获取到它们

@Target({ElementType.CONSTRUCTOR, ElementType.TYPE})  // 该注解可以在构造方法和类上面使用
@Retention(RetentionPolicy.RUNTIME)  // 该注解在整个运行阶段都可见
public @interface MyAnnotation {
	String[] value();
	int age() default 18;
}

注:自定义注解时,如果不设置Retention属性,则可见范围默认是SOURCE源码级别,如果想解析使用了注解的类,那么必须设置成RUNTIME

解析注解的实质是利用反射,从注解中解析出属性值。
字节码对象有获得注解相关的方法:

getAnnotation(Class annotationClass)

当注解解析出来后,接下来就可以按需求来定义注解的功能了······

你可能感兴趣的:(基础知识,Java注解)