#1. null κ°λ₯μ± (nullability)
NPEλ₯Ό νΌν μ μκ² λκΈ° μν μ½νλ¦° νμ μμ€ν μ νΉμ±
Nullable νμ
μ½νλ¦° νμ μμ€ν μ΄ nullμ΄ λ μ μλ νμ μ λͺ μμ μΌλ‘ μ§μνλ€.
νμ
μ΄λ¦ λ€μ ?
λ₯Ό λΆμ΄λ©΄ κ·Έ νμ
μ λ³μλ νλ‘νΌν°μ null μ°Έμ‘°λ₯Ό μ μ₯ν μ μλ€.?
κ° μλ νμ
μ κ·Έ λ³μκ° null μ°Έμ‘°λ₯Ό μ μ₯ν μ μλ€.
- Nullable νμ
μΈ λ³μμ λν΄
λ³μ.λ©μλ()
μ²λΌ λ©μλλ₯Ό μ§μ νΈμΆν μλ μλ€. - Nullable κ°μ NonNull νμ μ λ³μμ λμ ν μ μλ€.
val x: String? = null
val y: String = x //=> Error: Type mismatch: inferred type is String? but String was expected
- Nullable νμ μ κ°μ NonNull νμ μ νλΌλ―Έν°λ₯Ό λ°λ ν¨μμ μ λ¬ν μ μλ€.
nullμ΄ μλμ΄ νμ€ν μμμμλ ν΄λΉ κ°μ NonNull νμ μ κ°μ²λΌ μ¬μ©ν μ μλ€.
fun strLenSafe(s: String?): Int =
if (s != null) s.length else 0
>>> val x: String? = null
>>> println(strLenSafe(x))
0
>>> println(strLenSafe("abc"))
3
μλ°μ Optionalκ³Ό μ°¨μ΄μ
Optionalμ μ΄λ€ κ°μ΄ μ μλκ±°λ μ μλμ§ μμ μ μμμ νννλ λνΌ νμ
μ΄λ€.
μ½λκ° μ§μ λΆν΄μ§κ³ , λνΌκ° μΆκ°λμ΄ μ€ν μμ μ±λ₯μ μν₯μ μ€λ€.
μ½νλ¦°μ Nullable νμ κ³Ό NonNull νμ μ μ€ν μμ μ κ°μ νμ μ΄λ€. λͺ¨λ κ²μ¬λ μ»΄νμΌ νμμ μνλμ΄, λ³λμ μ€ν μμ λΆκ° λΉμ©μ΄ λ€μ§ μλλ€.
μμ ν νΈμΆ μ°μ°μ .?
null κ²μ¬μ λ©μλ νΈμΆμ ν λ²μ μ°μ°μΌλ‘ μννλ€.
νΈμΆνλ €λ κ°μ΄ nullμ΄ μλλΌλ©΄ .?
μ μΌλ° λ©μλ νΈμΆμ²λΌ λμνλ€.
nullμ΄λ©΄ μ΄ νΈμΆμ 무μλκ³ nullμ΄ λ°νλλ€.
.?
νΈμΆμ κ²°κ³Ό νμ
μ Nullableμ΄λ€.
μλΉμ€ μ°μ°μ :?
null λμ μ¬μ©ν λν΄νΈ κ°μ μ§μ ν λ μ¬μ©νλ€.
fun foo(s: String?) {
val t: String = s ?: "" // sκ° nullμ΄λ©΄ ""μ΄ κ²°κ³Ό
}
μλΉμ€ μ°μ°μμ μ°νμ return
, throw
λ±μ μ°μ°μ λ£μ μ μλ€.
(μ½νλ¦°μμλ return
, throw
λ±μ μ°μ°λ μμ΄λ€.)
=> μ΄ κ²½μ° μ’νμ΄ nullμ΄λ©΄ μ¦μ μ΄λ€ κ°μ λ°ννκ±°λ μμΈλ₯Ό λμ§λ€.
μμ ν μΊμ€νΈ as?
as?
λ μ΄λ€ κ°μ μ§μ ν νμ
μΌλ‘ μΊμ€νΈνλλ°, λμ νμ
μΌλ‘ μΊμ€ν
ν μ μμΌλ©΄ nullμ λ°ννλ€.
class Person(val firstName: String, val lastName: String) {
override fun equals(o: Any?): Boolean {
val otherPerson = o as? Person ?: return false // νμ
μ΄ μΌμΉνμ§ μμΌλ©΄ false λ°ν
// μμ ν μΊμ€νΈλ₯Ό νκ³ λλ©΄ μ€λ§νΈ μΊμ€νΈλλ€.
return otherPerson.firstName == firstName &&
otherPerson.lastName == lastName
}
override fun hashCode(): Int =
firstName.hashCode() * 37 + lastName.hashCode()
}
null μλ λ¨μΈ !!
NonNull νμ
μΌλ‘ (κ°μ λ‘) λ°κΏ μ μλ€.
nullμΈ κ°μ μ¬μ©νλ©΄ NPEκ° λ°μνλ€.
[μ€μ]
!!
λ₯Ό nullμ μ¬μ©νμ¬ λ°μν μμΈ μ€ν νΈλ μ΄μ€μλ μ΄λ€ μμμ μμΈκ° λ°μνλμ§ λ΄κ²¨ μμ§ μλ€. μ΄λ€ κ°μ΄ nullμ΄μλμ§ νμ€ν νκΈ° μν΄μλ !!
λ₯Ό ν μ€μ μ¬λ¬ κ° μ°λ μΌμ νΌνλ κ²μ΄ μ’λ€.
μ»΄νμΌλ¬κ° κ²μ¦ν μ μλ λ¨μΈμ μ¬μ©νκΈ° 보λ€λ λ λμ λ°©λ²μ μ°Ύμ보λΌλ μ€κ³μλκ° λ΄κ²¨μλ€.
let
ν¨μ
let
ν¨μλ μμ μ μμ κ°μ²΄λ₯Ό μΈμλ‘ μ λ¬λ°μ λλ€μ λκΈ΄λ€.
let
μ μ¬μ©νλ κ°μ₯ νν μλ Nullable κ°μ NonNullλ§ λ°λ ν¨μμ νλΌλ―Έν°λ‘ λκΈ°λ κ²½μ°μ΄λ€.foo?.let { β¦ }
κ³Ό κ°μ΄ μμ ν νΈμΆ ꡬ문μ μ¬μ©νμ¬ νΈμΆνλ©΄, NonNull νμ
μ μΈμλ‘ λ°λ λλ€λ₯Ό let
μ μ λ¬νλ€.
μ¬λ¬ κ°μ΄ nullμΈμ§ κ²μ¬ν΄μΌ νλ€λ©΄, let
νΈμΆμ μ€μ²©μμΌμ μ²λ¦¬ν μλ μμ§λ§ μ€μ²©μν€λ©΄ μ½λκ° λ³΅μ‘ν΄μ Έμ μμ보기 μ΄λ €μμ§λ€. μ΄ κ²½μ°μλ μΌλ°μ μΈ if λ¬Έμ μ¬μ©ν΄ λͺ¨λ κ°μ ν λ²μ κ²μ¬νλ νΈμ΄ λ«λ€.
λμ€μ μ΄κΈ°νν νλ‘νΌν°
lateinit
λ³κ²½μλ₯Ό λΆμ΄λ©΄ νλ‘νΌν°λ₯Ό λμ€μ μ΄κΈ°νν μ μλ€.
μ΄ νλ‘νΌν°λ νμ var
μ΄μ΄μΌ νλ€.
(val
νλ‘νΌν°λ final νλλ‘ μ»΄νμΌλλ©°, μμ±μ μμμ λ°λμ μ΄κΈ°νν΄μΌ νλ€.)
class MyService {
fun performAction(): String = "foo"
}
class MyTest {
private lateinit var myService: MyService // λμ€μ μ΄κΈ°νν NonNull νλ‘νΌν° μ μΈ
@Before fun setUp() {
myService = MyService()
}
@Test fun testAction() {
Assert.assertEquals("foo", myService.performAction())
}
}
Nullable νμ μ νμ₯ ν¨μ
fun String?.isNullOrBlank(): Boolean =
this == null || this.isBlank()
Nullable νμ
μ λν νμ₯ ν¨μλ₯Ό μ μνλ©΄, Nullable κ°μ λν΄ κ·Έ νμ₯ ν¨μλ₯Ό νΈμΆν μ μλ€. ν΄λΉ ν¨μ λ΄μμ this
λ nullμ΄ λ μ μλ€.
νμ νλΌλ―Έν°μ null κ°λ₯μ±
νμ
νλΌλ―Έν° T
λ₯Ό ν΄λμ€λ ν¨μ μμμ νμ
μ΄λ¦μΌλ‘ μ¬μ©νλ©΄ μ΄λ¦ λμ ?
κ° μλλΌλ T
λ nullμ΄ λ μ μλ νμ
μ΄λ€.
fun <T> printHashCode(t: T) { // Tμ νμ
μ Any?λ‘ μΆλ‘ λλ€.
println(t?.hashCode())
}
nullμ΄ μλμ λͺ μνλ €λ©΄ nullμ΄ λ μ μλ upper boundλ₯Ό μ§μ ν΄μΌ νλ€.
fun <T: Any> printHashCode(t: T) { // Tλ nullμ΄ λ μ μλ νμ
μ΄λ€.
println(t.hashCode())
}
νμ νλΌλ―Έν°λ nulμ΄ λ μ μλ νμ μ νμνλ €λ©΄ λ°λμ λ¬Όμνλ₯Ό νμ μ΄λ¦ λ€μ λΆμ¬μΌ νλ€.
null κ°λ₯μ±κ³Ό μλ°
μλ°μ @Nullable String
μ μ½νλ¦°μμ String?
κ³Ό κ°κ³ , @NotNull String
μ String
κ³Ό κ°λ€.
νλ«νΌ νμ
: μλ°μ νμ μ€ μ½νλ¦°μ΄ null κ΄λ ¨ μ 보λ₯Ό μ μ μλ νμ
μ½νλ¦°μμ νλ«νΌ νμ
μ μ μΈν μλ μλ€. μλ° μ½λμμ κ°μ Έμ¨ νμ
λ§ νλ«νΌ νμ
μ΄ λλ€.!
νκΈ°λ String!
νμ
μ null κ°λ₯μ±μ λν΄ μ무 μ 보λ μλ€λ λ»μ΄λ€.
μλ°μμ κ°μ Έμ¨ null κ°μ μ½νλ¦°μ NonNull λ³μμ λμ
νλ©΄ μ€ν μμ μ μμΈκ° λ°μνλ€.
#2. μ½νλ¦°μ μμ νμ (Primitive type)
- μλ°λ μμ νμ
κ³Ό μ°Έμ‘° νμ
μ ꡬλΆνλ€.
- μμ νμ λ³μμλ κ·Έ κ°μ΄ μ§μ λ€μ΄κ°μ§λ§, μ°Έμ‘° νμ λ³μμλ λ©λͺ¨λ¦¬μμ κ°μ²΄ μμΉκ° μ μ₯λλ€.
- μ½νλ¦°μ μμ νμ
κ³Ό λνΌ νμ
μ ꡬλΆνμ§ μλλ€.
- νμ κ°μ νμ μ μ¬μ©νλ©°, μμ νμ μ κ°μ λν΄ λ©μλλ₯Ό νΈμΆν μ μλ€.
μμ νμ : Int, Boolean λ±
μ€ν μμ μ μ«μ νμ
μ κ°μ₯ ν¨μ¨μ μΈ λ°©μμΌλ‘ ννλλ€.
λλΆλΆμ κ²½μ°, μ½νλ¦° Int
νμ
μ μλ°μ int
λ‘ μ»΄νμΌλλ€.
Int
μ κ°μ΄ nullμ΄ λ μ μλ νμ
μ κ·Έμ μμνλ μλ° μμ νμ
μΌλ‘ μ»΄νμΌν μ μλ€.
λ°λλ‘ μλ° μμ νμ
μ nullμ΄ λ μ μμΌλ―λ‘, μ½νλ¦°μμ μ¬μ©ν λ nullμ΄ λ μ μλ νμ
μΌλ‘ μ·¨κΈν μ μλ€.
nullμ΄ λ μ μλ μμ νμ : Int?, Boolean? λ±
nullμ΄ λ μ μλ μμ νμ
μ μλ° μμ νμ
μΌλ‘ ννν μ μλ€.
Nullable μμ νμ
μ μλ°μ λνΌ νμ
μΌλ‘ μ»΄νμΌλλ€.
μ λ€λ¦ ν΄λμ€μ κ²½μ°μλ λνΌ νμ
μ μ¬μ©νλ€.
JVMμ νμ
μΈμλ‘ μμ νμ
μ νμ©νμ§ μκΈ° λλ¬Έμ, μλ°μ μ½νλ¦° λͺ¨λ μ λ€λ¦ ν΄λμ€λ νμ λ°μ€ νμ
μ μ¬μ©ν΄μΌ νλ€.
μ«μ λ³ν
μ½νλ¦°μ ν νμ μ μ«μλ₯Ό λ€λ₯Έ νμ μ μ«μλ‘ μλ λ³ννμ§ μλλ€.
val i = 1
val l: Long = i.toLong() // λ³ν λ©μλλ₯Ό μ§μ νΈμΆν΄μ€μΌ νλ€.
μ½νλ¦°μ Booleanμ μ μΈν λͺ¨λ μμ νμ
μ λν λ³ν ν¨μλ₯Ό μ 곡νλ€.
(toInt()
, toByte()
, β¦)
μ½λμμ λμμ μ¬λ¬ μ«μ νμ μ μ¬μ©νλ €λ©΄ μμμΉ λͺ»ν λμμ νΌνκΈ° μν΄ κ° λ³μλ₯Ό λͺ μμ μΌλ‘ λ³νν΄μΌ νλ€.
Any, Any?: μ΅μμ νμ
Any νμ
μ΄ μ½νλ¦°μ λͺ¨λ nullμ΄ λ μ μλ νμ
μ μ‘°μ νμ
μ΄λ©°, Int λ±μ μμ νμ
λ λͺ¨λ ν¬ν¨λλ€.
nullμ ν¬ν¨νλ λͺ¨λ κ°μ λμ
ν λ³μλ₯Ό μ μΈνλ €λ©΄ Any?λ₯Ό μ¬μ©νλ€.
λ΄λΆμ μΌλ‘ Any νμ
μ μλ°μ Objectμ λμνλ€. νμ§λ§ toString
, equals
, hashcode
λ₯Ό μ μΈν Objectμ wait
, notify
λ±μ λ©μλλ Anyμμ μ¬μ©ν μ μλ€. μ¬μ©νλ €λ©΄ java.lang.Objectλ‘ μΊμ€ν
ν΄μΌ νλ€.
Unit: μ½νλ¦°μ void
Unit νμ
μ μν κ°μ λ¨ νλλΏμ΄λ©°, κ·Έ μ΄λ¦λ Unitμ΄λ€.
Unit νμ
μ ν¨μλ 묡μμ μΌλ‘ Unit κ°μ λ°ννλ€.
voidμ λ¬λ¦¬ Unitμ νμ μΈμλ‘ μΈ μ μλ€.
interface Processor<T> {
fun process(): T
}
class NoResultProcessor : Processor<Unit> {
override fun process() {
// do stuff
}
}
Nothing νμ : μ΄ ν¨μλ μ λ μ μμ μΌλ‘ λλμ§ μλλ€.
Nothingμ ν¨μμ λ°ν νμ
μ΄λ λ°ν νμ
μΌλ‘ μ°μΌ νμ
νλΌλ―Έν°μλ§ μΈ μ μλ€.
ν¨μκ° κ²°μ½ μ μ μ’
λ£λμ§ μμ(μμΈ λ°μ, ν
μ€νΈ μ€ν¨ λ±)μ ννν λ μ¬μ©νλ€.
#3. 컬λ μ κ³Ό λ°°μ΄
null κ°λ₯μ±κ³Ό 컬λ μ
List<Int?>
- 리μ€νΈ μ체λ νμ nullμ΄ μλλ€.
- 리μ€νΈ μμ κ° κ°μ΄ nullμ΄ λ μ μλ€.
List<Int>?
- μ 체 리μ€νΈκ° nullμ΄ λ μ μλ€.
- 리μ€νΈ μμλ nullμ΄ λ€μ΄κ° μ μλ€.
-> nullμ΄ λ μ μλ κ² μ»¬λ μ μ μμμΈμ§ 컬λ μ μ체μΈμ§ μ£Όμν΄μΌ νλ€.
nullμ΄ λ μ μλ κ°μ κ°λ 컬λ μ μμ null κ°μ κ±Έλ¬λ΄λ κ²½μ°,
filterNotNull
μ΄λΌλ ν¨μλ₯Ό μ΄μ©νλ©΄ νΈλ¦¬νλ€.
μ½κΈ° μ μ©κ³Ό λ³κ²½ κ°λ₯ν 컬λ μ
Collection
: μμλ₯Ό μΆκ°νκ±°λ μ κ±°νλ λ©μλκ° μλ€.MutableCollection
: μμ μΆκ°, μμ λ± λ©μλλ₯Ό μ 곡νλ€.
'κ°λ° > Kotlin' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[Ktor] 3. Response (0) | 2021.08.04 |
---|---|
[Ktor] 2. Request (0) | 2021.08.04 |
[Ktor] 1. ν΄λΌμ΄μΈνΈ, Engine (0) | 2021.08.04 |
[Kotlin In Action] 5. λλ€λ‘ νλ‘κ·Έλλ° (1) | 2021.05.29 |
[Kotlin In Action] 4. ν΄λμ€, κ°μ²΄, μΈν°νμ΄μ€ (0) | 2021.05.19 |