クラスをJavaで静的と宣言できないのはなぜですか?
-
01-10-2019 - |
質問
クラスを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();
}
出典:
同じトピックについて:
他のヒント
トップレベルのクラスはデフォルトで静的です。内部クラスはデフォルトでは非静的です。 staticを明示的にマークすることにより、内部クラスのデフォルトを変更できます。トップレベルであるため、トップレベルのクラスは、参照する親クラスがないため、非静的なセマンティクスを持つことはできません。したがって、トップレベルのクラスのデフォルトを変更する方法はありません。
だから、私はパーティーに遅れて来ますが、ここに私の2セントがあります - 哲学的にコリン・ヘバートの答えに追加されます。
高レベルでは、あなたの質問はオブジェクトとタイプの違いを扱います。多くの車(オブジェクト)がありますが、車のクラス(タイプ)は1つだけです。静的と宣言することは、「タイプ」スペースで動作していることを意味します。 1つしかありません。トップレベルのクラスキーワードは、すでに「タイプ」スペースのタイプを定義しています。その結果、「公共の静的クラスカー」は冗長です。
プライベートコンストラクターのクラスは静的です。
このようにクラスを宣言してください:
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)。
そしてここ:
静的キーワードは、非InnerクラスTの本文内のメンバータイプCの宣言を変更する場合があります。 その効果は、Cは内部クラスではないことを宣言することです。 Tの静的な方法には、その体内にTの現在のインスタンスがないように、CにはTの現在のインスタンスもありませんし、語彙的に囲まれたインスタンスもありません。
トップレベルのクラスに囲まれたタイプがないという理由だけで、静的キーワードはトップレベルのクラスでは意味がありません。
上で説明したように、クラスは別のクラスのメンバーでない限り、静的にすることはできません。
「複数のインスタンスがない」クラスを設計したい場合は、「シングルトン」のデザインパターンを調べたい場合があります。
初心者のシングルトン情報 ここ.
警告:
シングルトンパターンを使用することを考えている場合は、すべての力で抵抗してください。それは理解するのが最も簡単なデザインパターンの1つであり、おそらく最も人気があり、間違いなく最も虐待されています。 (出典:上記のリンクされているJavaranch)
Javaが静的インナークラスを定義する方法に加えて、C#の世界に従って静的クラスの別の定義があります [1]. 。静的クラスは、静的メソッド(関数)のみを備えたクラスであり、手続き上のプログラミングをサポートすることを目的としています。このようなクラスは、クラスのユーザーがヘルパー機能にのみ関心があり、クラスのインスタンスを作成することではないという点で、実際にはクラスではありません。静的クラスはC#でサポートされていますが、Javaにはこのような直接的なサポートは存在しません。ただし、ユーザーが特定のクラスのインスタンスを作成することができないように、JavaのC#Staticクラスを模倣するためにEnumsを使用できます(リフレクションを使用しても) [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がトップレベルのクラスの静的を取り除いた理由です。
もっと具体的な理由があるかもしれませんが、これは私にとって非常に論理的な意味を持ちました。
静的にできる唯一のクラスは、内部クラスです。次のコードは正常に機能します:
public class whatever {
static class innerclass {
}
}
静的な内部クラスのポイントは、外側のクラスオブジェクトへの参照がないことです。
これはコーヒーを飲むのと同じくらい簡単だと思います!これを見てください。クラスの定義中は静的キーワードを明示的に使用しません。
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);
}
}
見ることができます PlatformUI
静的な方法とプライベートコンストラクターが最終的なクラスを備えたクラスの日食。
public final class <class name>
{
//static constants
//static memebers
}
静的クラスを使用する利点がオブジェクトをインスタンス化してメソッドを使用することではない場合は、クラスを公開とし、この方法を静的と宣言するだけです。