如何显式调用一个对象的init块?

我有一个类似下面的类。 在第7行,我想直接调用init块,但是这似乎不可能没有使用reflection。

 object MyClass { var editor: Editor = getDefaultEditor() set(value) { field = value //Todo: figure out how to avoid duplicating init block project = editor.project!! document = editor.document.charsSequence.toString().toLowerCase() findModel = FindManager.getInstance(project).findInFileModel.clone() findManager = FindManager.getInstance(project) } var project: Project var document: String var findModel: FindModel var findManager: FindManager init { project = editor.project!! document = editor.document.charsSequence.toString().toLowerCase() findModel = FindManager.getInstance(project).findInFileModel.clone() findManager = FindManager.getInstance(project) } } 

但是我需要有init块来初始化属性而不需要实例化,所以如果我用setEditor(getDefaultEditor())替换init块中的代码,编译器会抱怨:“属性必须被初始化或者是抽象的”。 我如何避免重复init所有东西?

你可以使用lateinit来告诉编译器“我稍后将初始化这个属性”。

 lateinit var project: Project lateinit var document: String lateinit var findModel: FindModel lateinit var findManager: FindManager 

然后你可以在init块中省略初始化,并在需要的时候执行。

来自官方文件的通知:

修饰符只能用于在类的主体内声明的var属性(不在主构造函数中),只有当属性没有自定义getter或setter时。 属性的types必须是非空的,并且不能是原始types。

在初始化之前访问lateinit属性会抛出一个特殊的exception,清楚地标识正在访问的属性以及未初始化的属性。

我不知道是否可以显式调用init块。

但我认为这应该为你做:

 object MyClass { var editor: Editor = getDefaultEditor() set(value) { field = value init() } lateinit var project: Project lateinit var document: String lateinit findModel: FindModel lateinit var findManager: FindManager init { init() } private fun init() { project = editor.project!! document = editor.document.charsSequence.toString().toLowerCase() findModel = FindManager.getInstance(project).findInFileModel.clone() findManager = FindManager.getInstance(project) } } 

但更好的设计将是这样的:

 object MyClass { var editor: Editor = getDefaultEditor() fun getProject() = editor.project!! fun getDocument() = editor.document.charsSequence.toString().toLowerCase() fun getFindModel() = FindManager.getInstance(getProject()).findInFileModel.clone() fun getFindManager() = FindManager.getInstance(getProject()) }