【Java】PHPとJavaは::の意味が異なる。Javaの場合はメソッド参照。

徒然草2.0

ここ最近、JavaとPHPでアクセス修飾子(publicやprivate)の挙動が違うことに気づいた(気がつくのが遅すぎたかもしれない)。

おさらいになるが、PHPではpublicを省略すると、それはpublicと同義で扱われる。一方でJavaでは、publicを省略した場合、パッケージプライベート(package-private)となり、同じパッケージ内であればアクセスできるが、それ以外からはアクセスできない。つまり、publicとは異なるアクセス制限になる。

この違いは、知らなくてもさほど困らないが、IDE(統合開発環境)はこの差を厳密にチェックしてエラーを出してくるため、意識せざるを得ない。実際のところ、迷ったら明示的にpublicと書いておけば問題は起きにくい。ただ、省略していても、普通に使っている分にはたいてい動作してしまうので、気づかないことも多いと思う。とはいえ、他のパッケージからアクセスしようとしたときにビルドが失敗したり、単純なテストが通らなくなるといった形で露呈する可能性はある。

さて、本題にはいる。

「::」の使い方である。

PHPの場合、:: は静的メンバや定数へのアクセスに使われる。インスタンス化せずともstaticなメソッドや定数を呼び出せる記号だ。Rubyでも似たような用途で、定数やクラスメソッドにアクセスできる。つまり、PHPやRubyにおいて::は「クラスやモジュールに属するもの(静的なもの)」にアクセスするための演算子といえる。

この感覚から、Javaでも::を見たとき、同様に静的メンバを参照しているのだろうと思っていた。

例えば、Javaのコードでは、クラスインスタンス::メソッド というような記述をよく見る。特にmapメソッドの中で頻繁に使われるのを目にする。ただ、そのとき「なぜmapの中に静的メソッドが出てくるのか?」と疑問に思っていた。しかも、呼び出されているのは別に静的なメソッドでもない。

結論として、Javaの::はPHPやRubyとは異なり、「メソッド参照」と呼ばれるものだと分かった。これはラムダ式の簡略表記で、(x) -> x + 1 のように書けるあの構文の代替となる。感覚的に使っていたラムダ式の一種ということだ。

ちなみに、PHPでは -> (アロー演算子)はインスタンスのメソッドやプロパティへのアクセスに使う一方、Javaの -> はラムダ式の構文となる。また、PHPの . は文字列の連結に使われるが、Javaでは . はメンバアクセス演算子であり、用途がまったく異なる。

他にも、$ はPHPでは変数名に必須だが、Javaでは基本的に使われず、内部クラスの名前など特殊なケースにしか登場しない。@ はPHPではエラー抑制演算子だが、Javaではアノテーションを示すために使われる。さらに & はPHPでは参照渡しを意味するが、Javaではビット演算や論理演算(&や&&)で使われる。

これらの違いの中でも、やはり最も混乱しやすく、なおかつ見た目が似ているのに意味がまったく違うものが、Javaの「::」だと感じている。

徒然草2.0
スポンサーリンク
シェアする
gomiryoをフォローする
ごみぶろぐ

コメント

タイトルとURLをコピーしました