学习ing——注解

一、Java注解概述

注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

二、jdk的内置注解

2.1 内置注解分类

2.1.1 @Override

标记在成员方法上,用于标识当前方法是重写父类(父接口)方法,编译器在对该方法进行编译时会检查是否符合重写规则,如果不符合,编译报错。
这里解释一下@Override注解,在我们的Object基类中我们都知道有一个toString方法,我们通常在实体类中去重写此方法来达到打印对象信息的效果,这时候也会发现重写的toString方法上方就有一个@Override注解。如下所示:
在这里插入图片描述
于是,我们试图去改变重写后的toString方法名称,将方法名改为toStrings。你会发现在编译期就报错了!如下所示:
在这里插入图片描述
那么这说明什么呢?这就说明该方法不是我们重写其父类(Object)的方法。这就是@Override注解的作用。

2.1.2 @Deprecated

表示建议不再使用该元素。若某类或某方法加上该注解之后,表示此方法或类不再建议使用,在调用时也会出现删除线。但是,也并非代表完全不能使用,只是不推荐,因为还有更好的方法可以调用。
举个例子吧:
假设某手机下拥有某APP,目前是V1.0版本,它为用户提供了show1方法的功能。这时候APP对show1方法的功能又进行了扩展,打算发布V2.0版本。但是,我们V1.0版本需要抛弃吗?答案肯定是不能抛弃的,因为有一部分用户是一直用V1.0版本的。如果抛弃了该版本会损失很多的用户量,所以我们不能抛弃该版本。这时候,我们对功能进行了扩展后,发布了V2.0版本,我们给予用户的通知就可以了,也就是告知用户我们在V2.0版本中为功能进行了扩展。可以让用户自行选择版本。
但是,除了发布告知用户版本情况之外,我们还需要在原来版本的功能上给予提示,在上面的模拟场景中我们需要在show1方法上方加@Deprecated注解给予提示。通过这种方式也告知用户“这是旧版本时候的功能了,我们不建议再继续使用旧版本的功能”,这句话的意思也就正是给用户做了提示。用户也会这么想“奥,这版本的这个功能不好用了,肯定有新版本,又更好用的功能。我要去官网查一下下载新版本”,还会有用户这么想“我明白了,又更新出更好的功能了,但是这个版本的功能我已经够用了,不需要重新下载新版本了”。

public class DeprecatedTest {
    @Deprecated
    public void show1() {
        System.out.println("这是V1.0系统。");
    }

    public void show2() {
        System.out.println("这是V2.0系统,功能更多。");
    }
    }

在这里插入图片描述
那么我们怎么查看我上述所说的在功能上给予的提示呢?这时候我需要去创建一个方法,然后去调用show1方法,并查看调用时它是如何提示的。
在这里插入图片描述

其实,在官方API中也是通过该方式来标注已经过时(不再推荐的方法或类等元素),例如:java.util.Date
在这里插入图片描述
在这里插入图片描述

2.1.3 @SuppressWarnings

压制警告注解,可放置在类和方法上,该注解的作用是阻止编译器发出某些警告信息。
为了解释@SuppressWarnings注解,我们还使用上一个例子,因为在那个例子中就有黄色的warning出现。他说show2()方法和useApp()方法未被使用。
在这里插入图片描述

简单来说,你创建的show2()和useApp()方法,但是你在代码中并没有调用过此方法。以后你便会遇到各种各样黄色的warning。然后, 我们就可以使用不同的注解参数来压制不同的注解。但是在该注解的参数中,提供了一个all参数可以压制全部类型的警告。而这个注解是需要加到类的上方,并赋予all参数,即可压制所有警告。如下:
在这里插入图片描述
除了该处使用的"all以外@SuppressWarnings还有许多其它参数;常用参数如下:

  • unchecked:未检查的转化,如集合没有指定类型还添加元素
  • unused:未使用的变量
  • resource:有泛型未指定类型
  • path:在类路径,原文件路径中有不存在的路径
  • deprecation:使用了某些不赞成使用的类和方法
  • fallthrough:switch语句执行到底没有break关键字
  • rawtypes:没有写泛型,比如: List list = new ArrayList();
  • all:全部类型的警告
2.1.4 @SafeVarargs

在JDK 7中引入了@SafeVarargs,该注解主要用于处理可变长参数中的泛型。

2.1.5 @FunctionalInterface

@FunctionalInterface注解用于指定接口是函数式接口。

