前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用了这么多年的注解,你知道注解是干嘛的嘛?

用了这么多年的注解,你知道注解是干嘛的嘛?

作者头像
框架师
发布2020-07-20 16:18:25
5760
发布2020-07-20 16:18:25
举报
文章被收录于专栏:墨白的Java基地墨白的Java基地

正文

引言: 最近入职了新公司,前期比较忙,公司的项目用到了很多自定义注解,自定义注解由于是公司架构设计的,所以和同事沟通中发现很多小伙伴对注解一知半解,晚上在公司加了会班,发布这篇关于注解的文章,希望有帮助到你

什么是注解?

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

注解的作用

注解可以用来说明程序,给计算机解释,并非给开发人员看的,注解也可以用来被其他程序读取

注解的格式

注解格式为"@注解名称",在代码中存在,可以添加一些参数,如下:

代码语言:javascript
复制
@SpringBootApplication
public class SpringBootAdminClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootAdminClientApplication.class, args);
    }
}
  • Annotnation在哪里使用?

可以附加在package,class,method,field等上面,相当于给他们添加了额外的辅助信息,可以通过反射机制编程实现对这些元数据的访问

  • 作用分类:

编写文档:通过代码里标识的注解生成文档【生成文档doc文档】 代码分析:通过代码里标识的注解对代码进行分析【使用反射】 编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查【Override】

  • 常见注解:

  • @author:用来标识作者名,eclipse开发工具默认的是系统用户名。
  • @since: 从那个版本开始
  • @version:用于标识对象的版本号,适用范围:文件、类、方法。
  • @Override:用来修饰方法声明,告诉编译器该方法是重写父类中的方法,如果父类不存在该方法,则编译失败。

自定义注解

自定义注解: 注解本质上就是一个接口,该接口默认继承Annotation接口

代码语言:javascript
复制
public interface MyAnno extends java.lang.annotation.Annotation {}
  • 自定义注解
代码语言:javascript
复制
// 空注解
public @interface Mobai{
}
  • 含参数的注解

只能使用Java提供的基本数据类型,String可以,Class可以,枚举类,其他暂未测试,包装类不可以.自定义类不可以

代码语言:javascript
复制
public @interface Anno02 {
    // 属性
    String name();
    double price() default 99;
    String[] authors();

//    Anno01 abc(); // 注解
//    WeekDay w();
//    Class p();
}
enum WeekDay {
    SUN, MON
}
class Person {
}

注解的属性类型以及使用自定义注解

只能包含八种基本数据类型,String可以,注解,枚举,Class,或者以上类型的一堆数组,自定义类不可以

  • 注解可以用来保存数据
  • 使用自定义注解格式:

@注解名(属性名=属性值, 属性名=属性值) 需要注意的是:注解的属性可以有默认值,当使用注解时不赋值就使用默认值,赋值就按照赋的值

  • 定义注解
代码语言:javascript
复制
public @interface MoBai {
    // 名字
    String name();

    // 默认属性
    String value() default "框架师";
}
  • 使用注解
代码语言:javascript
复制
public class AnnactionTest {

    @MoBai(name = "墨白",value = "")
    public static void main(String[] args) {
    }

    @Test
    public void annTest(){
    }
}

自定义注解的特殊情况

当注解只有一个属性,并且属性名是value时,在使用注解时可以省略属性名

  • 自定义注解
代码语言:javascript
复制
public @interface MoBai {
    String value();
}
  • 使用注解
代码语言:javascript
复制
@MoBai("abc")
public class Demo11 {
    @MoBai(value = "abc")
    public static void main(String[] args) {
    }
}

元注解

@Target @Retention 什么是元注解:修饰注解的注解叫做元注解

@Target注解

