Dart中@immutable注解的工作原理及源码查询求助
@Immutable 注解的工作原理与源码示例
1. 核心本质
@Immutable是标记型注解,本身不包含业务逻辑,作用是给编译器、静态检查工具或运行时框架提供元数据,告知目标类/对象是不可变的——即实例创建后,内部状态无法被修改。
2. 不同语言的实现与源码
Java 生态
Java标准库没有内置@Immutable,但常见的第三方库或自定义实现如下:
自定义@Immutable注解源码
import java.lang.annotation.*; // 注解可作用于类、接口、枚举 @Target({ElementType.TYPE}) // 注解会被保留到运行时,支持反射读取 @Retention(RetentionPolicy.RUNTIME) // 子类不会继承该注解 @Inherited(false) public @interface Immutable { // 标记注解无属性,仅做标识用 }
配套运行时检查逻辑(反射实现)
如果要在运行时验证类是否符合不可变约定,可以写工具类:
import java.lang.reflect.Field; import java.lang.reflect.Modifier; public class ImmutableChecker { public static boolean isImmutable(Object obj) { Class<?> clazz = obj.getClass(); if (!clazz.isAnnotationPresent(Immutable.class)) { return false; } // 检查所有字段是否为final for (Field field : clazz.getDeclaredFields()) { if (!Modifier.isFinal(field.getModifiers())) { return false; } // 若字段是引用类型,递归检查是否也为不可变(简化版) Class<?> fieldType = field.getType(); if (!fieldType.isPrimitive() && !fieldType.isEnum() && !String.class.equals(fieldType)) { try { field.setAccessible(true); Object fieldValue = field.get(obj); if (fieldValue != null && !isImmutable(fieldValue)) { return false; } } catch (IllegalAccessException e) { return false; } } } return true; } }
Guava的@Immutable实现
Guava的@Immutable是编译期注解,核心是标记,配合Error Prone做静态检查:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.CLASS) public @interface Immutable { // 可选属性,指定是否允许子类继承 boolean allowedSubtypes() default false; }
它的作用是让Error Prone在编译时检查类是否符合不可变规则:所有字段final、无setter、引用类型字段也是不可变等。
Kotlin 生态
Kotlin的@Immutable是标准库注解,用于给编译器和序列化框架(如Gson、Jackson)提供元信息,源码如下:
@Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) public annotation class Immutable
Kotlin的数据类(data class)配合val声明的字段天然符合不可变特性,@Immutable主要是帮助第三方工具识别不可变类,优化序列化逻辑。
Python 生态
Python可通过自定义装饰器实现@Immutable效果,配合数据类使用:
from dataclasses import dataclass, FrozenInstanceError def Immutable(cls): # 替换__setattr__方法,禁止修改已存在的属性 original_setattr = cls.__setattr__ def new_setattr(self, name, value): if hasattr(self, name): raise FrozenInstanceError(f"Cannot modify immutable attribute '{name}'") original_setattr(self, name, value) cls.__setattr__ = new_setattr return cls # 使用示例 @Immutable @dataclass(frozen=False) class User: id: int name: str
3. 工作流程总结
- 编译期:静态检查工具(如Error Prone、Kotlin编译器)读取@Immutable注解,验证类是否符合不可变规则(字段final、无修改方法等),不符合则抛出编译错误。
- 运行时:框架或自定义工具通过反射读取注解,执行不可变验证(如禁止修改字段),或优化序列化/反序列化逻辑(无需处理状态变化)。
内容的提问来源于stack exchange,提问作者zbk
相关产品推荐
相关产品推荐

