面试官:什么是 Java 注解?(上)

简介: 哈喽,我是狗哥。随着开发经验的累积,我越发觉得基础真的非常重要。比如:大部分框架 (如 Spring) 都使用了注解简化代码并提高编码的效率,掌握注解是一名 JAVA 程序员必备的技能。但我发现很多工作 2、3 年的同学居然还没写过自定义注解,问起注解的原理也是一脸懵。我是很震惊的,你们咋理解代码的?基于此,今天我们就来一起学习下注解。

01 什么是注解?


Java 注解(Annotation),相信大家没用过也见过。个人理解,注解就是代码中的特殊标记,这些标记可以在编译、类加载、运行时被读取,从而做相对应的处理


注解跟注释很像,区别是注释是给人看的(想想自己遇到那些半句注释没有的业务代码,还是不是很难受?);而注解是给程序看的,它可以被编译器读取


1.1 注解的作用


注解大多时候与反射或者 AOP 切面结合使用,它的作用有很多,比如标记和检查,最重要的一点就是简化代码,降低耦合性,提高执行效率。比如我司就是通过自定义注解 + AOP 切面结合,解决了写接口重复提交的问题。


简单描述下我司防止重复提交注解的逻辑:请求写接口提交参数 —— 参数拼接字符串生成 MD5 编码 —— 以 MD5 编码加用户信息拼接成 key,set Redis 分布式锁,能获取到就顺利提交(分布式锁默认 3 秒过期),不能获取就是重复提交了,报错


640.png


如果每加一个写接口,就要写一次以上逻辑的话,那程序员会疯的。所以,有大佬就使用注解 + AOP 切面的方式解决了这个问题。只要在写接口 Controller 方法上加这个注解即可解决,也方便维护


1.2 注解的语法


以我司防止重复提交的自定义注解,介绍下注解的语法。它的定义如下:


// 声明 NoRepeatSubmit 注解
@Target(ElementType.METHOD) // 元注解
@Retention(RetentionPolicy.RUNTIME) // 元注解
public @interface NoRepeatSubmit {
 /**
     * 锁定时间,默认单位(秒)
     */
 long lockTime() default 3L;
}


Java 注解使用 @interface 修饰,我司的 NoRepeatSubmit 注解也不例外。此外,还使用两个元注解。其中 @Target 注解传入 ElementType.METHOD 参数来标明 @NoRepeatSubmit 只能用于方法上@Retention(RetentionPolicy.RUNTIME) 则用来表示该注解生存期是运行时,从代码上看注解的定义很像接口的定义,在编译后也会生成 NoRepeatSubmit.class 文件。


1.3 注解的元素


定义在注解内部的变量,称之为元素。注解可以有元素,也可以没有元素。像 @Override 就是无元素的注解,@SuppressWarnings 就属于有元素的注解。


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


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


带元素的自定义注解:


@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NoRepeatSubmit {
    /**
     * 锁定时间,默认单位(秒)
     */
    long lockTime() default 2L;
}


1.3.1 注解元素的格式


注解的元素格式如下:


// 基本格式
数据类型 元素名称();
// 带默认值
数据类型 元素名称() default 默认值;


1.3.2 注解元素的数据类型


注解元素支持如下数据类型:


所有基本类型(int,float,boolean,byte,double,char,long,short)
String
Class
enum
Annotation
上述类型的数组


声明注解元素时可以使用基本类型但不允许使用任何包装类型,同时注解也可以作为元素的类型,也就是嵌套注解


1.3.3 编译器对元素默认值的限制


遵循规则:


  • 元素要么具有默认值,要么在使用注解时提供元素的值。
  • 对于非基本类型的元素,无论是在源代码中声明,还是在注解接口中定义默认值,都不能以 null 作为值。


1.4 注解的使用


注解是以 @注释名 的格式在代码中使用,比如:以下常见的用法。


public class TestController {
    // NoRepeatSubmit 注解修饰 save 方法,防止重复提交
    @NoRepeatSubmit
    public static void save(Object o){
        // 保存逻辑
    }
    // 一个方法上可以有多个不同的注解
    @Deprecated
    @SuppressWarnings("uncheck")
    public static void getDate(){
    }
}


在 save 方法上使用 @NoRepeatSubmit (我司自定义注解),加上之后,编译期会自动识别该注解并执行注解处理器的方法,防止重复提交;


而对于 @Deprecated@SuppressWarnings (“uncheck”),则是 Java 的内置注解,前者意味着该方法是过时的,后者则是忽略指定的异常检查。

相关文章
|
16天前
|
XML Java 编译器
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
51 7
|
2月前
|
XML Java 编译器
Java学习十六—掌握注解:让编程更简单
Java 注解(Annotation)是一种特殊的语法结构,可以在代码中嵌入元数据。它们不直接影响代码的运行,但可以通过工具和框架提供额外的信息,帮助在编译、部署或运行时进行处理。
98 43
Java学习十六—掌握注解:让编程更简单
|
1月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
21天前
|
Java 编译器 数据库
Java 中的注解(Annotations):代码中的 “元数据” 魔法
Java注解是代码中的“元数据”标签,不直接参与业务逻辑,但在编译或运行时提供重要信息。本文介绍了注解的基础语法、内置注解的应用场景,以及如何自定义注解和结合AOP技术实现方法执行日志记录,展示了注解在提升代码质量、简化开发流程和增强程序功能方面的强大作用。
59 5
|
1月前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
58 4
|
1月前
|
Java 开发者 Spring
[Java]自定义注解
本文介绍了Java中的四个元注解(@Target、@Retention、@Documented、@Inherited)及其使用方法,并详细讲解了自定义注解的定义和使用细节。文章还提到了Spring框架中的@AliasFor注解,通过示例帮助读者更好地理解和应用这些注解。文中强调了注解的生命周期、继承性和文档化特性,适合初学者和进阶开发者参考。
57 14
|
1月前
|
前端开发 Java
[Java]讲解@CallerSensitive注解
本文介绍了 `@CallerSensitive` 注解及其作用,通过 `Reflection.getCallerClass()` 方法返回调用方的 Class 对象。文章还详细解释了如何通过配置 VM Options 使自定义类被启动类加载器加载,以识别该注解。涉及的 VM Options 包括 `-Xbootclasspath`、`-Xbootclasspath/a` 和 `-Xbootclasspath/p`。最后,推荐了几篇关于 ClassLoader 的详细文章,供读者进一步学习。
36 12
|
2月前
|
架构师 Java 开发者
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
在40岁老架构师尼恩的读者交流群中,近期多位读者成功获得了知名互联网企业的面试机会,如得物、阿里、滴滴等。然而,面对“Spring Boot自动装配机制”等核心面试题,部分读者因准备不足而未能顺利通过。为此,尼恩团队将系统化梳理和总结这一主题,帮助大家全面提升技术水平,让面试官“爱到不能自已”。
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
|
1月前
|
Java 编译器
Java进阶之标准注解
Java进阶之标准注解
32 0
下一篇
DataWorks