
Kotiln 포함한 모든 언어 및 코딩을 하다보면 마지막의 마지막에는 크나큰 문제에 부딪히게 된다.
그렇다 바로 버그 혹은 에러라고 부른다. 오늘은 버그를 잡는 행위, 디버깅에 대해 알아보고자 한다.
등 디버깅은 중요하면서도 꼭 해야만한다. 안하면 어차피 코드가 돌아가지도 않을테지만..
변수 타입 선언:
Kotlin은 변수의 타입을 자동으로 추론할 수 있기 때문에, 타입 선언을 생략할 수 있습니다. 하지만, 자료형을 잘못 지정하거나 필요한 경우에 지정하지 않으면 에러가 발생합니다.
val age: String = 25 // Int 값을 String으로 선언하려고 시도
Null Safety:
Kotlin은 null 안전성을 중요시합니다. 따라서 null 값을 허용하지 않는 변수에 null을 할당하려고 하면 에러가 발생합니다.
var name: String = null // null 값을 허용하지 않는 String 변수에 null 할당
해결: var name: String? = null
함수 선언:
Java와는 다르게 Kotlin에서 함수를 선언할 때 fun 키워드를 사용합니다. 이를 잊으면 에러가 발생합니다.
void display() { // 'fun' 키워드 누락
println("Displaying...")
}
해결: fun display() { ... }
클래스 상속:
Kotlin에서 클래스는 기본적으로 final입니다. 따라서 클래스를 상속하려면 open 키워드를 추가해야 합니다.
class Parent { ... }
class Child : Parent() // Parent 클래스가 open으로 표시되지 않았기 때문에 에러 발생
해결: open class Parent { ... }
프로퍼티 초기화:
Kotlin에서는 프로퍼티(변수)를 선언할 때 초기값을 제공하거나, 나중에 초기화하겠다는 것을 명시적으로 표시해야 합니다.
class User {
var name: String // 초기값이 없거나 lateinit 키워드 누락
}
해결: 초기값 제공 var name: String = "Default" 또는 lateinit var name: String
잘못된 범위 사용:
until과 ..의 차이를 헷갈려 잘못 사용하면 범위가 의도치 않게 설정될 수 있습니다.
for (i in 0 until 5) {
println(i) // 0, 1, 2, 3, 4 출력
}
for (i in 0..5) {
println(i) // 0, 1, 2, 3, 4, 5 출력
}
NullPointerException:
Null 참조를 사용하려고 할 때 발생합니다.
var name: String? = null
println(name!!.length) // !! 연산자 사용으로 강제 참조시도 시 NullPointerException 발생
IndexOutOfBoundsException:
잘못된 인덱스로 리스트나 배열에 접근하려고 할 때 발생합니다.
val numbers = listOf(1, 2, 3)
println(numbers[5]) // 인덱스 범위 초과
ClassCastException:
잘못된 타입으로 객체를 변환하려고 할 때 발생합니다.
val obj: Any = 12345
val str: String = obj as String // Int 객체를 String으로 캐스팅하려고 시도
ArithmeticException:
수학적 계산 중에 예외 상황이 발생할 때, 예를 들면 0으로 나누려고 할 때 발생합니다.
val result = 5 / 0 // 0으로 나눔
NoSuchElementException:
예상한 요소가 컬렉션에 없을 때 발생합니다.
val numbers = listOf(1, 2, 3)
println(numbers.first { it > 5 }) // 5보다 큰 첫 번째 요소가 없음
IllegalStateException:
객체의 현재 상태가 작업을 수행하기에 적합하지 않을 때 발생합니다.
val builder = StringBuilder()
val result = builder[2] // 비어 있는 builder에서 인덱스 2의 문자를 가져오려고 함
Resources.NotFoundException:
안드로이드에서 특정 리소스(ID, 이미지 등)를 찾을 수 없을 때 발생합니다.
val color = resources.getColor(R.color.non_existent_color) // 존재하지 않는 리소스 ID를 사용
이처럼 에러의 종류는 다양하다. 해결방법은 보면 알겠지만 대부분 한 번 씩은 실수하는 사항들이다.
잘못 썻거나 빼먹었거나, 초기화 하지 않았거나 하는것들은 나름 빠른 시간안에 잡을 수 있다. 하지만 그 외의 상황이 발상된다면 더 많은 시간과 갈라나가는 자신을 볼 수밖에 없을때가 있다.
그떄가 바로 코드가 돌아가서 테스트 중인데 어디선가 에러가 발생되어 멈춘다던가 팅기는 현상이 일어날때이다.
이럴때는 Logcat 을 사용해서 어디서 에러가나는지 찾아야한다. 안드로이드 스튜디오를 기준으로 설명하자면

