마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

Expecting member declaration 이 에러가 자꾸 뜨는데 왜 그런 건가요 ?

0 추천
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class ResisterActivity : AppCompatActivity() {

    private EditText // <- 이부분에서 자꾸 오류가 나네요

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_resister2)
    }
}

웅자띠 (180 포인트) 님이 2022년 5월 21일 질문
웅자띠님이 2022년 5월 22일 수정

1개의 답변

+1 추천
 
채택된 답변

번수 키워드와 변수명이 빠져있네요. ^^

코틀린에서는 아래처럼 var/val의 변수 키워드가 변수명 앞에 필요합니다. var는 쓰기가 가능하고 val은 readonly(읽기 전용)인 변수에 사용합니다. 대부분의 경우는 예기치않는 상태조작을 방지하는 않는 val가 더 좋은 선택이 됩니다.

private val myEditText: EditText
private var myEditText: EditText

 

그리고 님의 경우처럼 아직 초기화기 되지 않은 변수는 아래의 두가지 중의 한가지 방법을 사용하셔야 합니다.

1. lateinit var

해당 키워드를 사용하면 컴파일러에게 나중에 초기화를 하겠다고 알려줌으로써 컴파일 에러가 나지 않게 됩니다. 그리고 이 변수는 아래처럼 onCreate 등 가능한 곳에서 해당 변수를 초기화해 주어야 합니다. 만약 초기화 전에 이 변수에 접근하면 에러가 발생하게 됩니다.

private lateinit var myEditText: EditText


override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_resister2)
        
        // myEditText.setText("텍스트") --> 변수 초기화 전에 접근하면 런타임에러
         myEditText = findViewById(R.id.myEditText)
    }

 

2. by lazy

private val myEditText: EditText by lazy {
    findViewById(R.id.myEditText)
}

protected fun onStart() {
    super.onStart()
    myEditText.text("아무텍스트"); // 이 시점에서 findViewById(R.id.myEditText) 호출하고 초기화 됨.
}

by lazy 키워드를 사용하게 되면 lazy 초기화를 사용할 수 있습니다. lazy 변수는 바로 초기화가 되는 게 아니라 해당 변수를 최초로 접근하는 시점에 lazy블록 안에 있는 코드로 초기화가 됩니다. 그리고 이후부터너 해당변수에 접근해도 다시 초기화하지 않습니다. 이 방법이 적용될 수 있는 경우라면 lateinit var보다는 더 유용한 방법이라 보여집니다. findViewById같은 경우도 여기에 해당한다고 생각합니다.

참고로 findViewById대신에 ViewBinding을 사용하는 것이 타입에 안전한 코드를 작성할 수 있어 좀 더 나은 접근방법이라 생각합니다.

코틀린 강좌는 Google, Jetbrain 등 수많은 곳에서 무료로 제공하고 있으니 참고하시기 바랍니다.

 

 

 

spark (224,800 포인트) 님이 2022년 5월 22일 답변
웅자띠님이 2022년 5월 22일 채택됨
답변감사합니다. 처음 안드로이드 개발을 하다보니 부족한 부분이 너무 많네요 ㅠㅠ 학교 프로잭트라 일단 유튜브 보면서 따라하고 있어서 ㅠㅠㅠ
private lateinit var myEditText: EditText et_id, et_pw, et_name, et_call ;
    private var Button btn_resister ;

    override fun onCreate(savedInstanceState: Bundle?) { //액티비티 시작시 처음으로 실행되는 생명주기
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_resister2);

        //아이디 값 찾아주기
        et_id = findViewById(R.id.et_id) ;
        et_pw = findViewById(R.id.et_pw) ;
        et_name = findViewById(R.id.et_name) ;
        et_call = findViewById(R.id.et_call) ;

이 상황에서 자꾸 Property getter or setter expected 이 에러가 뜨는건 왜 그런건 가요 그 뒤로 자꾸 자동완성도 안되구 그래서요
먼저 각 라인끝의 세미콜론(;)을 제거하세요. 코틀린에서는 사용하지않는게 규칙입니다.
private lateinit var myEditText: EditText et_id, et_pw, et_name, et_call
이렇게 한가지 변수타입을  latetinit var를 이용해서 한꺼번에 선언할 수 없습니다.

private var Button btn_resister
변수를 초기화하거나 lateinit var또는 by lazy를 사용해야 합니다.

추가로 개인적인 견해로는 코틀린의 변수 초기화 방식은 자바에서 발전되었다고 생각합니다. 왜냐하면 개발자가 실수를 하지않도록 정확한 의도롤 요구하기 때문입니다.
근데 왜 저는 똑같이 emptyActivity 로 생성한건데 제가 따라하고있는 유튜버와 다른 class 가 생성된 거죠 ?? ㅠㅠㅠ
따라하고 있는 강의 는 위에 수정해서 이미지 올렸습니다
EmptyActivity를 어떻게 생성하셨는지는 모르겠지만, 안드로이드 스튜디오에서 empty activity를 만들 면 onCreate까지만 생성될 뿐, 멤버 변수는 자동으로 만들어 주지는 않는데요. 님의 경우는 생성 후에 수정한 걸로 보이는데요.
...