Java 注解介绍

注解(Annotation)是 Java 5 引入的一种新特性,它允许在代码中嵌入元数据(metadata),即描述数据的数据。注解提供了一种不修改代码逻辑但能够影响编译过程、代码执行或工具生成的机制。注解通常用于提供附加信息,编译器或运行时可以根据这些信息进行处理。

1. 注解的基本概念

注解本身不直接影响程序的执行,它们主要用来提供额外的信息,这些信息可以在编译时、类加载时或运行时进行处理。常见的注解包括 @Override@Deprecated@SuppressWarnings 等。

注解的基本语法:

// 单行注解
@AnnotationName
public class MyClass {
    // 类定义
}
  • 注解的声明以 @ 开头,后面跟着注解的名称。
  • 注解可以应用于类、方法、字段、参数、局部变量等位置。

2. 注解的类型

2.1 内置注解

Java 提供了一些内置注解,常见的包括:

  • @Override:表示方法重写,编译器会检查是否正确重写了父类方法。
  • @Deprecated:标记某个方法或类已不再推荐使用。
  • @SuppressWarnings:抑制特定的编译器警告。

2.2 自定义注解

Java 允许用户创建自定义注解。自定义注解的语法如下:

// 定义一个简单的注解
public @interface MyAnnotation {
    String value() default "default";  // 默认值为 "default"
}
  • @interface 用来定义一个注解类型。
  • 注解可以包含方法,这些方法在使用时会提供具体值。如果没有提供,注解的方法会使用默认值。

3. 注解的应用

注解可以用于多种目的,最常见的是:

  • 标记:为类、方法、字段等提供额外信息,方便工具或框架处理。
  • 编译时检查:通过注解帮助编译器进行代码检查,增强类型安全。
  • 运行时处理:注解信息可以通过反射获取,并在运行时执行相应操作。

3.1 使用内置注解

@Override 示例
class Animal {
    public void speak() {
        System.out.println("Animal speaks");
    }
}

class Dog extends Animal {
    @Override
    public void speak() {
        System.out.println("Dog barks");
    }
}

public class OverrideExample {
    public static void main(String[] args) {
        Animal myDog = new Dog();
        myDog.speak();  // 输出: Dog barks
    }
}
  • @Override 注解用于标识 Dog 类中的 speak() 方法是重写了父类 Animal 的方法。如果方法签名不匹配,编译器会提示错误。
@Deprecated 示例
class LegacyClass {
    @Deprecated
    public void oldMethod() {
        System.out.println("This method is deprecated");
    }
}

public class DeprecatedExample {
    public static void main(String[] args) {
        LegacyClass legacy = new LegacyClass();
        legacy.oldMethod();  // 编译器会提示警告: 使用了已弃用的方法
    }
}
  • @Deprecated 注解标识该方法已不推荐使用,编译时会发出警告。
@SuppressWarnings 示例
public class SuppressWarningsExample {
    @SuppressWarnings("unchecked")
    public void uncheckedWarningMethod() {
        // Suppresses unchecked warning
        List rawList = new ArrayList();
        rawList.add("Hello");
    }
}
  • @SuppressWarnings("unchecked") 注解用于抑制编译器发出的警告。

3.2 自定义注解的使用

定义自定义注解
public @interface MyAnnotation {
    String description() default "No description";  // 默认描述
    int version() default 1;                        // 默认版本
}
在代码中使用自定义注解
@MyAnnotation(description = "This is a custom annotation", version = 2)
public class CustomAnnotationExample {

    @MyAnnotation(description = "Method annotation", version = 1)
    public void myMethod() {
        System.out.println("This is a method with custom annotation");
    }
}
  • @MyAnnotation 是一个自定义注解,它可以应用于类或方法。
  • descriptionversion 是注解的元素,表示注解的属性,可以在使用时指定。
获取注解信息(反射)

在运行时,注解可以通过反射获取,并进行相关处理。例如,可以通过反射获取类或方法的注解,并基于注解的值执行某些操作。

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class AnnotationReflectionExample {
    public static void main(String[] args) throws Exception {
        Class<?> cls = CustomAnnotationExample.class;
        
        // 获取类的注解
        MyAnnotation classAnnotation = cls.getAnnotation(MyAnnotation.class);
        if (classAnnotation != null) {
            System.out.println("Class Description: " + classAnnotation.description());
            System.out.println("Class Version: " + classAnnotation.version());
        }
        
        // 获取方法的注解
        Method method = cls.getMethod("myMethod");
        MyAnnotation methodAnnotation = method.getAnnotation(MyAnnotation.class);
        if (methodAnnotation != null) {
            System.out.println("Method Description: " + methodAnnotation.description());
            System.out.println("Method Version: " + methodAnnotation.version());
        }
    }
}

