web-dev-qa-db-ja.com

Javaに一定の機能がないのはなぜですか?

Javaの定数の背後にある理由を特定しようとしていました。Javaを使用すると、finalキーワードを使用して定数を宣言できることがわかりました。

私の質問は、なぜJavaが定数(const)機能を導入しなかったのかということです。多くの人がそれがC++から来たと言うので、C++にはconstキーワードがあります。

あなたの考えを共有してください。

134
gmhk

constの意味
最初に、「const」キーワードのセマンティクスが人によって異なることを意味することを理解します。

  • 読み取り専用参照-Java finalセマンティクス-参照変数自体を別のインスタンス(メモリの場所)を指すように再割り当てすることはできませんが、インスタンス自体は変更可能です
  • 読み取り専用参照-C constポインター/参照セマンティクス-この参照を使用してインスタンスを変更できないことを意味します(たとえば、インスタンス変数に割り当てられず、可変メソッドを呼び出すことができません)-に影響します参照変数のみ。したがって、同じインスタンスを指す非const参照はインスタンスを変更できます。
  • 不変オブジェクト-インスタンス自体を変更できないことを意味します-インスタンスに適用されるため、非const参照は許可されないか、インスタンスの変更に使用できません
  • 上記のいくつかの組み合わせ
  • その他

const
第二に、「pro」対「con」引数のいくつかを本当に掘り下げたい場合は、この拡張リクエスト(RFE)の「バグ」の説明を参照してください。このRFEは、「読み取り専用参照」タイプの「const」機能を要求します。 1999年にオープンし、2005年にSunによって閉鎖/拒否された「const」トピックは、活発に議論されました。

http://bugs.Sun.com/bugdatabase/view_bug.do?bug_id=421107

両側には多くの良い議論がありますが、constに対するよくある(必ずしも説得力のある、または明確なカットではない)理由のいくつかは次のとおりです。

  • 誤用および/または悪用される可能性のある混乱したセマンティクスを持っている可能性があります(上記のWhat the What _const mean
  • そうでなければ利用可能な機能を複製する可能性があります(たとえば、不変のインターフェイスを使用して不変のクラスを設計する)
  • 機能クリープである可能性があり、値によるオブジェクトの受け渡しのサポートなど、他のセマンティック変更の必要性につながる

これらが良い理由か悪い理由かを議論しようとする前に、これらは私の理由ではないことに注意してください。それらは単に、私がRFEの議論をざっと読んで得たいくつかの理由の「要旨」です。私は必ずしもそれらに同意するわけではありません-なぜ私ではなく一部の人々がconstキーワードが良い考えではないと感じるかもしれないかを引用しようとしています。個人的には、より「コンスト」なセマンティクスが明確に言語に導入されることを望んでいます。

81
Bert F

C++のconstは、値が定数であることを意味しません。

C++のconstは、契約のクライアントがその値を変更しないことを約束することを意味します。

const式の値が変更されるかどうかは、スレッドベースの同時実行性をサポートする環境にいる場合により明確になります。

Javaはスレッドとロックの同時実行性をサポートするために最初から設計されたため、finalが持つセマンティクスを持つように用語をオーバーロードして混乱を増すことはありませんでした。

例えば:

#include <iostream>

int main ()
{
    volatile const int x = 42;

    std::cout << x << std::endl;

    *const_cast<int*>(&x) = 7;

    std::cout << x << std::endl;

    return 0;
}

出力42、7。

xconstとマークされていますが、非constエイリアスが作成されるため、xは定数ではありません。すべてのコンパイラがこの動作にvolatileを必要とするわけではありません(ただし、すべてのコンパイラは定数をインライン化できます)

より複雑なシステムでは、const_castを使用せずにconst/non-constエイリアスを取得するため、constは何かが変更されないことを意味するという習慣を身に付けることがますます危険になります。 constは、値が定数であることではなく、コードがキャストなしでは変更できないことを意味します。

7
Pete Kirkham

これは少し古い質問ですが、このスレッドが今日の会話で登場したので、とにかく2セントを寄付すると思いました。

これは正確に答えませんなぜconstがないのですか?buthowクラスを不変にします。 (残念ながら、受け入れられた回答へのコメントとして投稿するほどの評判はまだありません)

オブジェクトの不変性を保証する方法は、クラスを不注意に設計することです。これには、可変クラスよりも少し注意が必要です。

これは、Josh BlochのEffective JavaItem 15-Minimize Mutabilityに戻ります。本を読んでいない場合は、コピーを取り、数回読んでください。私はそれがあなたの比ur「Javaゲーム」に役立つことを保証します。

項目15で、Blochは、オブジェクトの状態を保証するために、クラスの可変性を制限することを提案しています。

本を直接引用するには:

不変クラスは、インスタンスを変更できないクラスです。各インスタンスに含まれるすべての情報は、作成時に提供され、オブジェクトの存続期間中は固定されます。 Javaプラットフォームライブラリには、ストリング、ボックス化されたプリミティブクラス、BigIntegerおよびBigDecimalを含む多くの不変クラスが含まれています。これには多くの正当な理由があります。不変クラスは、可変クラスよりも設計、実装、使用が簡単です。エラーが発生しにくく、より安全です。

次に、Blochは、5つの単純な規則に従って、クラスを不変にする方法を説明します。

  1. オブジェクトの状態を変更するメソッド(セッター、別名ミューテーター)を提供しないでください
  2. クラスを拡張できないことを確認します(これは、クラス自体をfinalとして宣言することを意味します)。
  3. すべてのフィールドをfinalにします。
  4. すべてのフィールドをprivateにします。
  5. 可変コンポーネントへの排他的アクセスを確保してください。 (オブジェクトの防御コピーを作成することにより)

詳細については、本のコピーを入手することを強くお勧めします。

5
grego

constのC++セマンティクスは、Java finalとは大きく異なります。設計者がconstを使用していた場合、不必要に混乱していたでしょう。

constが予約語であるという事実は、設計者がconstを実装するためのアイデアを持っていたことを示唆していますが、その後、彼らはそれに反対しました。 このクローズドバグ を参照してください。述べられている理由には、C++スタイルconstのサポートを追加すると互換性の問題が発生することが含まれます。

3
Stephen C