遅延初期化

2482 ワード

科特林は遅延初期化を使用し、これはクラスのコードの中でNullable(?)である.処理が乱用されるのを防止する.
初期化を遅らせるためのlatinitとlazyを見てみましょう.
lateinit
場合によっては、クラス内の変数(property)のみがNullableとして事前に宣言され、後で初期化(ジェネレータ呼び出し)する必要があります.
latinitキーワードはこの場合に使用されます.
class Person {
	var name: String? = null
    init{
    	name = "Lionel"
    }
    fun process() {
    	name?.plus(" Messi")
        print("이름의 길이 = ${name?.length}")
        print("이름의 첫 글자 = ${name?.substring(0,1)}")
    }
}
変数に値を入力するメソッドまたはPropertyを使用する場合、このメソッドはセキュリティコール(?.)です.乱用されて毒性を低下させる.
Lateinitを使用してSafe Callを使用せずにエンコードを試みます.
class Person {
	lateinit var name: String
    init {
    	name = "Lionel"
    }
    fun process() {
    	name.plus(" Messi")
        print("이름의 길이 = ${name.length}")
        print("이름의 첫 글자 = ${name.substring(0,1)}")
    }
}
latinitの特徴
  • varと宣言されたクラスのpropertyにのみ使用できます.
  • nullは許可されていません.
  • 基本資料型Int、Long、Double、Floatなどは利用できません.
  • 注意すべき点.
    lateinitは変数のみを事前に宣言する方法なので、初期化されていない場合にメソッドまたはpropertyを参照するとnull異常が発生し、アプリケーションが終了します.
    変数が初期化されていない場合は、NullableまたはNull値を使用して初期化することが望ましい.
    lazy
    Lazyは,読み出し前の変数としてvalを用いた遅延初期化である.
    latinitは入力値を変更できますが、lazyは入力値を変更できません.
    使い方も少し違います.
    class Company {
    	val person: Person by lazy { Person() }
        init {
        	// lazy는 선언 시에 초기화를 하기 때문에 초기화 과정이 필요없다.
        }
        fun process() {
        	print("person의 이름은 ${person.name}") // 최초 호출하는 시점에 초기화된다.
        }
    }
    by lazyと変数タイプの省略
    by lazyを使用すると、戻り値のタイプを推定できるので、前のコードで作成したperson変数のタイプを省略できます.
    怠け者の特徴
  • 注記に記載されているように、宣言時に初期化コードが一緒に記述されるので、追加の初期化は必要ありません.
  • lazyと宣言された変数を最初に呼び出すとbylazyの値に初期化されます.前述のコードでは,Companyクラスが初期化されても,それをPerson()に直接初期化するのではなくprocessメソッドでpersonを初期化する.nameが呼び出されると初期化されます.
  • Lazyは注意して使用する必要があります.
    遅延初期化は、最初の呼び出し時に初期化操作が発生するため、初期化に使用するリソースが大きすぎる(メモリが多すぎるか、コードが複雑すぎる)と、全体の処理速度に影響を与える可能性があります.
    たとえば,前述のCompanyクラスで扱うPersonクラスコードが複雑であればPersonに限る.nameを呼び出すには数秒かかる場合があります.
    したがって、複雑なコードを持つクラスでは、事前に初期化して使用することが望ましい.
    小テスト
    class Market {
    	lateinit var candy : Candy
        init{
        	Log.d("Candy", "사탕의 이름은 ${candy.name} 입니다.")
        }
    }
    次のコードを実行するとエラーが発生します.理由は何ですか?
    lateinitを使用する場合、変数のみが事前に宣言され、初期化されていない場合にメソッドまたはpropertyを参照するとnull例外が発生します.
    すなわち、initブロック内にはcandy変数、candyが初期化されていない.名前を使用してpropertyを参照したためnull異常が発生し、エラーが発生しました.