专栏首页Java后端技术栈cwnait【刨根问底】java注解--上

【刨根问底】java注解--上

从JDK1.5开始,Java增加了对元数据的支持,也就是Annotation,首先说明注释和注解不是同一回事,是有区别的。本次分享的注解,其实就是代码里的特色标记而已,这些标记可以在代码的编译、类加载、运行时被读取,并且执行相应的处理。通过使用注解,咱们可以在不改变原有逻辑的情况下,在源码文件中嵌入一下补充信息,代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者部署;

注解提供了一种为程序元素设置元数据的方法,从某些方面来说,注解就想修饰符一样,可以修饰类,接口,方法,属性等。

注意

注解本质是一个接口,并且程序 可以通过反射来获取指定程序元素的java.util.Annotation对象,然后通过java.lang.Annotation对象来取得注解里的元数据。

java注解计划分三次进行分享,本文是第一篇。java注解基本注解。

包含 :

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
   String[] value();
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SafeVarargs {}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

以上五个注解中

SafeVarargs 是jdk1.7中新增的,

FunctionalInterface 是jdk1.8中新增的

五个注解都是在 rt.jar中java.lang目录 下,接下来一个个分析:

@Override

@Orverride就是用来指定方法覆盖的,它可以强制一个子类必须覆盖父类中的某个方法,@Orverride是常见注解之一。案例代码:

public class Father {
    public void hello(String msg) {
        System.out.println("father hello " + msg);
    }
}
 public class Son extends Father {
    @Override
    public void hello(String msg) {
        System.out.println("son hello " + msg);
    }
}

表明Son已经重写了Father的say方法。标记@Orverride有个很明显的好处就是让子类知道自己是不是重写了父类的方法,如果不存在拟这个注解,那么咱们每次都得认真检查子类是不是已经重写了父类中的方法,比如说子类中hello 写错了,写成hell0 了,这个坑了。 如果加了注解后编译会报错的,如下:

注意

@Override注解只能修饰方法,不能修饰其他程序元素

@Deprecated

@Deprecated注解是用于表示某个程序元素(类,方法等)已经过时。如果咱们代码中使用已经过时的类或者方法时候,编译器会会给出警告提示。

@SuppressWarnings

@SuppressWarnings指示被注解的代码取消置顶编译警告,

比如以下代码,

public class  Son {
    public static void main(String[] args) {
        List<String> myList=new ArrayList();
    }
}

在new ArrayList()这里会提示如下:

Unchecked assignment: 'java.util.ArrayList' to 'java.util.List<java.lang.String>' less... (Ctrl+F1) 
Signals places where an unchecked warning is issued by the compiler, 
for example:
  void f(HashMap map) {
    map.put("key", "value");
  }
Hint: Pass -Xlint:unchecked to javac to get more details.

不让他提示就是用:

@SuppressWarnings(value = "unchecked")
public class  Son {
    public static void main(String[] args) {
        List<String> myList=new ArrayList();
    }
}

并且value一定要赋值为unchecked,提示才会去掉。

@SafeVarargs

    public static void main(String[] args) {
        List myList = new ArrayList<Integer>();
        myList.add(22);
        List<String> strings = myList;
        //会出现类型强转失败
        System.out.println(strings.get(0));
    }

上面这段代码会出现强转失败,这种错误发生也叫“堆污染”,把一个带泛型的变量传给了一个不带泛型的变量。关于泛型请看再谈泛型java---上再谈Java泛型---下。从jdk1.7开始,Java编译器将会进行严格的检查,Java编译器会发出相应警告信息。这样有助于咱们开发人员更早的发现可能存在的堆污染。

但是有时候不想看到这个警告,则可以使用如下几种方式来抑制住这个警告:

  1. 使用SwafeVarargs修饰引发静态的方法或者构造器,JDK1.9增强了该注解,允许使用该注解修饰私有方法。
  2. 使用SuppressWarnings(“unchecked”)
  3. 编译时使用-Xlint:varargs选项。

第三种方式一般使用很少,所以通常可以选择第一或者第二种。

@FunctionalInterface

在jdk1.8中规定,如果接口中只有一个抽象方法(可以办好多个默认方法或多个static方法),该接口就是函数式接口。@FunctionalInterface就是用来指定某个接口必须是函数式接口。

例如;

@FunctionalInterface
public interface MyFunctionalInterfaceDemo{
    static void methdo1() {
        System.out.println("method1");
    }
    default void method2() {
        System.out.println("method2");
    }
    //只定义了一个抽象方法
    void test();
}

我们编译上面这段代码,可能完全看不出程序中的@FunctionalInterface的作用,

因为@FunctionalInterface只是告诉编译器检车这个接口,保证该接口只能包含一个抽象方法,否则编译会报错。

@FunctionalInterface主要是帮助程序避免一些低级错误,

例如:在上面的MyFunctionalInterfaceDemo的接口中再增加一个抽象方法。

编译器就会报错了。

本文分享自微信公众号 - Java后端技术栈(t-j20120622),作者:lawt

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【注解驱动时代】细说@Value注解

    另外application.yml 获取方式一样,只是两种配置文件的样式不同。注意:yml文件中的冒号后面要有空格,冒号+空格=properties文件中的点....

    用户4143945
  • 如何搞定Mybatis 中的 9 种设计模式

    虽然我们都知道有很多设计模式,但是大多停留在概念层面,真实开发中很少遇到,Mybatis源码中使用了大量的设计模式,阅读源码并观察设计模式在其中的应用,能够更深...

    用户4143945
  • 徒手撸一个 Spring Boot 中的 Starter ,解密自动化配置黑魔法!

    我们使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中。Starter 为我们带来了众多的自动化配置,有了这些自动化配置,我们可以不费吹...

    用户4143945
  • Java描述设计模式(06):建造者模式

    知了一笑
  • Java 设计模式 代理模式

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://louluan.blog.c...

    亦山
  • 阅读开源框架,总结Java类的定义

    即使我们明白Java的类,也未必清楚该如何正确地定义一个Java类。阅读一些开源框架的源代码,会启发我们灵感,并给出好代码的规范,提炼设计原则与模式。

    张逸
  • 优雅地烘焙 DBService

    记得大二那年第一次接触 GreenDao 这个神奇的数据库,惊叹道,哇,原来代码还能这么写啊,不用自己手撸 SQLiteDatabase,不用写那些麻烦的 SQ...

    HelloVass
  • 通过例子介绍架构

    首先一个 APP 软件是一个大的系统,我们通常可以把这个大的系统划分为许多个小的模块,比如:登录注册功能,首页展示功能、个人信息功能等等某个具体的模块的功能。然...

    开发者
  • Android-实用的MVP

    code_horse
  • java学习:调用 java web service

    先写一个java的class:AwbModel(相当于要在web service中传输的实体对象) package webservicesample; pub...

    菩提树下的杨过

扫码关注云+社区

领取腾讯云代金券