2012-01-25 42 views
4

更新:这似乎是Eclipse相关的,而不是哈德森相关的,所以我相应的更新问题。javac编译不符

在命令行运行Maven的时候,我得到了一些编译器错误,但在我们组所有的开发人员对Eclipse代码工作正常(一些通用的复杂性,详情见下文)。这有什么不同以及如何处理它?

失败看起来像这样的代码:

299 private <T extends ProductClassDTO> List<T> convertProductClass(List<? extends ProductClassDTO> fromList) { 
300  List<T> toList = new ArrayList<T>(); 
301  for (ProductClassDTO from : fromList) { 
302   T to = convert(from); 
303   toList.add(to); 
304  } 
305  return toList; 
306 } 

这是构建服务器上的错误:

[ERROR] ...java:[302,26] type parameters of <T>T cannot be determined; no unique maximal instance exists for type variable T with upper bounds T,com.volvo.protom.util.dto.ProductClassDTO 

(我知道有其他问题+这个在SO答案,但他们似乎并不适用于这个特定的问题,因为更改为T to = <T>convert(from)不起作用,也许我应该做别的事情?)我猜错误是指这个类有几个convert方法,并且多于一个适合?

谢谢!

更新2:这些都是转换签名:

private void convert(TestObjectDTO from, TestObjectDTO to); 
private <T extends TestObjectDTO> T convert(TestObjectDTO from); 
private void convert(ProductClassDTO from, ProductClassDTO to); 
private <T extends ProductClassDTO> T convert(ProductClassDTO from); 
private void convert(TestObjectTypeDTO from, TestObjectTypeDTO to); 
private <T extends TestObjectTypeDTO> T convert(TestObjectTypeDTO from); 
+0

这可能是相关的http://stackoverflow.com/questions/314572/bug-in-eclipse-compiler-or-in-javac – stacker

+0

它是,但正如我所说的加入行302不工作在我们开发人员在Windows下使用编译器 –

+0

“转换”方法的签名是什么? – McDowell

回答

0

Eclipse和JDK javac稍有不同,请参阅@maximdim的评论。始终从命令行运行以确保兼容性(尽管Eclipse的javac似乎更加正确)。

-1

我想这些方法的签名不应该是什么。泛型参数出现的泛型方法仅返回类型(如<T extends ProductClassDTO> T convert(ProductClassDTO))通常不是您想要的。

这意味着,调用者调用方法并将结果投射到任何可能的子类型ProductClassDTO是合法的。通常只有一个可能的值满足这个要求:null。所以转换方法总是必须返回null以保证类型安全。否则ClassCastException可能会出现在调用代码中。

请记住,由于类型擦除时,convert方法无法知道调用者希望T是哪种类型的机会,所以他们无法返回根据T值不同类型的实例。

同样的问题发生在convertProductClass方法,虽然它并不坏在这里。该方法需要返回一个列表,其中只包含调用者可以自由解释为ProductClassDTO的任何子类型的值。唯一的值是null,空列表和仅包含null值的列表。使用列表时,所有其他情况可能导致ClassCastException

你可以做什么:

  • 如果转换方法返回总是相同的类型,改变返回 类型的方法,这种类型。
  • 如果呼叫者不关心具体类型,但只需知道它是ProductClassDTO的子类型,则分别将返回类型更改为ProductClassDTOList<ProductClassDTO>
  • 如果convert方法应根据调用者的愿望返回类型的实例,则需要通过将Class<T>的实例作为附加参数传递给所有这些方法来明确告诉它们返回的类型。然后convert方法可以使用此对象来创建适当类型的新实例。
+0

如果我将它分配给ProductClassDTO(它是一个接口)的实现类,它就可以工作。通过类是我想要避免的,因此没有这样的事情。如果我想要一些其他类型(通过列表),列表需要投射,这会变得冗长。无论如何,铸造到T解决了这个问题,所以我会坚持,而不是添加不必要的代码堆。 –

+0

@Jonas它现在可以正常工作,因为调用者和转换方法恰好对'T'使用相同的值。但是你的编译器会给出警告,因为当你改变其中的一个时,它可能会破坏(并且当时不会有任何编译器警告或错误,只是运行时出现异常)。所以我建议现在添加代码,以后再保存一个调试会话。 –

+0

此外,如果调用方和转换方法都一致,为什么不直接使用'ProductClassDTO'作为返回类型?或者它的实施类型?我从你的解释中看不到一个理由。 –