41. 【Java】注解:给代码“贴标签”

华为OD机试真题 2026.11.4. 新系统 【河流水系流量评估】 华为OD机试真题 新系统【河流水系流量评估】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题 【河流水系流量评估】多语言题解。 阅读详情

摘要: 本文全面解析Java注解(Annotation)的核心概念与应用实践。从内置注解(@Override、@Deprecated等)到自定义注解定义,从元注解(@Retention、@Target等)到反射读取机制,深入探讨注解在编译时检查、代码生成(Lombok)、框架配置(Spring、JUnit)、ORM映射等实际场景中的关键作用。

关键词: Java注解, 元注解, 反射, Spring框架, 自定义注解


在上一篇文章中,我们学习了反射——一种在运行时“透视”类内部结构的能力。你可以在运行时拿到一个类的所有信息:它有哪些字段、哪些方法、构造方法长什么样……

但你想过没有:如果我们能在类、方法、字段上“贴一些标签”,然后让反射代码去读取这些标签,根据标签来做不同的处理,那会发生什么?

这就是注解(Annotation) 的用武之地。

注解就像给代码贴上的“便利贴”或“标签”。它们本身不改变代码的执行逻辑,但可以被编译器、开发工具、或者运行时的反射代码读取,从而影响代码的处理方式。

你可能每天都在用注解而不自知:

@Override          // 告诉编译器:我在重写父类方法
@Deprecated        // 告诉编译器:这个方法不推荐使用了
@SuppressWarnings  // 告诉编译器:别警告这个
@Test              // JUnit:这是一个测试方法
@Autowired         // Spring:帮我把依赖注入进来

注解是 Java 生态中极其重要的基础设施。今天,我们就来彻底搞清楚注解——它是什么、怎么定义、怎么用、以及框架们是怎么通过注解+反射的组合拳来实现“魔法”的。


1. 注解是什么?—— 代码的“元数据”

注解(Annotation) 是 Java 5 引入的一种元数据机制。元数据就是“关于数据的数据”——它不改变代码本身的逻辑,而是给代码附加一些额外的信息。

打个比方:

  • 你写了一份简历(代码)。
  • 你在简历上贴了一张便签纸(注解),写着“这份简历是用于应聘 Java 开发岗位的”。
  • 简历本身的内容没变,但招聘方看到便签纸,就知道该怎么处理它了。

在 Java 中,注解可以附加在类、方法、字段、参数、局部变量、包等几乎所有代码元素上。


2. Java 内置的三个基础注解

在 JDK 中,有几个内置注解是每个 Java 程序员都应该熟悉的:

2.1 @Override

表示一个方法重写了父类或接口中的方法。它不是必需的,但加上它能帮助编译器检查你是否真的正确重写了。

public class Dog extends Animal {
    @Override   // 告诉编译器:我要重写父类的 sound()
    public void sound() {
        System.out.println("汪汪");
    }

    // 如果你写成 @Override public void sounds(),编译器会报错——因为父类没有 sounds() 方法
}

作用:防止你写错方法名或参数类型。如果你写了 @Override 但实际上没有重写任何方法,编译器会报错。

2.2 @Deprecated

标记某个元素已经“过时”了,不推荐使用。如果你使用了被标记的元素,编译器会给出警告。

public class OldUtils {
    @Deprecated
    public static void oldMethod() {
        System.out.println("这个老方法已经不推荐使用了");
    }

    public static void newMethod() {
        System.out.println("请用这个新方法");
    }
}

当你调用 oldMethod() 时,IDE 会划掉它(显示为删除线),并给出警告。这给开发者一个信号:这个 API 可能会在未来的版本中被移除,你应该迁移到新方法。

2.3 @SuppressWarnings

告诉编译器“不要对某些警告发出告警”。这通常在你知道自己在做什么,但编译器会发出不必要的警告时使用。

@SuppressWarnings("unchecked")
public void process() {
    List list = new ArrayList();   // 没有泛型,编译器会警告
    // 但你知道这是安全的,所以压制警告
}

常见的警告类型有:unchecked(未经检查的转换)、deprecation(使用了过时的 API)、rawtypes(使用了原始类型)等。

2.4 @FunctionalInterface(Java 8)

