📖
Kyu9's Repo
  • Library of mameil
  • 이슈 경험
    • 20230220_트랜잭션
    • 20230306_캐싱이슈
    • 20230722_테스트코드에서 @Transactional
    • 20230807_deadlock
  • 인턴 스터디
    • Gradle
    • Stream, Optional, 람다식
    • JVM의 메모리 구조, Garbage Collector
    • RESTful API
    • Microservice Architecture
    • HTTP
    • 웹서버란 무엇인가
    • Git Branch
    • TDD
    • Redis을 이용한 캐시
    • Thymeleaf
    • 정리가 필요한 자료들
    • SpringBoot Management
    • 테스크 코드 분할
  • 동아리 스터디
    • 기본 SQL 공부
      • SQL의 기본 개념
      • SELECT 문장을 이용하여 원하는 데이터 출력하기
        • 집합 연산자 사용하기
        • where절에 비교 연산자를 사용해보기
        • SELECT_EX
        • 산술 연산자 사용해보기
      • 단일 행 함수 사용
        • lower/upper 함수 사용하기
        • length함수 사용하기
        • concat함수 사용
        • substr/mid/substring 함수 사용
        • instr함수 사용하기
        • lpad/rpad 함수 사용하기
        • trim/ltrim/rtrim 함수 사용하기
        • replace 함수 사용하기
        • round 함수 사용하기
        • truncate 함수 사용하기
        • mod함수 사용하기
        • ceil함수 사용하기
        • floor함수 사용하기
        • power 함수 사용하기
        • Date fn(날짜 함수)
        • 형 변환 함수
        • 일반함수란
    • a-ha 실습
    • 혼자서 만들어본 게시판
    • AWS 강의
  • 학교 나머지 공부 자료
    • 웹프레임워크(Spring)
      • Spring이란?
      • Webframework1-1
      • Webframework1-2
      • SpringBoot의 특징
      • SpringBoot 생성 방법
      • Spring Data JPA
      • SpringBoot Security
      • SpringBoot HATEOAS
  • 공부 자료들
  • WS 온라인 자바 스터디
    • Week1(JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.)
    • Week2(자바 데이터 타입, 변수 그리고 배열)
    • Week3(연산자)
    • Week4(제어문)
    • Week5(클래스)
    • Week6(상속)
    • Week7(패키지)
    • Week8(인터페이스)
    • Week9(예외처리)
    • Week10(멀티쓰레드 프로그래밍)
    • Week11(Enum)
    • Week12(Annotation)
    • Week13(I/O)
    • Week14(Generic)
    • Week15(람다식)
  • 백준문제
    • 입출력과 사칙연산
      • We love kriii(10718)
      • 고양이(10171)
      • 개(10172)
      • A+B(1000)
      • A-B(1001)
      • AxB(10998)
      • A/B(1008)
      • 사칙연산(10869)
      • 나머지(10430)
      • 곱셈(2588)
    • for문
      • 구구단(2739)
      • A+B - 3(10950)
      • 합(8393)
      • 빠른 A+B(15552)
      • N 찍기(2741)
      • 기찍 N(2742)
      • A+B - 7(11021)
      • A+B - 8(11022)
      • 별 찍기 - 1(2438)
      • 별 찍기 - 2(2439)
      • X보다 작은 수(10871)
    • if문
      • 두 수 비교하기(1330)
      • 시험 성적(9498)
      • 윤년(2753)
      • 사분면 고르기(14681)
      • 알람 시계(2884)
      • 오븐 시계(2525)
      • 주사위 세개(2480)
      • 영수증(25304)
    • While문
      • A+B - 5(10952)
      • A+B - 4(10951)
      • 더하기 사이클(1110)
    • 1차원 배열
      • 최소, 최대(10818)
      • 최댓값(2562)
      • 숫자의 개수(2577)
      • 나머지(3052)
      • 평균(1546)
      • OX퀴즈(8958)
      • 평균은 넘겠지(4344)
    • 함수
      • 정수N개의 합(15596)
      • 셀프 넘버(4673)
      • 한수(1065)
    • 문자열
      • 아스키코드(11654)
      • 숫자의 합(11720)
      • 알파벳 찾기(10809)
      • 문자열 반복(2675)
      • 단어 공부(1157)
      • 단어의 개수(1152)
      • 상수(2908)
      • 다이얼(5622)
      • 크로아티아 알파벳(2941)
      • 그룹 단어 체커(1316)
    • 기본수학-1
      • 손익분기점(1712)
      • 벌집(2292)
      • 분수찾기(1193)
      • 달팽이는 올라가고 싶다(2869)
      • ACM 호텔(10250)
      • 부녀회장이 될테야(2775)
      • 설탕 배달(2839)
      • 큰 수 A+B(10757)
      • Fly me to the Alpha Centauri(1011)
    • 기본수학-2
      • 소수 찾기(1978)
      • 소수(2581)
      • 소인수분해(11653)
      • 소수 구하기(1929)
      • 베르트와 공존(4948)
    • 재귀
      • 하노이 탑 이동 순서(11729)
      • 피보나치 수 5(10870)
      • 별 찍기(2447)
    • 브루트 포스
      • 블랙잭(2798)
      • 분해합(2231)
      • 덩치(7568)
      • 체스판 다시 칠하기(1018)
      • 영화감독 슘(1436)
    • 집합과 맵
      • 숫자 카드(10815)
      • 문자열 집합(14425)
      • 숫자 카드2(10816)
      • 듣보잡(1764)
      • 대칭 차집합(1269)
      • 서로 다른 부분 문자열 갯수(11478)
    • 정렬
      • 수 정렬하기(2750)
      • 수 정렬하기 2(2751)
      • 수 정렬하기 3(10989)
      • 통계학(2108)
      • 소트인사이드(1427)
      • 좌표 정렬하기(11650)
      • 좌표 정렬하기2(11651)
      • 단어 정렬(1181)
      • 나이순 정렬(10814)
      • 커트라인(25305)
      • 좌표압축(18870)
    • 백트래킹
      • N과 M - 1(15649)
      • N과 M - 2(15650)
      • N과 M - 3(15651)
      • N과 M - 4(15652)
      • N-Queen(9663)
      • 스도쿠(2580)
      • 연산자 끼워넣기(14888)
      • 스타트와 링크(14889)
    • 이분 탐색
      • 수 찾기(1920)
    • 동적계획법
      • 피보나치 함수(1003)
      • 신나는 함수 실행(9184)
      • 01타일(1904)
      • 파도반 수열(9461)
      • RGB거리(1149)
      • 정수 삼각형(1932)
      • 계단 오르기(2579)
      • 1로 만들기(1463)
      • 쉬운 계단 수(10844)
      • 포도주 시식(2156)
      • 가장 긴 증가하는 부분 수열(11053)
      • 가장 긴 바이토닉 부분 수열(11504)
      • 전깃줄(2565)
      • LCS(9251)
      • 연속합(1912)
      • 평범한 배낭(12865)
      • 더하기(9095)
    • DFS와 BFS
      • 미로탐색(2178)
      • 바이러스(2606)
      • DFS와 BFS(1260)
      • 단지번호붙이기(2667)
      • 전쟁 - 전투(1303)
      • 숨바꼭질(1697)
      • 데스 나이트(16948)
      • 나이트의 이동(7562)
      • 녹색 옷 입은 애가 젤다지?(4485)
      • 음식물 피하기(1743)
      • A->B (16953)
      • 숨바꼭질 3(13549)
      • 숨바꼭질 2(12851)
    • 구현
      • 치즈(2636)
  • 프로그래머스 문제
    • SQL
      • Animal Table - Oracle
      • Animal Table - MySQL
      • Animal Table2 - Oracle
      • Animal Table 3,4 - Oracle
    • Lv1
      • 두 개 뽑아서 더하기
      • 제일 작은 수 제거하기
      • 문자열 내 p와 y의 개수
      • 예산
      • 자릿수 더하기
      • 두 정수 사이의 합
      • 같은 숫자는 싫어
      • 가운데 글자 가져오기
      • 수박수박수박수박수박수?
      • 나누어 떨어지는 숫자 배열
      • 2016년
      • 폰캣몬
      • 서울에서 김서방 찾기
      • 문자열을 정수로 바꾸기
      • 소수 만들기
      • 문자열 다루기 기본
      • 소수 찾기(에라토스테네스의 체)
      • 숫자 문자열과 영단어
      • 이상한 문자 만들기
      • 없는 숫자 더하기
      • 문자열 내림차순으로 배치하기
      • 문자열 내 마음대로 정렬하기
      • 약수의 개수와 덧셈
      • 콜라츠 추측
      • 자연수 뒤집어 배열로 만들기
      • 신규 아이디 추천
      • 비밀지도
      • 크레인 인형뽑기 게임
      • 실패율
      • 로또의 최고 순위와 최저 순위
      • 키패드 누르기
      • 정수 내림차순으로 배치하기
    • Lv2
      • 행렬의 곱셈
      • 영어 끝말잇기
      • 영어 끝말잇기
      • N개의 최소 공배수
      • 피보나치 수
      • 124 나라의 숫자
      • 짝지어 제거하기
      • 프린터
      • 다음 큰 숫자
      • 최댓값과 최솟값
      • 최소값 만들기
      • 숫자의 표현
      • JadenCase 문자열 만들기
      • 오픈채팅방
      • 영어 끝말잇기
      • 멀쩡한 사각형
      • 올바른 괄호
      • 위장
      • 기능개발
      • 더 맵게
      • 스킬트리
    • 완전탐색
      • 모의고사(Lv1)
      • 카펫(Lv2)
      • 소수 찾기(Lv2)
    • 정렬(Sorting)
      • K번째 수(Lv1)
      • 가장 큰 수(Lv2)
      • H-Index(Lv2)
    • 해시(Hash)
      • 완주하지 못한 선수(Lv1)
      • 전화번호 목록(Lv2)
    • 탐욕법(Greedy)
      • 체육복(Lv1)
      • 큰 수 만들기(Lv2)
      • 구명보트(Lv2)
    • 동적계획법(DP)
      • 정수 삼각형(Lv3)
    • 깊이/너비 우선 탐색(DFS/BFS)
      • 타겟 넘버(Lv2)
      • 네트워크(Lv3)
      • 단어 변환(Lv3)
  • 스프링부트 책
    • Day 1
    • Day 2
    • Day 3
    • Day 4
    • Day 5
    • Day 6
    • Day 7
    • Day 8
    • Day 9
    • Day 10
    • Day 11
    • Day 12
    • Day 13
    • Day 14
    • Day 15
    • Day 16
    • Day 17
  • JPA 책
    • 프로젝트 세팅 및 기본설정
    • 영속성 관리 개념
    • 엔티티 매핑
      • 실습 예제
    • 연관관계 매핑 기초
      • 실습 예제
    • 다양한 연관관계 매핑
      • 다대일, 일대다 관계
      • 일대일, 다대다 관계
      • 실습 예제
    • 고급 매핑
      • 상속 관계 매핑
      • @MappedSuperclass
      • 복합 키와 식별 관계 매핑
      • 조인 테이블
    • 프록시와 연관관계 관리
      • 프록시
      • 즉시 로딩과 지연 로딩
      • 영속성 전이, 고아 객체
    • 값 타입
      • 임베디드 타입
      • 값 타입과 불변 객체
      • 값 타입의 비교, 컬렉션
    • 객체지향 쿼리 언어
      • JPQL part1
      • JPQL part2
      • JPQL part3
      • QueryDSL
      • NativeSQL
      • 객체지향 쿼리 심화
    • 응용 애플리케이션
      • 엔티티 설정
    • 스프링 데이터 JPA
      • 공통 인터페이스
  • Kotlin In Action
    • 코틀린의 특징
    • 코틀린의 기초
    • 함수 정의와 호출
    • 클래스, 객체, 인터페이스
    • 람다 방식
    • 코틀린 타입 시스템
    • 연산자 오버로딩과 기타 관례
    • 고차함수
    • 제네릭스
    • 애노테이션과 리플렉션
    • 코루틴
  • Oracle
    • Oracle 기본
    • Oracle 심화
  • SQL_연습
    • Revising the Select Query
    • Basic Select
    • Advanced Select
    • Basic Select 2
  • SQL 첫걸음(책)
    • Day 1
    • Day 2
    • Day 3
    • Day 4
    • Day 5
    • Day 6
    • Day 7
    • Day 8
    • Day 9
    • Day 10
    • Day 11
    • Day 12
    • Day 13
    • Day 14
    • Day 15
    • Day 16
    • Day 17
    • Day 18
    • Day 19
    • Day 20
    • Day 21
    • Day 22
    • Day 23
    • Day 24
    • Day 25
    • Day 26
    • Day 27
    • Day 28
    • Day 29
    • Day 30
  • 더 자바 코드를 조작하는 다양한 방법
    • JVM 이해하기
    • 바이트코드 조작
    • 리플렉션
    • 다이나믹 프록시
    • 애노테이션 프로세서
  • 더 자바, 애플리케이션을 테스트하는 다양한 방법
    • JUnit5
    • Mockito
    • 도커와 테스트
    • 성능, 운영이슈, 아키텍처 테스트
  • 이펙티브 자바
    • item1 - 생성자 대신 정적 팩토리 메소드를 고려하라
    • item2 - 생성자에 매개변수가 많다면 빌더를 고려하라
    • item3 - 생성자나 열거타입으로 싱글턴임을 보증하라
    • item4 - 인스턴스화를 막기 위해선 private 생성자를 사용하라
    • item5 - 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
    • item6 - 불필요한 객체 생성을 피하라
    • item7 - 다 쓴 객체 참조를 해제하라
    • item8 - finalizer와 cleaner 사용을 피하라
    • item9 - try-finally 보다 try-with-resources을 사용하라
    • item10 - equals는 일반 규약을 지켜 재정의하라
    • item11 - equals을 재정의하려면 hashCode도 재정의하라
    • item12 - toString을 항상 재정의하라
    • item13 - clone 재정의는 주의해서 진행하라
    • item14 - Comparable을 구현할지 고민하라
  • Elastic Search
    • 강의 Summary
    • Elastic Summary 개념 정리
    • Elastic Summary 적용 정리
  • 토비의 스프링 강의
    • 스프링부트 살펴보기
    • 독립 실행형 서블릿 애플리케이션
  • k8s
    • minikube 설치
    • jenkins 추가
  • Article
    • Choosing the Right MessageBroker
