Pet*_*ker 12 java generics nested-generics
我目前正在尝试使用Java接口和泛型为概念模型实现API.模型(Transmodel V5.0)被详细描述为实体关系模型,但它没有指定使用的一些基本类型.例如,没有定义各种实体的标识符类型或用于在序列中建立排序的类型.
由于我希望尽可能保持API的通用性,因此我开始使用泛型来配置这些细节.我不想对类型做任何假设,包括不假设任何事情是一致的.每个实体可以具有不同的标识符类型,每个序列可以具有用于排序目的的不同类型.
我面临的问题是,一旦一个实体引用另一个实体,复杂性就会快速增长 - 我不仅需要为其标识符传递类型,还需要为配置引用实体所需的所有内容.
例如,我有:
/**
* @param <ID> The type for the identifier of this entity.
* @param <ID_JP> The type identifying journey patterns.
* @param <OP_JP> The ordering used for points in journey patterns.
* @param <JP> The type of journey pattern referenced by this entity.
*/
public interface VehicleJourney<
ID,
ID_JP, OP_JP extends Comparable<OP_JP>, JP extends JourneyPattern<ID_JP, OP_JP>
> extends IdentifiableObject<ID>
{
JP getJourneyPattern();
}
Run Code Online (Sandbox Code Playgroud)
我仍然可以阅读并理解它,但它变得有点冗长.然后可以在其他实体中引用像VehicleJourney这样的实体,这会使类型参数列表爆炸.这几乎是我能想到的最小的非平凡的例子.
有没有办法创建一个单一的Java实体来建模类型系统的整个配置?我正在考虑将附加所有标识符类型和排序类型的东西,然后可以作为一个传递,将上面的示例转换为如下所示:
public interface VehicleJourney<CONF, JP extends JourneyPattern<CONF>>
extends IdentifiableObject<???>
{
JP getJourneyPattern();
}
Run Code Online (Sandbox Code Playgroud)
在带有问号的地方,必须以某种方式从CONF中提取VehicleJourney标识符的类型.如果这是可行的,那么复杂性应保持在可管理的水平.
不会变得漂亮。
您可以使用非锚定类型,并通过将 id 和比较器类型分组的类型来简化:
public interface Meta<ID, COMP extends Comparable<COMP>> {
}
public interface IdentifiableObject<M extends Meta<?, ?>> {
}
public interface JourneyPattern<M extends Meta<?, ?>>
extends IdentifiableObject<M> {
}
public interface VehicleJourney<M extends Meta<?, ?>, JP extends JourneyPattern<?>>
extends IdentifiableObject<M> {
}
Run Code Online (Sandbox Code Playgroud)
您确实不需要提供名称来锚定类型的嵌套类型。当您拥有具体的类(甚至子接口)时,所有类型都将被锚定。例如:
public class VehicleJourneyImplMeta implements Meta<String, String> {
}
public class VehicleJourneyImpl extends IdentifiableObjectBase<VehicleJourneyImplMeta>
implements VehicleJourney<
VehicleJourneyImplMeta,
JourneyPattern<Meta<Integer, String>>> {
}
Run Code Online (Sandbox Code Playgroud)
您需要使用中间类(最有可能是匿名类)来委托对 Meta 中类型的访问:
VehicleJourney<Meta<String, String>, ?> v = something();
Meta<String, String> m = v.getObjectMeta();
String idOfV = m.getId();
Run Code Online (Sandbox Code Playgroud)
在方法级别的各种类型参数的帮助下,您可能可以完成这项工作。
在我看来,你(和我,以及大多数人)真正想要的是这样的:
public interface VehicleJourney<M extends Meta<?, ?>, JP extends JourneyPattern<?>>
extends IdentifiableObject<M> {
public JP.M.ID getIdOfReferencedX();
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,Java 不支持输入JP.M.ID作为返回类型。也许有人会为此提出 JSR。如果我没记错的话,字节码包含泛型类型参数的名称。
| 归档时间: |
|
| 查看次数: |
859 次 |
| 最近记录: |