2016-12-05 7 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) 
    } 
} 

しかし、私はsetEditor(getDefaultEditor())initブロック内のコードを置き換える場合、コンパイラはプロパティが初期化されなければならない「、と文句を言うだろうので、インスタンス化せずにプロパティを初期化するために、initブロックを持っている必要がありますか抽象的である "。 init内のすべてのものを複製することを避けるにはどうすればよいですか?

+0

ねえ。このコミュニティをより良くするためにいくつかの答えを受け入れてください:) – mklimek

答えて

3

lateinitを使用すると、コンパイラは「後でそのプロパティを初期化します」と言うことができます。

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

次に、あなたはinitブロック内の初期化を省略し、いつでも好きなときにそれを行うことができます。

公式ドキュメントからの通知:修飾子は(ない主なコンストラクタで)クラスの 本体内で宣言のvarプロパティにのみ使用することができ

、および プロパティがないだけカスタムゲッターまたはセッターを持っています。 プロパティの型はnullでなく、プリミティブ型であってはなりません。

初期化される前にlateinitプロパティにアクセスすると、 のアクセスされるプロパティとそれが初期化されていないという事実を明確に識別する特別な例外が にスローされます。

+0

私はlateinitがこの場合にはうまくいかないと思います。 – Jacob

+0

@Jacobそれは:) – mklimek

+0

ありがとう!プロパティがプリミティブ型の場合はどうですか? – breandan

0

明示的に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()) 
} 
関連する問題