标记一个接口是函数式接口(只有一个抽象方法)。编译器会检查该接口是否确实只有一个抽象方法。

@FunctionalInterface
public interface Calculator {
    int calculate(int a, int b);
    // 如果这里再加一个 abstract 方法,编译器会报错
}

函数式接口是 Lambda 表达式的基础——Lambda 只能用于函数式接口。


3. 自定义注解 —— 给你的代码“贴标签”

除了使用 JDK 内置的注解,你还可以定义自己的注解。语法很简单——用 @interface 关键字。

3.1 最简单的自定义注解
// 定义一个注解,名字叫 Log
public @interface Log {
    // 注解里可以定义"元素"(类似方法),其实就是配置参数
}

使用:

@Log
public void doSomething() {
    // ...
}
3.2 带参数的注解

注解可以有元素(element),相当于注解的配置参数。它们看起来像方法定义,但实际上是可选的配置项。

public @interface Log {
    // 指定日志级别,默认是 "INFO"
    String level() default "INFO";
    // 是否记录方法执行时间,默认 true
    boolean recordTime() default true;
}

使用带参数的注解:

// 使用默认值
@Log
public void method1() { }

// 指定 level,recordTime 用默认值
@Log(level = "WARN")
public void method2() { }

// 指定多个参数
@Log(level = "ERROR", recordTime = false)
public void method3() { }

规则:

  • 如果注解只有一个元素,且名称叫 value,使用时可以省略元素名,直接写值。
  • 其他情况下,需要 元素名 = 值 的写法。
public @interface Author {
    String value();   // 只有一个元素,叫 value
}

@Author("张三")   // 可以省略 value=
public class Demo { }
3.3 注解元素的类型

注解的元素(参数)可以是以下类型:

  • 基本类型(int、double、boolean 等)
  • String
  • Class(用 Class<?> 表示)
  • 枚举(enum)
  • 其他注解
  • 以上类型的数组
public @interface MyAnnotation {
    int intValue();
    String stringValue();
    Class<?> classValue();
    Log logValue();              // 另一个注解
    String[] stringArray();
}

4. 元注解 —— 注解的注解

当你定义一个注解时,你还可以用元注解(meta-annotation) 来注解你的注解,告诉编译器“这个注解该怎么用”。

JDK 提供了几个关键的元注解:

4.1 @Retention —— 保留策略

指定注解在哪个阶段“存活”:

值说明
RetentionPolicy.SOURCE只存在于源代码中,编译后就被丢弃(如 @Override、@SuppressWarnings)
RetentionPolicy.CLASS编译后存在于 .class 文件中,但 JVM 运行时不可见(默认值,很少用)
RetentionPolicy.RUNTIME运行时也可见,可以通过反射读取(框架开发最常用)
@Retention(RetentionPolicy.RUNTIME)   // 运行时可以通过反射读取
public @interface MyAnnotation { }
4.2 @Target —— 使用目标

指定注解可以放在哪些地方:

值说明
ElementType.TYPE类、接口、枚举
ElementType.FIELD字段(成员变量)
ElementType.METHOD方法
ElementType.PARAMETER方法参数
ElementType.CONSTRUCTOR构造方法
ElementType.LOCAL_VARIABLE局部变量
ElementType.ANNOTATION_TYPE注解(元注解)
ElementType.PACKAGE包
ElementType.TYPE_PARAMETER泛型类型参数(Java 8+)
ElementType.TYPE_USE任何类型的使用处(Java 8+)
ElementType.RECORD_COMPONENTRecord 组件(JDK 16+)
@Target({ElementType.METHOD, ElementType.TYPE})  // 只能用在方法或类上
public @interface MyAnnotation { }
4.3 @Documented

表示这个注解应该被包含在 Javadoc 生成的文档中。

@Documented
public @interface MyAnnotation { }
4.4 @Inherited

表示如果子类没有显式标注这个注解,子类会继承父类的注解。

@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation { }

@MyAnnotation
public class Parent { }

// Child 虽然没有标注 @MyAnnotation,但会继承父类的
public class Child extends Parent { }
4.5 组合使用示例
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)          // 运行时可见
@Target({ElementType.METHOD, ElementType.TYPE}) // 可用于类和方法
@Documented                                   // 包含在 Javadoc 中
public @interface ApiOperation {
    String value();          // 接口描述
    String httpMethod() default "GET";
    int timeout() default 3000;
}

