Gson vs Serializable

유진·2025년 7월 11일
0

둘은 직렬화/역직렬화 Converter이다

  • 직렬화: 자바 시스템 내부에서 사용하는 객체를 외부의 자바 시스템에서도 사용할 수 있도록 byte 코드로 데이터를 변환하는 기술
  • 역직렬화: 반대로 디스크에 저장된 데이터를 읽거나 네트워크 통신으로 받은 데이터를 자바 메모리에서 쓸 수 있도록 다시 반환하는 기술

그렇담, Retrofit, Ktor 등 네트워크 동신 라이브러리를 통해서 받아온 JSON을 다시 Java나 Kotlin으로 바꿔주는 것은 역직렬화에 해당이 된다.

추가로, JSON(JavaScript Object Notation)은 Name과 Value 이루어진 형식이다. JSON은 언어로부터 독립적이기 떄문에 다수의 언어 간의 데이터 교환에 사용이된다.

{
  "name" : "jin",
  "major" : "cse"
}

리스트는 이렇게 대괄호로 묶어서 표현한다

{
 userList :
  [
    {
      "name" : "jin",
      "major" : "cse"
    },
    {
      "name" : "dolahee",
      "major" : "math"
    },
    {
      "name" : "mi",
      "major" : "japanese"
    },   
  ]
}

이제, JSON을 Kotlin으로 바꾸어주는 라이브러리에 대해서 알아보도록 합시다

라이브러리를 쓰지 않고도 JSON을 파싱해서 쓸 수 있습니다.

[
  {
    "enum": "DODAM",
    "name": "도담 식당",
    "location": "신양관 2층",
    "time": "11:20~14:00(점심)\n17:00~18:30(저녁)",
    "etc": "2개 코너 운영\n일반식, 웰빙코너\n주말 11:20~13:30(점심)",
    "image": "https://eatssu-prod-bucket.s3.ap-northeast-2.amazonaws.com/reviewImg/f3609630-034c-4244-833d-bdd86d38de6620241008021323%E1%84%83%E1%85%A9%E1%84%83%E1%85%A1%E1%86%B7%E1%84%87%E1%85%B3%E1%86%AF%E1%84%85%E1%85%A5IMG_8219.jpg"
  },
  {
    "enum": "HAKSIK",
    "name": "학생 식당",
    "location": "학생회관 3층",
    "time": "-",
    "etc": "방학 기간 휴무",
    "image": "https://eatssu-prod-bucket.s3.ap-northeast-2.amazonaws.com/reviewImg/81ee23a7-2644-490d-97c2-328eed75375a20240929074206%E1%84%92%E1%85%A1%E1%86%A8%E1%84%89%E1%85%B5%E1%86%A8%E1%84%87%E1%85%B3%E1%86%AF%E1%84%85%E1%85%A5IMG_8221.jpg"
  },
  {
    "enum": "SNACK_CORNER",
    "name": "스낵 코너",
    "location": "학생회관 3층",
    "time": "-",
    "etc": "방학 기간 휴무",
    "image": "https://eatssu-prod-bucket.s3.ap-northeast-2.amazonaws.com/reviewImg/06da57d7-82a6-4c8c-aaba-8f976e7f219b20240929074148%E1%84%89%E1%85%B3%E1%84%82%E1%85%A2%E1%86%A8%E1%84%87%E1%85%B3%E1%86%AF%E1%84%85%E1%85%A5IMG_8220.jpg"
  },
  {
    "enum": "FOOD_COURT",
    "name": "푸드 코트",
    "location": "학생회관 2층",
    "time": "-",
    "etc": "준비 중",
    "image": "https://eatssu-prod-bucket.s3.ap-northeast-2.amazonaws.com/reviewImg/09b487f5-e431-4ab2-a339-76e472ea8d8320240926041925%E1%84%91%E1%85%AE%E1%84%8F%E1%85%A9IMG_0396%20%E1%84%8F%E1%85%B3%E1%84%80%E1%85%A6.jpeg"
  },
  {
    "enum": "DORMITORY",
    "name": "기숙사 식당",
    "location": "레지던스홀 지하 1층",
    "time": "11:00~13:30\n17:00~18:20",
    "etc": "조식은 운영되지 않습니다.\n방학기간 주말은 운영되지 않습니다.",
    "image": "https://eatssu-prod-bucket.s3.ap-northeast-2.amazonaws.com/reviewImg/afb759cb-1267-411c-a6a8-5a3e83813ddd20240929074112%E1%84%80%E1%85%B5%E1%84%89%E1%85%B5%E1%86%A8%E1%84%87%E1%85%B3%E1%86%AF%E1%84%85%E1%85%A5IMG_8218.jpg"
  }
]

