2014-03-07 126 views
0

我已经编写了一个使用Java编写的converter structure,我想创建一个工厂。在Java中使用泛型子类型对象创建泛型工厂

我的基本想法是,我传入一个有效类型的类并接收一个有效的子类型转换器,但失败的泛型和继承部分。

这是我的接口:

interface ItemRequestConverterFactory { 

    public <IR extends ItemRequest> ItemRequestConverter<IR> newInstance(Class<IR> clazz); 

} 

和实现:

public class DefaultItemRequestConverterFactory implements ItemRequestConverterFactory { 

    @Override 
    public <IR extends ItemRequest> ItemRequestConverter<IR> newInstance(Class<IR> clazz) { 
    if (clazz.equals(CreatePartRequestConverter.class)) 
    return new CreatePartRequestConverter(); 

    return null; 
    } 

} 

不幸的是,Eclipse的说: “类型不匹配:不能从CreatePartRequestConverter转换为ItemRequestConverter”。

我的通用签名中的问题在哪里?

回答

3

您似乎在类型参数和它们应该实际表示的类型之间不匹配:您正在将Class<IR>传递给newInstance方法。这是代表ItemRequest的课程。但是,您正在将此类实例与可能实现ItemRequestConverter接口的类进行比较。

虽然这编译时加适当的类型参数的CreatePartRequestConverter类,这可能不是你想要达到的目标:

interface ItemRequestConverter<IR extends ItemRequest>{} 
interface ItemRequest{} 
interface ItemRequestConverterFactory 
{ 
    public <IR extends ItemRequest> ItemRequestConverter<IR> newInstance(Class<IR> itemRequestClass); 
} 
class CreatePartRequestConverter<IR extends ItemRequest> implements ItemRequestConverter<IR> 
{ 
} 

class DefaultItemRequestConverterFactory implements ItemRequestConverterFactory 
{ 

    @Override 
    public <IR extends ItemRequest> ItemRequestConverter<IR> newInstance(Class<IR> itemRequestClass) 
    { 
     // Does not make sense: Comparing ItemRequest class with something 
     // that is probably an implementation of ItemRequestConverter 
     if (itemRequestClass.equals(CreatePartRequestConverter.class)) 
     { 
      return new CreatePartRequestConverter<IR>(); 
     } 
     return null; 
    } 
} 

取决于你真正想要达到的目标,你可以通过ItemRequestConverter类工厂方法(和相应的参数化方法):

interface ItemRequestConverter<IR extends ItemRequest>{} 
interface ItemRequest{} 
interface ItemRequestConverterFactory 
{ 
    public <IRC extends ItemRequestConverter<?>> ItemRequestConverter<?> newInstance(Class<IRC> itemRequestConverterClass); 
} 
class CreatePartRequestConverter implements ItemRequestConverter<ItemRequest> 
{ 
} 

class DefaultItemRequestConverterFactory implements ItemRequestConverterFactory 
{ 
    @Override 
    public <IRC extends ItemRequestConverter<?>> ItemRequestConverter<?> newInstance(
     Class<IRC> itemRequestConverterClass) 
    { 
     if (itemRequestConverterClass.equals(CreatePartRequestConverter.class)) 
     { 
      return new CreatePartRequestConverter(); 
     } 
     return null; 
    } 
} 

如果您还需要了解的ItemRequest类的信息,该方法签名会开始变得有点讨厌,并且必须更详细地分析其中如何提供或使用此类型的信息


编辑的评论:

我认为这是不可能的(编译时)类型检查的方式。这里的问题是,在您创建并返回新的ItemRequestConverter时,您无法确定它是否为ItemRequestConverter,其类型参数为IR。或者相反:在编译时您无法检测到CreatePartRequestConverter(即CreatePartRequest)的类型参数与IR相同。

基于到目前为止讨论的代码片段,我觉得应该可以简单地投在这种情况下。确保投是有效的,然后留给谁实现了一个负责“运行时类型检查”:

if (itemRequestClass.equals(CreatePartRequest.class)) 
{ 
    CreatePartRequestConverter result = new CreatePartRequestConverter(); 
    return (ItemRequestConverter<IR>) result; 
} 

,因为没有什么阻止你写

//       !!! 
if (itemRequestClass.equals(SomeCompletelyDifferentRequest.class)) 
{ 
    CreatePartRequestConverter result = new CreatePartRequestConverter(); 
    return (ItemRequestConverter<IR>) result; 
} 

所以有效做到这一点:

interface ItemRequestConverter<IR extends ItemRequest>{} 
interface ItemRequest{} 
interface ItemRequestConverterFactory 
{ 
    public <IR extends ItemRequest> ItemRequestConverter<IR> 
     newInstance(Class<IR> itemRequestClass); 
} 

class CreatePartRequest implements ItemRequest {} 
class CreatePartRequestConverter 
    implements ItemRequestConverter<CreatePartRequest> {} 

class DefaultItemRequestConverterFactory implements ItemRequestConverterFactory 
{ 
    @Override 
    public <IR extends ItemRequest> ItemRequestConverter<IR> newInstance(
      Class<IR> itemRequestClass) 
    { 
     if (itemRequestClass.equals(CreatePartRequest.class)) 
     { 
      CreatePartRequestConverter result = new CreatePartRequestConverter(); 
      return (ItemRequestConverter<IR>) result; 
     } 
     return null; 
    } 
} 

public class GenericFactoryTest 
{ 
    public static void main(String[] args) 
    { 
     ItemRequestConverterFactory factory = null; 
     ItemRequestConverter<CreatePartRequest> converter = 
      factory.newInstance(CreatePartRequest.class);   
    } 
} 
+0

这不完全是我想要实现的。我的目标是:'ItemRequestConverter 转换器= factory.newInstance(CreatePartRequest.class)'。 –

+0

@ Michael-O:添加了一个编辑 - 我认为这是不可能的类型安全的方式.... – Marco13

+0

我已经指出了这样的事情。演员是必要的。主要原因可能是类型擦除。 –