Kotlin nullの処理の詳細

2863 ワード

Kotlin nullの処理の詳細
Null PointerException、通称NPEは、初心者でも老鳥でも避けられない、常に遭遇する一つの異常を説明するのが簡単で、「空の針」という3つの文字にします。いつも不注意でこの落とし穴に落ちます。Kotlinの設計目標はコードのnull引用による危険を解消したいということです。つまり10億ドルの損失をもたらす大きな間違いです。
NPEの原因
Kotlinはコードの中のNPEを消したいですが、私達はいつも不注意で、いつもまたNPEの落とし穴に落ちて、下はNPEの原因があります。
  • は、throw Null Point Exceptionを明確に呼び出します()
  • 使用!オペレータ
  • 外部のJavaコードにより、この異常は
  • である。
  • 初期化プロセスにはいくつかのデータの不一致が存在する(コンストラクタに初期化されていないthisが使用されている)
  • NPEを避ける
    Kotlinでは、nullを指すことができる参照(null参照とすることができる)とnullを指すことができない参照(null参照ではない)とを明確に区別しています。例えば、通常のStringタイプ変数はnullを指すことができません。
    
    var a: String = "abc"
    a = null //     
    この時、a変数に対する呼び出しはすべて安全です。nullではないので、参照に対してはNPEに報告することなく、任意の操作ができます。AにNullを割り当てても、コンパイラが間違っています。通らせません。
    しかし、実際に開発した場合、すべての変数がnullできないことはあり得ません。いつもある場合、変数はnullです。この変数はどう設定すればいいですか?null値の変数を許可するには、nullの文字列として宣言できます。Stringとして書きます。
    
    var b: String? = "abc"
    b = null // ok
    このように、変数をnullに設定できる問題を解決しましたが、NPEのこの落とし穴はまた設置されました。もし油断したら、NPEはまたトラブルを引き起こします。
    私たちがまだこの属性にアクセスする必要があるということですか?いくつかの方法があります。
    条件文でnullチェックを行います。
    条件文により、変数のチェックがnullかどうか、nullと非nullの二つの場合にそれぞれ処理します。
    
    if (b != null && b.length > 0)
      print("String of length ${b.length}")
    else
      print("Empty string")
    
    
    注:
    この方案は現在のbの値に対してだけで、bの値は検査後、bの値が修正されてもこの値に対してnullではない検査をしなければならない、つまりbの値を修正するたびに、nullではないとbに検証しなければならない。これはコードの冗長性を招く。
    セキュリティコール
    安全コールとは?ちょっと理解できないようですが、nullだったらどうして安全がありますか?
    
    b?.length
    Kotlinでは「?」の使用が許可されています。演算子は変数を呼び出します。bがnullでない場合、この表式はb.lengthを返します。そうでなければnullを返します。使用したら?」その表式の値はまた、Int?もしコンパイラが誤報します。
    
    bob?.department?.head?.name
    セキュリティコールはチェーン式の呼び出しの場合に非常に有用です。このようなチェーン呼び出しは、属性チェーンのいずれかの属性がnullである限り、式全体がnullに戻ります。
    ?オペレータ
    もし左側の表式の値はnullではなく、表式の値を返します。そうでなければ、右式の値を返します。
    
    val l = b?.length ?: -1
    bがnullでなければ、bの長さを返します。nullであれば、-1に戻ります。
    注:
    右式は左式がnullの場合にのみ計算されます。
    Kotlinではthrowとreturnは表式であるので、Elvisオペレータの右側にも使用できます。このような使い方は、関数パラメータ値が正当であるかどうかを確認するために大きな便利をもたらすことができます。
    
    fun foo(node: Node): String? { 
    val parent = node.getParent() ?: return null 
    val name = node.getName() ?: throw IllegalArgumentException(“name expected”) 
    // … 
    } 
    
    !! オペレータ
    bがnullでない場合、この表式はnull以外の値を返します。例えば、私達の例ではStringタイプの値です。bがnullなら、この表式はnullです。
    NPEを投げる:
    
    val l = b!!.length()
    bがnullの時に一つの異常を投げ出して、あなたはそれを捕獲することができて、ある隅の中で呼びつけることを知らないのではありません時、やっと異常を報告して、頭をつかんで長い間ほほをかいて、やっとNPEがどこにありますかを探し当てます。
    セキュリティのタイプ変換
    もし対象が私達の期待の目標タイプでないならば、通常のタイプは転換してクラスのCastExceptionを招いて、安全なタイプの転換を使うことを選ぶことができて、もし変換が成功しないならば、それはnullに帰ります。
    
    val aInt: Int? = a as? Int
    読んでくれてありがとうございます。みなさんのご協力をお願いします。ありがとうございます。