这个注解定义了一个 API 操作描述,包含描述、HTTP 方法、超时时间等配置。


5. 通过反射读取注解 —— 注解的“灵魂”

如果注解只是贴在代码上却从来不被读取,那它就没有实际意义。大多数注解的价值在于:程序在运行时(或编译时)读取注解,并根据注解内容采取不同的行为。

用反射读取 RUNTIME 保留策略的注解:

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Log {
    String level() default "INFO";
}

public class AnnotationDemo {

    @Log(level = "WARN")
    public void testMethod() {
        System.out.println("测试方法执行");
    }

    public static void main(String[] args) throws Exception {
        Class<?> clazz = AnnotationDemo.class;
        Method method = clazz.getDeclaredMethod("testMethod");

        // 1. 检查方法是否有 @Log 注解
        if (method.isAnnotationPresent(Log.class)) {
            // 2. 获取注解实例
            Log log = method.getAnnotation(Log.class);
            // 3. 读取注解中的值
            String level = log.level();
            System.out.println("找到 @Log 注解,级别:" + level);
        } else {
            System.out.println("没有 @Log 注解");
        }

        // 4. 获取所有注解
        Annotation[] annotations = method.getAnnotations();
        for (Annotation ann : annotations) {
            System.out.println("方法上的注解:" + ann);
        }
    }
}

输出:

找到 @Log 注解,级别:WARN
方法上的注解:@Log(level=WARN)

6. 注解的应用场景 —— 注解在实际项目中做什么?

6.1 编译时检查(@Override、@FunctionalInterface)

这些注解只在编译时起作用,运行时被丢弃。它们帮助编译器做静态检查,让你写更安全的代码。

6.2 代码生成(Lombok)

Lombok 是一个经典的编译期注解处理器。你写:

@Data
public class User {
    private String name;
    private int age;
}

Lombok 在编译时自动生成 getName()、setName()、toString()、equals()、hashCode() 等全部代码。你写的类很短,但编译后的字节码里什么都有。

6.3 框架配置(Spring、JUnit、Spring Boot)

这是最广泛的应用场景。框架在运行时通过反射读取注解,动态创建对象、注入依赖、控制行为。

  • Spring:@Service、@Controller、@Autowired、@Transactional
  • JUnit:@Test、@BeforeEach、@AfterEach
  • Spring Boot:@SpringBootApplication、@RestController、@GetMapping
  • Jackson:@JsonProperty、@JsonIgnore
  • Jakarta(J2EE):@WebServlet、@WebFilter
@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }
}

Spring 在启动时会扫描这些注解,自动创建 UserController 的实例,把 UserService 注入进去,并注册 HTTP 路由。

6.4 测试(JUnit 5 的 @Test)
public class CalculatorTest {
    @Test
    void testAdd() {
        assertEquals(5, calculator.add(2, 3));
    }
}

JUnit 会扫描所有标注了 @Test 的方法,并在运行时自动执行它们。

6.5 ORM 映射(Hibernate、JPA)
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue
    private Long id;

    @Column(name = "user_name", nullable = false)
    private String name;
}

Hibernate 通过反射读取这些注解,知道如何把 User 对象映射到数据库的 users 表。

6.6 可重复注解(Java 8+)和类型注解

Java 8 引入了一些增强:允许同一个注解在一个地方出现多次(@Repeatable),也允许注解用在更多地方(比如 @NonNull String name 或 List<@NonNull String>)。


7. 注解 vs 配置文件 —— 怎么选?

在早期 Java 框架(如 Spring 2.x)中,大量使用 XML 配置文件。现在的趋势是**“约定大于配置”**,用注解替代大量的 XML 配置。

对比维度注解XML 配置文件
位置在代码中,与类一起单独的文件
类型安全强类型,编译器检查弱类型,写错了可能运行时才发现
可读性直接在代码上,直观需要切换文件
修改灵活性需要修改代码重新编译修改配置文件即可,无需编译
适用范围适合类内局部配置适合跨模块、跨应用的全局配置