Powered by GitBook
On this page
  • Null Safety
  • 코틀린의 원시 타입
  • 컬렉션과 배열

Was this helpful?

  1. Kotlin In Action

코틀린 타입 시스템

Null Safety

nullability 은 NullPointerException 어레러르 피하게 해주는 간단한 코틀린 타입 시스템의 특성이다 요 Exception 은 자바에서는 정말 예상하지 못하는 곳에서 넘어와서 해당 로직을 삑나게 하는 아주 나쁜놈이다 물론 이걸 방지하기 위해서 모든 가능성을 생각하면서 null 조건 체크를 해주는 것도 방법인데.. 이게 정말 말처럼 쉽지가 않다 에이 설마 여기서도 나겠어? 하던게 실제로 그렇게 나와버리는.. 그런 상황이 나온다 그래서 코틀린에서는 이러한 문제를 찾아내는 시간을 런타임에 체크하는 것이 아니라 컴파일 시점에 체크를 해준다 널이 될 수 있는지의 여부를 타입 시스템에 추가함으로써 컴파일러가 미리 감지해서 미연에 방지가 되도록 만들었다

널이 될 수 있는 타입은 코틀린에서 명시적으로 지원하고 있다 물론 nullable 하게 만드는 것도 가능하다 nullable 하게 만드는 방법은 타입을 선언하면서 그 뒤에 ?을 붙히는 것이다 그럼 기존에 사용하던 방법으로 생각해보면 ?을 붙히지 않은 기본적인 타입은 모두 nullable 하지 않고 컴파일러가 null이 들어갈 수 있다면 빨간줄로 경고한다 그럼 nullable한 코드는 어떻게 null을 처리할까? -> 이것에 대한 대답은 컴파일러에 있다 기존에 자바에서 하는 것과 같이 null과 비교하는 과정, 비교하려는것 != null 을 통해서 검사를 해줘면 컴파일러가 아 비교하려는 객체는 null 을 비교하는 부분을 확인하고 null이 아님을 확실하는 영역에서 작성되도록 도와준다 이외에도 코틀린에서는 널이 될 수 있는 값을 안전하게 다루도록 도와주는 특별한 연산자들이 많다

