Java基础之注解

1. 注解的写法

public @interface MyAnnotation {

    int STATUS=0;

    int age();

    String name();
}

关注点

  • 在interface前面加个@,来声明这是一个注解
  • 注解中的第一行代码,是一个常量,并且注解和接口一样,声明的常量默认也只能是public final类型的
  • 注解的第二三行代码,分别是一个int型和String型的变量,并且注解中不支持定义方法

在用该注解的时候,需要给注解中的变量赋值

@MyAnnotation(age=18,name="张三")

如果注解中只有一个变量,可以命名为value
此时赋值的时候,可以这样

public @interface MyAnnotation {

    int STATUS=0;

    String value();
}

@MyAnnotation("张三")

注解中的变量可以设置默认值,这样在用注解的时候,就不用给变量赋值,也可以编译通过了

public @interface MyAnnotation {

   String name() default "张三";
}

@MyAnnotation()

2. 元注解

注解上的注解就是元注解,并且元注解只能用在注解上,Java提供了4中元注解

@Target

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

ElementType是一个枚举类

  • ElementType.TYPE:修饰类、接口或枚举(enum)
  • ElementType.FIELD:注解成员变量
  • ElementType.METHOD:注解方法
  • ElementType.PARAMETER:注解方法参数
  • ElementType.CONSTRUCTOR:注解构造函数
  • ElementType.LOCAL_VARIABLE :注解局部变量
  • ElementType.ANNOTATION_TYPE 注解另一个自定义注解
  • ElementType.PACKAGE 注解包

@Retention

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

RetentionPolicy是一个枚举类

  • RetentionPolicy.SOURCE:在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码
  • RetentionPolicy.CLASS:默认值(自定义注解默认是RetentionPolicy.CLASS),编译器仅把注解保存在class文件中,在运行java程序时,JVM不会保留注释,即不能用反射(在运行期)来获取注释
  • RetentionPolicy.RUNTIME:编译器不仅把注解保存在class文件中,同时在运行java程序时,JVM也会保留注释,即可以通过反射来获取注释

android从源码到apk文件的大体流程
Java源码——>class文件——>dex文件——>apk
SOURCE对应Java源码到class文件,CLASS对应class文件到apk,RUNTIME则对应app运行期间

@Documented

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

作用
将此注解包含在 javadoc 中 ,它代表着此注解会被javadoc工具提取成文档。在doc文档中的内容会因为此注解的信息内容不同而不同

@Inherited

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}

作用
使用此注解声明出来的自定义注解,在使用此自定义注解时,如果注解在类上面时,子类会自动继承此注解,否则的话,子类不会继承此注解。这里一定要记住,使用Inherited声明出来的注解,只有在类上使用时才会有效,对方法,属性等其他无效。

3. Java自带注解

@Override

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

该注解的作用在于声明该方法是覆盖的父类的方法

来段代码

public interface Readable {
    boolean canRead();
}

public class English implements Readable{

    @Override
    public boolean canRead() {
        return false;
    }

    public String getName(){
        return "English";
    }

    public static void main(String[] args){
        System.out.println("测试注解@Override");
    }
}

当我们去掉canRead方法上的注解,编译器不会报错,程序也能正常运行
但是当我们在getName方法上加注解时,编译器会报错,程序运行也会报错
则得出的结论是
@Override就是一个标注,被标注的方法在子类中一定存在相同的方法,因为拼写错误时,子类没有此方法,则编译器会报错

@Deprecated

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

用于表明类(class)、方法(method)、字段(field)已经不再推荐使用,并且在以后的JDK版本中可能将其删除,编译器在默认情况下检测到有此标记的时候会提示警告信息。

@SuppressWarnings

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}

作用在于告诉编译器忽略某个警告信息
如@SuppressWarnings("deprecation")则会告诉编译器,不要在输出关于过时的警告信息

4. 注解的作用

前面讲了这么多,总结起来就一句话,注解其实就是一个标记,通过读取注解中的不同标记,编译器或程序会做出相应的事情
如上面的@SuppressWarnings("deprecation"),当编译器读取到这个标记时,则不会再输出关于过时的警告信息了

自定义注解标记的获取

@MyAnnotation(name = "我是Main类")
public class Main {

    @MyAnnotation(name = "我是main方法")
    public static void main(String[] args) throws NoSuchMethodException {

        Class c1=Main.class;
        MyAnnotation annotation1= (MyAnnotation) c1.getAnnotation(MyAnnotation.class);
        System.out.println(annotation1.name());

        Method method=c1.getMethod("main",String[].class);
        MyAnnotation annotation2=method.getAnnotation(MyAnnotation.class);
        System.out.println(annotation2.name());

    }
}

自定义注解,我们一般通过反射,来获取注解的信息,得到信息之后,可以根据不同的信息作出不同的操作即可

注解用反射获取注解信息,要求注解的必须为运行时注解
@Retention(RetentionPolicy.RUNTIME)
否则通过上述反射获取到的注解对象为null

5. 安卓中常见的注解

@NonNull和@Nullable

这两个注解是用来标注方法是否能传入null值,如果可以传入null值,则标记为Nullable,如果不可以则标注为NonNull。在我们做了一些不安全严谨的编码操作的时候,这些注释会给我们一些警告(程序编译和运行都不会报错)。比如说

NonNull.png

@SuppressLint
指示Lint应忽略带注释元素的指定警告

@Parcel
与implements Parcelable作用相同,免去手写Parcelable相关的代码

@UiThread和@WorkThread
指定方法工作在主线程/子线程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • 什么是注解(Annotation):Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息和...
    九尾喵的薛定谔阅读 3,073评论 0 2
  • 如果我能重回18岁的盛夏,我想,我会勇敢牵起他的手,谈一场无所畏惧的爱情。故事有点长,慢慢看就好。 1 “我们分手...
    祝从容阅读 1,041评论 22 25
  • 人生本就充满欢笑和泪水 别人负责欢笑 而你负责泪水 奥黛丽赫本我的女神,我大学期间看了你生前所有的影视作品。真...
    笨乖乖阅读 210评论 0 1
  • 1、在你的项目中全局安装karma;npm install -g karma; 2、进入你的测试脚本上一级,如: ...
    Ferrari_ma阅读 1,220评论 0 0
  • 因为不如意,才会如此想念你? 2017年7月23日 星期日 晴 太阳不要命的照着,晒得人发晕。 记不清这...
    九空阅读 194评论 4 5