我知道编辑这个网站吗?

2012-12-11 - 在 SCIFIO 中隐藏泛型

SCIFIO中的泛型

泛型类型在 SCIFIO 中的使用非常有意义:您有一个接口驱动的设计,旨在灵活且可扩展,但每个§§0§§§实现都与其他 SCIFIO 组件的具体实现紧密链接。使用泛型可确保这些组件内部操作的类型方便,每个组件仅与它们知道如何处理的对象进行交互(例如,为 APNG Format 提供 OME-TIFF Reader对象是没有意义的)。

两种情况

SCIFIO本质上有两个例子。

  • 通用算法。在本例中,开发人员正在编写可在各种图像格式上运行的通用图像 IO 算法。在这种情况下,没有已知的具体实例。
  • 具体算法。开发人员正在针对特定的已知图像格式进行编码。具体类型可以被实例化。

在第二种情况下,需要担心泛型。在第一种情况下,如果泛型位于 SCIFIO 接口的所有级别中,则您必须在任何声明中使用原始类型或通配符,并且可能需要在许多方法调用中进行强制转换。泛型对你来说是不利的,因为你根本不知道针对什么类型进行编码。

###隐藏泛型

为了再次保护开发人员继续通配符、原始类型和转换的影响,我们在 SCIFIO 中拆分了组件。每个组件都有一个基本接口(例如Metadata)和一个类型化子类(Reader)。基本接口引用其他组件的基本接口,类型化接口引用其他类型化接口(将通用参数传播到具体实现,在那里它们消失)。

因此,如果您想以通用方式使用 SCIFIO 组件,您可以使用基本接口,而不必找到与泛型作斗争来正确的语法。如果您想使用什么格式,则可以从接受返回和这些已知类型的方法中受益。无论哪种情况,泛型都提供编译时的安全性。

类型缩小的问题

基类/类型化接口的分割很好,因为当您沿着类层次结构下降并了解有关存在的类型的更多信息时,返回自然类型可以缩小范围。但是,方法参数不能以这种方式缩小:通用基接口意味着方法将与任何实现的参数一起使用(例如TypedReader)。当您到达TypedWriter时,它可以访问通用元数据参数M,如果setMetadata(M)§M extends Metadata,你不能只声明。该方法将具有与基接口中相同的类型。

为了避免不同命名的方法签名,我们遵循作为泛型参数出现的任何 SCIFIO 类的基本/类型模式,并创建:§§§6创建§§§和Writer#setMetadata。虽然这些类型化类扩展了与一个签名一起使用的基类,但提供了它们不同的特点,并允许公平地包含参数化方法,如TypedMetadata

这确实意味着,当您使用具体实现进行编程时,您可能会在 API 中看到一些额外的(不太具体的)方法签名,如果给出不正确的参数,这些方法签名将抛出 IllegalArgumentExceptions。但我们认为避免这样的代码是值得的:

/media/news/terrifying-generics.jpg

The Evolution of SCIFIO: Generics can be terrifying.