输出:

Class Description: This is a custom annotation
Class Version: 2
Method Description: Method annotation
Method Version: 1
  • 通过 Class.getAnnotation()Method.getAnnotation() 方法可以获取类和方法上的注解信息。

4. 注解的生命周期

注解的生命周期分为以下几种:

  1. 编译时注解:注解只在编译阶段存在,编译器会进行检查。
  2. 类加载时注解:注解在编译后存在于字节码中,类加载时可以被读取。
  3. 运行时注解:注解在运行时通过反射读取,程序可以根据注解进行相应的逻辑处理。

注解的生命周期由 @Retention 注解指定。

@Retention 注解

  • @Retention(RetentionPolicy.SOURCE):注解只在源代码中存在,编译后被丢弃。
  • @Retention(RetentionPolicy.CLASS):注解在编译后的字节码中存在,但不包含在运行时。
  • @Retention(RetentionPolicy.RUNTIME):注解在运行时可用,可以通过反射读取。
Retention 示例:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

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

class RuntimeAnnotationExample {
    @RuntimeAnnotation(value = "Example Annotation")
    public void annotatedMethod() {
        System.out.println("Method with runtime annotation");
    }
}

public class Main {
    public static void main(String[] args) throws Exception {
        Method method = RuntimeAnnotationExample.class.getMethod("annotatedMethod");
        if (method.isAnnotationPresent(RuntimeAnnotation.class)) {
            RuntimeAnnotation annotation = method.getAnnotation(RuntimeAnnotation.class);
            System.out.println("Annotation Value: " + annotation.value());
        }
    }
}

输出:

Annotation Value: Example Annotation
  • 通过 @Retention(RetentionPolicy.RUNTIME) 指定注解在运行时可用,允许使用反射来读取注解的值。

5. 注解与框架

在 Java 中,注解广泛应用于各种框架和库中,特别是在 SpringJUnit 等框架中。注解使得框架可以自动进行依赖注入、事务管理、单元测试等操作。

Spring 注解示例:

import org.springframework.stereotype.Component;

@Component
public class MyService {
    public void performService() {
        System.out.println("Service is performing an action");
    }
}
  • 在 Spring 框架中,@Component 注解标记类为一个 Spring 管理的组件,Spring 会自动创建并管理该对象。

JUnit 注解示例:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class MyTest {

    @Test
    public void testAddition() {
        assertEquals(2, 1 + 1);
    }
}
  • JUnit 使用 @Test 注解标记测试方法,并根据注解来自动执行测试。

6. 总结

特性 内置注解自定义注解注解的作用
常见注解 @Override@Deprecated@SuppressWarnings 自定义注解 提供元数据,编译器和框架处理注解信息
用途 编译时检查,警告抑制,方法重写标识 提供附加元数据,代码注释 增加代码可读性和灵活性,动态处理注解信息
生命周期 SOURCECLASSRUNTIME 可指定生命周期 通过反射处理注解数据,编译或运行时处理

建议:

  • 在适当的场合使用注解,尤其是当需要向框架或工具提供额外的元数据时。
  • 理解不同注解生命周期的意义,确保在运行时能访问到注解的值(使用 @Retention(RetentionPolicy.RUNTIME))。
Java碎碎念 文章被收录于专栏

来一杯咖啡,聊聊Java的碎碎念呀

全部评论

相关推荐

