当前位置:首页 > 技术分析 > 正文内容

玩转Java注解-元注解、内置注解、自定义注解的原理和实现

ruisui883个月前 (01-17)技术分析20

前言

Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。 重点:和 Javadoc 不同,Java 标注可以通过反射获取标注内容。 大话空话不用说太多,简而言之,在编译器生成类文件时,标注 可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。 反射+注解,是不是感觉Java变成一种动态语言?哈哈哈!

我觉得注解可以分为三个部分来讲:内置注解,元注解,自定义注解。

一、内置注解

1、@Override 重写

概念:检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。

//这个extends 不要在意,我写上去只是为了更加方便直观的去理解,Object是万物之源,不写也会默认是其子类,不用解释过多吧?
public class Annotation1 extends Object{

    @Override
    public String toString (){
        return "我是重新定义过的toString方法";
    }
}

@Override(重写),这个大家应该很熟悉,重写父类的方法。 我们可以看下Object类中toString()是什么样子的。

那么显而易见,使用了@Override(重写)注解,方法名、方法参数必须得和父类保持一致,否则会报错。 如下图所示:

如果不加@Override(重写)注解,则正常编译。

2、@Deprecated 过期警告

概念:标记过时方法。如果使用该方法,会报编译警告。 在开发中,我们经常能遇到这样的情况,如下图:

在jdk中有大量这样的方法,我就不举例了,自己写一个可能会更加方便理解。

public class Annotation1 extends Object{
    public static void main(String[] args) {
        testDeprecated.toString1();
    }
}
class testDeprecated {
    @Deprecated
    public static String toString1(){
        return "我是重新定义过的toString方法";
    }
}

注意点: 这个不是报错,只是警告,提醒我们这个方法可能会有问题,可能有更好的方法来实现!

3、@SuppressWarnings 忽略警告

概念:指示编译器去忽略注解中声明的警告。

平时开发中,我们会遇到这样的情况,如下图:

这也不是错误,这是提醒我们,该方法没有使用到,警告提醒的作用。 加上@SuppressWarnings注解后。

public class Annotation1 extends Object{
    public static void main(String[] args) {

    }
    @SuppressWarnings("all")
    public static void testSuppressWarnings(){
        System.out.println("测试+testSuppressWarnings忽略警告!");
    }
}

方法成功高亮起来,并且没有警告提示了!

我们可以点进去看下这个注解为什么需要参数?

看这里,这个不是方法哦,这是参数。

在注解中的参数格式:calss + 参数名 + ()! 这个需要强行记忆哦,回头我们自定义注解时也需要用到。 换一种写法加深理解!如下图:

注意点:当注解中只有一个参数时,我们无需加上参数名,注解会自动帮我们匹配的。

具体参数参考点击这里哦

二、元注解

概念:顾名思义,元注解就是给注解使用的注解!

1、@Retention 作用域-(常用)

概念:表示在什么级别保存该注解信息。 在实际开发中,我们一般都写RUNTIME,除非项目有特殊需求! 我们看下@Retention的源码。

可以看到,需要一个参数,进参数瞅瞅。

SOURCE: 源代码时有用。

CLASS: class文件中有用,但会被jvm丢弃。

RUNTIME: 运行时有用。

关系:RUNTIME>CLASS>SOURCE

后面我们自定义注解时,每个都需要用该注解!

2、@Documented 作用文档

概念:将此注解包含在 javadoc 中 ,它代表着此注解会被javadoc工具提取成文档。

老规矩看下源码:

无参的注解,作用域为RetentionPolicy.RUNTIME,运行时有用!这个只是用来作为标记,了解即可,在实际运行后会将该注解写入javadoc中,方便查看。

3、@Target 目标-(常用)

概念: 标记这个注解应该是使用在哪种 Java 成员上面!

参数源码:

注意这里是数组格式的参数,证明可以传多个值。

@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)——包

我们来试一下:

目标不对会报错的哦!我们将其改成方法上!编译即正常通过。

其他的作用域大家可以去自行尝试,篇幅问题,无法做到每个都去试一遍!

4、@Inherited 继承

概念:标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)。

这个很简单,就是当@InheritedAnno注解加在某个类A上时,假如类B继承了A,则B也会带上该注解。

4、新注解-(了解即可)

从 Java 7 开始,额外添加了 3 个注解:

@SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。

@FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。

@Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。

三、自定义注解

我们来定义一个属于自己的注解。

@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
@Inherited
@interface myAnnotation {
    String name() default "";
    int age() default 18;
    String like();
    String IDCard() default "";
}

格式:修饰符(pulic)+ @interface +注解名+ {参数等}

可利用default 设置默认值,设定了默认值后使用注解时不传值也不会报错,反之报错!

我们只需要传没有默认值的参数即可。

如果不传则报错:

总结

主要就是要注意元注解的使用,因为我们自定义注解时必须得用到! 其实注解主要配合反射来用,在此就不展开来叙述了。

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/378.html

标签: 注解的作用
分享给朋友:

“玩转Java注解-元注解、内置注解、自定义注解的原理和实现” 的相关文章

Gitlab+Jenkins通过钩子实现自动部署web项目,图文详细教程

扩展参考:Jenkins+Gitlab通过脚本自动部署回滚web项目至集群 一:基础环境介绍及准备1):Gitlab服务器:ubuntu 192.168.152.131 ---参考搭建:Linux安装gitlab,docker安装gitlab教程2):Jenkins服务器:ubunu 192.168...

一次Java内存占用高的排查案例,解释了我对内存问题的所有疑问

问题现象7月25号,我们一服务的内存占用较高,约13G,容器总内存16G,占用约85%,触发了内存报警(阈值85%),而我们是按容器内存60%(9.6G)的比例配置的JVM堆内存。看了下其它服务,同样的堆内存配置,它们内存占用约70%~79%,此服务比其它服务内存占用稍大。那为什么此服务内存占用稍大...

多项修正 尼康D4s发布最新1.10版固件

尼康公司与2014年8月27日发布了D4s的最新固件,固件版本号为C:1.10。这次固件升级,主要解决了一些BUG,并且对拍摄菜单与相机操作做了一定调整。下面是本次新固件的具体信息:尼康发布D4s最新C固件 1.10版对C固件升级到1.10版所作的修改:当选定运动VR模式并换上 AF-S 尼克尔 4...

有效地简化导航-Part 1:信息架构

「四步走」——理想的导航系统要做一个可用的导航系统,网页设计师必须按顺序回答以下4个问题:1. 如何组织内容?2. 如何解释导航的选项?3. 哪种导航菜单最适合容纳这些选项?4. 如何设计导航菜单?前两个问题关注构建和便签内容,通常称为信息架构。信息架构师通常用网站地图(site map diagr...

学前端,这30个CSS选择器,你必须熟记

你学会了基本的id,class类选择器和descendant后代选择器,然后就觉得完事了吗?如果这样,你就会错过许多灵活运用CSS的机会。虽然本文提到的许多选择器都属于CSS3,并且只能在现代的浏览器中使用,但学会这些是大有好处的。什么是CSS选择器呢?每一条css样式定义由两部分组成,形式如下:[...

Vue页面传参详解

一、两种方式方法1:name跳转页面this.$router.push({name:'anotherPage',params:{id:1}})另一页面接收参数方式:this.$route.params.id示例:控制台展示:方法2:path跳转页面this.$router.push(...