首页 > 解决方案 > kotlin null 安全容器'是一个可变属性,此时可能已更改

问题描述

class ExchangeRatesServiceImpl : ExchangeRatesService {

    private var container: ExchangeRatesContainer? = null

    /**
     * {@inheritDoc}
     */
    override val currentRates: Map<Currency, BigDecimal>
        get() {
            if (container == null || container.date != LocalDate.now()) {
                container = client.getRates(Currency.getBase())
                        log.info("exchange rates has been updated: {}", container)
            }
            return ImmutableMap.of<Currency, BigDecimal>(
                    Currency.EUR, container.rates[Currency.EUR.name],
                    Currency.RUB, container.rates[Currency.RUB.name],
                    Currency.USD, BigDecimal.ONE
            )
        }
}

line if (container == null || container.date != LocalDate.now()) 错误【因为 'container' 是一个可变属性,此时本可以更改】</p>

我该如何编译它?

标签: kotlin

解决方案


container在函数范围之外声明,因此理论上另一个线程可以在您检查null然后使用它之间修改它。为了防止这种情况,您应该创建一个初始化为 的局部变量container,并像这样使用它:

class ExchangeRatesServiceImpl : ExchangeRatesService {

private var container: ExchangeRatesContainer? = null

/**
 * {@inheritDoc}
 */
override val currentRates: Map<Currency, BigDecimal>
    get() {
        val tempContainer = container
        if (tempContainer == null || tempContainer.date != LocalDate.now()) {
            tempContainer = client.getRates(Currency.getBase())
                    log.info("exchange rates has been updated: {}", tempContainer)
        }
        return ImmutableMap.of<Currency, BigDecimal>(
                Currency.EUR, container.rates[Currency.EUR.name],
                Currency.RUB, container.rates[Currency.RUB.name],
                Currency.USD, BigDecimal.ONE
        )
    }
}

推荐阅读