一緒に書く習慣をつけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して3日目です。クリックしてイベントの詳細をご覧ください。
1.シングルトン実装の3つの方法
object
最初にコードを見てください:
object Pro {
}
复制代码
Proのシングルトンを実現するのはとても簡単です。それをJavaコードに逆コンパイルして、特定の実装原理を確認できます。
public final class Pro {
@NotNull
public static final Pro INSTANCE;
private Pro() {
}
static {
Pro var0 = new Pro();
INSTANCE = var0;
}
}
复制代码
まずPro
、クラスのコンストラクターがとして宣言されprivate
ます。次に、これが静的コードブロックによって実装されたシングルトンであることがわかります。クラスの静的コードブロックが1回だけ実行されるという機能を使用して、クラスはに属します线程安全且饿汉式
。 ;
Javaでは、Pro.INSTANCE
このシングルトンが取得されますが、kotlinは直接Pro
シングルトンを取得します
lazy
最初のコード:
class Pro private constructor() {
companion object {
val INSTANCE by lazy {
Pro()
}
}
}
复制代码
これは主に、コンパニオンオブジェクトによって静的変数として宣言されたプロパティを使用し、lazyのデフォルトの実装モードはロックスレッドセーフです。これは线程安全且懒汉式
シングルトン実装です。詳細については、Kotlin開発プラクティスの1つlazy
を参照してください。
- ダブルチェックロック
上記のコード:
@Volatile
var singleton: Pro? = null
fun getInstance(): Pro {
if (singleton == null) {
synchronized(Pro::class.java) {
if (singleton == null) {
singleton = Pro()
}
}
}
return singleton!!
}
复制代码
上記は、Javaダブルチェックロックのkotlin実装です。ここで:
@Volatile
コード命令の順序を保証するgetInstance
初期化が完了していることを確認するために、メソッドの内層と外層はsingleton
空singleton
であり、スレッドはロックを競合する必要はありません。getInstance
メソッドの内層はsingleton
空であり、前のスレッドが初期化されている場合singleton
、後続のスレッドが再度初期化されないようにします。
ご覧のとおり、これは线程安全且懒汉式
ある意味で実装されたシングルトンです。
2.typealias
複合型のエイリアスを取得します
このtypealias
キーワードは、主にタイプにエイリアスを与えるために使用されます。次の2つの使用シナリオを以下に説明します。
- 関数型エイリアス
日常の開発では、次のような関数型を一般的に使用する必要があります。
//拼接Int和String类型并返回String类型
val block: ((Int, String) -> String)? = null
复制代码
この関数型(Int, String) -> String)
は書くのが面倒で読みにくいので、今度はtypealias
次のものをアップロードします。
typealias Concat = (Int, String) -> String
val block: Concat? = null
复制代码
(Int, String) -> String)
使い勝手が良いだけでなくConcat
、この関数タイプの使用シナリオを簡単に確認できます。スプライシング
- 簡略化された汎用パス
を使用する場合ViewModel
、インターフェイスの戻り値を次のようにカプセル化することがよくあります。
class MainViewModel: ViewModel() {
val data: MutableLiveData<Response<String>> = MutableLiveData()
fun test() {
data.value = Response("haha")
}
data class Response<T>(val data: T? = null)
}
复制代码
Response
サーバーの戻り値をカプセル化するために使用されるジェネリック型T
は、応答データを逆シリアル化できるエンティティークラスを表します。
上記のように、各定義はジェネリック型でMutableLiveData
宣言する必要があります。これは、すべてのインターフェイス応答の統一されたカプセル化であり、明確な型であり、その中の型は動的に指定する必要がある型であるためです。作成された時間。Response<T>
Response
Response<T>
T
MutableLiveData
省略できますか?Response<T>
アップロードする時が来ました:Response
typealias
typealias ExternalLiveData<T> = MutableLiveData<MainViewModel.Response<T>>
复制代码
したがって、作成するたびMutableLiveData
に、次のように記述できます。
val data1: ExternalLiveData<String> = MutableLiveData()
复制代码