java - 我可以在 Java 泛型中传递复杂类型结构吗?

标签 java generics nested-generics

我目前正在尝试使用 Java 接口(interface)和泛型为概念模型实现 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();
}

我仍然可以阅读并理解它,但它变得有点冗长了。然后像 VehicleJourney 这样的实体可以在其他实体中引用,这使得类型参数列表爆炸。这几乎是我能想到的最小的重要示例。

有没有办法创建一个单一的 Java 实体来模拟类型系统的整个配置?我正在考虑将所有标识符类型和排序类型附加在一起然后可以作为一个传递的东西,将上面的示例变成这样的东西:

public interface VehicleJourney<CONF, JP extends JourneyPattern<CONF>> 
       extends IdentifiableObject<???>
{
    JP getJourneyPattern();
}

在带有问号的地方,必须以某种方式从 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> {

}

您真的不需要给出名称来锚定类型的嵌套类型。当您拥有具体类(或什至子接口(interface))时,所有类型都将被锚定。例如:

public class VehicleJourneyImplMeta implements Meta<String, String> {

}

public class VehicleJourneyImpl extends IdentifiableObjectBase<VehicleJourneyImplMeta> 
        implements VehicleJourney<
                VehicleJourneyImplMeta, 
                JourneyPattern<Meta<Integer, String>>> {

}

您需要使用中间类(很可能是匿名类)来委托(delegate)对 Meta 中类型的访问:

VehicleJourney<Meta<String, String>, ?> v = something();
Meta<String, String> m = v.getObjectMeta();
String idOfV = m.getId();

在方法级别的各种类型参数的帮助下,您可能可以完成这项工作。

在我看来你(和我,以及大多数人)真正想要的是这样的:

public interface VehicleJourney<M extends Meta<?, ?>, JP extends JourneyPattern<?>>
        extends IdentifiableObject<M> {

        public JP.M.ID getIdOfReferencedX();
}

不幸的是,Java 不支持键入 JP.M.ID 作为返回类型。也许有人会为此提出一个 JSR。如果我没记错的话,字节码包含泛型类型参数的名称。

关于java - 我可以在 Java 泛型中传递复杂类型结构吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21470984/

相关文章:

java - 如何让这个嵌套通用参数系统正常工作?

java - 类型不匹配,无法从元素对象转换为字符串

java - 如何使 ListView 的全宽触摸敏感以便单击某个项目?

ios - 在 Swift 4 中将 AnyObject 作为通用 T 参数传递

java - 嵌套通配符泛型变量矫揉造作

java - 当字段由字符串名称引用时,如何获取通用对象上字段的类

java - 为什么未选中 android.database.SQLException?

java - 如何使用 oauth API 2.0 为 hotmail 创建访问 token

templates - 为什么 Rust 不能使用泛型参数的大小作为数组长度?

java - 自动将多个集合合并为一个