JDK内置的三个基本注解
在编译时进行格式检查
- @override:限定重写父类方法,该注解只能用于方法
- @Deprecated:用于表示所修饰的元素(类,方法等)已经过时。
- @SuppressWarnings:抑制编译器警告(例如定义了一个变量但是没有使用,编译就会警告没有使用(idea中变量会呈灰色),加上这个注解后就不会警告了)
@SuppressWarnings("unused")
int num = 10;
@SuppressWarnings({"unused","rawtypes"})
ArrayList list = new ArrayList();
自定义注解Annotation
可以参照@SuppressWarnings定义
- 注解声明为:@interfacce
- 内部定义成员,通常使用value表示
- 可以定义成员的默认值,使用default定义
- 如果自定义注解没有成员,表明是一个标识作用。
如果注解有成员,在使用注解时,需要指明成员的值(无默认值时)。
public @interface MyAnnotation {
String value();
}
or
public @interface MyAnnotation {
String value() dafault "hello";
}
JDK提供的四种元注解
元注解:对现有的注解进行解释说明的注解
- Retention:指定所修饰的Annotation的生命周期:SOURCE/CLASS(默认)/RUNTIME(只有声明为RUNTIME的注解才能通过反射获取)
①SOURCE:Annotations are to be discarded by the compiler.
②CLASS:Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time. This is the default behavior.
③RUNTIME:Annotations are to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively.
//@Retention(RetentionPolicy.SOURCE)
//@Retention(RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.CLASS)
public @interface MyAnnotation {
String value() default "hello";
}
- Target:用于修饰Annotation定义,用于指定被修饰的Annotation能用于修饰那些程序元素。@Target也包含一个名为value的成员变量。
① TYPE:Class, interface (including annotation type), or enum declaration
② FIELD:Field declaration (includes enum constants)
③ METHOD:Method declaration
④ PARAMETER:Formal parameter declaration
⑤ CONSTRUCTOR:Constructor declaration
⑥ LOCAL_VARIABLE:Local variable declaration
⑦ ANNOTATION_TYPE:Annotation type declaration
⑧ PACKAGE:Package declaration - Documented:
- Inherited:被他修饰的Annotation将具有继承性,如果某个类使用了被@Inherited修饰的Annotation,则其子类将自动具有该注解。
MyAnnotation.java:
package com.pan;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
//@Retention(RetentionPolicy.SOURCE)
//@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "hello";
}
AnnotationTest.java
package com.pan;
import java.lang.annotation.Annotation;
public class AnnotationTest {
public static void main(String[] args) {
Class clazz = Student.class;
Annotation[] annotations = clazz.getAnnotations();
for(int i = 0; i < annotations.length;i++){
System.out.println(annotations[i]);//@com.pan.MyAnnotation(value=hello)
}
}
}
@MyAnnotation("hello")
class Person{
private String name;
private int age;
public Person(){}
@MyAnnotation()
public Person(String name, int age){
this.name = name;
this.age = age;
}
}
class Student extends Person{
public Student(){
super();
}
}
如果不加Inherited:
MyAnnotation.java:
package com.pan;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
//@Retention(RetentionPolicy.SOURCE)
//@Retention(RetentionPolicy.RUNTIME)
//@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "hello";
}
AnnotationTest.java
package com.pan;
import java.lang.annotation.Annotation;
public class AnnotationTest {
public static void main(String[] args) {
Class clazz = Student.class;
Annotation[] annotations = clazz.getAnnotations();
for(int i = 0; i < annotations.length;i++){
System.out.println(annotations[i]);//啥也没有
}
}
}
@MyAnnotation("hello")
class Person{
private String name;
private int age;
public Person(){}
@MyAnnotation()
public Person(String name, int age){
this.name = name;
this.age = age;
}
}
class Student extends Person{
public Student(){
super();
}
}
可重复注解(JDK8新特性)
①:在MyAnnotation上声明@Repeatable,成员值为MyAnnotations.class
②:MyAnnotation的Target和Retention和MyAnnotations相同
MyAnnotations.java
package com.pan;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotations {
MyAnnotation[] value();
}
MyAnnotation.java
package com.pan;
import java.lang.annotation.Inherited;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
//@Retention(RetentionPolicy.SOURCE)
//@Retention(RetentionPolicy.RUNTIME)
@Repeatable(MyAnnotations.class)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "hello";
}
AnnotationTest.java
package com.pan;
import java.lang.annotation.Annotation;
public class AnnotationTest {
public static void main(String[] args) {
Class clazz = Student.class;
Annotation[] annotations = clazz.getAnnotations();
for(int i = 0; i < annotations.length;i++){
System.out.println(annotations[i]);
//@com.pan.MyAnnotations(value=[@com.pan.MyAnnotation(value=hello), @com.pan.MyAnnotation(value=Hi)])
}
}
}
@MyAnnotation("hello")
@MyAnnotation("Hi")
class Person{
private String name;
private int age;
public Person(){}
@MyAnnotation()
public Person(String name, int age){
this.name = name;
this.age = age;
}
}
class Student extends Person{
public Student(){
super();
}
}
类型注解(JDK8新特性)
- ElementType.TYPE_PARAMETER:表示该注解能写在类型变量的声明语句中(如:泛型声明)
- ElementType.TYPE_USE:表示该注解能写在使用类型的任何语句中
package com.pan;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
//@Retention(RetentionPolicy.SOURCE)
//@Retention(RetentionPolicy.RUNTIME)
@Repeatable(MyAnnotations.class)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE,TYPE_PARAMETER,TYPE_USE})
public @interface MyAnnotation {
String value() default "hello";
}
class Generic<@MyAnnotation T>{
public void show() throws @MyAnnotation RuntimeException{
ArrayList<@MyAnnotation String> list = new ArrayList<>();
int num = (@MyAnnotation int)10L;
}
}