56

この質問にはすでに答えがあります。

私が理解しているように:

  • 静的クラスは入れ子クラスにのみ適用されます。つまり、入れ子クラスは外部クラスへの参照を持ちません。

  • 静的フィールドは、そのインスタンスが1つしかなく、同じクラスの他のメンバーによって共有されるという点で、グローバル変数に似ています。

  • 静的メソッドは、オブジェクトがまだインスタンス化されていなくても呼び出すことができることを意味します。

私はJavaコースの概要を学び、自分の知識を強固にすることを試みるとともに、異なるキーワードが異なる意味を表すのに使用されなかった理由を理解しようとしています。


  • とにかく、静的クラス/フィールド/メソッドという名前をOOPの標準命名法として使用しないでください。たとえば、pythonでは、javaの静的メソッドをクラスメソッドと呼びますが、異なる静的メソッドが存在します。答えが言うようにjavaで静的とはそれが何かを意味するクラス関連しかし、そのインスタンスにはありません。 - Bakuriu
  • 紹介したくない多すぎるキーワードを言語に変換する。先駆者の問題(コンパイラの実行可能ファイルを大きくし、コンパイルを遅くする各キーワード)を別にして、すべてのキーワードはおそらくユーザにとって1つ少ない有用な識別子を意味します。 (念のため、ドメイン固有の言語を使用しています。input予約キーワードです。それ痛みです、私はあなたに言います。似ている物事はで達成されることです違うコンテキストでは、キーワードを再利用することは有効なオプションです。 - DevSolar
  • 合理的な観点からは、これらはすべて同じことを行います。つまり、ものを取り、そのスコープをインスタンスからクラスに変更します。 CとC ++はどこにありますかstatic本当に過負荷です。 - Kevin
  • 「違う言葉ではない理由」を削除しました。この質問は言語デザイナーについての質問ではないことを明確にするため、タイトルから質問してください。意図はあるが、実際にはstaticつまり、本当に?」言語をよく理解していることを示すのは大きな問題だと思います。ほとんどのJavaプログラマは、これを尋ねることは考えず、ただ単に次のように扱うだけです。static魔法のように。 - Jeffrey Bosboom
  • @ user1803551質問は同じかもしれませんが、私はこの質問の答えがあなたのリンクのものより優れていると思います - stanek

6 답변


70

あなたの例はすべて正しいです、しかし、それらはすべて共通の特徴を共有します。静的という言葉は、囲んでいるインスタンス必要ありません。

  • 包含インスタンスなしで存在できるのは静的内部クラスだけです。たとえば、クラスがある場合Fooそして非静的な内部クラスBarそれならあなたはのインスタンスを作ることができませんBarのインスタンス外Foo

  • 静的メソッドは、メソッドを呼び出すためにクラスのインスタンスが不要であることを意味します。あなたは呼び出すことができますString.format実際なしでString例えばインスタンス。

  • 静的フィールドはクラスのインスタンスがなくても存在します。もしあなたのFooクラスはcounter静的なフィールドは、インスタンスをインスタンス化しなくてもアクセスできます。Fooクラス。

明確にするために、インターフェースは静的クラス、静的フィールド、および静的メソッドを持つことができると考えてください。しかし、それはそれらのもののうちのいずれかの非静的バージョンを持つことはできません(その概念に一種の特別なものであるデフォルトメソッドを無視して)。これは、インターフェイスのインスタンスを作成できないため、それを囲むインスタンスが存在しないためです。

その場合のキーワードは完全に冗長ですが、内部インターフェース、注釈、および列挙型を静的に宣言することもできます(たとえば、インターフェースメソッド抽象の宣言と同様)。インターフェイス、アノテーション、および列挙型は、最初から囲むクラスとは無関係なので、静的クラスでそれを取り除くことはできません。

最後のビザンチンポイント。静的インポートをすると(import static pack.age.Foo.*)クラス内の任意の静的項目への修飾されていない参照(それらが冗長に静的とマークされているかどうかにかかわらず、インタフェース、注釈、および列挙型を含む)を作成できるようになります。


  • 3番目の箇条書きでs / variable / class /? - immibis
  • と言っています - Pace

19

なぜ静的は文脈によって異なる意味を持つのですか?なぜ   違うキーワードが使われていませんか?

本当に違う意味はありません。

あなたは取ることができますstatic次のことが発生する可能性がある場所であれば、それを示すキーワード。

「特定のインスタンスとは関係なく、または関係なく」

  • 静的フィールドは、特定のインスタンスではなくクラスに属するものです。

  • 静的メソッドはクラスに定義されており、その概念はまったくありません。this。このようなメソッドは、インスタンスが渡された場合を除き、特定のインスタンスのインスタンスフィールドにはアクセスできません。

  • 静的メンバークラスは、それを囲むクラスの概念を持たず、そのようなインスタンスが渡されない限り(そのコンストラクターへの引数など)、その包含クラスの特定のインスタンスとは関係がない入れ子クラスです。


  • 答えの一般的な意味は正しいのですが、特定の部分には同意できません。 「このようなメソッドは、インスタンスがパラメータとして渡される場合を除き、特定のインスタンスのインスタンスフィールドにはアクセスできません。」 - いいえ、作成したインスタンス(クラシックファクトリ)または静的変数から取得したインスタンス(クラシックシングルトン)にアクセスできます。あなたの次の箇条書きと同じこと - 「そのようなインスタンスがそのコンストラクタへのパラメータとして渡されない限り」。 - そう、またはセッターメソッド、DI、静的フィールドなど、変数を設定できる他の方法 - Ordous
  • "いいえ、作成したインスタンス(従来のファクトリ)または静的変数から取得したインスタンスにアクセスできます。..同じことを言うのは違う言い方だよ。作成されたインスタンスは、静的メソッドと既存の関係を持つインスタンスではありません。私はあなたの反論の精神に反対することはできませんが、掲載されたことと矛盾するとは言いません。 - scottb
  • "静的フィールドとは、Classオブジェクト" - いいえ、Classオブジェクトに属しません。メソッドについても同じです。 - immibis
  • @immibis:同意しないことはできませんが、理解は区別をするための有用な概念モデルであると言えるでしょう。今日は意味の正確さの日でなければなりません。への参照を編集しました。Classオブジェクト全体。 - scottb

16

からコアJavaCay Horstmann著:

「静的」という用語には興味深い歴史があります。最初に、キーワードstaticがCに導入されました。   ブロックから出ても消えないローカル変数を示します。その文脈では、用語   “ static”は理にかなっています:変数はブロックの中に入ってもそのまま残ります   再び。その後、staticはCで2番目の意味を持ち、グローバル変数と関数を表します。   他のファイルからアクセスすることはできません。キーワードstaticは、避けるために単に再利用されました。   新しいキーワードを紹介します。最後に、C ++はキーワードを関連のない3番目のキーワードに再利用しました   解釈 - クラスには属しているが、クラスには属していない変数および関数を示すこと   クラスの特定のオブジェクトこれは、キーワードがJavaで持っているのと同じ意味です。


  • CとC ++の「静的」についての引用文の意見には同意できません。無関係な解釈がいくつかあります。それらすべての共通点は、変数または関数のメモリアドレスが何らかの形で固定されていることです。これはJavaの意味とよく一致していると思います。 - Thomas Padron-McCarthy
  • @ ThomasPadron-McCarthy:はい。しかし、Cの2番目の意味は実際には関係ありません。グローバル変数やグローバル関数のアドレスは静的であっても固定されているからです。 - Sebastian Reichelt

9

JavaはC ++とCを継承しています。これらの言語では、staticさらに2つの意味があります。として修飾されたローカル変数(関数スコープ)staticクラス内の静的フィールドの意味とやや似た意味を持ちます。ただし、Javaはこの「静的」というコンテキストをサポートしません。変数または関数をとして修飾するstaticCまたはC ++では、ファイルの有効範囲は「Ssh!リンカに伝えないでください」という意味です。 Javaはこの意味をサポートしていませんstaticどちらでも。

英語では、文脈によっては同じ単語が複数の意味を持つことがあります。辞書で一般的に使用されている単語を検索すると、その単語の定義が複数見つかります。いくつかの単語には複数の意味があるだけでなく、複数の品詞があります。たとえば、 "Counter"は、コンテキストに応じて、名詞、動詞、形容詞、または副詞になります。文脈によっては、他の単語が矛盾する意味を持つことがあります。 「謝罪」は「すみません」を意味します。または「すみません、すみません」という意味です。後者の最も良い例はG.H.ハーディによる "数学者の謝罪"です。この点で英語はまったくユニークではありません。同じことが、人間が互いにコミュニケーションをとるために使用する言語にも当てはまります。人間として、私たちは文脈によって異なる意味を持つ言葉にかなり慣れています。

コンピュータ言語でキーワードが少なすぎることと多すぎることとの間には、本質的な矛盾があります。 Lisp、forth、smalltalkは非常に美しい言語で、キーワードはほとんどありません。それらはいくつかの特別な文字を持っています。例えば、lispでは開き括弧と閉じ括弧です。ここで問題があります:あなたが事実の6ヵ月後にあなた自身が書いたコードを読んで頑張ってください。そのコードを他の人に引き渡すことができればさらに幸運です。その結果、これらの言語にもかなり限られた数の支持者しかいません。他の言語が一番上に行き、「キーワード」として膨大な数の単語を予約しています。 (完全な開示:私はこれらの言語でもプログラムを作成することを余儀なくされました、そして私はそれが嫌いでした。)

コンピュータ言語のキーワードが少なすぎたり多すぎたりすると、認知的不調和になります。同じキーワードを持っていても、文脈が違っても違いはありません。人間として、私たちはそれにかなり慣れているからです。


6

Javaチュートリアルは言う

クラスのメソッドや変数と同様に、静的な入れ子クラスは   その外部クラスに関連付けられています。そして静的クラスメソッドのように、   静的ネストクラスはインスタンス変数を直接参照できません。   その親クラスで定義されているメソッド   オブジェクト参照

基本的に「静的」とは、それによってマークされたエンティティがクラスのインスタンスから分離されていることを意味します。静的メソッドにはインスタンスが関連付けられていません。静的フィールドはすべてのインスタンス間で共有されます(基本的にインスタンス内ではなくクラス内に存在します)。

静的な入れ子クラスは、それを囲むインスタンスから切り離されます。内部に静的でないメソッドとフィールドを持つ静的な入れ子になったクラスのインスタンスを持つことができるので、それは少し混乱するのは正しいです。

静的という言葉は、「私はエンティティ、フィールド、メソッド、または内部クラスを宣言しています。囲んでいるインスタンス


6

私が見たように、静的の前述の使用法はすべて共通点がいくつかあります。すべての場合において、静的でない場合よりもクラス/フィールド/メソッドの方がクラスインスタンスとの関連性が低いということです。確かに、特に静的フィールドと静的メソッドの間の等価性は明らかであるべきです。それらは、他の言語のグローバルオブジェクトと同じように、シングルトン(クラスローダーごと)フィールドとそれらのフィールドで機能するメソッドを宣言する方法です。

おそらく、ネストされたクラスにstaticを使用することは、同じ趣旨では明らかに同じではありませんが、次のような側面を共有しています。この構文を使用するために包含クラスのインスタンスは必要ありません。

だから私はこれらが特に矛盾しているとは思わない。

プログラミング言語でキーワードが見かけ上異なる目的で再利用される理由についてのより一般的な質問に対する答えの1つは、言語が進化するにつれて機能が導入されることが多いということです。識別子として。たとえば、Javaは実際にはキーワードを予約しています。constたとえそれがその言語で使われていなくても、おそらく将来の拡張を見込んで!

新しいキーワードを追加することへのこの消極的な行為は、しばしば古いキーワードを過負荷にします。

リンクされた質問


関連する質問

最近の質問