Java static クラス
いまのところ、「Google Androidアプリケーション開発入門 画面作成からデバイス制御まで――基本機能の全容」 を教科書としてサンプルを実装したりしてるのですが、SQLite のサンプルで、インナークラスを static 宣言してるんですね。
ちょっと、見慣れない記法だと思ったのですが、どう使い分けるのだろう?
ちょっと挙動を試してみました。
Bar クラスと、Foo クラスを作成。
Barクラス
package test; public class Bar { private String m_str; public Bar() { m_str = "Bar"; } class Ham { public String getValue() { // 外部クラスの静的でないメンバーが参照できる return "Ham | " + Bar.this.m_str; } } static class Spam { public String getValue() { // ② 外部クラスの静的でないメンバーは参照できない // return Bar.this.m_str; return "Spam"; } } public void makeInstance() { // ① 同じようにインスタンスは作れる System.out.println(new Ham().getValue()); System.out.println(new Spam().getValue()); } }
Fooクラス
package test; public class Foo { public static void main(String[] args) { // ③ クラスからインスタンス化できない。インスタンス化してから // Bar.Ham h = new Bar.Ham(); Bar.Ham h = new Bar().new Ham(); // ④ クラスからインスタンス化できる // Bar.Spam s = new Bar().new Spam(); Bar.Spam s = new Bar.Spam(); System.out.println(h.getValue()); System.out.println(s.getValue()); new Bar().makeInstance(); } }
結果
Ham | Bar Spam Ham | Bar Spam
static クラス なので、なんか、インスタンスが作れない!? みたいに思ってしまうが、そんなことはない。
それぞれ、アウタークラスから、インナークラスのインスタンスは作成できる。(①)
ただし、当たり前と言えば当たり前だが、sutatic クラスからは、アウタークラスの static でないメンバー変数にアクセスできない(②)
Bar のインナークラスの、Ham と Spam のスコープ指定をしていないので、同一パッケージからは参照できる。
それぞれ、を同一パッケージの Foo クラスから参照してみる。
static でないインナークラスをアウタークラス以外のクラスからインスタンス化するには、アウタークラスをインスタンス化する必要がある。(③)
しかs、static なインナークラスは、アウタークラス以外のクラスからインスタンス化するには、static メソッドを参照するのと同じ仕方でインスタンス化できる。(④)
「staticのついた内部クラスは、パッケージのように使える」 とはそういう(④)意味か。
ちょっとしたクラス群をパッケージではなくて、クラスにまとめて使うには、有用そうだ。これが使い方の本命かしら。
static でない場合の書き方、
new Bar().new Ham();
これは、覚えにくいし、違和感あるが、
new Bar.Spam();
こっちの書き方なら自然だ。