现代实践:大部分配置用注解(因为它就在代码旁边,直观且类型安全),只有真正需要动态调整的部分(比如数据源配置、环境变量)才用配置文件。


8. 自定义注解实战 —— 实现一个“权限检查”注解

让我们自己动手写一个有用的注解。假设我们要实现一个“权限控制”的简单框架:

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

// ---- 1. 定义注解 ----
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface RequireRole {
    String value();  // 需要的角色,如 "admin"、"user"
}

// ---- 2. 使用注解的类 ----
class UserService {
    @RequireRole("admin")
    public void deleteUser(String username) {
        System.out.println("删除用户:" + username);
    }

    @RequireRole("user")
    public void viewProfile(String username) {
        System.out.println("查看用户资料:" + username);
    }

    public void publicMethod() {
        System.out.println("公开方法,任何人都可以调用");
    }
}

// ---- 3. 模拟的“权限检查框架” ----
class SecurityFramework {
    public static void invoke(Object target, String methodName, Object... args) throws Exception {
        Method method = target.getClass().getMethod(methodName, 
            java.util.Arrays.stream(args).map(Object::getClass).toArray(Class[]::new));

        // 检查方法上是否有 @RequireRole 注解
        if (method.isAnnotationPresent(RequireRole.class)) {
            RequireRole requireRole = method.getAnnotation(RequireRole.class);
            String neededRole = requireRole.value();

            // 模拟获取当前用户的角色(这里假设从某个地方读取)
            String currentUserRole = getUserRole();

            if (!currentUserRole.equals(neededRole) && !"admin".equals(currentUserRole)) {
                throw new SecurityException("权限不足!需要角色:" + neededRole);
            }
            System.out.println("✅ 权限验证通过,当前角色:" + currentUserRole);
        }

        // 执行方法
        method.invoke(target, args);
    }

    private static String getUserRole() {
        // 模拟从当前登录用户中获取角色
        return "user";  // 当前用户是普通用户
    }
}

// ---- 4. 测试 ----
public class AnnotationDemo {
    public static void main(String[] args) throws Exception {
        UserService service = new UserService();

        // 调用需要 admin 权限的方法(会失败)
        try {
            SecurityFramework.invoke(service, "deleteUser", "张三");
        } catch (SecurityException e) {
            System.out.println("❌ " + e.getMessage());
        }

        // 调用需要 user 权限的方法(会成功)
        SecurityFramework.invoke(service, "viewProfile", "李四");

        // 调用不需要权限的公开方法
        SecurityFramework.invoke(service, "publicMethod");
    }
}

输出:

❌ 权限不足!需要角色:admin
✅ 权限验证通过,当前角色:user
查看用户资料:李四
公开方法,任何人都可以调用

这个例子演示了:注解 + 反射,可以构建出非常优雅的 AOP(面向切面编程)框架——权限验证的逻辑被封装在框架里,业务代码只需要加一个 @RequireRole 注解,简洁又清晰。

Spring Security、Shiro 等框架的核心原理,跟这个例子本质上是相通的(当然它们的实现要复杂得多)。


9. JDK 21 中注解的增强

JDK 21 对注解没有重大结构性改动,但有几个值得注意的点:

  • Record 的注解支持:@Target(ElementType.RECORD_COMPONENT) 可以让注解标注在 Record 的组件上,配合反射可以读取。
  • 类型注解的持续完善:@Target(ElementType.TYPE_USE) 允许注解出现在任何类型使用的地方,比如 List<@NonNull String>。
  • @Deprecated 的增强:@Deprecated 现在有 forRemoval 和 since 参数,可以更精确地表达“即将移除”的 API。
  • @Nullable / @NonNull:虽然不是 JDK 内置的,但配合 javax.annotation 或 org.springframework.lang 的注解,在代码检查和工具中非常有用。

10. 最佳实践与注意事项

✅ 好的做法
  1. 选择合适的保留策略:如果要通过反射读取,用 RUNTIME;如果只是编译时检查,用 SOURCE。
  2. 明确注解的使用目标:用 @Target 明确限制注解可以用在什么地方,避免误用。
  3. 给注解元素提供默认值:让使用者可以只指定必要的参数。
  4. 用注解替代 XML 配置(在现代项目中)。
  5. 命名以功能为主:@Transactional、@Cacheable 一看就知道功能。
