以下のコードを見てください。
class Test{
public static void main( String argv[] ){
System.out.println( "Bugの数:" + Bug.num );
Bug bug1 = new Bug( "無限ループ" );
System.out.println( "Bugの数:" + Bug.num );
System.out.println( "Bugの数:" + bug1.num );
Bug bug2 = new Bug( "メモリリーク" );
System.out.println( "Bugの数:" + Bug.num );
System.out.println( "Bugの数:" + bug2.num );
}
}
class Bug{
static int num = 0;
String name = "hoge";
public Bug( String s ){
name = s;
num ++;
}
public int getNum(){ return num; }
public String getName(){ return name; }
}
>javac Test.java
>java Test
Bugの数:0
Bugの数:1
Bugの数:1
Bugの数:2
Bugの数:2
インスタンスの参照 bug1 、 bug2 から static なフィールドにアクセスできています。
逆にクラスから非 static なメンバにアクセスするとコンパイルエラーになります。
class Test{
public static void main( String argv[] ){
Bug bug1 = new Bug( "無限ループ" );
System.out.println( "Bugの名前:" + Bug.name );
System.out.println( "Bugの名前:" + Bug.getName() );
}
}
class Bug{
static int num = 0;
String name = "hoge";
public Bug( String s ){
name = s;
num ++;
}
public int getNum(){ return num; }
public String getName(){ return name; }
}
>javac
Test.java:4: static でない変数 name を static コンテキストから
参照することはできません。
System.out.println( "Bugの名前: " + Bug.name );
^
Test.java:5: static でないメソッド getName() を static コンテキスト
から参照することはできません。
System.out.println( "Bugの名前: " + Bug.getName() );
^
非 static なメンバはインスタンスと関連して記憶されています。
なので、クラスから非 static なメンバへアクセスしようとすると、どのインスタンスの メンバ にアクセスしたいのかコンパイラは判別できません。
そのためクラスから非 static なメンバにアクセスすると、コンパイルエラーとなります。
同様にクラスに関連付けられた static なメソッドから 非 static なメンバにアクセスするとコンパイルエラーになります。
class Test{
public static void main( String argv[] ){
Bug bug1 = new Bug( "無限ループ" );
System.out.println( "Bugの名前:" + Bug.getName() );
}
}
class Bug{
static int num = 0;
String name = "hoge";
public Bug( String s ){
name = s;
num ++;
}
public int getNum(){ return num; }
public static String getName(){ return name; }
}
>javac
Test.java:4: static でない変数 name を static コンテキストから
参照することはできません。
public static String getName(){ return name; }
^
これもクラスに関連付けられたメソッドからだと、どのインスタンスのフィールド( name )にアクセスしたいのか、コンパイラが判別できないからエラーになってしまいます。
今までのことをまとめてみると、以下のようになります。
static 宣言されたメンバはクラスに関連付けられる。
(インスタンスとは無関係にクラスが一つだけ保持する)
クラスから static 宣言されたメンバへはアクセスできる。
インスタンスの参照からも static 宣言されたメンバへはアクセスできる。
非 static なメソッドから static なメンバへアクセスすることはできる。
クラスから非 static なメンバへはアクセスできない。
static なメソッドから 非static なメンバへアクセスすることはできない。
要するにインスタンスや、インスタンスに関連付けられた非 static なメンバからは全てのメンバにアクセスできます。
クラスやクラスに関連付けられた static なメンバからは、static なメンバにはアクセスできますが、インスタンスに関連付けられた非 static なメンバにはアクセスできません。
(なぜならどのインスタンスのメンバなのか判別できないからです。)
---------------------------------------------------------------
むき〜〜〜!
カリン様、超神水を一ダース着払いで郵送しておくれ!