안전한 호출 연산자 ?. 이 있다 ?. 은 null 검사와 메소드호출을 한 번의 연산으로 수행한다 즉 s?.toUpperCase() 이렇게 작성하면 if(s!=null) s.toUpperCase() else null 이 것과 같은 의미이다 만약 호출하려는 값이 null 이면 해당 호출이 무시되고 null 값이 되지만 만약 호출하려는 값이 null 이 아니면 메소드 호출처럼 작동한다는 것이다 그리고 이것의 포인트는 연쇄해서 사용하는 것도 가능하다는 의미이다 예를 들어서 메뉴 밑에 메뉴옵션 밑에 메뉴옵션아이템이 있을 때 메뉴 옵션아이템에 접근하고 싶다 그럼 this.menu?.menuOption?.menuOptionItem 이렇게 접근하면 menu, menuOption에 대한 null 추가 검사 없이 menuOption을 바로 가져오는 것이 가능하다 이런 식으로 간결하게 null 체크를 할 수 있다는 점이 정말 좋은 것 같다 불필요한 if문 같은 것들도 줄일 수 있는 것이다

엘비스 연산자라고 불리우는 ?: 이 있다 null 인경우에 null 대신 default 값을 명시해주는 연산자이다 val s: String?: "ddd" 이건 만약에 s 변수에 정상적으로 String 값이 들어왔으면 그 값을 적용시키고 s 변수에 null 이 들어왔으면 "ddd" 가 나온다는 것이다 아까 위에서 메뉴.메뉴옵션.메뉴옵션아이템 요 구조에서 메뉴옵션아이템마저도 null 이면 안되니까 null인 케이스를 고려해줘야 했다면 이걸 사용하면 fun getMenuOptionItem() = menu?.menuOption?.menuOptionItem?: "no val" 이렇게 안전한 메뉴옵션아이템의 게터함수를 만드는 것이 가능하다 이외에 코틀린에서 return 이나 throw 같은 연산도 식으로 치기 때문에 엘비스 연산자 우항에 return 이나 throw 와 같은 연산도 넣을 수 있다 이러한 패턴은 함수의 전제조건을 검사할때 유용하다