❌ 避免的做法
  1. 不要在注解中放太多逻辑:注解不应该包含复杂逻辑,只是一个声明。
  2. 不要过度使用注解:如果某个配置需要经常变动,放在配置文件中更合适。
  3. 不要依赖注解的顺序:注解的解析不保证顺序,如果你的逻辑依赖顺序,可能在不同版本中行为不同。
  4. 不要把大型数据结构放进注解:注解的元素值是编译期常量,不能太大或太复杂。

11. 今天的总结

今天我们全面学习了注解:

  • 注解是什么:代码的元数据,“贴标签”的信息。
  • 内置注解:@Override(检查重写)、@Deprecated(标记过时)、@SuppressWarnings(压制警告)、@FunctionalInterface(标记函数式接口)。
  • 自定义注解:@interface 定义,可以带参数(元素)。
  • 元注解:@Retention(保留策略)、@Target(使用目标)、@Documented、@Inherited。
  • 反射读取注解:isAnnotationPresent()、getAnnotation(),运行时读取注解参数。
  • 应用场景:编译时检查、代码生成(Lombok)、框架配置(Spring)、测试(JUnit)、ORM(Hibernate)。
  • 注解 vs XML 配置:注解适合局部配置,XML 适合全局配置。
  • 实战示例:用注解 + 反射实现权限检查的简易框架。

注解是 Java 生态中最核心的基础设施之一。它让代码更“声明式”——你不需要写一大堆 XML 配置文件,也不需要手写大量样板代码。你只需要在合适的地方“贴个标签”,框架或工具就会自动帮你完成剩下的工作。


动手试试

  1. 定义一个 @Test 注解(RUNTIME),然后写一个“简易测试框架”,扫描某个类中所有标注了 @Test 的方法,自动执行它们,并统计成功/失败的数量(如果方法抛出异常视为失败)。

  2. 定义一个 @NotNull 注解,然后写一个 Validator,通过反射遍历对象的字段,如果字段上有 @NotNull 注解且值为 null,则记录一个错误。

  3. 定义一个 @FieldAlias 注解(有一个 value 元素),然后写一个方法,接收一个对象和一个 Map<String, Object>,把 Map 中的值按别名映射到对象的字段上(提示:用反射读取字段上的 @FieldAlias 注解)。

  4. 研究 Spring 框架中 @Autowired 的实现思路(不需要深入源码,思考一下:它是怎么找到所有标注了 @Autowired 的字段/构造方法,然后注入依赖的?)

  5. (挑战)写一个 @Cache 注解,标注在方法上,表示该方法的返回值应该被缓存。实现一个 CacheProxy,用反射代理方法调用,如果缓存中有结果就直接返回,否则执行方法并缓存结果。

注解的内容就讲到这里了。下一篇文章,我们将进入一个重要的阶段实战——用我们学到的所有知识(集合、Stream、Lambda、I/O、日期时间、异常、反射、注解等)来构建一个更完整的项目。

我们下一篇见。😃

📌 获取本系列示例代码请访问 GitCode。

HyperLynx(十八)DDR(一)DDR简介和DDR的数据仿真 LVTTL电平为单端信号,而SSTL电平本质上是差分对,其实现机制是将信号与参考电平Vref组成差分对进行比较,如图所示,VIH和VIL各有一个交流参数AC和直流参数DC,信号第一次越过AC门限的时刻,作为时序计算的参考点,此后只要信号保持DC门限内,逻辑状态保持不变,这种设计减小了噪声、振铃等对于信号质量的影响。经过调整后,控制器在发送颗粒1的DQS后,延时1ns再发送颗粒2的DQS,则颗粒1在1ns后收到对齐的DQS和CLK,颗粒2在2ns后收到对齐的DQS和CLK,从而满足了时序关系。 阅读详情

相关推荐

基于Apache SeaTunnel构建CDC数据同步管道

