回答:
重いC ++コーディングからJavaに移行するたびに、Javaのconst-correctnessの欠如に適応するのに少し時間がかかります。const
C ++ でのこの使用法は、知らない場合に定数変数を宣言することとは大きく異なります。基本的には、const-pointerと呼ばれる特別な種類のポインターを介してアクセスしたときにオブジェクトが不変であることを保証します。副作用があってはならないメソッドのみを含む。残念ながら、これは言語によって強制されていません。
ウィキペディアでは、このテーマに関する次の情報を提供しています。
興味深いことに、Java言語仕様では、constを予約済みキーワード(つまり、変数識別子として使用できないキーワード)と見なしていますが、セマンティクスは割り当てられていません。キーワードの予約は、Java言語の拡張にC ++スタイルのconstメソッドとconst型へのポインターを含めることができるようにするために行われたと考えられています。Javaでconstの正確性を実装するためのJava Community Processの拡張リクエストチケットは2005年に閉鎖されました。これは、constの正確性がおそらく公式のJava仕様に反映されないことを意味します。
final
ただし、Java も同様です。
final
たとえば、C ++ const
メソッドとは完全に異なる動作をするメソッド。
final
キーワードは、プロパティまたは変数が一度だけ割り当てられることを保証するだけです。たとえば、副作用を持つメソッドを呼び出すことによって、このオブジェクトの状態を変更することもできます。final
ポインタではなくオブジェクトを参照するという点でC ++のスタック割り当てにいくぶん似ていますが、それだけです。これはもちろんdom0がすでに言ったことに加えてです。
final
Javaではconst
、値型の場合はC ++のように機能しますが、T&
参照型の場合はC ++非定数のように機能します
どういうconst
意味か
まず、「const」キーワードのセマンティクスは、人によって意味が異なることを理解してください。
final
セマンティクス-参照変数自体を別のインスタンス(メモリロケーション)を指すように再割り当てすることはできませんが、インスタンス自体は変更可能ですconst
ポインター/参照セマンティクス-この参照はインスタンスの変更に使用できないことを意味します(例:インスタンス変数に割り当てられない、変更可能なメソッドを呼び出せない)-参照変数のみに影響するため、非const参照が同じインスタンスがインスタンスを変更する可能性がありますなぜか、なぜそうでないconst
か、本当に「賛成派」と「反対派」の議論の一部を掘り下げたい場合は、この拡張要求(RFE)の「バグ」の下の説明を参照してください。このRFEは、「読み取り専用参照」タイプの「const」機能を要求します。1999年にオープンし、2005年にSunによってクローズ/却下された「const」トピックは、激しく議論されました。
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4211070
双方には多くの良い議論がありますが、しばしば引用される(しかし、必ずしも説得力のある、または明確なわけではない)理由にconst
は、次のものがあります。
const
平均以上の)これらが良い理由か悪い理由かについて誰かが私に議論する前に、これらは私の理由ではないことに注意してください。これらは、私がRFEの議論をざっと読んで得たいくつかの理由の「要点」にすぎません。私は必ずしも自分自身に同意するわけではありません。単に、私ではなく一部の人々がconst
キーワードが良い考えではないかもしれないと感じる理由を挙げようとしています。個人的には、より明確な方法で言語に導入される「const」セマンティクスがもっと欲しいです。
volatile
理解するのはとても簡単ですか?またはfinal
?ええ。
const
C ++では、値が定数であることを意味しません。
const
C ++では、契約のクライアントがその値を変更しないことを約束することを意味します。
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。
けれどもx
としてマークされたconst
非constエイリアスが作成されるように、x
一定ではありません。すべてのコンパイラがvolatile
この動作を必要とするわけではありません(ただし、すべてのコンパイラは定数をインライン化することが許可されています)
より複雑なシステムではconst_cast
、を使用せずにconst / non-constエイリアスを取得するため、constが変更されないことを意味すると考える習慣がますます危険になります。const
単に、コードがキャストなしではコードを変更できないことを意味し、値が定数であることを意味しません。
const
、値が一定であることを意味しません。これは、値のクライアントがそれを変更しないように制約されていることを意味します。あなたの例ではエイリアスがないので、すべてのユーザーが同じ制約を受けています。これは一般的なケースではありません。const
値ではなくクライアントに影響します-変更できない、変更されないというわけではありません。
immutable interface
し、immutable object
Javaで模倣のconstへの(キャストと反射とbeatable)別の方法があります。"真の" constは、SealedObjectを使用して実行できますが、オブジェクトのユースケースが破壊されます。
これは少し古い質問ですが、このスレッドが今日の会話で出てきたので、とにかく2セントを寄付すると思いました。
これはなぜconstがないのか正確に答えていませんか?しかし、クラスを不変にする方法。(残念ながら、受け入れられた回答へのコメントとして投稿するにはまだ十分な評判がありません)
オブジェクトの不変性を保証する方法は、クラスを不注意に設計することです。これは、変更可能なクラスよりも少し注意が必要です。
これは、Josh Blochの効果的なJava アイテム15-最小化の可変性に戻ります。本をまだ読んでいない場合は、コピーを手に取り、数回読んでください。比喩的な"Javaゲーム"が表示されることを保証します。
項目15でBlochは、オブジェクトの状態を保証するためにクラスの可変性を制限する必要があることを示唆しています。
本を直接引用するには:
不変クラスは、インスタンスを変更できないクラスです。各インスタンスに含まれるすべての情報は、作成時に提供され、オブジェクトの存続期間中は修正されます。Javaプラットフォームライブラリには、String、ボックス化されたプリミティブクラス、BigIntegerおよびBigDecimalなど、多くの不変クラスが含まれています。これには多くの理由があります。不変クラスは、可変クラスよりも設計、実装、使用が簡単です。エラーが発生しにくく、より安全です。
次に、Blochは、5つの単純なルールに従って、クラスを不変にする方法を説明します。
final
)。final
。private
。詳細については、本のコピーを入手することを強くお勧めします。
のC ++セマンティクスはconst
、Java とは大きく異なりますfinal
。デザイナーが使用しconst
ていたとしたら、それは不必要に混乱していたでしょう。
const
予約語であるという事実は、設計者がを実装するためのアイデアを持っていることを示唆していますがconst
、それ以来、彼らはそれを拒否しました。このクローズされたバグを参照してください。上記の理由には、C ++スタイルのサポートを追加const
すると互換性の問題が発生することが含まれます。
Javaで「const」変数を作成する方法がありますが、これは特定のクラスに対してのみです。finalプロパティを持つクラスを定義し、それをサブクラス化するだけです。次に、「const」を使用する基本クラスを使用します。同様に、「const」メソッドを使用する必要がある場合は、それらを基本クラスに追加します。コンパイラーは、基本クラスの最終メソッドであると考えるものを変更することを許可しませんが、サブクラスのメソッドを読み取って呼び出します。
定数を定義するには2つの方法があります- const
とstatic final
、まったく同じセマンティクス。さらにstatic final
、より良い動作を説明しますconst
static
(特定のインスタンスに属していない)であり、final
変更できません。
static finalを使用して、Constと同様に機能するものを作成できます。これは過去に使用しました。
protected static final int cOTHER = 0;
protected static final int cRPM = 1;
protected static final int cSPEED = 2;
protected static final int cTPS = 3;
protected int DataItemEnum = 0;
public static final int INVALID_PIN = -1;
public static final int LED_PIN = 0;
const
基本的な機能はありません。タイトルとタグを適宜修正しました。