Javaでクラスを静的クラスとして宣言できないのはなぜですか。
ネストしたクラスだけが静的になることができます。そうすることで、外部クラスのインスタンスを持たずにネストしたクラスを使用できます。
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();
}
出典:
同じトピックについて:
最上位クラスはデフォルトでは静的です。内部クラスはデフォルトでは非静的です。明示的に静的にマークすることで、内部クラスのデフォルトを変更できます。参照する親クラスがないため、トップレベルクラスはトップレベルであるため、非静的セマンティクスを持つことはできません。したがって、最上位クラスのデフォルトを変更する方法はありません。
それで、私はパーティーに遅れて来ています、しかしここに私の2セントがあります - 哲学的にコリンHebertの答えに加えて。
大まかに言って、あなたの質問はオブジェクトとタイプの違いを扱います。車(オブジェクト)はたくさんありますが、Carクラス(タイプ)は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();
...
インスタンスなしでenum型を宣言することで、ユーティリティクラス(インスタンスを作成することはできません)を作成できます。つまり、インスタンスが存在しないことを明確に宣言しているのです。
public enum MyUtilities {;
public static void myMethod();
}
確かに彼らはできるが、唯一の 内なる 入れ子クラスそこでは、ネストしたクラスのインスタンスは外側のクラスの外側のインスタンスを必要としません。
しかし、トップレベルのクラスでは、言語設計者はこのキーワードを使用して何か有用なことを考えることができないため、許可されません。
public class Outer {
public static class Inner {}
}
...メンバクラスである限り、staticと宣言できます。
JLSから:
メンバクラスは静的にすることができます。その場合、メンバクラスは周囲のクラスのインスタンス変数にアクセスできません。あるいはそれらは内部クラスでもよい(8.1.3)。
そしてここ:
Staticキーワードは、非内部クラスTの本体内でメンバー型Cの宣言を変更することができます。 その効果は、Cが内部クラスではないことを宣言することです。 Tの静的メソッドがその本体にTの現在のインスタンスを持っていないのと同様に、CもTの現在のインスタンスを持っていませんし、字句的に囲むインスタンスも持っていません。
最上位クラスに包含型がないという理由だけで、静的キーワードは最上位クラスには意味がありません。
上で説明したように、クラスは他のクラスのメンバーでない限り静的にはできません。
「複数のインスタンスが存在できない」クラスを設計する場合は、「シングルトン」設計パターンを検討することをお勧めします。
初心者シングルトン情報 ここ 。
警告:
あなたがシングルトンパターンを使うことを考えているなら、あなたの全力で抵抗してください。それは理解するのが最も簡単なデザインパターンの1つであり、おそらく最も人気があり、そして間違いなく最も悪用されています。 (出典:上記リンクのJavaRanch)
Javaがどのように静的な内部クラスを定義するかに加えて、C#の世界 [1] によると、静的クラスの別の定義があります。静的クラスは静的メソッド(関数)のみを持つクラスで、手続き型プログラミングをサポートすることを目的としています。このようなクラスは、クラスのユーザーがヘルパー関数にのみ関心を持ち、クラスのインスタンスを作成することに関心がないという点で、実際にはクラスではありません。静的クラスはC#ではサポートされていますが、そのような直接のサポートはJavaでは存在しません。ただし、列挙型を使用して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();
}
}
静的にできる唯一のクラスは内部クラスです。次のコードは問題なく動作します。
public class whatever {
static class innerclass {
}
}
静的内部クラスのポイントは、外部クラスオブジェクトへの参照がないということです。
Javaでコーディングしたものはすべてクラスに入ります。クラスを実行するたびに、JVMはオブジェクトをインスタンス化します。 JVMは、定義上、多数のオブジェクトを作成できます。静的とは、すべてのオブジェクトに対して同じコピーのセットがあることを意味します。
したがって、プログラムを実行するたびにJavaが最上位クラスを静的にすることを許可していた場合は、オブジェクトが作成され、同じメモリ位置に上書きされ続けます。
実行するたびにオブジェクトを置き換えるだけの場合は、作成のポイントは何ですか。
そのため、Javaが最上位クラスの静的クラスを削除したのはこのためです。
もっと具体的な理由があるかもしれませんが、これは私にとって論理的に意味のあることです。
私はこれがコーヒーを一杯飲むのと同じくらい簡単にできると思います。ちょっとこれを見てください。クラスを定義するときに静的キーワードを明示的に使用しません。
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);
}
}
EclipseのPlatformUI
で静的メソッドを持つクラスとプライベートコンストラクタを持つクラスを見れば、それ自体は最終的なものになります。
public final class <class name>
{
//static constants
//static memebers
}
静的クラスを使用する利点が、オブジェクトをインスタンス化してメソッドを使用しないことであれば、そのクラスをpublicとして宣言し、このメソッドをstaticとして宣言するだけです。