报告将应用程序服务分配到 static final 字段/不可变属性的情况。

static final 字段 (Java) 或带支持字段的 static 不可变属性 (Kotlin)

注意:在下文中,Kotlin 中的 static 指的是非匿名对象或顶层声明的成员。

此类服务分配会导致全局状态,使得在测试中无法删除一个应用程序并设置另一个应用程序,因此,同一进程中的重复测试可能会失败。 唯一的例外是用来存储虚拟/默认实例的显式构造函数调用。

避免存储服务的推荐方式是在本地检索服务。 或者,可以将其包装在 java.util.function.Supplier(Java、Kotlin)中或将属性转换为函数 (Kotlin)。

示例 (Java):


// 错误:
private static final ManagingFS ourInstance = ApplicationManager.getApplication().getService(ManagingFS.class);

// 正确:
private static final Supplier<ManagingFS> ourInstance = CachedSingletonsRegistry.lazy(() -> {
  return ApplicationManager.getApplication().getService(ManagingFS.class);
});

// 例外:
private static final UniqueVFilePathBuilder DUMMY_BUILDER = new UniqueVFilePathBuilder()

通过 static 不可变属性检索服务实例 (Kotlin)

虽然将服务分配到没有支持字段的属性不会导致上述问题,但使用显式 getInstance() 方法检索服务比使用属性更可取:

为了获得更好的工具性能,建议始终保持显式方法返回值类型。

示例:


@Service
class MyApplicationService {
  companion object {
    @JvmStatic
    val instance: MyApplicationService // 错误
       get() = service()
  }
}

@Service
class MyApplicationService {
  companion object {
    @JvmStatic
    fun getInstance(): MyApplicationService = service() // 正确
  }
}

2023.3 最新变化