注解的原理

怎么定义一个注解

  注解可以在类名前加上@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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值