1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

はじめてのKotlin:nullに対して型安全かどうかをためしてみよう

Last updated at Posted at 2017-10-04

はじめに

 Null Safty (nullに対して安全)というのはプログラミング言語において実行安全性を確保するために重要な指標となります。

 ここでは、 Kotlin (コトリン)がどれだけ Null Safty なのかを実コードで調べてみます。

nullの代入

 まずは不変変数にnullを代入してみましょう。変数が null を持つ可能性がある場合には、型宣言の型名のすぐ後ろに ? 記号を指定します。ここで、? 記号は Safe Accessor と呼ばれます。

null.で初期化するコード例
fun main(args: Array<String>) {
  //val hate Null: String = null //コンパイルエラー
  val expectNull: String? = null
  
  println( "expectNull is $expectNull ." )
}

  Safe Accessor である ? 記号を指定しない場合にはコンパイルエラーになります。このコンパイルエラーのおかげで実行時例外発生を抑止することができます。

コンパイルエラー
prog.kt:2:26: error: null can not be a value of a non-null type String
  val hateNull: String = null
                         ^

nullの可能性のある値の代入

 さらに、ここでわざと null の可能性がある値を変数に代入してみます。

 代入時にある変数を評価するとき、null であっても例外が発生しないようにするには変数の後ろに ? 記号を指定します。

nullの可能性がある値を代入するコード例
fun main(args: Array<String>) {
  var mayNullString: String? = null
  val length = mayNullString?.length
  //val length = mayNullString.length //コンパイルエラー発生

  println( "mayNullString's length is $length." )
}
実行結果
mayNullString's length is null.
?記号を指定しない場合のコンパイルエラー
prog.kt:4:29: error: only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
  val length = mayNullString.length //????
                            ^

 期待する型を指定して不変変数を初期化

 次に、期待する型を指定して不変変数を初期化してみます。このような場合には as? キーワードを指定します。

期待する型の値でのみ初期化するコード例
fun main(args: Array<String>) {
  val someString = "Bording locations are "
  val expectInt: Int? = someString as? Int
  println( "expectInt is '$expectInt' ." )
  val expectString: String? = someString as? String
  println( "expectString is '$expectString' ." )
}
実行結果
expectInt is 'null' .
expectString is 'Bording locations' .

nullかどうかの判定

 次に null かどうかを判定してみます。 null 判定するということは、変数が null を持つことをゆるす必要があります。そのためには、型宣言の型名のすぐ後ろに ? 記号を指定します。

null判定するコード例
fun main(args: Array<String>) {
  var stringForJudge: String? = "indicate by white circles and from No.1 to 12."
  val lengthOfString = 
    if( stringForJudge != null ) stringForJudge.length else -99
  println( "lengthOfString is $lengthOfString ." )
}
実行結果
lengthOfString is 46 .

わざと例外が発生するように指定

 最後に null の場合に null 安全ではなく、Javaのように普通に NullPointerException で例外が発生するようにわざと指定してみます。

 このような場合には、対象となる変数を !! 記号で修飾します。

 また、 null をゆるす場合には someString?.length のようにプロパティの前に ? 記号を付加します。ここで、 ? 記号は Elvis operator  と呼ばれます。

コード例
fun main( args: Array<String>){
  var someString: String? = "ばあばとじいじ"
  val length1 = someString!!.length
  someString = null
  val length2 = someString?.length
  //val length2 = someString!!.length //例外発生

  println( "length1 is $length1.\nlength2 is $length2." )
}
length2の初期化で!!を指定した場合
Exception in thread "main" kotlin.KotlinNullPointerException
	at ProgKt.main(prog.kt:5)
length2の初期化で?を指定した場合
length1 is 7.
length2 is null.

以上です。いかがだったでしょうか?。Javaをご存じの方はいかに Kotlin が null に対して安全かがお分かりいただけたのではないでしょうか?。

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?