Java泛型抽象工厂问题

Java泛型抽象工厂问题,java,generics,design-patterns,abstract-factory,Java,Generics,Design Patterns,Abstract Factory,我正在努力使这项工作成功: public abstract class MapperFactory<M extends TaskMapper<? extends Message, ? extends Message, ? extends TaskForm>> { public static <M extends TaskMapper<? extends Message, ? extends Message, ? extends TaskForm>

我正在努力使这项工作成功:

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;
    }

}
有没有办法修复这个错误

当然可以替换:

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!");
    }
publicstaticgetmapperfactory(消息msgIn,消息msgOut){
if(msgIn.ismyapper())
返回新的MyTaskMapperFactory();
抛出新的IllegalStateException(“未找到映射器!”);
}
这是可行的,但这不是我想要的答案

这似乎是一般抽象工厂模式的一个问题。
也欢迎使用定制对象提供源示例的答案。

返回语句适用于类型转换:

return (BpmMapperFactory<MAPPER>)new Bpm007PrepareDocTaskMapperFactory();
返回(BpmMapperFactory)新Bpm007PrepareDocTaskMapperFactory();

该代码将永远不会以其当前形式执行,因为Bpm007PrepareDocTaskMapper没有扩展BpmCommonMessageDto,因此msgIn不可能是Bpm007PrepareDocTaskMapper的实例。

根据《有效Java》,第二版,第28项:

如果类型参数在方法声明中仅出现一次,请将其替换为通配符

getMapperFactory方法仅在返回类型中使用类型参数M。遵循此建议将给出以下方法签名,并且该方法将编译:

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

publicstaticmapperfactory我的解决方案是用一把火尽可能多地杀死泛型:

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;
    }

}
抽象类MapperFactory getMapperFactory(消息msgIn,消息msgOut){
if(msgIn.isMyMapper())返回新的MyTaskMapperFactory();
抛出新的IllegalStateException(“未找到映射器!”);
}
公共摘要M getTaskMapper();
}
类MyTaskMapperFactory扩展了MapperFactory{
@凌驾
公共MyTaskMapper getTaskMapper(){
返回新的MyTaskMapper();
}
}
接口任务映射器{
公共F表格(I msgIn、O msgOut、F taskForm);
公共卫生服务(F任务表);
}
类MyTaskMapper实现TaskMapper{
公共MyTaskForm填充表单(IncomingMessage msgIn,Outgout Message msgOut,MyTaskForm taskForm){
返回null;
}
公共支出信息填写表(MyTaskForm taskForm){
返回null;
}
}

如果您不关心类的类型参数是什么,或者不需要比类签名更严格地约束它们,那么在使用它的每个方法中,确实没有必要重复类的类型参数。

我编辑了
if
部分-感谢您提供的信息,这还没有完成,在这里不相关。有没有避免强制转换的方法?
MAPPER
不是遵循Java约定的好类名。请将类名尽可能小(但仍然清晰)。并将
MAPPER
重命名为
MAPPER
?奇怪/长的类名只是把问题和答案搞混了。@他的映射器不是类名。它是泛型类型(如HashMapIt中的T)的名称。它仍然是一个类型名。在Java中,所有大写字母都是常量。@his-不,不是,不管怎样。。。约定是只使用BalusC在此处所述的单个字母,因此我更改了代码以遵循约定。更简短的是,签名可以是
public static MapperFactory getMapperFactory()
。与
MapperFactory
的类签名相比,该方法对任何类型参数的约束都不多。公共抽象任务映射器getTaskMapper()
也是如此。(也可能是
public abstract M getTaskMapper()
,无法判断类型参数背后的意图。)“如果有疑问,请少用泛型”可能是一条很好的经验法则。
public static MapperFactory<? extends TaskMapper<Message, ? extends Message, ? extends String>> getMapperFactory(Message msgIn, Message msgOut)
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;
    }

}