这个注解默认情况下可以放在任意位置,也可以限制注解放在那些位置 @Target(ElementType.TYPE) 注解只能放在类或者接口上 @Target(ElementType.CONSTRUCTOR) 注解只能放在构造方法上 @Target(ElementType.FIELD) 注解只能放在成员变量上 @Target(ElementType.METHOD) 注解只能放在成员方法上 @Target(ElementType.LOCAL_VARIABLE) 注解只能放在局部变量上 具体可以看一下源码,源码解释的比较详细

@Retention

这个注解默认是存在Class阶段,并且限制了注解存活时间;如下 SOURCE = = = = = = = = = = >>CLASS = = = = = = = = = = = = = >>RUNTIME 源代码阶段(.java) = = = = >>编译 = = = >>.class = = = = = = >>运行

  • 自定义注解
代码语言:javascript
复制
//@Target(ElementType.TYPE) // 注解只能放在类或者接口上
//@Target(ElementType.CONSTRUCTOR) // 注解只能放在构造方法上
//@Target(ElementType.FIELD) // 注解只能放在成员变量上
//@Target(ElementType.METHOD) // 注解只能放在成员方法上
//@Target(ElementType.LOCAL_VARIABLE) // 注解只能放在局部变量上
@Retention(RetentionPolicy.RUNTIME)
public @interface MoBai {
}
  • 使用注解
代码语言:javascript
复制
@MoBai
public class Demo12 {
    @MoBai
    private String a;

    @MoBai
    public Demo12() {

    }

    @MoBai
    public static void main(String[] args) {
        @MoBai
        int x = 10;
    }
}

注解的解析

  • 什么是注解解析

  • 获取注解中保存的数据
  • 注解解析相关接口
代码语言:javascript
复制
AnnotatedElement接口中:
Annotation getAnnotation(Class annotationClass) 获取一个注解**
Annotation[] getAnnotations()  获取多个注解
boolean isAnnotationPresent(Class annotationClass) 判断有没有指定的注解

注意: Constructor , Field , Method实现了AnnotatedElement接口

如何解析注解

  • 注解在谁头上,就用谁来获取注解
  • 注解在构造方法上,使用Constructor对象获取注解
  • 注解在成员方法上,使用Method对象获取注解
  • 注解在成员变量上,使用Field对象获取注解
  • 使用反射
  • 创建自定义注解
代码语言:javascript
复制
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * Software:IntelliJ IDEA 2020.1 x64
 * Author: MoBai·杰
 * [@]Interface:MoBook
 * 注解描述: 自定义注解
 */
// 限定方法使用
@Target(ElementType.METHOD)
// 活到运行时候
@Retention(RetentionPolicy.RUNTIME)
public @interface MoBook {
    String name();

    double price();

    String[] authors();
}
  • 定义数据类使用注解
代码语言:javascript
复制
/**
 * Software:IntelliJ IDEA 2020.1 x64
 * Author: MoBai·杰
 * ClassName:Book
 * 类描述: 书籍类
 */
public class Book {
    @MoBook(name = "框架师", price = 25.0, authors = "墨白")
    public void sell() {

    }
}
  • 测试类
代码语言:javascript
复制
public class TestMoBook {
    public static void main(String[] args) throws Exception {
        // 1.获取Class对象
        Class className = Class.forName("com.mobai.annion.Book");
        // 2.获取Method对象
        Method method = className.getMethod("sell");
        // 3.通过method对象获取注解
        Annotation[] annotations = method.getAnnotations();
        // 4.遍历数组
        for (Annotation annotation : annotations) {
            System.out.println("annotation = " + annotation);
        }
        // 3.3 boolean isAnnotationPresent(Class annotationClass)
        //  判断有没有指定的注解
        boolean b = method.isAnnotationPresent(MoBook.class);
        System.out.println(b);
        if (b) {
            // 3.2 Annotation getAnnotation(Class annotationClass) 获取一个注解
            MoBook ann = method.getAnnotation(MoBook.class);
            System.out.println(ann.name() + "::" + ann.price() + "::" + Arrays.toString(ann.authors()));
        }
    }
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 框架师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云代码分析
腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档