class Menu(val menuId: String, val menuVersion: MenuVersion)
calss MenuOption(val menuOptionId: String, val menuId: String, val menuOptionVersion)
class MenuVersion(val version: String, val yyyymmdd: String)

fun printMenuVersion(menuOption: MenuOption){
    val getMenuVersion = menuOption.menuId?.menuVersion?: throw IllegalArgumentException("No Version")
        with(getMenuVersion){
            println(yyyymmdd)
            println(version)
        }
}

이런 식으로 사용할 수 있다

타입 캐스팅이 존재하고 as? 이렇게 사용한다 자바의 타입 캐스트처럼 as로 타입을 변경하는 것이 가능하다 근데 만약에 타입캐스팅에 문제가 있으면 당연하게 타입캐스팅예외가 나올 것이다 그러면 is을 통해서 타입 검사를 먼저 진행하고 as 으로 변환해야하는데 좀 귀찮은 방식이다 그런데 as? 이렇게 하면 알아서 처리해주는 것 만약에 타입 캐스팅이 안되면 예외를 던지는게 아니라 null 을 던지게 되어있다 이렇게 안전하게 캐스트를 수행하고 엘비스 연산자를 자주 사용하는 패턴이 자주 보인다

널 아님 단언 이라는데.. 그냥 !! 이 느낌표 2개를 의미하는 것 같다 !! 은 코틀린에서 널이 될 수 있다는 타입의 값을 다룰때 사용한다 이걸 붙히면 어떤 값이든 널이 될 수 없는 타입으로 강제로 변환해준다 그래서 만약에 실제 null에 대해서 !!을 적용해주면 널에러가 발생한다