Apache SeaTunnel是一个数据集成开发平台,其发展经历了几个重要阶段:ETL时代(90年代):面向结构化数据库的数据同步,用于构建数据仓库。MPP和分布式技术流行:使用技术如Hive进行数据仓库的构建。此阶段主要使用mapreduce程序进行数据搬运和转换。数据湖技术流行:重视数据集成,强调先同步数据至数据湖仓储,再进行业务面向的转换和设计。CDC,即变更数据捕获,是一种捕获数据库变更事件(如插入、更新、删除)的技术。

weixin_54625990的博客 2172

Spring AI + GPT-5.5 + Ollama 配置教程:Base URL、超时与流式调用

由于不同 Spring AI、Spring Boot 小版本之间仍可能存在差异,创建项目时应检查 Spring Initializr、Spring AI BOM 和官方兼容矩阵,不要直接复制旧教程中的 Starter 名称和版本号。多人项目最好隔离不同客户端,并在脱敏前提下记录最终 URL、状态码、请求耗时、请求 ID 和模型 ID。Spring AI 接入模型 API,至少要同时确认 Starter、Base URL、请求路径、API Key、模型 ID、连接超时、读取超时和流式客户端这 8 项。

2601_95893075的博客 215

麒麟V10系统下CoreDump文件自动归档与快速定位指南(附coredumpctl实战)

本文详细介绍了在麒麟V10操作系统下,如何利用systemd-coredump机制和coredumpctl工具实现CoreDump文件的自动化管理与高效调试。内容涵盖从系统架构解析、自动化配置策略,到使用coredumpctl进行快速查询、过滤与深度分析的实战指南,旨在帮助运维人员和开发者快速定位系统崩溃的根本原因,提升问题排查效率。

gg901的博客 220

V8 机制、手写核心函数与 TypeScript 类型体操

或固定初始化(如数组先定长、对象先给全字段)保持类型与形状稳定;这些都比"换框架"更基础。只能处理纯数据(丢函数、Date、RegExp、循环引用报错)。生产级深拷贝要处理:原始值短路、循环引用、V8(Chrome / Node 的 JS 引擎)不是"解释一行跑一行"那么简单,它用。图:V8 执行流程——解释执行 + 热点优化,优化失败会 Deopt 回退。JS 内存自动管理,但"自动"不等于"不会漏"。是"固定间隔最多执行一次"。手写 Promise 是"懂异步"的试金石。是"停下后才执行最后一次",

qq_38468358的博客 326

kaggle——销量预测的baseline(M5 Forecasting - Accuracy)

前言 在刚刚结束的kaggle比赛M5 Forecasting - Accuracy中,因为是第一次参加,笔者也是花了大量的时间和精力在上面,最终拿到一块银牌(所以我拿到了大学第一个考试挂科。。。求求电磁场老师高抬贵手给点平时分放我一马吧。。。早上看到kaggle成绩异常兴奋,中午考完直接爆炸=。=),当然运气占了很大因素,这次比赛private leadboard的shake up非常大,排名波动几千名都存在的。笔者运气不错,是向上的shake:)。这里总结一下销量预测的基本流程。 从下图可以看到这次比

weixin_43901221的博客 5431

AMP架构下的核间通信:RPMSG与共享内存原理详解

本文以RK3568等异构多核硬件为例,深入浅出解析了AMP架构下核间通信的核心逻辑,阐明RPMSG并非替代共享内存,而是以共享内存为数据载体、硬件信箱为中断通知工具、VirtIO为数据管理规则,构建的标准化高层协议与框架,为开发者提供简洁API,实现不同操作系统核心间高效通信。

qq_61335271的博客 2049

【JVM】对象内存布局

HotSpot JVM 中,Java 对象内存布局由对象头(12字节,含Mark Word与压缩Klass Pointer)、实例数据及对齐填充构成,总大小为8字节倍数。对象头支持锁状态动态复用,指针压缩使引用仅4字节,但堆超32GB时失效。实例字段按类型优先级重排序以减少间隙,最小对象大小为16字节。通过JOL工具可精准验证布局,理解锁机制、GC、伪共享等底层行为。

2301_79732484的博客 147

VPI与Matlab协同仿真:相干光通信接收端DSP算法全解析

