static について:簡単に説明すると
static とは
修飾子
の一つであり Java の
キーワード
の一つです。
static を使用するとクラスメソッド、クラスフィールドを宣言することができます。
static について:もっと詳しく
static には以下の3通りの使用方法があります。
・フィールドを修飾する。
・メソッドを修飾する。
・static イニシャライザをつくる。
このうち、
staticイニシャライザ
についてはその項目を参照してください。
ここでは
フィールド
と
メソッド
の修飾について説明します。
static で宣言されたフィールドとメソッドは通常のフィールド・メソッドと何が違うのでしょうか。
通常クラスのフィールド・メソッド(=
メンバ
)を使用する場合、最初に new でクラスのインスタンスを生成する必要があります。
しかし static 宣言されたメンバについてはインスタンスが無くてもクラスから直接利用することができます。
static 宣言されたフィールド・メソッドはクラスフィールド・クラスメソッドになるからです。
通常のフィールド・メソッドは個々のインスタンス毎に別々に保持していますが、static 宣言された
フィールド・メソッドについてはいくらインスタンスが生成されても、
クラスがただ一つだけ保持しています。
以下のコードを見てください。
class Test{
public static void main( String argv[] ){
System.out.println( "Bugの数:" + Bug.num );
Bug bug1 = new Bug( "無限ループ" );
System.out.println( "bug1の名前:" + bug1.getName() );
System.out.println( "Bugの数:" + bug1.getNum() );
Bug bug2 = new Bug( "メモリリーク" );
System.out.println( "bug2の名前:" + bug2.getName() );
System.out.println( "Bugの数:" + bug2.getNum() );
Bug bug3 = new Bug( "不正な値" );
System.out.println( "bug3の名前:" + bug3.getName() );
System.out.println( "Bugの数:" + bug3.getNum() );
}
}
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
bug1の名前:無限ループ
Bugの数:1
bug2の名前:メモリリーク
Bugの数:2
bug3の名前:不正な値
Bugの数:3
static で宣言されたフィールド num はインスタンスとは無関係に、クラス Bug に関連付けられている様子が分かりますね。
逆に非 static なフィールドである name はインスタンス毎に別々に保持されています。
個々のインスタンスの name はお互い独立して保持されるので、違う名前を付けることができます。
ところで、このコードの Bug の getNum( ) メソッドを良く見てください。
public int getNum(){ return num; }
非 static なメソッドから、static なフィールド num にアクセスできています。
このように、非 static なメソッドから static なメンバへアクセスすることはできます。
また、インスタンスへの参照から static なメンバへアクセスすることもできます。
以下のコードを見てください。
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 なメンバにはアクセスできません。
(なぜならどのインスタンスのメンバなのか判別できないからです。)
自分でも色々コードをいじって試してみて下さいね。
|
SJC-P対策問題集
Java認定試験( SJC-P/310-035 )対策のメルマガ問題集も好評発刊中!
もちろん無料です。
またバックナンバーも見やすくしてオンライン問題集として随時アップしていきます。
受験しない人でも Java の基礎知識を学習するのに最適です。
SJC-P対策参考書
現在、Java認定試験(SJC-P/310-035)対策の参考書は本当にたくさん出版されてます。
ここでは、その中から厳選した本当に役立つ参考書を紹介します。
無駄な出費を抑えるためにも、ぜひ参考にして下さい。
SJC-P対策Java用語集
Java認定試験( SJC-P/310-035 )合格のために必要な Java の用語を集めました。
試験対策にはもちろん、試験以外で Java を学習する際にもご活用下さい。
更新履歴
このサイトの最新情報はここで確認できます。
また、今までこのサイトがどのような軌跡を辿ってきたのかも知ることができます。
Javaを始める人へ
これからJavaを始めようとしているあなたへ。
Javaの勉強を始めるにはどうしたら良いのかを説明しています。
また、初心者に役立つ情報を提供していきます。
Java認定資格の概要
Java認定資格にはどのようなものがあるのか。
資格取得のためにはどのような知識が必要なのか。
その他、資格を取得することのメリットなど、Java認定資格の概要を説明します。
LINK
Javaの勉強に役立つリンク。
その他のプログラミングに関するリンク。
ソフトウェアに関するリンクなど、管理人の主観で集めたリンク集です。
相互リンクも常時募集中!
詳細は以下のページで確認して下さい。
このサイトについて
このサイト「1発合格★Java認定試験!」についての説明です。
サイトで掲載しているソースコードや問題や免責事項などについて説明しています。
初めての人は一度のぞいてみて下さい。
ちょっとひと息
仕事や試験勉強に疲れたら、ここでちょっと一息つきませんか。
一生懸命に打ち込むのも良いけど、たまには何も考えずにゆっくり休むのも良いものです。
たまにはのんびり脳みそをリフレッシュしましょう。
|