java屬性的初始化
在說kotlin屬性初始化之前我們先來看下java屬性的初始化
//可以不設置初始值悠菜,默認為null
private Object object;
//可以不設置初始值,默認為null败富,類創(chuàng)建時就進行默認復制
private static Object sObject;
{
object = new Object();
System.out.println("對象代碼塊");
}
//靜態(tài)代碼塊在類創(chuàng)建時就進行初始化
static {
//object須為動態(tài)的悔醋,
sObject = new Object();
System.out.println("靜態(tài)代碼塊");
}
//構造函數(shù),創(chuàng)建實例對象的時候
public UserBean() {
object = new Object();
System.out.println("構造函數(shù)");
}
大體分為成員變量初始化兽叮、靜態(tài)成員初始化芬骄、代碼塊初始化、靜態(tài)代碼塊初始化
執(zhí)行順序打印如下:
image.png
kotlin屬性初始化
-
1.類體內定義屬性鹦聪,同時初始化
image.png
從上圖可以看出账阻,編譯器直接報錯了,屬性必須要被初始化泽本。那么我們手動給他賦值為null呢淘太,再來看看:
image.png
結果編譯器還是報錯,提示null不能賦值為一個非空值,意思是name默認為非空蒲牧。寫到這里撇贺,突然想到?可以聲明修飾一個可空的屬性冰抢,于是就有了
image.png
編譯通過松嘶,說明這種方式的初始化必須的給一個非null的默認值,或者通過挎扰?指定一個null的初始值翠订,初始值為null時,下面使用的地方也一定要通過name?進行訪問遵倦,示例如下:
init {
name?.length
}
- 2.主構造函數(shù)內定義屬性尽超,使用傳入的參數(shù)初始化屬性
class User constructor(var name: String) {
}
- 3.類體內定義屬性,init 塊里初始化
init {
name = "haha";
}
再來看下lateinit和by lazy的區(qū)別:
lateinit
lateinit延遲初始化梧躺,lateinit只能修飾var橙弱,不能修飾val,當我們使用lateinit時就是告訴編譯器這個屬性的初始化時機由開發(fā)者把控燥狰,當我們未給這個被lateinit修飾的變量任何初始化時棘脐,
image.png
原因就是編譯器會把lateinit修飾的變量在這個類中所有方法遍歷一遍,看有沒有對它進行初始化龙致,沒初始化就會報錯蛀缝。因此lateinit修飾的變量一定是要進行初始化的
by lazy
by關鍵字在kotlin中表達的委托的概念,by lazy只是會在使用到的時候進行初始化(類似懶漢式的單例),使用代理的方式調用get/set方法目代,所以var 不能聲明by lazy修飾的屬性
class User private constructor() {
companion object{
val instance:User by lazy {
User()
}
}
}