OK、ジェネリックトークナイザー(「UserPlaceTokenizer」)をいじりましたが、あきらめました:問題は、ファクトリーが具象クラスのトークナイザーを必要とするため、最初にジェネリックトークナイザーを作成しようとしたことです:
public static class Tokenizer<T extends UserPlace> implements PlaceTokenizer<T> {
@Override
public final T getPlace(final String token) {
return (T) new UserPlace(token); //BAD
}
@Override
public final String getToken(final T place) {
return place.getToken();
}
}
問題は、UserPlace から (T) へのキャストです。これは機能しません (UserPlace を具体的なサブクラスにキャストすることはできません)。したがって、トークナイザー インターフェイスを満たすために、このインスタンスを取得するには、どこかで「新しい ShowUserPlace(...) を返す」必要があります。長い話を長くしすぎないようにするために: 以前の解決策に戻ります: 拡張クラスはスーパークラスのコンストラクターをコピーし、単に独自のコンストラクターを呼び出す (スーパー コンストラクターを呼び出す) 個別のトークナイザーを提供します。
public class ShowUserPlace extends UserPlace {
public ShowUserPlace(String token) {
super(token);
}
@Prefix(value = "showUser")
public static class Tokenizer implements PlaceTokenizer<ShowUserPlace> {
@Override
public final ShowUserPlace getPlace(final String token) {
return new ShowUserPlace(token);
}
@Override
public final String getToken(final ShowUserPlace place) {
return place.getToken();
}
}
}
暫定的な解決策は、インターフェイスのメソッドを提供する抽象トークナイザーでした。getPlace は抽象メソッド (T を返す) を呼び出し、具体的な実装は具体的なコンストラクター (スーパー コンストラクターのみを呼び出す) を呼び出します。最後に、このソリューションは上記のソリューションとほぼ同じ行数とコピーされたコードを持ちます:-|。
私はまだこれについて悪い気持ちを持っています - おそらく彼らはまだ「..WithFactory」を使った解決策であるか、この種のユースケースに直面するためのまったく異なる方法です。