fun ignoreNulls(s: String?){
    //s 같은경우는 nullable인데 null이 들어갈 수 없는 변수에 넣었기 때문에 발생?
    val sNotNull: String = s!!
    println(sNotNull.length)
}

!!은 컴파일러에게 null 값이 들어갈 수 없는 변수이지만 null이 들어가도록 하겠다 라는 의미이다 문제가 발생할 수도 있다는 것을 의미하기 떄문에 약간 눈에 잘 보이도록 일부러 이렇게 만들었다고 한다 근데 좋은 방법일때도 있는게 컴파일러 기준으로 함수 내부의 값이 null이 아님을 체크했더라도 안전하다고 판단하지 못하는 경우가 있다 그래서 호출된 함수가 언제나 널이 아님이 확실하다면 사용하기 딱이다 그리고 참고?로 !! 이걸 한 라인에서 연속해서 사용하면 어디서 문제가 났는지 파악이 힘들다 그냥 어디줄에서만 에러났다고 나와서 파악하기 힘들기 때문에 연속으로 사용하는건 좋지 않다는 점

let 함수 let 함수는 원하는 식을 평가해서 결과가 널인지 검사한 다음에 그 결과를 변수에 넣는 작업을 간단한 식을 사용해서 한꺼번에 처리하는 것이 가능하다 가장 자주 사용하는 방식은 널이 될 수 있는 값을 널이 아닌 값만 인자로 받는 함수에 넘기는 경우이다 그러한 방식은 if(객체 != null) myFun(객체) 이런식으로 했었을 것이다 위의 식을 객체?.let { 객체 -> myFun(객체) }, 객체?.let{myFun(객체)} 이렇게 변경해주는 것이 가능하다 이것의 의미는 어떠한 객체가 null 이면 아무런 작업을 하지 않지만, let 람다 내부에서는 해당 객체가 Null이 아니라고 가정하고 식이 진행된다 아주 편리하게 보이는데, 이게 null 체크를 여러개 해야하는 경우에는 조금 코드가 복잡해져서 알아보기가 어렵다 그래서 null 체크가 많이 필요한거면 따로 if 으로 뺴서 검사하는게 좋긴하다

