を処理するためのカスタムフォーマッタを登録したいSet<Integer>
。
明白な方法:
Formatters.register(Set<Integer>.class, new AnnotationIntegerSetFormatter());
結果は「不法な表現の開始」になります。これを行う正しい方法は何ですか、それとも不可能ですか?
を処理するためのカスタムフォーマッタを登録したいSet<Integer>
。
明白な方法:
Formatters.register(Set<Integer>.class, new AnnotationIntegerSetFormatter());
結果は「不法な表現の開始」になります。これを行う正しい方法は何ですか、それとも不可能ですか?
Set<Integer>.class
この型の汎用コンポーネントはコンパイル時に消去されるため、これは正当なJavaではありません。を使用すると機能するSet.class
はずですが、これによりすべてのタイプのハンドラーが登録されますSet<T>
。
Formatters.register(Set.class, new AnnotationIntegerSetFormatter());
;を使用して終了しました parse
まだ戻ることができSet<Integer>
、print
にキャストするだけSet
ですSet<Integer>
:
public class AnnotationIntegerSetFormatter extends Formatters.AnnotationFormatter<IntegerSet,Set> {
@Override
public Set<Integer> parse(IntegerSet annotation, String text, Locale locale) {
Set<Integer> set = new TreeSet<Integer>();
for (String part : text.split(","))
set.add(Integer.parseInt(part));
return set;
}
@Override
public String print(IntegerSet annotation, Set value, Locale locale) {
List<Integer> sorted = new ArrayList<Integer>();
sorted.addAll((Set<Integer>) value);
Collections.sort(sorted);
return join(",", sorted.toArray());
}
private static String join(String separator, Object... values) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < values.length; i++) {
if (values[i] == null)
continue;
if (sb.length() > 0)
sb.append(separator);
sb.append(values[i].toString());
}
return sb.toString();
}
}
完全を期すために、私が使用した注釈は次のとおりです。
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface IntegerSet {
int min() default Integer.MIN_VALUE;
int max() default Integer.MAX_VALUE;
}
Collection
これは注釈ベースであるため、1つのタイプに複数のフォーマッターを登録し、注釈で区別できるように見えます。