我正在编写一个能够处理六边形网格的库。
用户可以访问 HexagonGridBuilder
对象,他可以在其中设置网格的宽度、高度和许多其他参数,并且其 build()
方法返回一个HexagonGrid
对象。 HexagonGrid
有多种获取Hexagon
的方法(例如通过网格坐标或像素坐标)。
我的问题是我想允许用户将任意卫星数据放入 HexagonGrid
上的每个 Hexagon
对象中。这样做的最佳做法是什么?
我可以提供通用方法来允许用户将卫星数据传递给 Hexagon
:
private Object satelliteData;
public <T> void setSatelliteData(T satelliteData) {
this.satelliteData = satelliteData;
}
@SuppressWarnings("unchecked")
public <T> T getSatelliteData() {
return (T) satelliteData;
}
这显然是有缺陷的,因为它涉及在不确定对象类型的情况下转换对象。
我可以修改我的 HexagonGridBuilder
,这样用户就可以为他的卫星数据传递一个 Class
对象,这样我就可以验证他是否提供了正确的类型:
public <T> void setSatelliteData(T satelliteData) {
if (!satelliteClass.isAssignableFrom(satelliteData.getClass())) {
// throw some exception
}
this.satelliteData = satelliteData;
}
但这仍然会涉及 getSatelliteData()
方法中未经检查的转换:
@SuppressWarnings("unchecked")
public <T> T getSatelliteData() {
return (T) satelliteData;
}'
正确的解决方案似乎使整个库通用,所以我有一个卫星数据类型的通用参数,但它涉及使每个类都涉及通用:
HexagonGrid<SATELLITE_DATA_TYPE> hexagonGrid =
new HexagonGridBuilder<SATELLITE_DATA_TYPE>().build();
所以我不确定该选择哪一个。哪个是最不 hacky 的解决方案?还是有其他我没有考虑到的事情?
编辑:我真正想知道的是,让我涉及的所有类通用化(这会使它们更难理解并且有点困惑)是否值得麻烦,或者我可以在我的构建器中使用 2 个通用方法和一个 plus 方法来提供类吗?原因是用户可能不会使用任何卫星数据,所以会大惊小怪。
最佳答案
您需要放置<T>
作为整个 HexagonGrid
的类型参数类,而不仅仅是方法。然后您可以将您的字段定义为 private T satelliteData
, 消除 <T>
s 在方法上,并删除显式强制转换。这基本上就是您上次谈到的方法。
如果您出于某种原因想要使用构建器而不是构造器,则不必泛化构建器;您可以将类型参数传递给 build
方法。参见 EnumSet#noneOf有关这看起来如何的示例。
(此外,考虑到您的其他要求,您可能需要考虑制作类型参数 <T extends Satellite>
,或者您的基本卫星接口(interface)是什么。)
关于java - 如何处理我的库中任意用户提供的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18161973/