2017-10-29 79 views
0

我正在從開發人員網站開發Android藍牙聊天項目,我正在嘗試使用Kotlin而不是java。我是Kotlin的新手,我只是對使用init塊和lateinit關鍵字以及我的伴侶對象的「正確」方式感到困惑。在我張貼的代碼中,我沒有伴侶對象,但我想知道我是否應該。到目前爲止,我主要只是使用伴侶對象來模仿java的靜態類成員,或者有時包含類常量。至於我的init塊我基本上用於構造函數。除此之外,通過類聲明中定義的實際構造函數傳遞成員的賦值。至於lateinit,我使用它來聲明我不想立即初始化的成員,但也不希望爲空。請讓我知道,如果這是正確的用法或事情的改變,如果它不是。這裏是我的代碼:何時使用lateinit,init塊和companion對象。 Kotlin

inner class AcceptThread(val secure:Boolean) : Thread(){ 
    lateinit var mmServerSocket:BluetoothServerSocket 
    lateinit var mSocketType:String 

    init { 
     var tmp:BluetoothServerSocket? = null 
     mSocketType = if (secure) "Secure" else "Insecure" 

     try { 
      if (secure){ 
       tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, UUID_SECURE) 
      } else{ 
       tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME_INSECURE, UUID_INSECURE) 
      } 
     }catch (ioe:IOException){ 
      Log.e(TAG, "Socket Type: $mSocketType listen() failed", ioe) 
     } 
     mmServerSocket = tmp!! 
     mState = STATE_LISTEN 
    } 
} 

回答

3

你不需要lateinit這裏考慮你初始化的變量中構造函數。例如,如果您想在像onCreate()這樣的生命週期方法中初始化變量,那麼您可以使用lateinit var

另外,我覺得你可以重構你的初始化塊,以消除TMP變量:

inner class AcceptThread(val secure:Boolean) : Thread() { 
val mmServerSocket: BluetoothServerSocket 
val mSocketType: String = if (secure) "Secure" else "Insecure" 

init { 
    try { 
     mmServerSocket = if (secure) { 
      mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, UUID_SECURE) 
     } else { 
      mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME_INSECURE, UUID_INSECURE) 
     } 
    } catch (ioe: IOException) { 
     Log.e(TAG, "Socket Type: $mSocketType listen() failed", ioe) 
    } 
    mState = STATE_LISTEN 
} 
+0

我與這個具有唯一的問題是,我無法使用瓦爾的mmServerSocket。我收到一條消息,說明屬性必須初始化或抽象。那麼不要使用lateinit?只要使它成爲一個可空的var?你會建議什麼? –

+0

所以很明顯,使用try-catch塊你不能使用val,考慮到try-catch意味着你不能保證獲得一個有效的變量值,這種做法有意義。所以我認爲這裏最好的做法是使用可空的var。 – ItWillDo

+0

好的謝謝你的幫助。我做了這些改變,一切工作都很順利。 –

2

請讓我知道,如果這是正確的用法或一件事情是我 變化,如果事實並非如此。

有兩件事我會指出你的代碼。

  1. ,因爲你是初始化在構造函數中兩個變量不需要在兩個mmServerSocketmSocketTypelateinit關鍵字。如果變量在創建之後被初始化,您將需要它。
  2. 有一種情況可能會引發異常。如果引發IOException,變量tmp可以爲空。在這種情況下,當您將tmp指定爲mmServerSocket時,將會拋出KotlinNullPointerException。 您有幾種可能性來解決它:你可以處理在catch塊默認情況下,可以使mmServerSocket空,等等。