이렇게요

    private fun parsingJson(json: String): ArrayList<RestaurantInfo> {
        val jsonArray = JSONArray(json)
        val list = ArrayList<RestaurantInfo>()

        for (index in 0 until jsonArray.length()) {
            val jsonObject = jsonArray.getJSONObject(index)

            val enumString = jsonObject.optString("enum", "")
            val enumValue = enumValues<Restaurant>().find { it.name == enumString } ?: Restaurant.HAKSIK
            val name = jsonObject.optString("name", "")
            val location = jsonObject.optString("location", "")
            val photoUrl = jsonObject.optString("image", "")
            val time = jsonObject.optString("time", "")
            val etc = jsonObject.optString("etc", "")

            val restaurantInfo = RestaurantInfo(enumValue, name, location, photoUrl, time, etc)
            Timber.d(restaurantInfo.toString())
            list.add(restaurantInfo)
        }
        return list
    }

별로 예쁘진 않은것 같습니다. 자 이제 조금 더 나아가서 라이브러리를 활용해보겠습니다.

  • ✅ 장점
    • 의존성 없음: 외부 라이브러리 없이 바로 사용 가능
    • 단순한 구조에서는 유용
  • ❌ 단점
    • 노가다성: 필드 하나하나 수동으로 꺼내야 함
    • 에러에 취약: 필드 누락, 타입 불일치 시 런타임 오류 발생
    • 중첩 구조 대응 어려움: 중첩된 JSON 처리 시 복잡도 급증

빠르게 프로토타입을 만들 때는 괜찮지만, 스케일이 커질수록 유지보수 지옥으로 변합니다.

Gson

Gson은 Google에서 만든 JSON 파서로, 안드로이드에서 널리 사용됩니다. 아래처럼 간단하게 쓸 수 있죠.


val gson = Gson()
val list = gson.fromJson(json, object : TypeToken<List<RestaurantInfo>>() {}.type)
  • ✅ 장점
    • 자동 매핑: JSON을 객체로 바로 매핑
    • 커스터마이징 가능: 어댑터로 enum 처리 등 쉽게 확장 가능
    • 성숙한 생태계: 거의 모든 자바/안드로이드 프로젝트에서 사용 가능
  • ❌ 단점
    • 리플렉션 기반: 성능이 다소 느림
    • 코틀린 친화도 낮음: val, constructor, default value 등의 코틀린 특성을 잘 지원하지 않음
    • Multiplatform 미지원

      자바 기반 프로젝트나 코틀린 초기 프로젝트에선 무난하지만, 최신 코틀린 환경에선 조금 불편해질 수 있음.

kotlinx-serialization

코틀린 멀티플랫폼 지원과 함께 등장한 공식 직렬화 라이브러리입니다. @Serializable만 붙이면 끝.

@Serializable
data class RestaurantInfo(...)
    
val data = Json.decodeFromString<List<RestaurantInfo>>(json)
  • ✅ 장점
    • 컴파일 타임 안전성: 실수 줄어듦 (런타임 에러 → 컴파일 에러)
    • 빠른 성능: 리플렉션 없이 컴파일러가 직접 코드를 생성
    • Multiplatform 지원: 안드로이드 외에도 iOS, JS 등에서 사용 가능
    • 코틀린 친화적: val, default parameter, sealed class 등 완벽 지원
  • ❌ 단점
    • 초기 설정 약간 번거로움: gradle 플러그인, @Serializable, 커스텀 enum 처리 등
    • 라이브러리 무게감: 기본 Json 외에 Protobuf, CBOR 등 지원하려면 의존성 추가됨

순수 코틀린 기반 프로젝트라면 최적의 선택. 특히 Multiplatform이나 성능, 타입 안정성이 중요할 때 강력함.

결론

항목Gsonkotlinx.serialization
Enum fallbackregisterTypeAdapter로 커스텀 JsonDeserializer 구현@Serializable(with = ...) + fallback 구현 필요
Unknown key 무시기본값 유지 (@SerializedName, 생략 가능)Json { ignoreUnknownKeys = true }
성능/호환성Java 기반, 유연하고 많은 Android 프로젝트에서 사용됨Kotlin-first, 코틀린 멀티플랫폼 호환
profile
안드로이드... 좋아하세요?

0개의 댓글