4

JSR 308は、Javaに型注釈を追加することを提案しています。承認後、プログラマーはJavaタイプが現在許可されている場所であればどこでも注釈を追加できるようになります。これには、メソッド/フィールド/ローカル/パラメーターの装飾だけでなく、コンストラクター呼び出し、型キャスト、そして最も不思議なことにインスタンスのチェックも含まれます。Checker Frameworkは、 JSR 308を使用し@NonNullて、オブジェクト型や文字列などの型修飾子を実装@Regexします。

チェッカーが行うことは、コードを静的に分析することだけです。これがコンパイル時のチェックです。それはいいです。しかし、私が欲しいのは、実行時にチェックを実行できるメカニズムです。次のように宣言できます。

@Regex String p1 = "[a-z]+";
@Regex String p1 = "[a-z)+";    // compile time error from annotation processor

私も書くことができます:

if (x instanceof @Regex String) ...

ただし、これはと同じx instanceof Stringで、実行時チェックは実行されません。小切手で任意のコードを実行してブール値を返すことができるコンパイル時アノテーションプロセッサまたはランタイムバイトコードマニピュレータが必要です。instanceofこれはJavaで可能ですか?

4

2 に答える 2

5

はい、できます。しかし、それは些細なことではなく、注釈プロセッサでアクセス可能なAPIではサポートされていません。アクセス可能なAnnotationProcessorAPIは、新しいクラスの生成に制限されており、既存のバイトコードを変更することはできません(JDK 8でも)。アノテーションプロセッサレベルでコンパイラ固有のクラスにキャストできます。これにより、より多くのオプションが有効になります。ただし、コンパイラの内部APIを使用して、使用可能なコンパイラ(JDTおよびJavaC)ごとに書き換える必要があります。非常によく似た処理を行うプロジェクトLombok(http://projectlombok.org/ )をご覧ください。悲しいことに、ロンボクはまだJDK8の新しいタイプの注釈と互換性がありません。

于 2012-10-01T07:39:54.957 に答える
2

正規表現の例では、解決策は非常に単純です。また、解決策がそれほど単純ではない場合についてもいくつか情報を提供します。

ランタイムテストを実装する方法は、型システムがデータ自体のプロパティを計算しているか、来歴(データのソース)のプロパティを計算しているかによって異なります。これは、 CheckerFrameworkマニュアルの「ランタイムテストとタイプの改良」セクションのテキストです。

一部の型システムは、Checker Frameworkが、assertステートメントの後などの条件の範囲内で型を改良するために使用できるランタイムテストをサポートしています。

型システムがこのようなランタイムテストをサポートするかどうかは、型システムがデータ自体のプロパティを計算しているか、来歴(データのソース)のプロパティを計算しているかによって異なります。データに関するプロパティの例は、文字列が正規表現であるかどうかです。来歴に関するプロパティの例は、測定単位です。数値の表現を調べて、それがキロメートルまたはマイルのどちらを表すことを意図しているかを判断する方法はありません。

1)データのプロパティの場合、最も簡単なオプションは、instanceofテストを避け、代わりに、CheckerFrameworkに付属しているテストisRegex(など)を使用することです。

たとえば、代わりに

  if (x instanceof @Regex String) ...

書きます

  if (RegexUtil.isRegex(x)) ...

これで完了です。

instanceofの代わりに本当に使用したい場合はisRegex、コンパイラをハックして、の各ソースコードオカレンスをに変換する必要がありx instanceof @Regex StringますRegexUtil.isRegex(x)。バイトコードの書き換えを介してこれを行うこともできます。

2)来歴に関するプロパティの場合、実装の労力ははるかに大きくなります。プログラム内の各データ(オブジェクトとプリミティブの両方を含む)の表現に来歴ビットを追加し、データの操作に加えて適切に操作できるように、すべての操作(独自のプログラムとライブラリ内)を変更する必要があります来歴ビットを維持します。これをすでに実行しているツールは、構築できる可能性がありますが、DynCompです。これは、Daikon不変検出器の一部として配布されています。

于 2014-09-30T08:03:36.433 に答える