430

Javaでクラスを静的クラスとして宣言できないのはなぜですか。


  • 反対の質問:もしあなたがトップレベルのクラスをstatic? - Joachim Sauer
  • いいえ、静的内部クラス以外はできません。しかし、それで何を達成したいですか? - manolowar
  • @ Joachim Sauer:C#が解釈するstaticクラスabstract finalつまり、インスタンス化できず、拡張できません。つまり、静的メンバーのみを含めることができます。これは、ヘルパーメソッドのみを含むクラスに役立ちます。 - bcat
  • @bcatこれはC#にも当てはまりますが、Javaクラスは抽象クラスまたは最終クラスのどちらでもかまいません。クラスがインスタンス化されるのを防ぐために、プライベートコンストラクタを宣言することができます。 - Lorenzo Polidori
  • @JoachimSauer単純なことですが、クラス内のすべてのメンバを強制的に静的にすることをお勧めします(場合によっては、各メソッドまたはプロパティを宣言する必要もあります)。 - hmartinezd

14 답변


462

ネストしたクラスだけが静的になることができます。そうすることで、外部クラスのインスタンスを持たずにネストしたクラスを使用できます。

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();
}

出典:

同じトピックで:


  • 最初の句が正確ではないにもかかわらず+1。チュートリアルが述べているように、「非静的な入れ子クラスは内部クラスと呼ばれます」。 (JLS:「内部クラスとは、明示的または暗黙的にstaticとして宣言されていない入れ子のクラスです。」 - Carlos Heuberger
  • あなたは最も確実に正しいです。しかし、これがどのように質問に答えているのかわかりません。 - Joeri Hendrickx
  • @Carlos Heuberger、あなた、そのとおりです、投稿を更新しました。 @Joeri Hendrickx、質問は「クラスがなぜ静的クラスとして宣言できないのか?」という質問でした。これは、静的クラスの使用方法と、それらがネストクラスになる必要がある理由についての説明です。 - Colin Hebert
  • ここで与えられた解決策は大丈夫です...しかし、私はまだ静的クラスがjava..someで不可能であることを論理的に説明していませんOOPs概念の説明が正しい答えになるでしょう。私はそれを待っています - Punith Raj
  • それは本当ですが、あなたが考えている質問は、あなたが「静的クラス」とは何かを自問し始めたときに、通常それ自身で解決します。だろう。 Javaでは、静的要素は、それを囲むクラスのインスタンスなしでそれにアクセスしたり呼び出したりできることを意味します。そのキーワードをクラス自体に適用した場合、どういう意味でしょうか。あなたの意図は何ですか?何を期待しますか?これで何が起こり得るかがわかったので、それが「実際には意味をなさない」のどちらかになることを確信しています。または「遠くに取得」されます。 (意味がありますが、これで終わりです。これは選択されたものです)。 - Colin Hebert

31

それで、私はパーティーに遅刻しています、しかしここに私の2セントがあります - 哲学的にコリンHebertの答えに加えて。

大まかに言って、あなたの質問はオブジェクトとタイプの違いを扱います。多くの自動車(オブジェクト)がありますが、Carクラス(タイプ)は1つだけです。何かを静的なものとして宣言することは、あなたが「タイプ」空間で操作していることを意味します。 1つだけです。最上位クラスのキーワードは、既に "type"スペースで型を定義しています。結果として、 "public static class Car"は冗長です。


  • はい。別の言い方をすると、最上位クラスはデフォルトでは静的であるため、キーワードは必要ありません。 - Warren Dew
  • さて、私はウォーレンデューが言ったことに付け加えます - 「静的メンバーにアクセスするとき、トップレベルクラスはデフォルトで静的です」。 - Dexter
  • 過小回答。クラス内のすべてのメソッドを静的にし、コンストラクタをprivateにする新しいキーワードがあればいいでしょう。静的な名前にはしないでください。混乱を招くだけです。 - G_V
  • @G_V Javaはそのようなモンスターを作成することができましたが、Javaは愚かなことを困難にするためのその方法からほとんど外れています。統計は一般的に悪い考えです。静的クラスは恐ろしいものです(それ自体がアンチパターンと見なされるシングルトンよりも悪いです)。多くの人がこれを理解していないので、キーワードを付けるのは非常に悪い考えです。代わりに、私たちは悪いことを困難にし、それをそのままにしておきます。 「シングルトン」はありません。どちらかのキーワード。 Propertyキーワードはありません。これらはすべて悪いコードを引き起こします(人々はまだPropertiesをあまりにも多く使用しているのでJavaもそれらをサポートするかもしれませんが)。 - Bill K

31

最上位クラスはデフォルトでは静的です。内部クラスはデフォルトでは非静的です。明示的に静的にマークすることで、内部クラスのデフォルトを変更できます。参照する親クラスがないため、トップレベルクラスは、トップレベルであるため、非静的セマンティクスを持つことはできません。したがって、最上位クラスのデフォルトを変更する方法はありません。


  • »最上位クラスはデフォルトでは静的です。«これが最良の答えです。あなたがそれらを参照するために何かのインスタンスを必要としないので、それらは静的です。どこからでも参照できます。参加しています静的ストレージ(C記憶域クラスのように)。 - 他の人が指摘したように(別の答えへのコメントでIain Elder)、言語デザイナーはそれを許可したかもしれませんstatic最上位クラスのキーワードで、静的メンバーのみを含み、インスタンス化されていないことを示して強制する。しかし、それは人々をstatic入れ子クラスでは意味が異なります。 - Lumi

29

プライベートコンストラクタを持つクラスは静的です。

このようにあなたのクラスを宣言してください:

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 final intと書くと、ECodeOauthUnknown = 0x10となります。もう静的ではありません。 - user1883212
  • 誰かがここで何が起こっているのか疑問に思う場合は、これは"静的クラス"のC#定義と一致します。 - msdn.microsoft.com/ja-jp/library/79b3xss3%28v=vs.90%29.aspx。 「静的クラス」のJava定義を考えると、すべての非内部クラスは静的です(兄弟姉妹の回答を参照)。 - Calum
  • @ user1883212は別として、この答えは読者を混乱させるとさえ言っていますが、ここではプライベートコンストラクタがどういうわけか重要であるが、それはまったく問題ではありません。 - tlwhitec
  • .NETの世界では、クラスが抽象クラスと最終クラスの両方としてマークされている場合(static classC#で宣言した場合、コンパイラはコードでその型の変数を宣言することも、一般的な型パラメータとして使用することもできません。別の方法でインスタンス化または継承できるクラスにアクセス可能なコンストラクタがないだけでは、その型の変数の宣言も、総称型パラメータとしての使用も妨げられません。 - supercat
  • この答えは全く間違っています。プライベートコンストラクタはそれとは関係ありません。このコードは、静的な属性とメソッドしかないクラスの例にすぎません。静的クラスとは関係ありません。 - user207421

12

確かに彼らはできるが、唯一の内なる入れ子クラスそこでは、ネストしたクラスのインスタンスは外側のクラスの外側のインスタンスを必要としません。

しかし、トップレベルのクラスでは、言語設計者はこのキーワードを使用して何か有用なことを考えることができないため、許可されません。


  • 最初の句が正確ではないにもかかわらず+1。 JLSによると、「内部クラスは明示的または暗黙的にstaticと宣言されていない入れ子のクラスです。」 (ちょっと専門用語、私は知っている...) - Carlos Heuberger
  • 最上位クラスは宣言できませんがstaticできることがあると意味があります。たとえば、静的ヘルパーメソッドのみを含むクラスはインスタンス化するのは意味がありませんが、Java言語ではそれをやめることはできません。デフォルトのコンストラクタを宣言することで、そのクラスを他のクラスに対してインスタンス化不可能(そして実質的には静的)にすることができます。privateコンストラクタが表示されないため、インスタンス化を禁止します。 - Iain Samuel McLean Elder

12

インスタンスなしでenum型を宣言することで、ユーティリティクラス(インスタンスを作成することはできません)を作成できます。つまり、インスタンスが存在しないことを明確に宣言しているということです。

public enum MyUtilities {;
   public static void myMethod();
}


  • 型としての列挙型は特定の期待です。列挙型の項目のセットです。他の方法でプライベートコンストラクタを持つクラスを持つことができたときに、それを"ユーティリティクラス"に使用するのは意味的に混乱します。 - Visionary Software Solutions
  • @VisionarySoftwareSolutions私にとって、この特殊性は、クラスのインスタンスを作成することを間接的に不可能にするのではなく、このクラスのインスタンスが存在しないことを意味します。 - Peter Lawrey

8

public class Outer {
   public static class Inner {}
}

...メンバクラスである限り、staticと宣言することができます。

JLSから:

メンバクラスは静的にすることができます。その場合、メンバクラスは周囲のクラスのインスタンス変数にアクセスできません。あるいはそれらは内部クラスでもよい(8.1.3)。

そしてここ:

staticキーワードは、非内部クラスTの本体内でメンバー型Cの宣言を変更することがあります。その効果は、Cが内部クラスではないことを宣言することです。Tの静的メソッドの本体にTの現在のインスタンスがないのと同様に、CにもTの現在のインスタンスはありません。また、字句的に囲むインスタンスもありません。

最上位クラスに包含型がないという理由だけで、静的キーワードは最上位クラスには意味がありません。



5

上で説明したように、クラスは他のクラスのメンバーでない限り静的にはできません。

「複数のインスタンスが存在できない」クラスを設計する場合は、「シングルトン」設計パターンを検討することをお勧めします。

初心者シングルトン情報ここに

警告:

あなたが使用することを考えているなら   シングルトンパターン、すべてに抵抗   あなたの力それは最も簡単なの一つです   理解するDesignPatterns、おそらく   最も人気のある、そして間違いなく   最も虐待された。(出典:上記リンクのJavaRanch)


4

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();
    }
}