lateinit -> 나중에 초기화 코틀린에서는 일반적으로 생성자에서 모든 파라미터에 대한 초기화를 해줘야하며, 프로퍼티 타입이 널이 될 수 없는 타입이라면 반드시 널이 아닌 값으로 그 프로퍼티는 초기화 해줘야 한다 근데 초기화 값을 제공받으면 null이 될 수 없는 타입을 사용할 수 밖에 없다, 그럼 맨날 null 체크하던가 !! 을 써줘야 한다 그래서 사용하는게 lateinit으로 나중에 초기화하는 것이 가능하다 근데 val은 final이기 때문에 요건 적용못하고 var에서만 사용하는 것이 가능하다 이걸사용하고 만약에 초기화되기 전에 해당 프로퍼티에 접근하면 그냥 initialized 에러가 발생해서 찾기가 더 쉽다 애초에 nullpointerexception 보다는 바로 어디가 문제인지 파악하기 쉽다

null 이 될 수 있는 타입 확장 null이 될 수 있는 타입에 대한 확장 함수를 정의해두면 그냥 메소드 호출을 통해서 확장함수인 메소드가 알아서 널을 처리해준다 예를 들면 String에서 isEmpty나 isBlank이라는 함수가 존재하는데 각각의 메소드는 null로부터 안전한 메소드가 아닌다 null에 대한 체크가 없기 때문이다 근데 사실 isNullorEmpty, isNullorBlank 이러한 메소드가 있다 두 메소드의 역할은 다음과 같다 null이면 true를 반환하고 null이 아니면 isBlank을 호출한다 이렇게 null이 될 수 있는 타입에 대한 확장을 정의해주면 널이 될 수 있는 값에 대해 그 확장 함수를 호출하는 것이 가능하다 만약에 사용하는 것이 아니라 직접 확장함수를 작성한다면 그 확장 함수를 null이 될 수 있는 타입에 대해 정의할지에 대한 여부를 고민하고 내부에서 꼭 null에 대한 처리를 확인하자

