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

我可以在Java泛型中传递复杂类型结构吗?,java,generics,nested-generics,Java,Generics,Nested Generics,我目前正在尝试使用Java接口和泛型为概念模型实现API。该模型(Transmodel V5.0)被详细描述为一个实体关系模型,但它没有指定所使用的一些基本类型。例如,未定义各种实体的标识符类型或用于建立顺序的类型 因为我想让API尽可能通用,所以我开始使用泛型来配置这些细节。我不想对这些类型做任何假设,包括不假设任何东西都是一致的。每个实体可以具有不同的标识符类型,每个序列可以具有用于排序目的的不同类型 我面临的问题是,一旦一个实体引用另一个实体,复杂性就会快速增长——我不仅需要传递其标识符的

我目前正在尝试使用Java接口和泛型为概念模型实现API。该模型(Transmodel V5.0)被详细描述为一个实体关系模型,但它没有指定所使用的一些基本类型。例如,未定义各种实体的标识符类型或用于建立顺序的类型

因为我想让API尽可能通用,所以我开始使用泛型来配置这些细节。我不想对这些类型做任何假设,包括不假设任何东西都是一致的。每个实体可以具有不同的标识符类型,每个序列可以具有用于排序目的的不同类型

我面临的问题是,一旦一个实体引用另一个实体,复杂性就会快速增长——我不仅需要传递其标识符的类型,还需要传递配置被引用实体所需的一切

例如,我有:

/**
*@param此实体的标识符的类型。
*@param标识旅程模式的类型。
*@param行程模式中用于点的顺序。
*@param此实体引用的旅程模式类型。
*/
公共接口车辆旅程<
身份证件
ID_JP,OP_JP扩展可比,JP扩展行程模式
>扩展可识别对象
{
JP getJourneyPattern();
}
我仍然可以阅读并理解它,但它越来越冗长了。然后,可以在其他实体中引用诸如VehicleTraveley之类的实体,这会导致类型参数列表爆炸。这几乎是我能想到的最小的非平凡的例子

有没有一种方法可以创建一个Java实体来模拟类型系统的整个配置?我正在考虑一种附加了所有标识符类型和排序类型的方法,然后可以作为一种方法传递,将上面的示例转化为如下内容:

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

        public JP.M.ID getIdOfReferencedX();
}
公共接口车辆旅程
扩展可识别对象
{
JP getJourneyPattern();
}

在带有问号的地点,必须以某种方式从CONF中提取车辆行程标识符的类型。如果这是可行的,那么复杂性应该保持在可管理的水平。

不会很好

您可以使用未编排的类型,并通过使用将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> {

}
公共接口元数据{
}
公共接口可识别对象>
扩展可识别对象{
}
公共接口车辆旅程>
扩展可识别对象{
}
您确实不需要指定名称来锚定类型的嵌套类型。当您拥有具体类(甚至子接口)时,所有类型都将被锚定。例如:

public class VehicleJourneyImplMeta implements Meta<String, String> {

}

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

}
公共类VehicleJourneyImplMeta实现元{
}
公共类VehicleJourneyImpl扩展了IdentifiableObjectBase
实现汽车旅行<
汽车旅行社,
行程模式>{
}
您需要通过使用中间类(最有可能是匿名类)委托访问Meta中的类型:

VehicleJourney<Meta<String, String>, ?> v = something();
Meta<String, String> m = v.getObjectMeta();
String idOfV = m.getId();
vehicletravel v=something();
metam=v.getObjectMeta();
字符串idOfV=m.getId();
借助于方法级别的各种类型参数,您可能可以实现这一点

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

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

        public JP.M.ID getIdOfReferencedX();
}
公共接口车辆旅程>
扩展可识别对象{
public JP.M.ID getIdOfReferencedX();
}

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

我确信C++有一个方法来实现这一点,而且不管它是什么,它都会使我的脑袋爆炸。如果没有继承,我不这么认为。你可以删除新的类型,而不需要用有意义的名字来扩展复杂的参数。不幸的是,这有很严重的副作用。@ AJB,C++有Type Debug,但是它们在编译器输出中不起作用:(斯卡拉有类型变量,几乎(但不完全)需要什么。我相信类型参数是‘擦除’的,所以可能不容易回溯。