2

静的にできる唯一のクラスは内部クラスです。次のコードは問題なく動作します。

public class whatever {
    static class innerclass {
    }
}

静的内部クラスのポイントは、外部クラスオブジェクトへの参照がないということです。


  • '静的インナー'は矛盾しています。 '静的' '内側'相互に排他的です。探している単語は入れ子になっていますが、内側の単語ではありません。 - user207421

2

Javaでコーディングしたものはすべてクラスに入ります。クラスを実行するたびに、JVMはオブジェクトをインスタンス化します。 JVMは、定義上、多数のオブジェクトを作成できます。静的とは、すべてのオブジェクトに対して同じコピーのセットがあることを意味します。

そのため、プログラムを実行するたびにJavaが最上位クラスを静的にすることを許可していた場合は、オブジェクトが作成され、同じメモリ位置に上書きされ続けます。

実行するたびにオブジェクトを置き換えるだけの場合は、それを作成することが重要です。

そのため、Javaが最上位クラスの静的クラスを削除したのはこのためです。

もっと具体的な理由があるかもしれませんが、これは私にとって論理的に意味のあることです。


  • 内部クラスは外部クラスに関連付けられているため、依存するオブジェクトが異なるため、静的クラスになることができます。 - user2626445
  • それは彼らができる理由だからです。ではない静的にしてください。 - user207421

1

私はこれがコーヒーを一杯飲むのと同じくらい簡単にできると思います。 ちょっとこれを見てください。 クラスを定義するときに静的キーワードを明示的に使用しません。

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);
    }
}


  • 静的キーワードを修飾子として使用するのではなく、静的クラス定義を参照することで、このようなクラスを静的クラスと見なすことができると思います。 - Erfankam
  • プライベートコンストラクタを作成するようにしてください。そうしないとあなたが言うことができるでしょうnew StaticClass()それほど意味があるわけではありません。プライベートコンストラクタでは、そのインスタンスを許可しません。 - grinch

1

一目でわかるPlatformUIEclipseでは、静的メソッドを持つクラスと、それ自体が最終的なプライベートコンストラクタを使用します。

public final class <class name>
{
   //static constants
   //static memebers
}


0

静的クラスを使用する利点が、オブジェクトをインスタンス化してメソッドを使用しないことであれば、そのクラスをpublicとして宣言し、このメソッドをstaticとして宣言するだけです。

リンクされた質問


関連する質問

最近の質問