null์ ์ฐธ์กฐํ ๋ ๋ฐ์ํ๋ NullPointerExeption(NPE)๊ฐ ํฐ์ง๋ ๊ฒ์ ๋ฐฉ์งํ๋ค.
์ฌ๊ธฐ์ ๋ฐฉ์ง๋ ์ปดํ์ผ ํ์์ NPE๋ฅผ ์ฐพ์๋ด๋ ๊ฒ์ด๋ค.
[ java ]
[ ์๋ ์ฝ๋๋ ์คํ๋๊ณ ๋ฐํ์์ NPE๋ฅผ ๋ฐ์์ํจ๋ค. ]
String str = "str";
str = null;
[ Kotlin ]
[ ์ด๋ ์ฝ๋๋ ์ปดํ์ผ ํ์์ ์๋ฌ๋ฅผ ๋ฐ์์ํจ๋ค. ]
str: String = "str"
str = null
Kotlin์์ null์ ํ์ฉํ๊ณ ์ ํ๋ค๋ฉด? (nullable)
var str: String? = "str"
str = null
null์ ํ์ฉํ ์ ์๊ฒ ๋์๋๋ฐ null์ ์ฐธ์กฐํด์ NPE๊ฐ ํฐ์ง๋ ์ํฉ์ ์ํ๋ ๊ฒ์ ์ ๋ ์๋๋ค. ์์ ํ๊ฒ null์ ํ์ฉํ๋ ํ๋กํผํฐ์ ์ ๊ทผํ ์ ์์ด์ผ ํ๋ค.
์ด๋ฅผ ์ํด ?.
๋ฌธ๋ฒ์ ์ง์ํ๋ค.
?.
๋ฅผ ๊ธฐ์ค์ผ๋ก ์ผ์ชฝ ํ๋กํผํฐ๊ฐ null์ด๋ผ๋ฉด ์ฐธ์กฐ์ฐ์ฐ์ ๊ฒฐ๊ณผ null์ ๋ฆฌํดํ๊ณ null์ด ์๋๋ผ๋ฉด ์ ์์ ์ผ๋ก ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.
fun test() {
var str: String? = "str"
println(str?.length)
str = null
print(str?.length)
}
๋ค์์ผ๋ก ์๋น์ค ์ฐ์ฐ์์ด๋ค. ?:
์๋น์ค ์ฐ์ฐ์๋ null์ ์ฐธ์กฐํ์ ๋ null์ด ์๋ ํน์ ๊ฐ์ ๋ฆฌํดํ ์ ์๋ค.
fun test() {
var str: String? = "str"
println(str?.length)
str = null
print(str?.length ?: "์ด๊ฑด null..")
}
null safetyํ์
์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ต์ํ์ง ์์์ ์๊ฐ๋ณด๋ค ๋ฒ๊ฑฐ๋กญ๋ค. ์ํฐํฐ ํด๋์ค๋ฅผ ๊ตฌ์ฑํ ๋ id
ํ๋๋ ๋ฐ๋์ ?
ํ์
์ด ๋๋ค. (save๋ ๋ idํ๋๊ฐ ์ฑ์์ง๊ธฐ ๋๋ฌธ) id๊ฐ์ ๊ต์ฅํ ๋น๋ฒํ๊ฒ ์ฌ์ฉ๋๋๋ฐ ์ฌ์ฉํ ๋๋ง๋ค ๋ณ๊ฑฐ ์๋์ง๋ง ๋ถ๊ฐ์ ์ธ ์ฒ๋ฆฌ๋ฅผ ํ๋ ๊ฒ์ด ๊ฝค๋ ๋ฒ๊ฑฐ๋กญ๋ค. (์ปดํ์ผ ์๋ฌ๊ฐ ๋๋ฌด ๋ง์ด ๋๋ค..)
ํ์ง๋ง ์ด ๊ฒฐ๊ณผ NPE๋ฅผ ๋ง๋์ง ์๋๋ค๋ฉด ์ถฉ๋ถํ ๊ฐ์น๊ฐ ์๋ ๊ฒ์ด๋ผ ์๊ฐํ๋ค.
Member
์ํฐํฐ์ id๊ฐ์ผ๋ก Member
๋ฅผ ์กฐํํ๋ ๊ฒฝ์ฐ๋ฅผ ์๊ฐํด๋ณด์.
Java
์ ๊ฒฝ์ฐ JPA
์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ findById
๋ฉ์๋๋ Optional
ํ์
์ ๋ฐํํ๋ค.
์ด ๋ถ๋ถ์ kotlin null-safety๋ฅผ ์ฌ์ฉํด์ ๊ตฌํํด๋ณธ๋ค.
@Transactional(readOnly = true)
fun getMember(memberId: Long) : MemberResponseDto {
// ์ผ๋ฐ์ ์ธ findById๋ java์ Optional์ ๋ฆฌํดํ๋ค.
// findByIdOrNull๊ณผ ์๋น์ค ํํ์์ผ๋ก findById๋ฅผ ๋์ ํ๋ค.
val findMember: Member = memberRepository.findByIdOrNull(memberId) ?: throw IllegalArgumentException("์กด์ฌํ์ง ์๋ ID ์
๋๋ค.")
return MemberResponseDto(findMember.id, findMember.username)
}
findByIdOrNull
๋ฉ์๋๋ ์กฐํ๊ฒฐ๊ณผ๊ฐ ์๋ค๋ฉด null์ ๋ฐํํ๋ค.
?:
์๋น์ค ํํ์์ ์ด์ฉํด์ null ๊ฐ์ ๋ํด ๋์์ ์ ์ํ ์ ์๋ค. ์ ์์ ์ ๊ฒฝ์ฐ null ์ธ ๊ฒฝ์ฐ ์์ธ๋ฅผ ๋ฐ์์์ผฐ๋ค.