Android-0.注解及自定义注解@interface

注解

注解(Annotation) 为所有注释类型扩展的公共接口

元注解

@Retention

https://developer.android.com/reference/java/lang/annotation/Retention

定义了注解的生命周期,注解的生命周期有三个阶段:
第一阶段:注解只存在于java源文件,在编译成class文件时去掉注解。
第二阶段:注解存在于class文件,在将class文件转换成内存中的字节码的时候去掉注解。
第三阶段:注解存在于内存中的字节码。

@Retention(RetentionPolicy.SOURCE):注解信息只会保留在源码里,源码经过编译后,注解信息会被丢弃,不会保留在编译好的class文件里,即第一阶段。@Override@SuppressWarnings都属于这类注解,可以做一些检查性的操作。

@Retention(RetentionPolicy.CLASS):注解信息会保留在源码里和class文件里,在执行的时候,不会加载到虚拟机(JVM)中,即第二阶段。注解默认使用这种方式。

@Retention(RetentionPolicy.RUNTIME):源码、class文件和执行的时候都有注解的信息,VM将在运行期也保留注解信息,因此可以通过反射机制读取注解的信息,我们自定义的注解通常使用这种方式划重点),为第三阶段。@Deprecated属于此类注解。

@Target

https://developer.android.com/reference/java/lang/annotation/Target

@Target说明注解的作用目标,默认值为任何元素。取值有以下:

@Target(ElementType.TYPE) //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE) //局部变量
@Target(ElementType.ANNOTATION_TYPE) //注解
@Target(ElementType.PACKAGE) //包
public enum ElementType {
    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
    /**
     * @since 1.8
     */
    TYPE_PARAMETER,// Type parameter declaration

    /**
     * @since 1.8
     */
    TYPE_USE//  Use of a type
}
@Inherited

https://developer.android.com/reference/java/lang/annotation/Inherited

@Inherited说明子类可以继承父类中的该注解

@Documented

https://developer.android.com/reference/java/lang/annotation/Documented?hl=ru

@Documented表明制作javadoc时,是否将注解信息加入文档。如果注解在声明时使用了@Documented,则在制作javadoc时注解信息会加入javadoc

@Deprecated

https://developer.android.com/reference/java/lang/Deprecated

@Deprecated意为“废弃的,过时的”,也就是就是说这个方法已经废弃了,不建议使用,通常是因为它很危险,或者因为存在更好的替代方案。

@Override

https://developer.android.com/reference/java/lang/Override

@Override意为“重写、覆盖”,最常用的就是覆盖toString

public class OverrideTest {
    
    @Override
    public String toString() {
        return super.toString();
    }
}

编译器会自动检测,父类或超类有没有该方法toString,如果没有,编译器就会报错。

@SuppressWarnings

@SuppressWarnings意为“抑制警告”,简单的说就是去掉编译器警告。

public class OverrideTest {
    @SuppressWarnings("unchecked")
    @Override
    public String toString() {
        return super.toString();
    }
}

"unchecked"用于去掉未经检查的警告。

自定义注解

注解的原理

在某个类上加一个注解,可以理解为相当于给这个类的class加了一个Annotation对象
isAnnotationPresent检测指定注解类型的注解是否存在于此元素上,true表示存在,false表示不存在。
getAnnotation返回此元素上指定注解类型的那个Annotation对象。
在这里插入图片描述

自定义注解及其应用

自定义一个最简单的注解:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MyAnnotation {

}

@Retention@Target在前面都有解释,把自定义的注解加到某个类上:

@MyAnnotation
public class AnnotionTest {
}

用反射测试AnnotionTest 的定义上是否有@MyAnnotation

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (AnnotionTest.class.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation myAnnotation = AnnotionTest.class.getAnnotation(MyAnnotation.class);
            Log.e(BuildConfig.TAG, "MyAnnotation:" + myAnnotation);
        }

MyAnnotation是一个类,这个类的实例对象myAnnotation 是通过反射得到的, 一旦在某个类上使用了@MyAnnotation,那么这个MyAnnotation类的实例对象myAnnotation 就会被创建出来了。

为注解增加属性
添加属性

语法:类型 属性名();

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MyAnnotation {
    String color(); // 添加属性
}
-->// 应用属性
@MyAnnotation(color = "green")
public class AnnotionTest {
}
-->// 取得属性值
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (AnnotionTest.class.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation myAnnotation = AnnotionTest.class.getAnnotation(MyAnnotation.class);
            String color = myAnnotation.color(); // 输出green
为属性指定默认值

语法:类型 属性名() default 默认值;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MyAnnotation {
    String color() default "blue";//为属性指定默认值
}
value属性

如果注解中有一个名称为value的属性,且你只想设置value属性(即其他属性都采用默认值或者你只有一个value属性),那么可以省略掉“value=”部分。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MyAnnotation {
    String color() default "blue"; // 为属性指定默认值
    String value(); // 定义一个名称为value的属性
}
-->// 应用属性
@MyAnnotation("abc") // value赋值为"abc"
public class AnnotionTest {
}
-->// 取得属性值
    protected void onCreate(Bundle savedInstanceState) {
        if (AnnotionTest.class.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation myAnnotation = AnnotionTest.class.getAnnotation(MyAnnotation.class);
            String color = myAnnotation.color();
            String value = myAnnotation.value(); // "abc"
数组类型的属性

增加数组类型的属性:int[] arrayAttr() default {1,2,4};
应用数组类型的属性:@MyAnnotation(arrayAttr={2,4,5})
如果数组属性只有一个值,这时候属性值部分可以省略大括号,如:@MyAnnotation(arrayAttr=2),这就表示数组属性只有一个值,值为2

枚举类型的属性

增加枚举类型的属性:EumTrafficLamp lamp() default EumTrafficLamp.RED;
应用枚举类型的属性:@MyAnnotation(lamp=EumTrafficLamp.GREEN)

注解类型的属性
public @interface NewAnnotation {
    String value();
}

为注解添加一个注解类型的属性,并指定注解属性的缺省值:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MyAnnotation {
    NewAnnotation annotationAttr() default @NewAnnotation("xdp");
}

自定义注解综合示例

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MyAnnotation {
    String color() default "blue"; // 为属性指定默认值
    String value(); // 定义一个名称为value的属性
    int[] arrayAttr() default {1, 2, 4}; // 添加一个int类型数组的属性
    ColorEnum lamp() default ColorEnum.RED; // 添加一个枚举类型的属性,并指定枚举属性的缺省值
    NewAnnotation annotationAttr() default @NewAnnotation("xdp"); // 为注解添加一个注解类型的属性,并指定注解属性的缺省值
}

–> 应用属性

@MyAnnotation(color = "red",
              value = "hgy413",
              arrayAttr = {1, 4, 5},
              lamp = ColorEnum.GREEN,
              annotationAttr = @NewAnnotation("def"))
public class AnnotionTest {

}

–> // 取得属性值

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (AnnotionTest.class.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation myAnnotation = AnnotionTest.class.getAnnotation(MyAnnotation.class);
            String color = myAnnotation.color(); // red
            String value = myAnnotation.value(); // hgy413
            int length = myAnnotation.arrayAttr().length; // 3
            ColorEnum colorEnum = myAnnotation.lamp(); // ColorEnum.GREEN
            String newValue = myAnnotation.annotationAttr().value(); // def

参考
Java基础加强总结(一)——注解(Annotation)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值