타입 파라미터의 nullable 코틀린에서 함수나 클래스의 모든 타입 파라미터는 기본적으로 nullable이다 그리고 nullable 인 타입을 포함하는 어떤 타입이라도 타입 파라미터르 대신하는 것이 가능하다 타입 파라미터 T를 클래스나 함수 안에서 타입 이름으로 사용하면 ?이 없더라도 T는 nullable 이다 만약에 타입 파라미터가 null이 아닌 것을 확실히 하려면 null이 될 수 없는 타입 상한을 지정해야한다 근데 요 부분은 제네릭할때 다시 잘 봐보자

자바와 nullable 자바와 코틀린 사이에서는 코드의 막힘없이 서로 공유가 가능하고 잘 사용되는데, 코틀린은 널 세이프하지만 자바에서는 그걸 어떻게 처리할 수 있냐 자바에서도 @NotNull, @Nullable 이라는게 있으니까 자바와 코틀린을 혼재해서 사용할때는 같이 잘 사용해야할 듯

플랫폼 타입 플랫폼 타입이란 컴파일러가 널 관련 정보를 알 수 없는 타입이다 만약 해당 타입이 널이 될 수 있는 타입으로 처리해도 되고, 널이 될 수 없는 타입으로 처리해도 된다 약간 null에 대한 설정을 해주는 보다는 정말 자바에서처럼 널에 대한 위험성을 가지고 사용하는 느낌이다 그래서 null 체크를 2번하든 null safe 하지 않든 컴파일러가 전혀 신경쓰지 않는 타입이다 근데 안전하게 개발하도록 도와주는 걸 포기하고 이러한 타입을 사용할 때가 있는가에 대한 대답은 필요없는 null 체크가 있는 경우가 존재한다 이게 뭐 딱히 정해진 타입이 이러한 타입이에요 이런건 아니고 자바에서 @NotNull, @Nullable과 같은 null에 대한 애노테이션이 붙어있지 않은 그러한 소스를 코틀린에서 볼때 플랫폼 타입이다 이렇게 이야기하는 것이다 상속할 때도 자바의 메소드를 상속받을 때 메소드의 파라미터가 nullable일때와 notnull 일때의 두 가지 가능성을 고려해서 구현하는 것이 가능하다

코틀린의 원시 타입

자바에서 원시타입(primitive type), 참조타입(reference type) 이렇게 나누어지고, 프리미티브 타입에는 직접 값이 들어가지만 참조 타입은 메모리상의 객체 위치에 들어간다 원시 타입은 컬렉션에 넣거나 원시타입에 대한 메소드호출이 없기 때문에 만약에 사용하기 위해서는 굳이 또 Wrapper 타입을 통해서 프리미티브 타입을 감싸서 사용하곤 한다 근데 코틀린에서는 따로 구분하지 않고 공통 Int을 사용하기 때문에 간단하게 사용할 수 있다 더 신기한건 그냥 다 무시하고 항상 같은 타입을 사용하는 것이 아닌 실행 시점에 가장 효율적인 방식으로 표현된다

타입의 변환 코틀린에서는 하나의 타입의 숫자를 다른 타입의 숫자로 자동 변환해주지 않는다 대신 모든 원시 타입에 대한 변환함수를 to원시타입 이렇게 생긴 변환 함수를 제공해주기 때문에 타입 변환을 명시를 통해서 사용할 수 있으며 자바에서와 같이 overflow 에러도 날 수 있으니 유의해서 타입변환을 해야하며, 자바에서 사용했던 것 처럼 리터럴(long이면 L, float이면 F 등) 이렇게 리터럴을 허용한다

