인프런 커뮤니티 질문&답변

비가싫어요님의 프로필 이미지
비가싫어요

작성한 질문수

자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide)

15강. 코틀린에서 배열과 컬렉션을 다루는 방법

Java 코드를 Kotlin 코드로 가져올 때 Wrapping 한다는게 무슨 뜻일까요?

해결된 질문

작성

·

260

1

안녕하세요. 16:52초에 Java 코드를 보며, 맥락을 확인하고 Java 코드를 가져오는 지점을 Wrapping 한다고 설명을 해주셨는데 이 때 Wrapping에 대하여 좀 더 설명을 해주실 수 있을까요?

코틀린으로 코드를 짜려고 하면 아무래도 자바로 짠 자료들이 많아서 자바 코드를 코틀린 코드로 옮길 때 컬렉션 타입을 어떻게 해야할 지 조금 고민이 되는 경우가 많아서 질문 드려봅니다!

답변 1

4

최태현님의 프로필 이미지
최태현
지식공유자

안녕하세요, 파이팅해야지님! 좋은 질문 감사드립니다 😊

 

코드와 함께 빠르게 설명드려 보겠습니다!

// Java Code
public class JavaCode {
  public List<String> processUserNames() {
    // ... 구현
  }
}

여기 JavaCode가 있습니다. 보시는 것처럼 List<String> 을 반환하고 있군요!

 

Kotlin에서 위와 같은 Java Code를 가져와 사용하게 되면 위의 List<String>

 

코틀린 타입으로

  • List<String> 인지

  • List<String?> 인지

  • List<String>? 인지

  • List<String?>? 인지

주의해서 사용해야 하는데요!

 

만약 제가 코틀린 코드의 다양한 위치에서 processUserNames() 를 호출해야 한다고 해보겠습니다.

 

그럼 저는 "타입을 주의해서 사용해야 한다"는 사실을 알고 있기 때문에 다음과 같이 코드를 작성할 겁니다.

아래에서 명시한 List<String?>getProcessUserNames()의 코드 구현을 직접 확인 한 후, List 안에 null이 들어갈 수 있다고 가정했습니다. (즉, 자바 코드의 맥락을 확인했습니다)

// 첫 번재 사용, AService
val users: List<String?> = javaCode.processUserNames()
// 두 번재 사용, BService
val users: List<String?> = javaCode.processUserNames()
// 세 번재 사용, AService
val users: List<String?> = javaCode.processUserNames()

 

 

이렇게 되면 우리는 플랫폼 타입에 신경 써서 users 타입을 정확하게 지정해주었고, 실제로도 문제 없이 잘 동작하게 됩니다!

하지만, 만약 Java Code도 함께 유지보수가 되고 있어 코드에 변경이 있다면, 그래서 코드 구현의 맥락이 변경되어 List<String?> 이 아니라 List<String>? 을 반환하게 수정되었다면 우리가 작성했던 코드는

  • 변경을 잊지 않고 챙겨주더라도 호출했던 코드를 하나씩 확인해가며 고쳐야 합니다.

    • 3개 정도는 바꿀만 하지만, 더 많다면 살짝 눈물이 흐르죠.. 🥲

 

 

그래서 우리는 "wrapping"을 할 수가 있습니다. 예를 들어 아래와 같은 코드를 작성하는 겁니다.

// PlatformTypeUtils.kt 파일 (혹은 JavaCode와 같은 패키지를 kotlin 폴더에 구성)
// 반드시 확장함수를 사용해야 하는 것은 아닙니다. 여기서는 wrapping의 느낌만 봐주세요!!

fun JavaCode.processUserNamesWrapper(): List<String?> {
  return this.processUserNames()
}

 

그리고 우리가 필요한 곳에서는 "wrapping" 함수를 사용하는거죠

// 첫 번재 사용, AService
val users = javaCode.processUserNamesWrapper()
// 두 번재 사용, BService
val users = javaCode.processUserNamesWrapper()
// 세 번재 사용, AService
val users = javaCode.processUserNamesWrapper()

이 경우는 코틀린 코드로 타입을 직접 명시해주었기 때문에 굳이 val users: List<String?> 이라고 타입을 적지 않아도 되고,

만약 Java Code가 변경되어 타입이 바뀐다면, 우리가 만들었던 processUserNamesWrapper() 라는 함수만 변경해주면 됩니다! 😊

 

결론적으로 wrapping의 의미는

  • 자바 코드가 필요한 지점에서

  • 자바 코드를 바로 호출하지 않고 (= 자바 코드의 영향 범위를 넓히지 않고)

  • Kotlin 코드로 자바 코드 를 한 번 감싸 (= 자바 코드의 영향 범위를 국한 시킨 다음)

  • 감싸진 Kotlin 코드를 호출한다

로 봐주시면 될 것 같습니다.

 

답변이 도움이 되었으면 좋겠습니다. 또 궁금하신 점 있으시면 언제든 편하게 질문 남겨주세요.

감사합니다! 🙇 🙏

와 친절한 답변 감사드립니다! 이해가 잘 되었습니다~😊

비가싫어요님의 프로필 이미지
비가싫어요

작성한 질문수

질문하기