科大讯飞2025届春招面经汇总(技术岗+非技术岗)1.&nbsp;技术岗(Java/大数据/算法方向)面试流程:笔试&nbsp;→&nbsp;技术一面&nbsp;→&nbsp;技术二面&nbsp;→&nbsp;HR面笔试:编程题(2道,********中等难度,如动态规划、图论)八股文(数据库、操作系统、网络)项目相关(如Redis缓存优化、JWT认证)技术一面(1小时):Java基础:HashMap&nbsp;vs&nbsp;ConcurrentHashMap(底层结构、线程安全)JUC包工具类(如AQS、线程池)JWT结构及安全性问题数据库:MySQL索引优化(B+树&nbsp;vs&nbsp;Hash索引)优惠券超卖问题(分布式锁实现方案)系统设计:设计一个延迟订单取消系统(定时任务&nbsp;vs&nbsp;消息队列)技术二面(1小时):项目深挖:介绍一个高并发项目(如秒杀系统)如何优化SQL查询性能?算法题:手撕代码:合并K个有序链表(优先队列实现)时间复杂度分析及优化场景题:如何设计一个实时数据仓库(Flink+Kafka)HR面(30分钟):职业规划、加班接受度、期望薪资2.&nbsp;产品运营岗面试流程:群面&nbsp;→&nbsp;业务面&nbsp;→&nbsp;HR面群面(案例分析):设计一个AI教育产品的推广方案讨论用户增长策略(如K12市场)业务面(45分钟):项目经历:在团队中的职责、遇到的困难及解决方案最有成就感的一件事(需量化结果)行业洞察:如何看待AI+教育的发展趋势?如何发现用户需求?(用户调研/数据分析)HR面(30分钟):个人优缺点、为什么选择科大讯飞?3.&nbsp;测试工程师岗面试流程:笔试&nbsp;→&nbsp;技术一面&nbsp;→&nbsp;技术二面技术一面:测试基础:白盒测试&nbsp;vs&nbsp;黑盒测试单元测试框架(如JUnit)编程题:手写一个二分查找算法操作系统:进程&nbsp;vs&nbsp;线程(通信方式)技术二面:项目相关:如何设计自动化测试框架?遇到过哪些Bug?如何定位?场景题:如何测试一个语音识别系统?💡&nbsp;面试建议1.&nbsp;技术岗:刷题:********高频题(动态规划、链表、二叉树)八股文:重点复习JUC、MySQL索引、分布式锁项目复盘:准备1-2个高并发/大数据项目,突出优化点2.&nbsp;非技术岗:熟悉科大讯飞业务(如AI教育、医疗)准备用户增长/产品运营案例分析3.&nbsp;反问环节:可问团队技术栈、新人培养计划🌟&nbsp;科大讯飞面试特点技术岗:偏重底层原理(如HashMap红黑树转换)非技术岗:关注行业洞察与执行力HR面:可能涉及加班文化(部分岗位需接受弹性工作制)内推链接:https://campus.iflytek.com?refrenceCode=BB37621内推码:BB37621&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
点赞 评论 收藏
分享
04-26 03:01
小学 Java
时间线4-1&nbsp;投递&nbsp;&nbsp;&nbsp;&nbsp;4-21&nbsp;笔试&nbsp;&nbsp;&nbsp;&nbsp;4-25&nbsp;一面面经1.使用maven的时候包冲突什么表现,怎么解决2.写maven配置文件有用&nbsp;dependencyManagement3.java异常处理怎么处理4.throws和throw的区别5.异常处理代码块return写哪里6.catch里面写return&nbsp;finally代码块会执行吗7.RuntimeException&nbsp;和非RuntimeException&nbsp;有什么区别,分别举个例子8.new了一个对象会在堆内存的哪个区域9.new的对象很大的话10.gc的分类有哪几种11.spring&nbsp;boot的aop用的spring&nbsp;boot&nbsp;的aop还是aspectj的有什么区别12.redis一般会出现哪几种异常,怎么防止13.数据淘汰策略举几个例子14.redis使用的时候突然断电了,数据会丢失吗15.MySQL里面对一个表做左连接,左表5条数据,右表3条数据,连接结果有几条数据16.sql语句里面去重有什么语句17.从输入URL到页面展示发生了什么18.https连接端口号多少19.消息队列了解的多吗20.用mq处理消息的时候怎么保证事务的一致性(答的分布式事务)21.问了问跟着老师做的项目,需求分析和实际编码的时间占比是几比几22.cache用的什么23.redis数据和db数据的一致性,可能出现的问题和对应的解决方案24.金融这种强一致性的方案讲讲25.ai有做什么学习和了解26.大致讲讲rag的原理27.微调和rag的优劣势分别是什么28.agent有了解吗问问未来方向,学校的活动经历,兴趣爱好,在学校里面敬佩的人
阿里巴巴一面413人在聊 查看29道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务