- TIP : 숫자 작성할 때 var number = 1_000L 과 같이 작성 가능
1. 변수
- val collections에도 element는 추가할 수 있음
- primitive, reference type 구분 없지만, 실제 연산할떈 primitive type으로 변환되어 연산됨
2. Null 처리
- Safe Call ( ?. ) : null이 아니면 실행, null이면 실행하지 않음
|
|
- Elvis 연산자 ( ?: ) : 앞의 연산 결과가 null이면 뒤의 값을 사용
|
|
- 플랫폼 타입 : Kotlin에서 Java 코드를 가져왔을 때
- null, nonnull 타입 둘 다 사용 가능
- 가능하면 Java 코드 직접 확인하거나, Kotlin으로 wrapping하여 사용하자.
|
|
3. Type
- 기본 Type 변환 : 기본 타입끼리는 toXX 같은 함수를 사용
|
|
- 사용자 정의 Type : 스마트 캐스트 (Smart Cast) 활용
|
|
- Any : Java의 Object 역할 + Primitive Type의 최상위도 포함
- null은 포함 X, null도 포함하고 싶다면 Any?로 사용
- equals, hashCode, toString 존재
- Unit : void 비슷, 하지만 Unit은 그 자체로 제네릭에서 타입 인자로 사용 가능
- Nothing : 함수가 정상적으로 끝나지 않았음을 표시
|
|
- String interpolation
|
|
- String indexing
|
|
4. 연산자
Kotlin에선 >, < , ≥, ≤ 사용하면 자동으로 compateTo 호출해줌
== (값 비교,동등성 : equals 자동 호출 ) , === (주소 비교, 동일성 : 같은 0x101 주소)
in, !in : 컬렉션 / 범위에 포함되어 있는지?
a..b : a부터 b까지의 범위 객체를 생성
|
|
- 연산자 오버로딩
|
|
5. 조건문
- if문은 Kotlin에선 expression (Java에선 statement)
- expression : 하나의 값으로 평가될 수 있는 문장
|
|
Java에선 삼항연산자가 expression이지만, Kotlin은 if문이 expression이므로 삼항 연산자가 필요x
- 따라서 삼항 연산자가 없음
When문
|
|
6. 반복문
- forEach
|
|
- Progression : 등차수열, Range (Range는 Progression을 상속받음)
|
|
7. 예외
- try-catch-finally : 그대로 (단, kotlin에선 expression, return 등 사용 가능)
- Kotlin에서는 모든 에러가 Unchecked Exception
- Checked : 무조건 처리해줘야 하는 Exception
- Unchecked Exception : 꼭 처리하지 않아도 되는..
- try with resources
|
|
8. 함수
- 기본
|
|
- Default paramters
|
|
- named argument ( 파라미터 이름을 명시 가능, builder 비슷하게 사용 가능)
|
|
- 가변인자 (vararg)
|
|
9. 클래스
- 클래스와 프로퍼티
|
|
- 생성자 검증, init
|
|
- Custom getter, Setter
|
|
10. 상속
- 추상 클래스
|
|
- 상속 받는 클래스
|
|
- Interface
|
|
- Interface 구현 클래스
|
|
- Backing Field (getter, setter가 제공되는 property) 를 Interface에 선언 가능
|
|
- 클래스 상속시 주의할 점 (초기화 실행 순서)
- 상위 Class의 Constructor, Init 블락에선 하위 클래스의 Field에 접근하지 말 것!
- 상위 Class의 Constructor, Init 블럭에 사용되는 Property는 open 사용하지 말자!
|
|
- 키워드 정리
- final (기본, 생략가능) : override 할 수 없게 막는다.
- open : override를 열어 준다.
- abstract : 반드시 override 해야 한다.
- override: 상위 타입을 오버라이드 한다. (Java에선 Annotation이지만 Kotlin에선 키워드)
11. 접근 제어
Java, Kotlin의 접근 제어
- Public
- Java/Kotlin : 모든 곳에서 접근 가능
- Protected
- Java : 같은 패키지, 또는 하위 클래스에서 접근 가능
- Kotlin : 선언된 클래스, 또는 하위 클래스에서만 접근 가능
- default(Java) / internal(Kotlin)
- Java : 같은 패키지에서만 접근 가능
- Kotlin : 같은 Module에서만 접근 가능
- Module : 한 번에 컴파일되는 Kotlin 코드 (같은 Gradle 프로젝트 등..)
- private
- Java/Kotlin : 선언된 클래스 내에서만 접근 가능
- Public
Property 접근 지시어
|
|
- Java/Kotlin 혼합 사용시 주의점
- Internal 키워드는 Bytecode 변환 (Java 변환시) public으로 변환됨
- 따라서 Java 코드에서는, Kotlin에서의 Internal 키워드를 가져올 수 있음
- Kotlin의 Prtotected 또한 마찬가지 (Java에서는 같은 패키지에서도 접근 가능)
12. object
- static 함수와 변수
- static : 정적으로 인스턴스끼리의 값을 공유
- companion object : 클래스와 동행하는 유일한 object
|
|
- Companion Object 활용 (Java와의 차이점)
- 하나의 객체로 간주됨
- 따라서 이름을 붙이거나 Interface 만들 수 있음
|
|
- Singleton
- object 키워드 사용
|
|
- 익명 클래스 (Anonymous class)
- 특정 Interface, Class 상속받은 구현체를 일회성으로 사용할 때
|
|
13. 중첩 클래스 (nested class)
- 자주 안 쓸 것 같아서 생략..
14. Data class, Enum class, Sealed Class/Interface
- Data class
- DTO를 편하게 사용 가능
- field, constructor, getter, equals, hashCode, toString 를 기본적으로 제공
|
|
- Enum class
|
|
- Sealed Class/Interface
- 상속이 가능한 추상 클래스를 만들고 싶은데, 외부에서는 상속하지 못 했으면 좋겠다
- 컴파일 타임에 하위 클래스 타입을 모두 기억해, 런타임때 다른 클래스 타입 추가 불가
- 하위 클래스는 같은 패키지에 있어야 함
- Enum과의 차이점
- Class 상속 가능
- Enum은 인스턴스가 싱글톤이지만, Sealed Class는 멀티 인스턴스 가능
|
|
15. Collections (컬렉션)
Collections
- 컬렉션이 불변인지, 가변인지 설정 필요
- Mutable(가변) 컬렉션 : element 추가,삭제 가능
- Immutable(불변) 컬렉션 : element 추가,삭제 불가
- 단, 불변 컬렉션이라도 Reference Type의 엘리먼트 필드는 바꿀 수 있다.
- 예를 들어서, Index 1번 데이터에 접근해서 Price 필드를 1000 → 2000원으로 바꾸는건 가능
List
|
|
- Set
|
|
- Map
|
|
컬렉션의 null 가능성
- List<Int?> : List 자체는 null X, 리스트 안에는 nullable
- List? : List 자체는 nullable, 리스트 안에는 null X
- List<Int?>? : List 자체도 nullable, 리스트 안에도 nullable
Java와 혼용시 주의할 점
- Java는 불변/가변 리스트를 구분하지 않음
- Kotlin의 불변 리스트를, Java에서 가변 리스트처럼 사용할 수 있음
- Kotlin의 Non-null 리스트를, Java에서 null을 추가할 수 있음
- Kotlin에서 Collections.unmodifiable을 사용하거나, 방어 로직 사용
- Platform Type으로 타입 문제 생길 수 있음
- Java는 불변/가변 리스트를 구분하지 않음
16. Extension(확장), Infix(중위) , inline, Local(지역) 함수
- 확장 함수
- Kotlin : Java와의 100% 호환성을 목표로함
- 그래서 Java로 만들어진 라이브러리에 Kotlin 코드가 추가 가능하면 좋겠다
- 클래스 내부 메소드처럼 사용하지만, 코드는 외부에 작성할 수 있게 하자!
- 제한 :
- 확장함수가 public인데, private, protected 멤버를 가져오면 캡슐화가 깨지므로..
- 캡슐화 유지 위해, private, proteced 멤버 가져올 수 없음
- 멤버함수/ 확장함수의 시그니쳐(이름) 같은 경우
- 멤버 함수가 우선적으로 호출
- 따라서, 멤버함수가 이후 추가된다면 오류 생길 수도 있다.
- 확장함수가 public인데, private, protected 멤버를 가져오면 캡슐화가 깨지므로..
- Kotlin : Java와의 100% 호환성을 목표로함
|
|
- 중위 함수
- 변수, argument가 각각 하나씩만 있는 경우
- var.functionName(argument) 대신
- var functionName argument로 호출 가능
|
|
- 인라인 함수
- 우리가 아는 그 인라인 함수..
- 함수를 파라미터로 전달하는 오버헤드 줄일 수 있음
|
|
- 지역 함수
- 함수 안의 함수
|
|
17. lambda
Java에서는 함수를 변수 할당, 파라미터로 전달 불가 (1급 객체 X)
- Fruit::isApple 처럼 가능한 것 처럼 보이지만, 실제로는 Predicate라는 Interface를 넘김
Kotlin에서는 함수를 변수 할당,파라미터로 전달 가능 (1급 객체 O)
lambda 생성, 호출
|
|
- Parameter로 함수 받기
|
|
- Closure
- Kotlin은 lambda가 실행되는 시점에, 참조하고 있는 변수들을 모두 포획해서 값을 가진다.
- 아래 코드에선 targetFruitName =”수박” 시점을 포획해서 가지고 있는다.
- 이러한 데이터 구조를 Closure라고 부르고, 이런 구조여야 lambda가 1급 객체일 수 있다.
|
|
18. Collection 내장 함수+ FP
- filter
|
|
- filterIndexed : filter에서 index가 필요한 경우
|
|
map, mapIndex : 각각의 원소에 대해 lambda 함수 실행
mapNotNull : mapping의 결과가 null이 아닌 것만 추출
|
|
- all : 조건을 모두 만족하면 true, 아니면 false
|
|
- none : 조건을 모두 불만족하면 true, 아니면 false
|
|
- any : 하나라도 만족하면 true, 아니면 false
|
|
- count : 개수
|
|
- sortedBy, sortedByDescending : 오름차순, 내림차순 정렬
|
|
- distinctBy : 변경된 값을 기준으로 중복 제거
|
|
- first, firstOrNull, last, lastOrNull : 첫번째, 마지막 값
- 빈 리스트라서 first, last가 가져올 값이 없으면 Exception 발생
|
|
- groupBy : 어떤 Key를 기준으로 Grouping (List → Map)
|
|
- associateBy : 어떤 중복되지 않는 Key를 기준으로 Map 변환(List→ Map)
- 단, id가 중복값 있을 시 값이 유실될 수 있다.
- id가 중복값인 경우, 가장 마지막 값이 value가 된다.
|
|
- Map에서도 위의 함수들 대부분 사용 가능
|
|
- 중첩된 Collections 처리
- flatMap, flatten
|
|
19. TakeIf, scope Function
- TakeIf : 주어진 조건을 만족하면 그 값이, 그렇지 않으면 null 반환
- TakeUnless : 주어진 조건 만족하지 않으면 그 값이, 그렇지 않으면 null 반환
|
|
- Scope function : 일시적인 영역을 형성하는 함수
- 즉, lamba를 활용해 일시적 영역을 만들고
- 코드를 더 간결하게 하거나
- method chaining에 활용하는 함수
- 즉, lamba를 활용해 일시적 영역을 만들고
|
|
- Scope function의 종류
- let, run : lambda의 결과를 반환
- let : it 사용 (생략 불가능한 대신, 다른 이름 붙일 수 있음)
- run : this 사용 (생략 가능한 대신, 다른 이름 붙일 수 없음.)
- also, apply : 객체 자체를 반환
- also : it 사용
- apply : this 사용
- with : 유일하게 확장함수 아님. this 사용, lambda의 결과를 반환
- let, run : lambda의 결과를 반환
|
|