Androidに次のKotlinクラスがあります。
class ThisApplication: Application() {
lateinit var network: INetwork
override fun onCreate() {
super.onCreate()
network = Network()
}
}
これで、外部クラスは次のようにするだけでINetwork参照を取得できます。
application.network
ただし、これにより、外部クラスがその値を上書きすることも可能になります。
application.network = myNewNetworkReference
2番目のオプションは避けたいです。残念ながら、フィールドの初期化はval
コールバック内で行う必要があるため、フィールドをonCreate
にすることはできません。
また、フィールドをプライベートにして、次のような関数を使用して公開することも考えました。
private lateinit var network: INetwork
fun getNetwork() = network
ただし、getNetwork()を呼び出す人は誰でも、次のように新しい値を割り当てることができます。
application.getNetwork() = myNewNetworkReference
ネットワークフィールドを外部クラスによって読み取り専用にする方法を教えてください。またはさらに良いことに、コンストラクター内で初期化できない場合でも、それをval
にする方法はありますか?
外部クラスからのアクセスを制限するために、アクセサーの可視性を変更できます。あなたの場合、private
セッターとpublic
ゲッターとlateinit
修飾子が必要です。
_lateinit var network: INetwork
private set
_
または、読み取り専用の遅延プロパティ:
_val network: INetwork by lazy { Network() } //you can access private property here, eg. applicationContext
_
このコードについてあなたからいくつかの誤解があります:
_private lateinit var network: INetwork
fun getNetwork() = network
_
Kotlinはpass-by-valueであり、 Javaが行う です。したがって、application.getNetwork() = myNewNetworkReference
は有効なステートメントではありません。関数の戻り値に値を割り当てることはできません。
実際の変数とは別に、ゲッター/セッターの可視性を変更できます。
lateinit var network: INetwork
private set
val network: INetwork by lazy { ... }
あなたのシナリオで機能しますか?
ラムダ式は、フィールドnetwork
への最初の参照で呼び出されます。明らかに、これはOnCreate
メソッドの初期化を延期することと同じではありませんが、コンストラクターで初期化せずにval
にする方法です。
他の委任の選択肢もあります。 Kotlinのドキュメント チェックする価値があります。