2016-02-19 13 views
56

私はそれを理解したよう:なぜstaticは文脈によって異なる意味を持っていますか?

  • 静的クラスは、ネストしたクラスに適用され、そしてそれは、ネストされたクラスは、外部クラスへの参照を持っていないことを意味します。

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

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

は、私は、Javaのコースへの導入を取っていますし、私の知識を固めるしようとしているだけでなく、さまざまなキーワードが異なる意味を表すために使用されなかった理由を把握しようとしています。

+0

とにかく、OOPの標準的な名前としてstatic class/field/methodという名前を使用しないでください。たとえばPythonでは、javaの静的メソッドをクラスメソッドと呼びますが、静的メソッドは別のものです。答えは* javaで*静的とはクラス*に関連するもので、インスタンスには関係しないものを意味します。 – Bakuriu

+1

*あまりにも多くの*キーワードを言語に導入したくありません。パイオニアの問題(コンパイラ実行可能ファイルを大きくし、コンパイルを遅くする各キーワード)を除いて、すべてのキーワードは、おそらくユーザにとって有用な識別子ではありません。 (ポイントは、入力が予約されているドメイン固有の言語で作業しています*それは痛みです、私はあなたに言います)*異なる*コンテキストで*類似の*ものが達成されるとキーワードを再使用することは有効なオプションです。 – DevSolar

+1

合理的な観点から、これらはすべて実際に同じことをしています。事を取り、その範囲をインスタンスからクラスに変更します。 CとC++は 'static'が実際にオーバーロードされる場所です。 – Kevin

答えて

70

例はすべて正しいですが、すべて共通の機能を共有しています。静的という語は、を取り囲むのインスタンスを含む必要はないことを意味します。

  • 静的な内部クラスのみが、インスタンスを囲まずに存在することができます。たとえば、クラスFooと非静的内部クラスBarがある場合は、Fooのインスタンス外でBarのインスタンスを作成することはできません。

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

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

インターフェイスが静的クラス、静的フィールド、および静的メソッドを持つことができることを明確にする点を考慮してください。しかし、これらのものの非静的なバージョンを持つことはできません(概念の中にアドホックに分類されるデフォルトのメソッドは無視されます)。これは、インタフェースのインスタンスを決して作成することができないため、囲むインスタンスが存在しない可能性があるからです。

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

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

+1

s /変数/クラス/の3番目の箇条書きポイントですか? – immibis

+0

@immibisありがとう – Pace

6

私が見ているように、静的な言及はすべて共通点があります。すべての場合において、クラス/フィールド/メソッドが静的な場合よりもクラスインスタンスに結びついていないことを意味します。確かに静的フィールドと静的メソッドの間の同等性は明らかです。これらは、他の言語のグローバルオブジェクトと同様の方法で、これらのフィールドで動作するシングルトン(クラスローダーごとの)フィールドとメソッドを宣言する方法です。

はおそらくネストしたクラスの静的を使用することは、同じ精神のように明らかではありませんが、それはあなたがこの構造を使用することを含むクラスのインスタンスを必要としないという側面を共有しません。

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

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

新しいキーワードを追加するのが嫌なので、古いキーワードが過度に読み込まれることがよくあります。クラスメソッドと変数と同様

6

Java Tutorial says

、静的ネストされたクラスは、その外側のクラスに関連付けられ あります。静的クラスメソッドのように、静的ネストされたクラス は、インスタンス変数またはその囲むクラスに定義されている メソッドを直接参照することはできません。 オブジェクト参照によってのみ使用できます。

基本的に「静的」とは、それがマークされたエンティティがクラスのインスタンスと離婚したことを意味します。静的メソッドにはインスタンスが関連付けられていません。静的フィールドはすべてのインスタンス間で共有されます(本質的にクラスに存在し、インスタンスには存在しません)。
静的ネストされたクラスは、囲むインスタンスから離されます。静的メソッドと静的メソッドを持つ静的ネストされたクラスのインスタンスを内部に持つことができるので、ちょっと混乱するかもしれません。静的が持っているのはなぜ

19

「私は親インスタンスに関係がないとしているエンティティ、フィールド、メソッドまたは内部クラスを宣言しています」と言って、静的単語の
考えますコンテキストに応じて異なる意味がありますか?なぜ は異なるキーワードが使われていませんでしたか?

実際には異なる意味はありません。

あなたはそれが発生する可能性のある場所に、次の示すためにstaticキーワードを取ることができます:staticフィールドが1である

「任意の特定のインスタンスに関係または関係なし」を

  • をこれは特定のインスタンスではなくクラスに属します。

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

  • 静的メンバークラスは、その囲むクラスの概念を持たず、そのインスタンスが渡されない限り(そのコンストラクタへの引数などの)囲まれているクラスの特定のインスタンスとは関係がないネストされたクラスです。 。ケイHorstmannによってCore Javaから

