目录:
注解定义
注解作用
JDK内置的常见注解
注解的分类
自定义注解
注解定义
注解(Annotation),也叫元数据,一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明、注释。
注解作用
编写文档:通过代码里标识的元数据生成文档。
代码分析:通过代码里标识的元数据对代码进行分析。
编译检查:通过代码里标识的元数据让编译器能实现基本的编译检查。
JDK内置的常见注解
@Override:此注解能够实现编译时检查,当某方法前边添加此注解时,表示此方法为重写父类中的方法。如果此方法不是父类的方法。例如本来想重写toString,却写成了tostring,则编译无法通过,会提示错误。
@Deprecated:此注解是对不应该或被弃用的方法进行标识,当开发者使用时会给予警告提示。这个功能在一些 jar 包,框架中经常可以看到,还保留这些方法是为了向前兼容。
@SuppressWanings:此注解的作用是告诉编译器对被批注的元素内部的某些警告保持静默,此注解里边需要制定参数,比如 unused、all、 deprecation 等。
举例:
定义 Person 接口:
public interface Person {
public String name();
public int age();
@Deprecated
public void fight();
}
后来我觉得 fight 不太合适,但是不能直接删掉,因为可能还有开发者使用这个接口方法,所以我将 fight() 批注Deprecated,表示弃用此方法。
编写 Student 类,因为实现了 Person 接口,所以必须重写三个方法。
public class Student implements Person {
@Override
public String name() {
return null;
}
@Override
public int age() {
return 0;
}
@Override
public void fight() {
}
}
测试类 Main:
public class Main {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
Person person = new Student();
person.fight();
}
}
当调用 fight()方法时,编译器给我警告,说此方法已经过时。严格的公司提交代码中不能存在警告,这就需要在此方法上面加上@SuppressWarnings(“deprecation”),表示忽略方法里的过时警告。
注解的分类
按照运行机制分为:
源码注解
注解只在源码中存在,编译成 . class 文件就不存在了。编译时注解
注解在源码和 .class 文件中都存在。刚才的Override、Deprecated、SuppressWarnings 都是编译时注解,在编译时起作用,比如没重写的话,就报一个编译时错误。运行时注解
在运行时还起作用,甚至影响运行逻辑的注解。比如框架中注入的注解。
按照来源分为:
JDK内置注解
第三方注解
自定义注解
当然还有元注解,即给注解的注解。
自定义注解
1、使用@interface关键字定义注解
2、成员必须以无参数无异常的方式进行声明
3、可以使用 default 为成员指定一个默认值
4、成员类型是受限的,合法类型除了基本数据类型以外,还包括 String、Class、Annotation、Enumeration。
5、如果注解类只有一个成员,则成员名是value(),使用时才可以省略成员名和等号。
6、注解类可以没有成员,没有成员的注解成为标识注解
如下格式:
public @interface Phone {
String brand();
String author();
int price() default 5288;
}
上面提到过源码时注解,编译时注解和运行时注解,这是怎么来定义区分的呢?
看下面代码,我对上面自定义注解加了四条元注解,这表示什么含义呢?
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Phone {
String brand();
String author();
int price() default 5288;
}
1、@Target 表示注解作用域。
CONSTRUCTOR(构造方法可以声明)、FIELD(字段可以声明)、LOCAL_VARIABLE(局部变量可以声明)、 METHOD(方法可以声明)、PACKAGE(包可以声明) 、PARMETER(参数可以声明)、TYPE(类、接口可以声明)
2、@Retention 表示注解生命周期。
SOURCE(只在源码显示,编译时丢弃)、CLASS(编译时会记录到Class中去,运行时忽略)、RUNTIME(运行时存在,可以通过反射读取)
3、@Inherited 是标识元注解,表示允许子类继承。
4、@Documented 表示生成 javadoc 时会包含注解。
通过上面的定义和限制后,使用自定义注解如下:
@Phone(brand = "华为",author = "China",price = 3299)
public static void main(String[] args) {
}