최상위 타입 Any, Any? 자바에서는 Object가 클래스의 최상위 타입인 것 처럼 코틀린에서는 Any가 모든 클래스의 최상위 타입이다 근데 자바에서는 int 같은건 원시타입이기 때문에 Integer로 감싸야 그제서야 Object을 상속한 개념이 되었다면 코틀린에서는 그냥 원시타입까지 한데 모아서 Any를 조상타입으로 가지고 있다 any는 널이 될 수 없는 타입이고, 널을 포함하는 모든 값을 대입할 변수를 선언하기 위해서는 Any? 이렇게 사용한다 그리고 내부에서 Any 타입은 java.lang.Object에 대응하기 때문에 자바 메소드에서 Object을 인자로 받거나 반환하면 코틀린에서는 Any로 그 타입을 취급하는 것이 가능하다

코틀린에서의 void타입인 Unit 코틀린에서 void을 표현할 때는 명시적으로 void 이렇게 선언하던가 아무런 키워드를 안적었었는데, Unit을 작성하는 것이 void을 선언하는 의미이다 코틀린에서 Unit으로 선언하고 그 함수가 제네릭 함수를 따로 상속받지 않는다면 그 함수는 내부적으로 void으로 컴파일된다 unit은 모든 기능을 갖는 일반적인 타입이고, unit을 인자로도 사용하는 것이 가능하다 이외에도 코틀린에서는 결코 성공적으로 값을 돌려주는 일이 없기 때문에 반환 값이라는 개념 자체가 의미 없는 함수가 있는데, Nothing 이라는 타입을 사용해주면 아무런 값도 포함하기 않아서 함수의 반환 타입이나 반환 타입으로 쓰일 타입 파라미터로만 사용될 수 있다 컴파일러는 Nothing이 반환 타입인 함수가 정상종료되지 않는 것을 알고 분석하기 쉽게 찾는 것이 가능한 것이다

컬렉션과 배열

타입 인자의 널 가능성에 대해서는 간단하게 봤었지만 이건 타입 시스템 일관성을 지키기 위해 필수적으로 확인해야하는 사항이다 컬렉션 안에 null 을 넣을 수 있는지에 대한 여부는 어떤 변수의 값이 널이 될 수 있는지 여부와 마찬가지로 중요하다 리스트에서 null을 체크하기 위해서 타입에서 ?을 통해서 null을 허용하거나 허용하지 않거나 작업할 수 도 있으며, filterNotNull 을 통해서 컬렉션안에 널이 없다는 것을 확인하는 것 등 이렇게 진행할 수 있다 코틀린에서의 컬렉션은 읽기 전용 컬렉션과 변경 가능 컬렉션이 존재한다 그래서 컬렉션을 생성할 때 방식이 다르다 List -> 읽기전용타입은 listOf 을 통해서 만들고 사용하거나 조회하는 것이 가능 -> 변경가능타입은 mutableListOf, arrayListOf Set -> 읽기전용타입은 setOf 을 통해서 -> 변경가능타입은 mutableSetOf, hashSetOf, linkedSetOf, sortedSetOf Map -> 읽기전용타입은 mapOf 을 통해서 -> 변경가능타입은 mutableSetOf, hashMapOf, linkedMapOf, sortedMapOf

리스트말고 배열은 어떻게 사용하나 코틀린에서 배열을 만드는 방법은 arrayOf 함수에 원소를 넘겨서 배열을 만드는 방식, arrayOfNulls 함수에 정수값을 인자로 넘겨서 모든 원소가 null이고 인자로 넘긴 값과 크기가 같은 배열을 만들 수 있다 그리고 배열 크기와 람다를 인자로 받아서 람다를 호출해서 각 배열 원소를 초기화하는 방식도 존재한다

Previous람다 방식Next연산자 오버로딩과 기타 관례

Last updated 2 years ago

Was this helpful?