Kotlin 伴生对象始终会在您尝试加载其包含类时创建,并且扩展点实现的创建开销应该很低。 插件中过多的类加载是 IDE 启动的一个大问题。
错误模式:
class KotlinDocumentationProvider : AbstractDocumentationProvider(), ExternalDocumentationProvider {
companion object {
private val LOG = Logger.getInstance(KotlinDocumentationProvider::class.java)
private val javaDocumentProvider = JavaDocumentationProvider()
}
}
这里 KotlinDocumentationProvider
是在 plugin.xml
中注册的扩展:
<lang.documentationProvider language="JAVA"
implementationClass="org.jetbrains.kotlin.idea.KotlinDocumentationProvider"
order="first"/>
在此示例中,只要有人调用 new KotlinDocumentationProvider()
,就会从磁盘加载 JavaDocumentationProvider
。
扩展点实现中的 Kotlin 伴生对象只能包含记录器和简单常量。
其他声明可能会导致过多类加载或提前初始化开销大的资源(TokenSet、Regex 等)。
加载扩展类时。
请注意,即使标记为 @JvmStatic
的声明也会为伴生对象生成一个额外的类,这可能会导致开销巨大的计算。
这些声明必须存储在对象中或处于顶层,而不是存储在伴生对象中。
将声明移到顶层:
// 正确做法,使用顶层 fun
internal fun mnRunConfigurationType(): MnRunConfigurationType = runConfigurationType<MnRunConfigurationType>()
internal class MnRunConfigurationType : ConfigurationType {
companion object { // 错误做法
fun getInstance(): MnRunConfigurationType = runConfigurationType<MnRunConfigurationType>()
}
...
之前:
internal class SpringBootImportsFileType : LanguageFileType(SPILanguage.INSTANCE, true) {
companion object {
val FILE_TYPE = SpringBootImportsFileType()
...
之后:
internal object SpringBootImportsFileType : LanguageFileType(SPILanguage.INSTANCE, true) {
...
在 plugin.xml
中使用 INSTANCE
fieldName:
<fileType name="Spring Boot Imports"
fieldName="INSTANCE"
implementationClass="com.intellij.spring.boot.spi.SpringBootImportsFileType"/>
之前:
class AntActionsUsagesCollector : CounterUsagesCollector() {
override fun getGroup(): EventLogGroup = GROUP
companion object {
private val GROUP = EventLogGroup("build.ant.actions", 1)
@JvmField
val runSelectedBuildAction = GROUP.registerEvent("RunSelectedBuild")
}
}
之后:
object AntActionsUsagesCollector : CounterUsagesCollector() {
override fun getGroup(): EventLogGroup = GROUP
private val GROUP = EventLogGroup("build.ant.actions", 1)
@JvmField
val runSelectedBuildAction = GROUP.registerEvent("RunSelectedBuild")
}
2023.3 最新变化