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();
こっちの書き方なら自然だ。
