私はヌルフィールドをチェックhiberbateためjavax.validation.constraints.NotNullを使用しています。今私はsimplefyコンストラクタコードにロンボクを使用していますが、私は必要なフィールドのコンストラクタに含ま場を作るために@NonNullアノテーションを使用する必要があります。私はそれらを一緒に使用する必要がありますか?
少なくとも4つのがあり、完全に非NULL注釈が何をするかの異なった意味合いが。ほとんどの注釈は、これらの異なるものの一つを意味します。したがって、はい、それは、複数のそのような注釈を適用することに意味を作ることができます。私の経験ではほとんどの開発者は、彼らが異なることを意味しているという事実を考えられなかったので残念ながら、これらのアノテーションの実際の意味は、かなり、マディードされています。実際に、私が出会ったほとんどの開発者は、NULLかどうかの注釈が信じられないほど複雑で漠然と定義されているという事実を完全に忘れています。
型システムの解釈(「にすることはできません!」)
この解釈は、として強いようになろうとしているタイプの表明であるString
中でString x;
それは次のとおりです。あることは不可能そのためx
、変数が文字列でないオブジェクトを参照するために、それが不可能であるため、当然、それは完全に役に立たない考えですこれをチェックします。その宣言を考えると、のようなものは、String z = (String) x
それが実際には、コンパイラの警告だそう無用です。
そしてそれは、そのようなアノテーションです。この例はcheckerframework、日食、とのIntelliJのとおりです。org.checkerframeworkchecker.nullness.qual.NonNull
、org.jetbrains.annotations.NotNull
およびEclipseのorg.eclipse.jdt.annotation.NonNull
すべての主にこの意味を暗示する(checkerframeworkと日食が注釈type_useあるのに対し、IntelliJの1は、paramsパラメータとメソッドに適用されますが、私はこれが複雑なことを言った:P)。
これらのアノテーションは、「にすることはできません」暗示により、書き込み時のチェックのために使用されています。書き込みが同じ理由String x = 5;
ですぐにあなたがそのコードを書いて、あなたの前にも、ファイルの保存など、あなたのIDEに赤い波線の下線、そう書き、言って、あるsomeMethod(map.get(key))
のsomeMethodのパラメータは、次のいずれかでアノテートされ、NonNull
注釈が。それは、「あなたはいけない」、それである「私もあなたをさせませんことをあなたが行うことができない」ほどではありません。
もちろん、javacのコンパイラは、実際にそのように動作していない、それはそのように見えるようにしようとしているのIDEおよびツールです。あなたはStringにString型の変数をキャストすることはないと同じように、あなたが実際にあなたがチェックすべきことを意味しているようなNULLかどうかの注釈を考慮していません。番号; 平均:それはないです。これは、チェックがすでに行われていますし、あなたがもう一度チェックする必要はありません意味します。
もちろん、複雑だ:これらの非NULL注釈の意味を壊すから実際に停止しますが...(などkotlincなど)いくつかのツールにかかわらJavaコンパイラの意志はとにかく、明示的nullchecksを注入するという事実を周りに踊ること。ジェネリック医薬品は、あなたがジェネリック医薬品は後方互換性を維持するためにコンパイル時のオンボルトであるという事実を回避するには、明示的なキャストを書いたことがない場所では、いくつかのtypechecksを注入するのjavacを引き起こす可能性がありますどのようなビット。アイデアは、あなたが考えるべきではありませんこれらの実装の詳細を検討することです。
DBの解釈
Hibernateが生成するためにテンプレートとしてクラスを使用するとCREATE TABLE
、SQL文を、それは次のような制約やルールと設定するために注釈を使用することができると便利です。あなたは、フィールドをマークすることがあります同じ理由:「SQLにこれを入れるとき:「SQL列にこれを回すときは、これに一意のインデックスを置くためにDBエンジンを教えて」、あなたはとしてそれをマークすることもできます列は、「それにnull以外の制約を置くためにDBエンジンに伝えます。
銃やおばあちゃんのように型システムの解釈に関連するので、これはです:あなたは、DB内の行を表すオブジェクトを持つことができますが、成功した制約に破壊による保存しないであろうすべての時間を。例えば、任意の自動カウントUNIDフィールドは、通常は0であり、それはそのように保存しないでしょう(「用事ことに0というDBエンジンのアップグレードを、それなしで挿入し、この番号でDBエンジンのシーケンス塗りをしましょう)。これらであるそれはそう:それは本当にすべてのJavaへの平均は何もしません。SQLエンジンは、挿入/更新が失敗制約に起因する障害が発生したことを示すの世話をします。もちろん、DBへの往復を保存し、これは単純なことが許されていないので、あなたは相当呼び出すと、ほとんどのDBのフレームワークは、nullcheckます.save()
か.store()
。しかし、それはそのDBの制約にただのショートカットです。
検証の解釈
時には、外部のものを表すJavaでオブジェクト。DB行等(やや前意味と重複)、または、たとえば、ユーザによって提出されたウェブフォーム。このようなオブジェクトには、表現して下さい正確にそれが表す実際の外部のものの実際の状態を。いぼや無効珍糞漢糞とすべて。
そして、通常、あなたはこれらを検証することができますフレームワークを持っています。それの何の検証NULL以外は意味します:このフィールドはnullにすることができ、あなたがnullに設定しようとすると、何の例外が発生しません(それゆえ、彼らがすることができます)。しかし、長尺物が有効である場合、あなたは私に言わせれば、そのフィールドは、ヌルが残っている、答えは:いいえ。
ロンボク島の解釈
残念ながら、すべての他のフレームワークが行うだけのようロンボクmuddiesやや海.. 何ロンボクの@NonNull
手段は、それが現れる場所によって異なります。パラメータの場合、それは意味:私はすでに自分でそれを書いていない限りロンボクは、メソッドの最初の行として明示的nullcheckを生成してください。
以下のために」:フィールドで、それは意味し@RequiredArgsConstructor
、このフィールドは必須考える; nullcheckが生成されたコンストラクタで(例外をスロー)また、NULLかどうかの注釈をコピー該当する場合、そのため、セッターは、このフィールドのために作られている場合。 。そのnullcheckの内部を追加します。」
あなたの特定のケース
NULLかどうかの注釈は完全に異なるものを意味することを考えると、それゆえ、潜在的にあなたのコード内の同じ構造に複数のそのような注釈を適用するクレイジーではありません。あなたがDBエンジンは、SQLの生成したい場合はNON NULL
、このクラスをテンプレートとして使用されている場合、制約を、そしてこのテーブルの行を表す任意のオブジェクトに対してすぐに意味をなすことができ、両方を追加し、無効な状態でそれを置くしようとする試みを拒否します。あなたはオブジェクトが一般的な原則は空白のオブジェクトを構築することで、その後、セッターで時に各フィールドの値の1を設定した場合、ほとんど常にそうである無効な状態を表すためにのために許容可能であることを好む場合-その後、ロンボクのを追加しないでください注釈。
きっとあなたは右、すべての複雑さを紹介してきましたか?
さえかすか。実際の脳ツイスターについて、検討しcheckerframeworkの@PolyNullを、これは適切な型システムが本当に処理することができるはずであるものの単純化しすぎであることを考えます!
免責事項:私はプロジェクトロンボクのためのコアの貢献者です。