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

Kotlin中Elvis运算符(空合并运算符)为何出现异常行为?

Kotlin 1.8.0中空合并链式调用的异常行为

问题描述

在selectedLanguage和configManager.get().agency均为null的场景下,两段逻辑看似一致的Kotlin代码表现完全不同:

异常代码(调用时返回null)

companion object {
    private const val DEFAULT_LANGUAGE_CODE = "en-us"
}

val currentLanguageCode: String
get() {
    return selectedLanguage?.code ?: configManager.get().agency?.language ?: DEFAULT_LANGUAGE_CODE
}

正常代码(调用时返回默认值"en-us")

val currentLanguageCode: String
get() {
    val selectedCode = selectedLanguage?.code
    val configCode = configManager.get().agency?.language
    return selectedCode ?: configCode ?: DEFAULT_LANGUAGE_CODE
}

反编译分析

我把两段代码转成字节码再反编译为Java,从结果看两段逻辑应该是等价的,但实际运行结果却不同:

正常代码反编译后的Java实现

// 正常工作版本
public final String getCurrentLanguageCode() {
   CommunityLanguage var10000 = this.selectedLanguage;
   String selectedCode = var10000 != null ? var10000.getCode() : null;
   ConfigAgency var3 = ((CaptureConfig)this.configManager.get()).getAgency();
   String configCode = var3 != null ? var3.getLanguage() : null;
   String var4 = selectedCode;
   if (selectedCode == null) {
      var4 = configCode;
   }

   if (var4 == null) {
      var4 = "en-us";
   }

   return var4;
}

异常代码反编译后的Java实现

// 返回null的异常版本
public final String getCurrentLanguageCode() {
   String var1;
   label18: {
      CommunityLanguage var10000 = this.selectedLanguage;
      if (var10000 != null) {
         var1 = var10000.getCode();
         if (var1 != null) {
            break label18;
         }
      }

      ConfigAgency var2 = ((CaptureConfig)this.configManager.get()).getAgency();
      var1 = var2 != null ? var2.getLanguage() : null;
   }

   if (var1 == null) {
      var1 = "en-us";
   }

   return var1;
}

从反编译代码可以看到,异常版本最后同样有判断var1是否为null并赋值默认值的逻辑,但实际运行却返回了null,有没有人知道原因?


内容的提问来源于stack exchange,提问作者Matt Wolfe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 16:45:16