前回の記事
Java Gold SE11対策 ネストしたクラスシリーズ①インナークラスについて
の続きとして本記事では「static インナークラス」についてまとめていく。
インナークラスをstaticで修飾したものがstaticインナークラス
インナークラスは外側のクラス「エンクロージングクラス」のメンバであるので、
エンクロージングクラスをインスタンス化しないと利用することができないという制約がある。
この制約のために、例えばエンクロージングクラスに引数を受け取るコンストラクタがあって、そのエンクロージングクラスの中にあるインナークラスがあるとする。
自分はそのインナークラスに用がある場合、用のないエンクロージングクラスをインスタンス化せねばならない。
更にエンクロージングクラスのコンストラクタの引数を具体的にどうするかも特に決まっていないとしたら、意味のない適当な値あてがうという粗末な処理を書くことになる。
この「 エンクロージングクラスをまずインスタンス化しなくてはならない 」という制約から解放してくれるのがこの staticインナークラス である。
staicインナークラスのインスタンス化にはエンクロージングクラスのインスタンスは不要なのだ。
staticインナークラスのインスタンス化
インナークラスとstaticインナークラスのインスタンス化の違いを見比べてみよう。
まずは普通のインナークラスだ。
OuterクラスにInnerというインナークラスが実装されている。
public class Outer {
class Inner {
// 何らかの処理
}
}
これをインスタンス化するには下記のようにエンクロージングクラスであるOuterクラスをインスタンス化しなくてはならない。
public class Main {
public static void main(String args){
Outer outerClass = new outer();
Outer.Inner innerClass = outerClass.new Inner();
}
}
このinnerクラスをstaticに変更する。
public class Outer {
public static class Inner {
// 何らかの処理
}
}
static修飾子がつけられたinnerクラスのインスタンス化は下記のようにエンクロージングクラスのインスタンス化は行わない。
public class Main {
public static void main(String args){
Outer.Inner innerClass = new Outer.Inner();
}
}
エンクロージングクラスのフィールド/メソッドへのアクセス
下記のようなstaitcインナークラスを実装したクラスがあるとする。
staticインナークラスからエンクロージングクラスのstaticなフィールド/メソッドと非staticなフィールド/メソッドにアクセスすると次のようになる。
エンクロージングクラスのstaticなフィールド/メソッドへのアクセス→ 正常に処理される
エンクロージングクラスの非staticなフィールド/メソッドへのアクセス→ コンパイルエラーになる
public class Outer {
//staticなフィールド変数
public static String birthday = 19490914;
//非staticなフィールド変数
public int age = "75";
//staticなメソッド
public static void staticMethodExample(){
System.out.println("staticメソッドですよ");
}
//非staticなメソッド
public static void notStaticMethodExample(){
System.out.println("非staticメソッドですよ");
}
//staticインナークラス
public static class Inner {
//問題ない
System.out.println("誕生日は" + birthday);
//コンパイルエラーになる
System.out.println("年齢は" + age);
//問題ない
Outer.staticMethodExample();
//コンパイルエラーになる
Outer outerclass = new Outer();
outerclass.notStaticMethodExample();
}
}
staticで修飾されたものは クラスがロードされたタイミング で static領域 に配置されるのに対し、非staticのものは インスタンス化されたタイミング で ヒープ領域 に配置される。
使用可能なタイミングも、配置されるメモリの領域も異なるためにこうした制約があるのだ。
次回はローカルクラスについてまとめる。