C++とJavaにおけるstaticキーワードの違いを徹底解説
C++とJavaのどちらにもstaticキーワードが用意されています。両者はほぼ同じ役割を果たしますが、言語の設計思想の違いから、いくつかの基本的な相違点が存在します。本記事では、C++のstaticとJavaのstaticの違いについて、コード例を交えながら詳しく解説します。
静的データメンバ(staticデータメンバ)
静的データメンバの基本的な挙動は、JavaとC++で共通しています。静的データメンバはクラスに属するプロパティであり、そのクラスから生成されるすべてのオブジェクト間で共有されます。オブジェクトごとに個別のコピーが作られるのではなく、クラス全体で1つだけ存在する点がポイントです。
以下は、生成されたオブジェクトの数をカウントする例です。コンストラクタが呼ばれるたびに静的変数をインクリメントすることで、オブジェクトの生成数を把握できます。
Javaの例
public class Test {
static int ob_count = 0;
Test() {
ob_count++;
}
public static void main(String[] args) {
Test object1 = new Test();
Test object2 = new Test();
System.out.println("The number of created objects: " + ob_count);
}
}
出力結果
The number of created objects: 2
C++の例
#include<iostream>
using namespace std;
class Test {
public:
static int ob_count;
Test() {
ob_count++;
}
};
int Test::ob_count = 0;
int main() {
Test object1, object2;
cout << "The number of created objects: " << Test::ob_count;
}
出力結果
The number of created objects: 2
どちらの言語でも、2つのオブジェクトを生成した結果「2」というカウントが表示され、静的変数がすべてのオブジェクトで共有されていることが確認できます。なお、C++ではクラス外で「int Test::ob_count = 0;」のように定義が必要な点に注意してください。
静的メンバ関数(staticメソッド)
C++とJavaでは、静的メンバ関数(staticメソッド)を定義できます。これらもクラスのメンバですが、通常のメンバ関数と比べていくつかの制限があります。
- 静的メソッドから呼び出せるのは、他の静的メソッドのみです。
- アクセスできるのは静的メンバ変数のみで、インスタンス変数にはアクセスできません。
- 「this」や「super」(superはJavaのみ)を参照することはできません。
一方で、C++とJavaのどちらでも、オブジェクトを生成することなく静的メンバにアクセスできます。クラス名を指定して直接呼び出せるのが大きな特徴です。
Javaの例
// このコードはMyClass.javaという別ファイルに記述します
public class MyClass {
static int x = 10;
public static void myFunction() {
System.out.println("The static data from static member: " + x);
}
}
// このコードはTest.javaという別ファイルに記述します
public class Test {
public static void main(String[] args) {
MyClass.myFunction();
}
}
出力結果
The static data from static member: 10
C++の例
#include<iostream>
using namespace std;
class MyClass {
public:
static int x;
static void myFunction(){
cout << "The static data from static member: " << x;
}
};
int MyClass::x = 10;
int main() {
MyClass::myFunction();
}
出力結果
The static data from static member: 10
いずれの例でも、MyClassのインスタンスを生成せずに、クラス名を使って静的メソッドを直接呼び出しています。Javaでは「MyClass.myFunction()」、C++ではスコープ解決演算子「::」を用いた「MyClass::myFunction()」という呼び出しが可能です。
静的ブロック(staticブロック)はJava独自の機能
Javaには静的ブロック(staticブロック)と呼ばれる機能があります。これは「静的節(static clause)」とも呼ばれ、クラスの静的初期化を行うために使用されます。静的ブロック内に記述されたコードは、クラスがロードされる際に一度だけ実行されます。この機能はC++には存在しません。
静的ローカル変数の扱いの違い
C++では、関数内に静的なローカル変数(staticローカル変数)を宣言できます。この変数は関数の呼び出し間で値が保持されるため、状態を維持したい場合に便利です。一方、Javaでは静的なローカル変数はサポートされておらず、コンパイルエラーとなります。Javaで同様の挙動を実現したい場合は、クラスの静的メンバ変数を代わりに利用する必要があります。
まとめ
C++とJavaのstaticキーワードは、静的データメンバや静的メンバ関数という基本概念では共通していますが、Java独自の静的ブロックの存在や、静的ローカル変数の可否といった違いがあります。これらの相違点を理解しておくことで、両言語をより適切に使いこなせるようになるでしょう。
-
Javaのthisキーワードでstaticメンバーは参照できる?理由とサンプルコードを解説
いいえ、thisキーワードを使ってクラスのstatic(静的)メンバーを参照することはできません。その理由は、thisキーワードが「現在のオブジェクト(インスタンス)」を指すのに対し、staticメンバーはクラス自体に属しており、オブジェクトなしで呼び出し可能だからです。つまり、Javaではstaticメンバーはインスタンスを生成しなくても、クラス名を通じて直接アクセスできます。なぜthisとstaticは組み合わせられないのかstaticメソッドやstaticブロックの中でthisを使用すると、コンパイルエラーが発生します。これは、staticなコンテキストにはインスタンスが存在しないため、
-
Java 8のインターフェースで使える静的メソッドの基本と実践例
Java 8におけるインターフェースの静的メソッドとはJava 8以降、インターフェースには静的メソッド(staticメソッド)を定義できるようになりました。これにより、ユーティリティ的なヘルパーメソッドをインターフェース内に直接記述でき、関連する処理をひとまとめに管理しやすくなります。静的メソッドは「インターフェース名.メソッド名()」の形式で呼び出すのが基本です。実装クラスのインスタンスからは直接呼び出せず、オーバーライドもできない点に注意しましょう。静的メソッドを持つインターフェースの定義例次の例では、Vehicleインターフェースにデフォルトメソッド print() と、静的メソッド