怎么定义一个注解
注解可以在类名前加上@interface将一个类定义为注解。
元注解
元注解有五个:
1、@Retention:应用在一个注解上时,用来说明这个注解的存活时间,它内部定义了三个生命周期。
public enum RetentionPolicy {
// 在编译前注解将被丢弃
SOURCE,
// 注解被保留到编译时时
CLASS,
// 注解保留到运行时
RUNTIME
}
2、@Documented:将注解中的元素包含到Javadoc中
3、@Target:注解能运用的地方
public enum ElementType {
// 可以给类型加注解,如类、接口、枚举
TYPE,
// 可以给属性加注解
FIELD,
// 可以改方法加注解
METHOD,
// 可以给方法的参数加注解
PARAMETER,
// 可以给构造方法加注解
CONSTRUCTOR,
// 可以给局部变量加注解
LOCAL_VARIABLE,
// 可以给注解加注解
ANNOTATION_TYPE,
// 可以给包加注解
PACKAGE,
// 可以给参数的声明加注解
TYPE_PARAMETER,
// 可以给类的使用加注解
TYPE_USE
}
4、@Inherited:一个注解类加上它的话,如果这个类的子类没有使用任何注解的话,子类也有这个注解。如:
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Test {}
@Test
public class A {}
public class B extends A {} // B类也有@Test注解
5、@Repeatable:可重复的注解,也就是在同一个地方可以重复使用。
@interface Persons {
Person[] value();
}
@Repeatable(Persons.class)
@interface Person{
String role default "";
}
@Person(role="artist")
@Person(role="coder")
@Person(role="PM")
public class SuperMan{
}
例子中Persons代表一个容器,它内部有相应的对象的数组作为属性。
注解的属性
注解只有成员变量,没有方法。注解的成员变量以无参的方法来声明,方法名定义了成员成员变量的名称,返回值定义了成员变量的类型。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
int id();
String msg();
}
成员变量的赋值:属性名 = “” 的形式。
@TestAnnotation(id=3,msg="hello annotation")
public class Test {
}
注解的成员变量的默认值用default指定:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
public int id() default -1;
public String msg() default "Hi";
}
在有默认值的前提下使用注解没有赋值表示使用默认值:
@TestAnnotation()
public class Test {}
当注解只有一个属性值时,可以直接填属性的值进行赋值:
public @interface Check {
String value();
}
@Check("hi")
int a;
如果注解没有属性,使用这个注解的时候可以不用加括号。
Java预置的注解
1、@Deprecated:用来标记过时的元素,表示某个变量、方法、类过时。
public class Hero {
@Deprecated
public void say(){
System.out.println("Noting has to say!");
}
public void speak(){
System.out.println("I have a dream!");
}
}
2、@Override:提示子类要重写父类中被@Override修饰的方法。
3、@SuppressWarnings:阻止警告。使用该注解可以忽略编译器的警告。
4、@SafeVarargs:提醒开发者不要用参数做不安全的操作。它会阻止编译器产生unchecked这样的警告。
@SafeVarargs // Not actually safe!
static void m(List<String>... stringLists) {
Object[] array = stringLists;
List<Integer> tmpList = Arrays.asList(42);
array[0] = tmpList; // Semantically invalid, but compiles without warnings
String s = stringLists[0].get(0); // Oh no, ClassCastException at runtime!
}
上面的代码会在运行抛出类型转化异常。
参考资料:https://zhuanlan.zhihu.com/p/27643133