本文详细解析了如何利用VPI与Matlab协同仿真,构建完整的相干光通信接收端DSP算法处理闭环。重点介绍了从VPI导出数据后,在Matlab中实现时钟恢复、偏振解复用和载波相位估计等核心算法的步骤与原理,并阐述了如何通过误码率计算完成仿真验证,为相干光通信系统算法研究与验证提供了高效实用的方法。

ll5678的博客 608

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

要努力去发光,而不是被照亮~ 113

API安全攻防实战:从信息搜集到漏洞利用的完整路径

本文详细解析了API安全攻防实战的全过程,从信息搜集到漏洞利用,涵盖了渗透测试的核心技巧和工具使用。通过真实案例展示如何发现和利用API漏洞,如HTTP方法滥用、内容类型转换攻击等,并提供企业级防御策略和测试心得,帮助安全研究人员提升API安全防护能力。

weixin_30394981的博客 434

华为OD机试双机位C卷 - 比赛 / 评委评分 (C++ & Python & JAVA & JS & GO)

华为OD机试双机位C卷 比赛,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。华为OD机试-比赛,华为OD机考-比赛。

qq_45776114的博客 1700

Spring Boot 数据源与 MyBatis(-Plus) 自定义配置详解

本文详解 Spring Boot 中单数据源环境下 HikariCP 与 MyBatis-Plus 的自定义配置。通过手动声明 SqlSessionFactory,实现下划线转驼峰、日志输出、一级缓存策略等精细化控制。结合 HikariCP 核心参数调优(如最大连接数、连接生命周期),确保高性能与稳定性。适用于仅需访问单一数据库的场景,避免多数据源复杂性,兼顾性能与可维护性。

BADAO_LIUMANG_QIZHI的博客 190

Spring Boot集成ShardingSphere实现数据加密及数据脱敏 | Spring Cloud 48

利用ShardingSphere实现: - 数据加密 - 数据脱敏

gmHappy 1万+

LeetCode Hot 100 二叉树专题(二)3 题(Java)

本篇文章共 3 题:543. 二叉树的直径、102. 二叉树的层序遍历、108. 将有序数组转换为二叉搜索树。 每道题都统一按「① 题目分析 & 解题思路 → ② 常见解法(附代码)及讲解 → ③ 知识点总结」的顺序组织;代码使用 Java 编写,节点定义沿用 LeetCode 默认的 TreeNode。

2401_88612756的博客 352

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Decorator

TaskDecorator 是异步场景下"跨线程传递上下文"的标准方案,主要用于传递 MDC、用户信息、数据源路由等上下文数据,核心价值是让异步任务的日志链路不中断、业务上下文不丢失。TaskDecorator 是 Spring 提供的一个钩子接口,用于在异步任务执行前对 Runnable 进行包装,常用于跨线程传递上下文。如果你在项目中遇到具体的异步上下文传递问题,可以把代码贴出来,我帮你给出最合适的 Decorator 方案 👍。✅ 核心能力:在线程切换时,把"父线程的上下文"搬到"子线程"

wlwork66的博客 102

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

JDK 下载安装:装完 Java 提示「不是内部或外部命令」?环境变量没配

JDK 是写 Java 程序必须装的东西。它包含运行 Java 的虚拟机(JRE)和编译 Java 的编译器(javac)——装了它,能跑、.java文件能编译成可执行程序。免费,学习和小规模生产都不花钱。

科小怪的博客 609

数据库乐观锁深度解析:MySQL、PostgreSQL 实战 + Spring Boot 集成指南

Oracle 提供了ORA_ROWSCN伪列(System Change Number),记录最后修改行的 SCN,类似 PostgreSQL 的xmin。实践中通常仍使用 version 字段方案,逻辑与 MySQL 完全相同。-- Oracle:通过 ORA_ROWSCN 实现乐观锁-- 更新时比对 SCN// 自定义注解// AOP 切面@Aspect@Component@Slf4jtry {

yjc_1111的专栏 392

C++ 多态详解:作用、原理与实战用法

多态是C++面向对象的核心特性,通过虚函数实现运行期动态绑定,使同一接口在不同对象上表现出不同行为。其核心作用包括统一接口、提升可扩展性、降低耦合、支持运行时分派与批量处理。实现依赖虚函数表(vtable)和虚指针(vptr),需注意虚析构函数、对象切片等陷阱。相比编译期多态(模板),运行期多态灵活性高但有调用开销。合理结合两者,可兼顾代码的灵活性与性能,是构建可扩展、低耦合系统的关键。

