5

私はこの仕事をするのに苦労しています:

public abstract class MapperFactory<M extends TaskMapper<? extends Message, ? extends Message, ? extends TaskForm>> {

    public static <M extends TaskMapper<? extends Message, ? extends Message, ? extends TaskForm>> MapperFactory<M> getMapperFactory(Message msgIn, Message msgOut) {

        if (msgIn.isMyMapper())
            return new MyTaskMapperFactory();

        throw new IllegalStateException("Mapper not found!");
    }

    public abstract TaskMapper<? extends Message, ? extends Message, ? extends TaskForm> getTaskMapper();

    public static class MyTaskMapperFactory extends MapperFactory<MyTaskMapper> {

        @Override
        public TaskMapper<? extends Message, ? extends Message, ? extends TaskForm> getTaskMapper() {
            return new MyTaskMapper();
        }

    }
}

public interface TaskMapper<I extends Message, O extends Message, F extends TaskForm> {

    public F fillForm(I msgIn, O msgOut, F taskForm);

    public O fillMsgOut(F taskForm);
}

public class MyTaskMapper implements TaskMapper<IncomingMessage, OutgoingMessage, MyTaskForm > {

    public MyTaskForm fillForm(IncomingMessage msgIn, OutgoingMessage msgOut,
            MyTaskForm taskForm) {
        return null;
    }

    public OutgoingMessage fillMsgOut(MyTaskForm taskForm) {
        return null;
    }

}

問題はコンパイルエラーです:

タイプの不一致:MapperFactory.MyTaskMapperFactoryからMapperFactoryに変換できません

ここの私のMapperFactoryで:

if (msgIn.isMyMapper())
            return new MyTaskMapperFactory();

このエラーを修正する方法はありますか?

もちろん交換:

public static <M extends TaskMapper<? extends Message, ? extends Message, ? extends TaskForm>> MapperFactory<M> getMapperFactory(Message msgIn, Message msgOut) {

        if (msgIn.isMyMapper())
            return new MyTaskMapperFactory();

        throw new IllegalStateException("Mapper not found!");
    }

と:

public static MapperFactory<?> getMapperFactory(Message msgIn, Message msgOut) {

        if (msgIn.isMyMapper())
            return new MyTaskMapperFactory();

        throw new IllegalStateException("Mapper not found!");
    }

うまくいくでしょうが、それは私が探している答えではありません。

これは、一般的な一般的な抽象ファクトリパターンの問題のようです。カスタム作成されたオブジェクトを使用してソースサンプルを提供する回答も歓迎します。

4

3 に答える 3

4

効果的なJava、第2版、アイテム28によると:

タイプパラメータがメソッド宣言に1回だけ現れる場合は、ワイルドカードに置き換えてください。

getMapperFactoryメソッドは、戻り型で型パラメーターMのみを使用します。このアドバイスに従うと、次のメソッドシグネチャが与えられ、メソッドがコンパイルされます。

public static MapperFactory<? extends TaskMapper<Message, ? extends Message, ? extends String>> getMapperFactory(Message msgIn, Message msgOut)

編集:コードを見れば見るほど、MapperFactoryをパラメーター化すべきではないと思います。このパラメーターはここのコードでは使用されていません。getTaskMapperはTaskMapperを返します。

于 2012-02-13T18:10:20.213 に答える
1

returnステートメントは、型キャストで正常に機能します。

return (BpmMapperFactory<MAPPER>)new Bpm007PrepareDocTaskMapperFactory();

Bpm007PrepareDocTaskMapperはBpmCommonMessageDtoを拡張しないため、そのコードは現在の形式では実行されません。したがって、msgInをBpm007PrepareDocTaskMapperのインスタンスにすることはできません。

于 2012-02-08T12:40:42.103 に答える
1

私の解決策は、火で可能な限り多くのジェネリックを殺すことです:

abstract class MapperFactory<M extends TaskMapper<?, ?, ?>> {

    public static MapperFactory<?> getMapperFactory(Message msgIn, Message msgOut) {
        if (msgIn.isMyMapper()) return new MyTaskMapperFactory();
        throw new IllegalStateException("Mapper not found!");
    }

    public abstract M getTaskMapper();
}


class MyTaskMapperFactory extends MapperFactory<MyTaskMapper> {

    @Override
    public MyTaskMapper getTaskMapper() {
        return new MyTaskMapper();
    }

}


interface TaskMapper<I extends Message, O extends Message, F extends TaskForm> {

    public F fillForm(I msgIn, O msgOut, F taskForm); 

    public O fillMsgOut(F taskForm);

}

class MyTaskMapper implements TaskMapper<IncomingMessage, OutgoingMessage, MyTaskForm> {

    public MyTaskForm fillForm(IncomingMessage msgIn, OutgoingMessage msgOut, MyTaskForm taskForm) {
        return null;
    }

    public OutgoingMessage fillMsgOut(MyTaskForm taskForm) {
        return null;
    }

}

クラスの型パラメーターが何であるかを本当に気にしない場合、またはクラスのシグニチャーよりも制約する必要がない場合は、クラスの型パラメーターを使用するすべてのメソッドで繰り返す必要はありません。

于 2012-02-14T15:45:53.763 に答える