먼지나는 블로그
Kotlin 개발 vs Java 개발 본문
1. NULL 처리
kotlin은 nullable한 타입과 nullsafe한 타입으로 구분됨
Integer a = 100;
val b: Int? = 100
val c: Int = 100
-> Integer 클래스 타입 변수 a에 100값을 넣어줌 ( Java로 작성됨 )
-> b는 nullable한 타입으로 null을 허용하지만 c는 null값을 허용하지 않는 nullsafe 타입임 ( Kotlin으로 작성됨 )
a = null;
/// 중략 ///
a.sum(); // NullPointException이 날 수 있음.
-> a에 null을 대입함 ( Java에서 Int로 쓸 경우 Primitive Type(기본자료형) 으로 null이 들어갈 수 없지만 Integer 클래스 타입이기 때문에 null을 대입할 수 있음 )
// null safe한 코드를 구성해야함
if (a != null)
a.sum();
}
-> a의 sum함수를 호출하게 되면 Java에선 a가 null이기 때문에 NullPointerException 즉, NPE가 일어남 (에러발생)
자바코드를 짤 땐 a가 null이 될 수 없도록 객체를 생성해주거나 a가 null이 아님을 예외처리 해야 함(or try catch문)
b?.sum() // null일 경우 실행하지 않음
c.sum() // 애초에 nullsafe 함
-> b의 sum함수를 호출하려고 할때 b는 nullable한 타입이기 때문에 실행하기 위해선 ?나 null safe type으로 치환해주는 !!를 붙여야 실행이 가능함
(컴파일 과정에서 b는 nullable한 타입이기 때문에 null처리가 되있지 않으면 NPE가 발생할 수 있기 때문임)
-> c는 애초에 null이 들어갈 수 없는 nullsafe한 타입이므로 동작하는 데 문제없음
2. Scope Funtion (범위 지정 함수)
kotlin에서는 간결한 코드를 작성하는데 도움을 주는 확장함수(extension function)를 제공함
확장함수는 람다를 인자로 받아 동작하는데 이때, 확장함수를 실행하는 주체를 수신자 또는 수신자 객체라 부르고
확장함수엔 범위지정함수(Scope Funtion) let with run apply also가 존재함
Fuction | Object reference | Return value | is extension funtion |
let | it | Lambda result | yes |
run | this | Lambda result | yes |
run | - | Lambda result | no |
with | this | Lambda result | no |
apply | this | Context object | yes |
also | it | Context object | yes |
2-1. Apply 함수
// Java로 작성할 시
Person person = new Person();
person.firstName = "Fast";
person.lastName = "Campus";
java로 구현한 코드를 살펴보면 중복되는 부분이 있는 것을 확인할 수 있음
이 부분을 간결하게 표현하기 위해서 apply함수를 이용해 아래의 코드로 표현할 수 있음
// Kotlin apply() 함수를 이용했을 때
val person = Person().apply{
firstName = "Fast" //this는 생략할 수 있음
lastName = "Campus"
}
-> apply함수는 객체의 확장함수로써 block 함수를 literal fuction receiver로 받음
따라서 내부에서 this를 통해 객체접근이 가능하고 해당 객체를 반환하게 됨 (주로 객체를 초기화할 때 사용됨)
2-2 Also 함수
Random.nextInt(100).also{ value ->
print("getRandomInt() generated value $value")
}
apply함수와는 다르게 T 즉, 객체가 parameter로 전달됨
Random.nextInt(100).also{
print("getRandomInt() generated value $it") //value를 생략하고 it을 통해 접근함
}
따라서 람다의 입력값으로 내려오게 되며 해당 람다의 입력값은 it으로 접근할 수 있게 됨
apply함수와 마찬가지로 해당 객체가 반환되며 객체의 유효성을 확인하거나 디버깅 용도로 사용됨
아래는 자바로 위의 코드와 같은 동작을 하는 예제코드
//자바로 구현했을 시
int value = Random().nextInt(100);
System.out.print(value);
2-3. Let 함수
// Kotlin
val number: Int?
val sumNumber = number?.let{
"${sum(10, it)}"
}
주로 null이 아닌 객체에서 람다를 실행할 떄 사용하는 함수 ( non-null 체크 시에 유용하게 사용됨)
람다를 실행할 때 사용되며 .?을 사용할 때 let 내에 들어오는 parameter의 변수는 절대 null이 아니게 됨
apply와 also 함수와는 다르게 객체 자신이 반환되는 것이 아닌 코드 block의 수행 결과가 반환되는 특징을 가지고 있음
-> number가 null이라면 let 뒤에 나오는 내용이 실행 되지않고 아니라면 it을 통해 number에 있는 값을 넘겨받게 됨
// Java
Integer number = null;
String sumNumberStr = null;
if(number != null){
sumNumberStr = "" + sum(10, number);
}
val number: Int?
val sumNumber = number?.let{
"${sum(10, it)}"
}.orEmpty()
String 멤버 함수 중 하나인 orEmpty() 함수를 이용할 수도 있음
String이 nullable일 경우 null인 String을 null이 아닌 빈값으로 변경시켜줌
2-4. With 함수
Person person = new Person();
person.work();
person.sleep();
System.out.println(person.age);
val person = Person()
with(person){
work()
sleep()
println(age)
}
with함수의 반환값은 람다의 결과값이다
with함수를 이용하여 person의 함수와 객체 work, sleep, age를 한꺼번에 실행함. (this 생략가능)
확장함수로는 사용할 수 없음
2-5. Run 함수
service.port = 8080
Result result = service.query()
val result = service.run{
port = 8080
query()
}
-> query()의 반환값이 result에 저장됨
특정 값을 계산할 필요가 있거나 객체구성(초기화)과 결과계산이 한꺼번에 이뤄질 때 유용하게 사용됨
With 함수와 비슷하게 람다의 결과값이 반환값이 된다
확장함수로 사용이 가능하다
3. Data Class
public class JavaObject {
private String s;
JavaObject(String s) {
this.s = s;
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
// copy
// toString
// hashCode 등등 생략
}
data class JavaObject(val s: String)
데이터를 저장하는 목적으로 만든 클래스
일반 Java Class와 달리 데이터클래스는 ToString. Hashcode, equals 등 함수를 알아서 생성함
가장 위에 있는 긴 코드를 한줄로 축약할 수 있음
4. Lamda Expression
button.setOnClickListener(new View.onClickListener() {
@override
public void onClick(View view) {
,,,
}
})
button.setOnClickListener { v ->
}
람다함수 : 함수에 함수를 전달하고 전달된 함수를 실행시키는 역할을 함
메소드가 하나만 있을 경우에는 아래코드처럼 간단하게 람다식으로 표현할 수 있음 (v를 생략하고 it으로 가능)
5. lateinit, lazy init
var nullableNumber: Int? = null
lateinit var lateinitNumber: Int
// 추후 초기화하는 코드
lateinitNumber = 10
// 사용할 때
nullableNumber?.add()
lateinitNumber.add()
lateinit : NullSafe한 코드를 사용하기 위해 non-null Type으로 변수를 선언함
즉, 추후에 초기화할 것임을 명시해 선언 시 non-null Type으로 지정됨
따라서 선언 후 초기화 해주지 않으면 에러가 발생함
val lazyNumber: Int by lazy {
100
}
// 사용하기 전까지는 lazyNumber 라는 변수에 100 이 할당되지 않음.
lazyNumber.add()
// 사용할 때 100이 할당됨
lazyinit : 변수를 사용하기 전까지는 값이 할당되지 않음
'내맘대로 공부 > kotlin' 카테고리의 다른 글
kotlin firebase 설정 및 로그인 구현 (0) | 2021.07.15 |
---|---|
Kotlin Collection 개념 (0) | 2021.07.11 |
BMI 계산기 구현 (0) | 2021.07.10 |
kotlin 문법 훑어보기 (+추가) (1) | 2021.07.05 |