Java でクラスを static として宣言できないのはなぜですか?
14 に答える
ネストされたクラスのみを静的にできます。そうすることで、外側のクラスのインスタンスを持たずにネストされたクラスを使用できます。
class OuterClass {
public static class StaticNestedClass {
}
public class InnerClass {
}
public InnerClass getAnInnerClass() {
return new InnerClass();
}
//This method doesn't work
public static InnerClass getAnInnerClassStatically() {
return new InnerClass();
}
}
class OtherClass {
//Use of a static nested class:
private OuterClass.StaticNestedClass staticNestedClass = new OuterClass.StaticNestedClass();
//Doesn't work
private OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
//Use of an inner class:
private OuterClass outerclass= new OuterClass();
private OuterClass.InnerClass innerClass2 = outerclass.getAnInnerClass();
private OuterClass.InnerClass innerClass3 = outerclass.new InnerClass();
}
ソース:
同じトピックで:
最上位クラスはデフォルトで静的です。デフォルトでは、内部クラスは非静的です。明示的に static とマークすることで、内部クラスのデフォルトを変更できます。トップレベル クラスは、トップレベルであるため、参照する親クラスが存在しないため、非静的セマンティクスを持つことはできません。したがって、最上位クラスのデフォルトを変更する方法はありません。
だから、私はパーティーに遅れていますが、ここに私の2セントがあります.Colin Hebertの答えに哲学的に追加します.
大まかに言えば、質問はオブジェクトとタイプの違いを扱っています。多くの車 (オブジェクト) がありますが、Car クラス (タイプ) は 1 つだけです。何かを static として宣言するということは、「型」空間で操作していることを意味します。1つしかありません。最上位のクラス キーワードは、"type" スペースで既に型を定義しています。その結果、「public static class Car」は冗長です。
プライベート コンストラクターを持つクラスは静的です。
次のようにクラスを宣言します。
public class eOAuth {
private eOAuth(){}
public final static int ECodeOauthInvalidGrant = 0x1;
public final static int ECodeOauthUnknown = 0x10;
public static GetSomeStuff(){}
}
初期化せずに使用できます:
if (value == eOAuth.ECodeOauthInvalidGrant)
eOAuth.GetSomeStuff();
...
インスタンスなしで列挙型を宣言することにより、(インスタンスを作成できない) ユーティリティ クラスを作成できます。つまり、インスタンスがないことを具体的に宣言しています。
public enum MyUtilities {;
public static void myMethod();
}
確かにできますが、内部のネストされたクラスのみです。そこでは、ネストされたクラスのインスタンスが外側のクラスの外側のインスタンスを必要としないことを意味します。
しかし、最上位クラスの場合、言語設計者はこのキーワードを使用して役立つことを何も思いつかなかったので、許可されていません。
public class Outer {
public static class Inner {}
}
...メンバークラスである限り、静的に宣言できます。
JLS から:
メンバー クラスは静的である場合があり、その場合、周囲のクラスのインスタンス変数にアクセスできません。または、それらは内部クラスである可能性があります (§8.1.3)。
そしてここ:
static キーワードは、非内部クラス T の本体内のメンバー型 C の宣言を変更する場合があります。その効果は、C が内部クラスではないことを宣言することです。T の静的メソッドがその本体に T の現在のインスタンスを持たないのと同様に、C にも T の現在のインスタンスはなく、字句的に囲んでいるインスタンスもありません。
トップレベルのクラスにはエンクロージングタイプがないという理由だけで、 static キーワードはトップレベルのクラスには意味がありません。
上で説明したように、別のクラスのメンバーでない限り、クラスを静的にすることはできません。
「複数のインスタンスが存在できない」クラスを設計しようとしている場合は、「シングルトン」設計パターンを検討することをお勧めします。
初心者向けシングルトン情報はこちら.
警告:
シングルトンパターンの使用を考えている場合は、全力で抵抗してください。これは、最も理解しやすく、おそらく最も人気があり、間違いなく最も悪用されているデザインパターンの 1 つです。 (ソース: 上記のリンクの JavaRanch)
Java が静的内部クラスを定義する方法に加えて、C# の世界[1]に従って静的クラスの別の定義があります。静的クラスは、静的メソッド (関数) のみを持つクラスであり、手続き型プログラミングをサポートすることを目的としています。このようなクラスは、クラスのユーザーがヘルパー関数にのみ関心があり、クラスのインスタンスの作成には関心がないという点で、実際にはクラスではありません。C# では静的クラスがサポートされていますが、Java ではそのような直接的なサポートは存在しません。ただし、enum を使用して Java の C# 静的クラスを模倣し、ユーザーが (リフレクションを使用しても) 特定のクラスのインスタンスを作成できないようにすることができます[2] :
public enum StaticClass2 {
// Empty enum trick to avoid instance creation
; // this semi-colon is important
public static boolean isEmpty(final String s) {
return s == null || s.isEmpty();
}
}
Java でコーディングするものはすべてクラスに入ります。クラスを実行するたびに、JVM はオブジェクトをインスタンス化します。JVM は多数のオブジェクトを作成できます。定義上、静的とは、すべてのオブジェクトに同じコピー セットがあることを意味します。
そのため、Java がプログラムを実行するたびに最上位クラスを静的にすることを許可した場合、Java はオブジェクトを作成し、同じメモリ ロケーションにオーバーライドし続けます。
オブジェクトを実行するたびにオブジェクトを置き換えるだけの場合、オブジェクトを作成する意味は何ですか?
これが、Java が最上位クラスの static を削除した理由です。
もっと具体的な理由があるかもしれませんが、これは私にとって非常に論理的な意味がありました。
静的にできる唯一のクラスは内部クラスです。次のコードは問題なく動作します。
public class whatever {
static class innerclass {
}
}
静的内部クラスのポイントは、外部クラス オブジェクトへの参照がないことです。
PlatformUI
Eclipseで、静的メソッドとそれ自体がfinalであるプライベートコンストラクターを持つクラスを探すことができます。
public final class <class name>
{
//static constants
//static memebers
}
これは、一杯のコーヒーを飲むのと同じくらい簡単にできると思います!. これを見てください。クラスを定義する際に static キーワードを明示的に使用しません。
public class StaticClass {
static private int me = 3;
public static void printHelloWorld() {
System.out.println("Hello World");
}
public static void main(String[] args) {
StaticClass.printHelloWorld();
System.out.println(StaticClass.me);
}
}
静的クラスの定義ではないでしょうか。クラスだけにバインドされた関数を使用するだけです。この場合、ネストされた別のクラスを使用できることに注意してください。これを見てください:
class StaticClass1 {
public static int yum = 4;
static void printHowAreYou() {
System.out.println("How are you?");
}
}
public class StaticClass {
static int me = 3;
public static void printHelloWorld() {
System.out.println("Hello World");
StaticClass1.printHowAreYou();
System.out.println(StaticClass1.yum);
}
public static void main(String[] args) {
StaticClass.printHelloWorld();
System.out.println(StaticClass.me);
}
}
静的クラスを使用する利点がオブジェクトをインスタンス化してメソッドを使用することではない場合は、クラスをパブリックとして宣言し、このメソッドを静的として宣言するだけです。