Scala では演算子もメソッドとして実装されていて、obj1 op obj2 なんてコードは、obj1.op(obj2) と同じ意味を持つ。
となると、気になってくるのは obj1 が null の場合どうなるのよ?ってことで・・・色々と試してみた。
scala> null == null res0: Boolean = true scala> null.==(null) res1: Boolean = true
null でもメソッドは呼べるらしい。
ちょっとひねって、
scala> val nullStr: String = null
res2: String = null
scala> nullStr == "null"
res3: Boolean = false
scala> nullStr + "" == "null"
res4: Boolean = true
scala> nullStr.+(" str")
res5: String = null str
これも大丈夫。
てことは、メソッドの起動段階では null チェックが入らず、this に null が格納されうるということ?
って予想を立てて、こんな例。
scala> class Hoge {
| def isNull: Boolean = this == null
| }
defined class Hoge
scala> new Hoge() isNull
res0: Boolean = false
scala> val n: Hoge = null
n: Hoge = null
scala> n isNull
java.lang.NullPointerException
at .<init>(<console>:7)
at .<clinit>(<console>)
at RequestResult$.<init>(<console>:3)
at RequestResult$.<clinit>(<console>)
at RequestResult$result(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.i...
scala>
あれー?
てことは暗黙の型変換使うしかない・・・?
scala> class Hoge
defined class Hoge
scala> class ExHoge(val hoge: Hoge) {
| def isNull: Boolean = hoge == null
| }
defined class ExHoge
scala> implicit def hogeWrapper(target: Hoge): ExHoge = new ExHoge(target)
hogeWrapper: (Hoge)ExHoge
scala> val n: Hoge = null
n: Hoge = null
scala> n isNull
res0: Boolean = true
scala> new Hoge isNull
res1: Boolean = false
scala>
おー、できた。
isNull の代わりに記号を使ってみる。
scala> class Hoge
defined class Hoge
scala> class ExHoge(val hoge: Hoge) {
| def ? : Boolean = hoge == null // 条件演算子じゃないよ!
| // ?(): Booleanを略して
| // ? : Booleanってしてるだけ!
| }
defined class ExHoge
scala> implicit def hogeWrapper(target: Hoge): ExHoge = new ExHoge(target)
hogeWrapper: (Hoge)ExHoge
scala> val n: Hoge = null
n: Hoge = null
scala> n?
res0: Boolean = true
scala> new Hoge?
res1: Boolean = false
scala>
楽しい!
でも、もっと簡単に null 安全なメソッドが作りたい・・・
Scala では var よりも val の方が推奨されているらしいので、Java に比べれば null 安全なメソッドを作りたいという要求はあまり起こらないのかも。
Java でも Scala の暗黙の型変換を明示的に記述するような ExString とか作ってたし、それがより簡単に記述できるようになった、ってのは喜ぶべきかな。