遅延初期化
2482 ワード
科特林は遅延初期化を使用し、これはクラスのコードの中でNullable(?)である.処理が乱用されるのを防止する.
初期化を遅らせるためのlatinitとlazyを見てみましょう.
lateinit
場合によっては、クラス内の変数(property)のみがNullableとして事前に宣言され、後で初期化(ジェネレータ呼び出し)する必要があります.
latinitキーワードはこの場合に使用されます.
Lateinitを使用してSafe Callを使用せずにエンコードを試みます. varと宣言されたクラスのpropertyにのみ使用できます. nullは許可されていません. 基本資料型Int、Long、Double、Floatなどは利用できません. 注意すべき点.
lateinitは変数のみを事前に宣言する方法なので、初期化されていない場合にメソッドまたはpropertyを参照するとnull異常が発生し、アプリケーションが終了します.
変数が初期化されていない場合は、NullableまたはNull値を使用して初期化することが望ましい.
lazy
Lazyは,読み出し前の変数としてvalを用いた遅延初期化である.
latinitは入力値を変更できますが、lazyは入力値を変更できません.
使い方も少し違います.
by lazyを使用すると、戻り値のタイプを推定できるので、前のコードで作成したperson変数のタイプを省略できます.
怠け者の特徴注記に記載されているように、宣言時に初期化コードが一緒に記述されるので、追加の初期化は必要ありません. lazyと宣言された変数を最初に呼び出すとbylazyの値に初期化されます.前述のコードでは,Companyクラスが初期化されても,それをPerson()に直接初期化するのではなくprocessメソッドでpersonを初期化する.nameが呼び出されると初期化されます. Lazyは注意して使用する必要があります.
遅延初期化は、最初の呼び出し時に初期化操作が発生するため、初期化に使用するリソースが大きすぎる(メモリが多すぎるか、コードが複雑すぎる)と、全体の処理速度に影響を与える可能性があります.
たとえば,前述のCompanyクラスで扱うPersonクラスコードが複雑であればPersonに限る.nameを呼び出すには数秒かかる場合があります.
したがって、複雑なコードを持つクラスでは、事前に初期化して使用することが望ましい.
小テスト
lateinitを使用する場合、変数のみが事前に宣言され、初期化されていない場合にメソッドまたはpropertyを参照するとnull例外が発生します.
すなわち、initブロック内にはcandy変数、candyが初期化されていない.名前を使用してpropertyを参照したためnull異常が発生し、エラーが発生しました.
初期化を遅らせるための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の特徴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変数のタイプを省略できます.
怠け者の特徴
遅延初期化は、最初の呼び出し時に初期化操作が発生するため、初期化に使用するリソースが大きすぎる(メモリが多すぎるか、コードが複雑すぎる)と、全体の処理速度に影響を与える可能性があります.
たとえば,前述のCompanyクラスで扱うPersonクラスコードが複雑であればPersonに限る.nameを呼び出すには数秒かかる場合があります.
したがって、複雑なコードを持つクラスでは、事前に初期化して使用することが望ましい.
小テスト
class Market {
lateinit var candy : Candy
init{
Log.d("Candy", "사탕의 이름은 ${candy.name} 입니다.")
}
}
次のコードを実行するとエラーが発生します.理由は何ですか?lateinitを使用する場合、変数のみが事前に宣言され、初期化されていない場合にメソッドまたはpropertyを参照するとnull例外が発生します.
すなわち、initブロック内にはcandy変数、candyが初期化されていない.名前を使用してpropertyを参照したためnull異常が発生し、エラーが発生しました.
Reference
この問題について(遅延初期化), 我々は、より多くの情報をここで見つけました https://velog.io/@lsysysy/지연-초기화テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol