You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 04:45:44