+1

答えの一般的な意味は正しいが、私はいくつかの特定の部分に同意できない。 "このようなメソッドは、インスタンスがパラメータとして渡された場合を除いて、特定のインスタンスのインスタンスフィールドにはアクセスできません。 - いいえ、作成するインスタンス(古典的なファクトリ)または静的変数(古典的なシングルトン)から取得するインスタンスにアクセスできます。あなたの次の箇条書きポイントと同じもの - "そのようなインスタンスがコンストラクタにパラメータとして渡されない限り" - ええ、またはその他の方法で、セッターメソッド、DI、静的フィールドなどを含む変数を設定できます。 – Ordous

+0

* "作成したインスタンス(古典的なファクトリ)または静的変数から取得するインスタンスにアクセスすることはできません"同じことを言い方が違うと、私は言います。作成されるインスタンスは、静的メソッドとの既存の関係を持つインスタンスではありません。私はあなたの反論の精神に同意しないでしょうが、投稿されたものと矛盾するとは言いません。 – scottb

+0

"静的フィールドは、' Class'オブジェクトに属するものです - いいえ、Classオブジェクトに属しません。メソッドと同じです。 – immibis

16

用語「静的」好奇心の歴史を持っています。最初に、キーワードstaticはC言語で に導入され、ブロックが終了したときに消えないローカル変数を示します。この文脈では、 という用語は「静的」と意味します。ブロックが再び入力されると、変数はそのまま残り、ブロックされます。 次にstaticはCで2番目の意味を持ち、他のファイルからはアクセスできないグローバル変数と関数を指します。 が新しいキーワードを導入するのを避けるために、キーワードstaticは再利用されました。最後に、C++は関連性のない第3のキーワードを再利用して、クラスに属する変数と関数を表しますが、クラスの特定のオブジェクトには含まれません。 これはキーワードがJavaで持っているのと同じ意味です。

+1

私は、いくつかの無関係の解釈をしているCとC++の "静的"についての見積もりには同意しません。それらの共通点の一つは、変数または関数のメモリアドレスが何らかの形で固定されていることです。私はこれがJavaの意味によく対応していると思います。 –

+0

@ ThomasPadron-McCarthy:そうですが、グローバル変数や関数のアドレスは 'static'に関係なく固定されているので、Cの2番目の意味は実際にはそれとは関係ありません。 –

9

JavaはC++およびCから継承します。これらの言語では、staticには2つの追加の意味があります。 staticとして修飾されたローカル変数(関数スコープ)は、クラス内の静的フィールドの意味にいくらか類似しています。しかし、Javaは "静的"というこのコンテキストをサポートしていません。変数または関数をファイルスコープのCまたはC++のstaticに修飾すると、「Ssh!リンカーに通知しないでください!」という意味です。 Javaではこの平均値staticもサポートしていません。

英語では、文脈によって同じ単語が複数の意味を持つことがあります。辞書内の一般的に使用されている単語を調べると、その単語の複数の定義が見つかります。いくつかの単語は複数の意味を持つだけでなく、複数の品詞を持っています。たとえば、「カウンター」は、文脈に応じて、名詞、動詞、形容詞、または副詞になります。文脈によっては、他の言葉は矛盾した意味を持つことがあります。 「謝罪」は、「大変申し訳ありません!それは「私はまったく残念ではありません!後者の最も優れた例は、G.H. Hardyによる「数学者の謝罪」です。この点で英語は一意ではありません。同じことが、人間がお互いにコミュニケーションをとるために使用する言語にも当てはまります。人間としては、文脈に応じて異なる意味を持つ言葉によく慣れています。

キーワードが少なすぎるとコンピュータ言語の数が多すぎるのには、固有の競合があります。 Lisp、forth、およびsmalltalkは非常に美しい言語であり、キーワードがあるとしてもほとんどありません。彼らはいくつかの特殊文字を持っています。例えば、lispにはカッコを開いたり閉じることができます。 (全開示:これらの3つの言語すべてでプログラミングしましたが、私はそれを愛していました)問題はここにあります:自分が実際に書いたコードを読んで幸運を祈る。そのコードを他の人に転嫁することは、さらに良い運をもたらします。その結果、これらの言語には、限られた数の支持者もいる。他の言語は一番上にあり、膨大な数の単語を「キーワード」として予約しています。 (全開示:私はそれらの言語でもプログラムを余儀なくされていましたが、私はそれを嫌っていました)

コンピュータ言語のキーワードが少なすぎたり少なすぎたりすると、認識の不協和音が発生します。同じキーワードを持つことで、異なるコンテキストが異なることはありません。なぜなら、人間としては、これに慣れているからです。

関連する問題