2012-02-08 84 views
5

我努力使这项工作:Java泛型抽象工厂问题

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

} 

的问题是一个编译错误:

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

任何:

Type mismatch: cannot convert from MapperFactory.MyTaskMapperFactory to MapperFactory

在我MapperFactory这里

想法如何解决这个错误?

当然更换作者:

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!"); 
    } 

会的工作,但是这不是我要找的答案。

这似乎是一般抽象工厂模式的问题。 使用自定义制作对象提供源样本的答案也受到欢迎。

+0

按照Java约定,'MAPPER'不是一个好的类名。 – 2012-02-13 11:52:12

+0

请尽可能使您的班级名称尽可能小(但仍然清晰)。并将'MAPPER'重命名为'Mapper'?奇怪/长的类名称只是混淆/混淆了问题*和*答案。 – Bohemian 2012-02-13 12:01:50

+0

@他的MAPPER不是类名。它是泛型类型的名称,如HashMap中的T 2012-02-13 12:06:47

回答

4

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

If a type parameter appears only once in a method declaration, replace it with a wildcard.

你getMapperFactory方法只用在返回类型的类型参数M。根据这一建议提供了以下方法签名和方法编译:

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

编辑:更多的我看代码,我越觉得MapperFactory不应该被参数化。该代码中未使用该参数,getTaskMapper返回一个TaskMapper。

+2

更短,签名可以是'public static MapperFactory getMapperFactory()'。该方法不会限制任何类型参数超过MapperFactory类的类签名。 '公共抽象TaskMapper getTaskMapper()'也是如此。 (它也可能是'public abstract M getTaskMapper()',不能说出类型参数背后的意图是什么。)*“如果有疑问,使用更少的泛型”*可能是一个很好的经验法则。 – millimoose 2012-02-14 15:39:36

1

return语句正常工作与类型转换:

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

该代码永远不会在其目前的形式,虽然执行,因为Bpm007PrepareDocTaskMapper没有延伸BpmCommonMessageDto,这样的MsgIn不可能是Bpm007PrepareDocTaskMapper的一个实例。

+0

我编辑了'if'部分 - 感谢信息,这还没有完成,这里没有关系。 任何方法来避免演员? – 2012-02-08 14:36:38

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

} 

这真的没有必要重复一类的类型参数在使用它的每一个方法,如果你不这样做真正关心他们是什么或不需要限制他们比班级签名更多。