三、元注解

元注解就是用来描述注解的注解。一般使用元注解来限制自定义注解的使用范围、生命周期等等。常见的元注解有:

  • @Target
  • @Retention
  • @Inherited
  • @Documented

3.1 @Target

@Target注解用于确定Annotation所修饰的对象。我们知道Annotation可用于packages、types(类、接口、枚举)、类型成员(方法、成员变量、枚举值)、方法参数等等。所以,可用@Target表示Annotation修饰的目标。
同一个注解可作用于多种元素。例如:某注解既可以在方法上使用也可以在类上面。
在java.lang.annotation包中通过枚举ElementType定义注解修饰的目标,代码如下:

public enum ElementType {
    /**标明该注解可以用于类、接口(包括注解类型)或enum声明*/
    TYPE,

    /** 标明该注解可以用于字段(域)声明,包括enum实例 */
    FIELD,

    /** 标明该注解可以用于方法声明 */
    METHOD,

    /** 标明该注解可以用于参数声明 */
    PARAMETER,

    /** 标明注解可以用于构造函数声明 */
    CONSTRUCTOR,

    /** 标明注解可以用于局部变量声明 */
    LOCAL_VARIABLE,

    /** 标明注解可以用于注解声明(应用于另一个注解上)*/
    ANNOTATION_TYPE,

    /** 标明注解可以用于包声明 */
    PACKAGE,

    /**
     * 标明注解可以用于类型参数声明
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * 类型使用声明
     * @since 1.8
     */
    TYPE_USE
}

在此,我们来看看熟悉的注解@Override的源码:
在这里插入图片描述从此处,我们可以看到:使用@Target注解指定@Override注解只能作用于方法。

接下来,我们再来看看熟悉的注解@Deprecated的源码:
在这里插入图片描述

3.2 @Retention

Java文件从生成到执行,要经过三个主要的阶段:java源文件,class文件,JVM运行。
在这里插入图片描述
@Retention定义了Annotation的保留策略,它亦类似于开发过程中常提到的生命周期。我们可通过@Retention指定Annotation保留至哪个阶段。有的Annotation仅出现在源代码中而被编译器丢弃,而另一些却可以保留至class文件。类似地,有的在class文件中的Annotation在运行时会被虚拟机忽略,而另一些在运行时被读取。
在此,我们来看看熟悉的注解@Override的源码:
在这里插入图片描述
从此处,我们可以看到:使用@Retention注解指定@Override注解仅保留在源码阶段。

接下来,我们再来看看熟悉的注解@Deprecated的源码:
在这里插入图片描述
从此处,我们可以看到:使用@Retention注解指定@Deprecated注解将保留至运行阶段。

3.3 @Inherited

@Inherited用于指示注释类型的自动继承。例如,如果某个类使用了被@Inherited修饰的注解,则其子类将自动具有该注解。
第一步:自定义注解


package com.annotation.test2;

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface InheritedAnnotation {
    String value();
}

第二步:在父类中使用自定义注解

package com.annotation.test2;

@InheritedAnnotation("@InheritedAnnotation on class of ParentClass")
public class ParentClass {


}

第三步:子类继承父类

package com.annotation.test2;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: Is good
 * @Description:
 */
public class ChildClass extends parentClass{
    
}

第四步:从子类上获取注解并测试

package com.annotation.test2;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: Is good
 * @Description:测试元注解@Inherited
 */
public class TestAnnotation {
    public static void main(String[] args) {
        Class<?> clazz = ChildClass.class;
        Class<InheritedAnnotation> annotationClass=InheritedAnnotation.class;
        boolean isPresent=clazz.isAnnotationPresent(annotationClass);
        if (isPresent) {
            InheritedAnnotation annotation = (InheritedAnnotation) clazz.getAnnotation(annotationClass);
            String value = annotation.value();
            System.out.println("value=" + value);
        }
    }
}

在这里插入图片描述

3.4 @Documented

@Documented表示在生成javadoc文档时将该Annotation也写入到帮助文档。
还拿api中过时的Date中的方法来说,在api中显示Date中的getYear方法是这样的。
在这里插入图片描述
正如你看到的,注解在api中显示了出来,证明该注解是@Documented注解修饰并文档化的。那我们就看看这个注解是否被@Documented修饰吧。
在这里插入图片描述

4、总结

又是学习的一天,还有很多的东西需要进一步地掌握。如有错误,请指正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值