2017-10-29 10 views
0

나는 개발자의 사이트에서 안드로이드 블루투스 채팅 프로젝트를 진행하고 있으며, 자바 대신 Kotlin을 사용하려고합니다. 저는 Kotlin에 익숙하지 않습니다. 그리고 제 친구들 객체와 함께 init 블록과 lateinit 키워드를 사용하는 "올바른"방법에 대해 혼란을 느끼고 있습니다. 코드에서 나는 내가 동반자 객체를 가지고 있지 않지만 내가해야하는지 궁금해하고있다. 지금까지 나는 주로 java 클래스의 정적 클래스 멤버를 모방하거나 때때로 클래스 상수를 포함하는 방법으로 동반자 객체를 사용합니다. 내 init 블록에 대한 기본적으로 생성자를 사용하고 있습니다. 그것은 클래스 선언에 정의 된 실제 생성자를 통해 전달 된 멤버의 할당입니다. lateinit에 관해서는, 나는 그것을 초기화하여 즉시 초기화하고 싶지 않지만 nullable로 만들고 싶지 않은 멤버를 선언하는 데 사용하고 있습니다. 이것이 올바른 사용법인지 또는 그렇지 않은 경우 변경해야한다는 점을 알려주십시오.lateinit, init 블록 및 컴패니언 객체를 사용하는 경우. 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

을 만들 수 있습니다 생성자. 예를 들어 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을 사용하지 않습니까? 그냥 null 허용 var? 너는 무엇을 제안 하겠는가? –

+0

try-catch 블록에서는 val을 사용할 수 없으므로 try-catch를 사용하면 변수에 유효한 값을 가져올 수 없다는 것을 의미합니다. 그래서 여기서 가장 좋은 방법은 nullable var를 사용하는 것이라고 생각합니다. – ItWillDo

+0

도움 주셔서 감사합니다. 나는이 변화를 만들었고 모든 것이 잘 작동하고있다. –

2

날이 올바른 사용법이나 사물 인 경우, 그렇지 않은 경우는 변화에 나를 알아 주시기 바랍니다 : 여기 내 코드입니다.

코드와 관련하여 두 가지 사항을 지적합니다. 생성자에서 두 변수를 초기화되기 때문에

  1. 당신은 모두 mmServerSocketmSocketTypelateinit 키워드가 필요하지 않습니다. 변수가 생성 된 후에 초기화 되었다면 필요했을 것입니다.
  2. 예외가 발생할 수있는 경우가 하나 있습니다. 변수 tmpIOException이 던져지면 null 일 수 있습니다. 이 경우 tmpmmServerSocket에 할당하면 KotlinNullPointerException가 발생합니다. 당신은 그것을 해결하기 위해 몇 가지 가능성이있다 : 당신이 catch 블록의 기본 케이스를 처리 할 수 ​​있습니다, 당신은 당신이 당신의 변수를 초기화하는 것 고려 여기 lateinit 필요하지 않습니다 mmServerSocket 널 (NULL), 등