【Java入門(2)オブジェクト指向:基本編 #6】static

 

みのる
こんにちは。笑顔で感謝!✨ みのるコーチです。
今回も、ご覧いただき、ありがとうございます。

今回は

Java入門2 オブジェクト指向:基本編 #6
static

というテーマでお送りします。

彩香
static は、最初の頃から 使ってきていますが
いよいよ その意味が明かされる時が きましたね…。

とても、楽しみです。今回も、よろしくお願いします。

剛留
static についてですね…。待ってました~。

今回も、全集中でいきますっ!

【Youtube版】

Youtubeでもお伝えしていますので
是非チェックしてくださいね。

【1】 クラスフィールド

ここまで

クラス内で定義したフィールドは
インスタンス化すると実体として値を持つ。

という事をお伝えしてきました。

これに対して、今回は クラスフィールド
についてお伝えします。

このフィールドは、インスタンス化せずに利用できます。

そして、フィールド定義の前に static をつけます。

また、staticフィールドという呼び方もします。

クラスフィールド
✅ インスタンス化せずに利用できる。

✅ フィールド定義の前に static をつける。

✅ staticフィールドとも言う。

クラスフィールドの定義方法ですが…

最初に static をつけて、データ型・変数名
を記述します。

通常のフィールド定義の前に static を
つけた形ですね。

(クラスフィールドの定義)
static データ型 変数名;

クラスフィールドを利用する場合を見ていきましょう。

クラス外からは利用する場合には
クラス名にドット演算子をつけて表します。

クラス名.フィールド名

です。
また、クラス内のメソッドで利用する場合には

フィールド名

だけで、利用することができます。
ここは、通常のフィールドの利用と同じですね。

クラスフィールドの利用
(利用する場合:クラス外から)

クラス名.フィールド名

(利用する場合:クラス内から)

フィールド名

また、この クラスフィールドは
クラス共通の変数として 利用することとなります。

例を見てみましょう…

public class SalesEmployee {
     static final String COMPANY_NAME = “●●商事”;
        :
        :
    }
System.out.println(“■会社名:” + SalesEmployee.COMPANY_NAME);

この例では、SalesEmployee というクラスの中で
クラスフィールドを定義しています。

String型の COMPANY_NAME で
“●●商事” で初期化されていますが…

final 修飾子がついているため 定数ですね。

これに、static修飾子がついているため
クラスフィールドになります。

ちなみに、final修飾子と static修飾子の
記述する順番ですが…

Java言語仕様では

static final

この順が推奨されています。
( final static と書いても動作します。 )

そして、この COMPANY_NAME を
クラスの外から利用する時には…

このように、SalesEmployee.COMPANY_NAME

…というように
クラス名.フィールド名 で使用できます。

彩香
static をつけたフィールドは
クラスで共通の変数として使うんですね。

そして、インスタンス化せずに使える…。
理解しました。

剛留
OK牧場です!

【2】 クラスメソッド

フィールドと同様に、メソッドのほうも…

クラス内で定義したメソッドは
インスタンス化すると利用できる。

という事をお伝えしてきました。

そして、こちらも クラスメソッド
というものがあります。

このメソッドは
クラスをインスタンス化せずに利用できます。

そして、メソッド定義の前に static をつけます。

また、staticメソッドという呼び方もします。

クラスメソッド
✅ インスタンス化せずに利用できる。

✅ メソッド定義の前に static をつける。

✅ staticメソッドとも言う。

定義の方法を見ておきましょう。

戻り値の型、メソッド名、丸括弧、仮引数の型 仮引数名,…
そして、メソッド内の処理ブロックと…

見慣れた定義の方法の前に stataic がついています。

(クラスメソッドの定義)
static 戻り値の型 メソッド名(仮引数の型 仮引数名,…) {
  メソッド内の処理
}

そして、呼び出しの方法ですが
クラス外から呼び出す場合には

クラス名 にドット演算子をつけて
その後にメソッド名(実引数,…) という形で記述します。

また、クラス内からは
メソッド名(実引数,…) の形で呼び出すことができます。

定義の時の記述のしかた、呼び出す時の記述のしかた…
押さえておきましょう。

メソッド呼び出し
(クラス外から)

クラス名.メソッド名(実引数,…)

(クラス内から)

メソッド名(実引数,…)

Java入門1 メソッド編では…

static は、すぐに使えるという意味の修飾子。

…とお伝えしました。

それは、インスタンス化しないで
すぐに使えるという意味でした。

そして、Java入門1 メソッド編では、static修飾子のついた
メソッドを、メソッド名のみで呼び出していましたが…

これは同じクラス内に定義していたためです。

別のクラスで定義した場合には…

クラス名.メソッド名(実引数,…)
という呼び出し方になります。

また、メインメソッド には static がついています。

これは、JVM は クラスをインスタンス化せずに…

メインメソッドを クラスメソッドとして
利用しているからなのです

