私は Checker Framework の初心者なので、完全に間違ったことをしている可能性があります。
モデルのマイクロタイプを取り除きたいので、書く代わりに
private TypeAId id;
のようなものを書きたいと思います
private @TypeAId String id;
すべてのキーは文字列であるか、文字列として表すことができるためです。
これを行う適切な方法は何ですか?修飾子の階層と境界に関するドキュメントを読んでいますが、すべてが複雑すぎるようで、基本がわかりません。
私が望むのは、@TypeAId、@TypeBId などの単純な注釈を付けることです。そのため、以下のコードはコンパイル時にエラーを生成するはずです。
@TypeAId String aId;
@TypeBId String bId = "B_ID";
String justString = "JUST_A_STRING";
aId = bId; // Fail
aId = justString; // Fail
更新 1 :「サブタイピング」を使用する必要があるように見えますが、サブタイプ注釈の書き方がわからないため、以下が適用されます。
@TypeAId String aId;
@TypeBId String bId = "B_ID";
String justString = "JUST_A_STRING";
aId = bId; // Fail
aId = justString; // Fail
justString = aId; // Pass, because @TypeAId is a "subtype" of String
更新 2 : 現時点では:
@DefaultQualifierInHierarchy
@SubtypeOf({})
@ImplicitFor(literals = {LiteralKind.NULL, LiteralKind.STRING})
@DefaultFor({TypeUseLocation.LOWER_BOUND})
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
public @interface ObjectId {
}
@SubtypeOf({ObjectId.class})
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
public @interface TypeA {
}
@SubtypeOf({ObjectId.class})
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
public @interface TypeB {
}
private Map<@TypeA String, SomeObject> someObjects;
そして得る:
error: [type.argument.type.incompatible] incompatible types in type argument.
private Map<@TypeA String, SomeObject> someObjects;
^
found : @TypeA String
required: [extends @ObjectId Object super @ObjectId null]