Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的自引用泛型_Java_Generics_Nested Generics - Fatal编程技术网

Java中的自引用泛型

Java中的自引用泛型,java,generics,nested-generics,Java,Generics,Nested Generics,我不明白为什么我不能铸造一个自我引用的泛型 在Java中,我有一个自引用泛型。有很多事情(Intents)和查找(解决)这些事情的策略(ResolutionStrategys) 下面定义了自参考Intent类型。我希望在编译时定义只能接收接受相同意图的ResolutionStrategy的类 public interface Intent<I extends Intent<I, R>, R extends Resolution> { void resolve(Re

我不明白为什么我不能铸造一个自我引用的泛型

在Java中,我有一个自引用泛型。有很多事情(
Intent
s)和查找(解决)这些事情的策略(
ResolutionStrategy
s)

下面定义了自参考
Intent
类型。我希望在编译时定义只能接收接受相同意图的
ResolutionStrategy
的类

public interface Intent<I extends Intent<I, R>, R extends Resolution>
{
    void resolve(ResolutionStrategy<I, R> strategy);

    R getResolution();
}
可识别解析
解析
的一个简单而无趣的实现

到目前为止一切都很好。然后,计划是为这些
Intent
s构建一个漂亮的图表,然后对它们进行迭代,将它们传递给
ResolutionStrategyFactory
,以获得解决它们的相关策略。然而,我无法将
OrgIntent
转换为任何足以添加到列表中的通用对象

private <I extends Intent<I, R>, R extends Resolution> DirectedAcyclicGraph<Intent<I, R>, DefaultEdge> buildGraph(Declaration declaration) throws CycleFoundException
{
        DirectedAcyclicGraph<Intent<I, R>, DefaultEdge> dag = new DirectedAcyclicGraph<>(DefaultEdge.class);
        // Does not compile
        Intent<I, R> orgIntent = new OrgIntent("some name");
        // Compiles, but then not a valid argument to dag.addVertex()
        Intent<OrgIntent, IdentifiableResolution> orgIntent = new OrgIntent("some name");
        // Compiles, but then not a valid argument to dag.addVertex()
        OrgIntent orgIntent = new OrgIntent("some name");

        //Then do this
        dag.addVertex(orgIntent);
        ...

正如zapl在评论中所建议的,泛型没有提供足够强的类型保证来处理您所描述的模式。特别是因为Java泛型是非具体化的,所以JVM无法在转换为更一般的类型(
Intent
)后恢复更具体的类型(
OrgIntent
)。由于泛型类型信息在运行时丢失,JVM只能依赖具体的原始类型(
Intent

这是同样的原因,例如,您不能定义两个具有不同泛型签名但具有相同具体签名的方法-
foo(List)
foo(List)
在运行时都变得简单
foo(List)
,因此编译器不允许您在同一类中定义两个这样的方法

从广义上讲(恐怕我对您的用例理解不够透彻,无法更精确地理解),解决方案是通过关联的或。例如,您可以使用以下签名:

R resolve(Class<I> intentClass, I intent);
R解析(类intentClass,I intent);
中提供的建议也应该有帮助:

但是,有时您需要更大的灵活性[比固定数量的类型参数]。。。。其思想是参数化键而不是容器。然后将参数化键提供给容器以插入或检索值。泛型类型系统用于确保值的类型与其键一致

Java的类型系统不够强大,无法表达[键和值之间的类型关系]。但我们知道这是真的,当我们需要取回最喜欢的东西时,我们会利用它


?我看不出它与您的
I
R
中的任何内容有什么关系code@JeremyKato谢谢不,那不行,因为
OrgIntent
本身不是泛型的。@zapl谢谢。你是对的;我想将各种不同的
Intent
实现添加到
directedacycgraph
中。基本上,图表应该包含任何意图。但是我希望每个意图都有编译时安全性,即传递给它的
ResolutionStrategy
的类型。这有意义吗?我的意思是:你可以在
列表中存储
Double
Integer
,但你不会得到
Double
Integer
。您只能将它们作为
Number
,然后进行运行时类型检查,以确定它们是什么。对于您的DAG,除了基本的
意图
分辨率
之外,您可能无法使用所有优秀的泛型类型。谢谢大家的输入。我并没有忘记通用疯狂的程度,我意识到这是一个相当疯狂的代码!
private <I extends Intent<I, R>, R extends Resolution> DirectedAcyclicGraph<Intent<I, R>, DefaultEdge> buildGraph(Declaration declaration) throws CycleFoundException
{
        DirectedAcyclicGraph<Intent<I, R>, DefaultEdge> dag = new DirectedAcyclicGraph<>(DefaultEdge.class);
        // Does not compile
        Intent<I, R> orgIntent = new OrgIntent("some name");
        // Compiles, but then not a valid argument to dag.addVertex()
        Intent<OrgIntent, IdentifiableResolution> orgIntent = new OrgIntent("some name");
        // Compiles, but then not a valid argument to dag.addVertex()
        OrgIntent orgIntent = new OrgIntent("some name");

        //Then do this
        dag.addVertex(orgIntent);
        ...
private DirectedAcyclicGraph<Intent<?, ? extends Resolution>, DefaultEdge> buildGraph(Declaration declaration) throws CycleFoundException
{
    DirectedAcyclicGraph<Intent<?, ? extends Resolution>, DefaultEdge> dag = new DirectedAcyclicGraph<>(DefaultEdge.class);
    OrgIntent orgIntent = new OrgIntent("some name");
    dag.addVertex(orgIntent);
R resolve(Class<I> intentClass, I intent);