如何显式调用一个对象的init块?
我有一个类似下面的类。 在第7行,我想直接调用init
块,但是这似乎不可能没有使用反射。
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时。 属性的类型必须是非空的,并且不能是原始类型。
在初始化之前访问lateinit属性会抛出一个特殊的异常,清楚地标识正在访问的属性以及未初始化的属性。
我不知道是否可以显式调用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()) }