2016-12-05 28 views
0

我有一个类似下面的类。在第7行,我想直接调用init块,但是如果不使用反射,这似乎不可能。如何显式调用对象的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块,以便没有实例初始化属性,所以如果我更换init块与setEditor(getDefaultEditor())中的代码,那么编译器会抱怨说,“属性必须被初始化或抽象“。我如何避免重复init中的所有内容?

+0

嘿。接受一些答案,使这个社区更好:) – mklimek

回答

3

您可以使用lateinit要说到编译器的“我以后再初始化属性”。

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

然后你就可以在init块省略初始化并做到这一点只要你想。

从官方文档的通知:

改性剂只能在 体类(不是在主构造)的内部声明无功特性被使用,并且仅当 属性不有一个自定义的getter或setter。 属性的类型必须是非空的,并且它不能是原始类型。

访问一个lateinit物业已经初始化之前抛出一个 特殊异常明确标识被访问 财产,它没有被初始化的事实。

+0

我认为lateinit不应该在这种情况下工作。 – Jacob

+0

@Jacob它会:) – mklimek

+0

谢谢!如果该属性是原始类型呢? – breandan

0

我不知道是否有可能显式调用初始化块。

但我认为这应该为你做:

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()) 
}