では、

クラスメソッドの例を見てみましょう。

public class Calc {
  static int square(int value) {
    return value * value;
  }
}
public class Driver {
  public static void main(String[] args) {
    int valSquared = Calc.square(3);
    System.out.println(valSquared);
  }
}

Calc というクラスに クラスメソッド square があります。

int型 value という仮引数を受け取って
2乗した値を戻り値として返すメソッドです。

そして、Driverクラスの メインメソッドから
squareメソッドを呼び出す場合には、このように…

Cal.square(3) という形で
クラス名とドット演算子を用いて呼び出します。

ここでは、int型リテラルの 3 を実引数にしていますので
戻り値 9 が返ってきて、valSquare には 9 が代入され…

System.out.println(valSquared) で 9 が表示されます。

この、定義の方法、呼び出し方、押さえておきましょうね。

【3】 static修飾子

前のコーナーまでで…

クラスフィールドとクラスメソッドを定義する時に
static修飾子をつける。

…と、お話してきました。

また、このクラスフィールド、クラスメソッドに対して…

インスタンス化してから利用する
フィールド、メソッドを それぞれ…

インスタンスフィールド
インスタンスメソッド

と呼びます。

これも、使われることがある用語なので
チェックしておきましょうね。

彩香
ここまで話を聞いて、クラスフィールドと
クラスメソッドは 便利に使えそうに思えました。

インスタンス化しないで使えるので…

ほとんど、クラスフィールドと
クラスメソッドにしてしまって 大丈夫ですか?

みのる
これは便利…、と思ったわけですね。

そして、ここで、注意点もありますので
お伝えしていおきます。

staticとは「静的な」という意味です。

これは、インスタンスのように
「動的」に作られるのではなく…

メモリ上に配置されて動かないという意味です。

イメージを見ていきましょう。

クラスは必要な時にメモリ上に配置されます。

ただし、この時に使えるのは クラスフィールドと
クラスメソッドだけです。

インスタンスフィールドとインスタンスメソッドは
インスタンス化してから 利用することができます。

そして、そしてインスタンスは、動的ですので…

「使用が終了した」とJVMが判断すると
解放されます(消されます)。

この インスタンス をメモリ領域から 解放する事は
JVMが「よろしく」やってくれます。

この機能を…

「ガベージコレクション」

といいます。

ただし、クラスフィールド、クラスメソッドは
ガベージコレクションの対象となりません。

静的なメンバですので、メモリ上に留まります。

と、ここで、注意点ですが…。

プログラムを作成していると、スタティックフィールドや
スタティックメソッドにしてしまったほうが…

簡単と思う場合が、確かに出てきます。

ただし、これを多様してしまうと、今お話したように…

静的にメモリに常駐してしまう フィールド・メソッドが
増えて、メモリを 圧迫してしまう事になります。

ですので…

クラスフィールド・クラスメソッドの使用
✅ 頻繁に使用する。

✅ クラスで共有する必要がある。

…といった理由がある場合に限る。

…という 意識を持つと 良いですね。

オブジェクト指向の基本として…

必要な時に、必要な分だけオブジェクト化(インスタンス化)
して使用する という考えがあるのです。

剛留
クラスフィールドは、クラス共通の変数
という話がありましたが…

インスタンスメソッドからも 使えるのですか?

みのる
この部分も、ポイントになります。

同じクラスから作られたインスタンスが あるとすると…

それぞれのインスタンスメソッドから
クラスフィールド、クラスメソッドは利用できます。

共通のものとして、利用する事となります。

そして、クラスメソッドからは インスタンスフィールド
インスタンスメソッドは 利用できません。

クラスメソッドは、インスタンス化せずに
利用できますし(起動されますし)…

クラスが複数回 インスタンス化 される事もあるので
インスタンスを 特定することができないからです…。

この部分も、押さえておきましょう。

【4】 クラス図の表現

クラスフィールド、クラスメソッド の
クラス図での表現方法を見ておきましょう。

それは、下線をつけて表現します。

今回の例では、会社名を表す COMPANY_NAME
インスタンス化した回数を保持する instanceCnt…

会社名を表示する displayCompany() です。

それから、メインメソッドも
スタティックメソッドですね。

この、クラス図の表現方法も、押さえておきましょう。

【 まとめ 】

【1】 クラスフィールド
✅ インスタンス化せずに
  利用できる。
✅ フィールド定義の前に static をつける。
✅ staticフィールドとも言う。
【2】 クラスメソッド
✅ インスタンス化せずに利用できる。
✅ メソッド定義の前に static をつける。
✅ staticメソッドとも言う。
【3】 static修飾子
✅ 「静的な」という意味。
✅ メモリ上に、静的に配置される。
✅ 多様するとメモリを圧迫するため
  用途を限定して使用すること。
【4】 クラス図の表現
✅ クラスフィールド・クラスメソッドには
  下線をつける。