我正在编写一个能够处理六边形网格的库。
用户可以访问HexagonGridBuilder
对象,在该对象中,他可以为网格设置宽度,高度和许多其他参数,并且其build()
方法返回HexagonGrid
对象。 HexagonGrid
有各种方法来获取Hexagon
(例如通过网格坐标或像素坐标)。
我的问题是我希望允许用户在Hexagon
上的每个HexagonGrid
对象中放置任意卫星数据。这样做的最佳做法是什么?
我可以提供通用方法,允许用户将卫星数据传递到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();
所以我不确定选择哪一个。哪个是最不讨厌的解决方案?或者还有其他我没想过的东西?
编辑:我真正希望知道的是,让我所涉及的所有类都变得通用(这将使它们更难理解并且有点混乱)或者我可以在我的构建器中使用2个泛型方法和一个plus方法来提供类吗?原因是用户可能不会使用任何卫星数据,因此会大惊小怪。
答案 0 :(得分:3)
您需要将<T>
作为类型参数放在整个HexagonGrid
类上,而不仅仅放在方法上。然后,您可以将字段定义为private T satelliteData
,消除方法上的<T>
,并删除显式转换。这基本上就是你上次谈到的方法。
如果您有理由使用构建器而不是构造函数,则不一定要对构建器进行泛化;您可以将type参数传递给build
方法。有关其外观的示例,请参阅EnumSet#noneOf。
(另外,考虑到您的其他要求,您可能需要查看制作类型参数<T extends Satellite>
,或任何基本卫星接口。)