2402_85743155的博客 369

java框架大全

java框架大全

qq_39326137的博客 180

SecureRandom做随机源,这个Java随机字符串工具类有3个方法

本文分享一款JDK17环境下的Java随机字符串工具类,内置3个开箱即用的方法,全部采用SecureRandom加密安全随机源,不存在弱随机、可预测、取模偏差等问题。工具类支持默认62字符集随机串、纯数字随机串、自定义字符集随机串三种生成模式,支持Unicode码点级别的字符集处理,兼容Emoji等增补字符,边界处理严格,异常信息明确,适合验证码、邀请码、盐值、随机口令、短链码等场景,源码可直接复制使用。

Java后端 | AI智能体应用实战派 | 电脑技能行家 291

Java实现批量线段相交检测(跨积判定+扫描线优化与踩坑复盘)

【代码】Java实现批量线段相交检测(跨积判定+扫描线优化与踩坑复盘)

m0_64476639的博客 313

Agent 状态栏在上下文中的具体位置

Agent状态栏以user角色消息形式追加至上下文末尾,而非修改system消息,避免破坏KVCache。此举仅为API技术实现,内容由框架自动生成,非真实用户输入,通过<agent_status>标签标识,确保模型获取最新状态且不影响缓存。该设计遵循“动态信息追加、静态信息固定”原则,实现高效、低延迟的状态传递。

lj1109053360的专栏 68

ubuntu安装hadoop系统

本文详细介绍了基于VMware克隆虚拟机搭建三节点Hadoop分布式集群的全过程:使用同一Ubuntu镜像克隆出master、worker1、worker2三台虚拟机,依次配置主机名、固定IP(如192.168.82.10/11/12)、SSH服务及免密登录,确保节点间网络互通。随后安装Java,下载配置Hadoop并分发至各节点,最终初始化启动集群,验证其存储与计算功能,实现高效的大数据环境部署。

qq_43592674的博客 301

Spring事务和事务传播机制

3. 可重复读(REPEATABLE READ): 事务不会读到其他事务对已有数据的修改, 即使其他事务已提交. 也就可以确保同⼀事务多次查询的结果⼀致, 但是其他事务新插⼊的数据, 是可以感知到的. 这也就引发了幻读问题. 可重复读, 是 MySQL 的默认事务隔离级别.p1事务可以认为是⽗事务, 嵌套事务是⼦事务. ⽗事务出现异常, ⼦事务也会回滚, ⼦事务出现异常, 如果不进⾏处理, 也会导致⽗事务回滚.

txxzjmzlh的博客 202

RuoyiOffice 容器化落地:镜像分层、JVM 配额与三探针的联动配置

拆解 RuoyiOffice 上容器的三道坎:多阶段镜像分层、按 cgroup 配额切分 JVM 内存、startup/liveness/readiness 三探针分工,附可复制的 Dockerfile、JVM 参数与 K8s YAML。

2301_78967866的博客 299

读懂 Dart Future:从 async/await 到并发等待

Dart 中的 Future 用于处理异步操作,如网络请求、文件读取等。它表示一次可能延迟完成的计算,成功时返回指定类型值(如 Future<String>),失败时抛出异常。通过 async/await 可以同步式编写异步代码,提升可读性。await 暂停当前函数执行,但不影响事件循环。Future.wait() 可并发等待多个异步任务,timeout() 设置超时限制,catchError() 处理错误。注意:async 不自动开启新线程,耗时计算仍可能阻塞主线程;避免丢弃未处理的 Future,必要时

侯仕奇的博客 349

【随笔】KV缓存量化:省下的显存,要付出多少数值误差

用可运行量化器解释位宽、比例信息、分组和离群值的关系,核算KV缓存实际载荷,并给出Transformers配置与容量、延迟、质量验收方法。

code2cat的博客 447
上一篇: 40. 【Java】反射:窥探类的“内在”
下一篇: 42. 【Java】阶段实战:图书管理系统
gugucoding
博客等级 码龄140天 7粉丝 102原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值