하단에 빨간색 처진 부분에 Logcat이라고 써진 부분을 클릭하면

이러한 화면이 나오는걸 볼 수 있다. 보는 봐야같이 빨간색 글씨로 E라고 써잇는 부분이 에러가 뜬 부분이다.
대체로 뭐때문에 에러가 났는지 알려주기때문에 바로 알아볼 수있지만 그마저도 안될때는 다음과 같은 코드를 에러가 날것같은 혹은 난거 같은 코드 사이에 껴 넣어줘야한다.
Log.v("", "Verbose level log")
Log.d("", "Debug level log")
Log.i("", "Information level log")
Log.w("", "Warning level log")
Log.e("", "Error level log")
앞부분에는 tag를 입력 뒤에는 Logcat에서 알아 볼 수 있는 글씨를 써 넣어주면 된다.
tag는 로그캣 상단 부분에 필터 역활을 해준다.
예를 들어 tag부분에 Log를 적고 뒤 msg 부분에 this here error 를 적고 실행한다면 다음과 같은 화면이 나온다.
코드 형식은 이렇다.
Log.d("tag", "this here error")

하나씩 설명하자면 1번에는 본인이 사용중인것 혹은 저장해둔 에뮬레이터를 선택 할 수있다. 만일 Logcat에서 로그가 안나온다면 저부분에 에뮬레이터가 잘 못 선택 된건 아닌지 먼저 보도록하자.
2번에 보면 package:mine tag 이라고 적힌걸 볼 수 있다. tag 라는 필터를 줘서 tag라고 적힌 부분만 골라서 보여주는게 가능하다. 본인에게 알맞게 작성해서 로그를 볼 수 있게 하면 된다.
3번을 또 보면 제대로 로그가 나오는걸 볼 수 있다. Log.d("tag", "this here error") 라고 적은대로 tag가 나오고 마지막에 this here error라고 잘 출력된걸 볼 수있다.
이걸 써서 에러가 날것 같은 부분 혹은 에러가 날것으로 추정되는 부분에 넣는다면 쉽게 에러가 난 지점을 찾을 수 있다. 추가로 만일 데이터를 넘겨받고 한다면 데이터를 넘겨받고 하는 코드 부분에 로그를 넣을 경우 데이터가 제대로 넘어가는지 안넘어 가는지 알 수 있을 것이다.
csharpCopy code
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapp, PID: 12345
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
at com.example.myapp.MainActivity.someFunction(MainActivity.java:50)
java.lang.NullPointerException은 널 객체 참조에 메서드를 호출하려고 했을 때 발생합니다.MainActivity.java:50에서 이 오류가 발생했음을 알 수 있습니다.vbnetCopy code
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapp, PID: 12345
java.lang.OutOfMemoryError: Failed to allocate a 1234568 byte allocation with 123456 free bytes and 123KB until OOM
at com.example.myapp.MainActivity.loadLargeImage(MainActivity.java:100)
java.lang.OutOfMemoryError은 메모리 부족으로 인해 발생합니다.MainActivity.java:100에서 대용량 이미지를 로드하려고 했을 때 메모리 부족 문제가 발생했음을 알 수 있습니다.yamlCopy code
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapp, PID: 12345
android.content.res.Resources$NotFoundException: Resource ID #0x7f0800e3
at com.example.myapp.MainActivity.onCreate(MainActivity.java:30)
android.content.res.Resources$NotFoundException은 참조한 리소스(ID #0x7f0800e3)를 찾을 수 없을 때 발생합니다.MainActivity.java:30에서 존재하지 않는 리소스를 참조하려고 했음을 알 수 있습니다NullPointerException 또는 리소스 참조 오류 때문입니다.runOnUiThread 또는 Handler를 사용하여 UI 업데이트를 메인 스레드에서 실행하세요.이상 디버깅에 관한 글이였다.