BaseFoo不能用不同的参数继承:< T,X.Bar< T>>和< T,X.Foo< T>> [英] BaseFoo cannot be inherited with different arguments: <T,X.Bar<T>> and <T,X.Foo<T>>
问题描述
这是一个简化版本的 Java继承流利方法在多级别层次结构中返回类型。
给出以下代码:
public enum X {
;
static interface BaseFoo< T,S扩展BaseFoo< T,S>> {
S foo();
}
静态接口Foo< T>扩展BaseFoo< T,Foo>> {
void foo1();
}
静态接口BaseBar< T,S扩展了BaseBar< T,S>>扩展BaseFoo< T,S> {
S bar();
}
静态界面Bar< T>扩展了BaseBar< T,Bar>,Foo< T> {
void bar1();
}
}
运行
X.java:15:错误:BaseFoo不能用不同的参数继承:< T,X.Bar< T>>和< T,X.Foo< T>>
静态界面栏< T>扩展BaseBar< T,Bar>,Foo< T> {b $ b ^
任何人都有解决方案吗?
免责声明:我试图使用该模式实施流畅的界面。
背景:让人们更容易理解为什么我需要这个,这是故事。我想创建一个容器系列: Traversal
< - Sequence < -
List
。因此, Traversal
有一个方法 Traveral< T>接受(Visitor< T>)
(no PECS for总之,这个方法应该总是在迭代访问者遍历元素后返回 this
。当我有 List
类型时,我希望方法返回 List< T>
,而不是遍历< T>
,因为我想让它可以调用像 myList.accept(v).head(15)
,其中 head(int)
是一个 List 不是
遍历的方法
类或接口不能实现或扩展通用接口的不同实例。您的 Bar
界面违反了此规则。让我们来看看接口声明:
静态接口Bar< T>扩展了BaseBar< T,Bar>,Foo< T>
因此, Bar< T>
接口:
-
BaseBar< T,Bar< T>>
-
Foo
为此,这两个接口从相同接口 BaseFoo
的不同实例化扩展。 < / p>
-
BaseBar< T,S扩展BaseBar< T,S>>扩展BaseFoo< T,S>
-
Foo< T>扩展BaseFoo< T,Foo< T>>
这些继承的接口最终也是超级接口 Bar
界面。因此,你的 Bar
接口试图从2个不同的 BaseFoo
实例中扩展,这是非法的。使用一个简单的例子来理解原因:
//假设这是允许的
类Demo实现Comparable< Demo> ,可比< String> {
public int compareTo(Demo arg){...}
public int compareTo(String arg){...}
}
然后在类型擦除之后,编译器会为泛型方法生成2个桥接方法。该类被翻译为:
类Demo实现了Comparable< Demo> ,可比< String> {
public int compareTo(Demo arg){...}
public int compareTo(String arg){...}
//编译器添加的桥接方法
public int compareTo(Object arg){...}
public int compareTo(Object arg){...}
}
因此,这会导致在类中创建重复的桥接方法。这就是为什么它不被允许。
This is a simplified version of Java inherited Fluent method return type in multiple level hierarchies.
Given the following code:
public enum X {
;
static interface BaseFoo<T, S extends BaseFoo<T, S>> {
S foo();
}
static interface Foo<T> extends BaseFoo<T, Foo<T>> {
void foo1();
}
static interface BaseBar<T, S extends BaseBar<T, S>> extends BaseFoo<T, S> {
S bar();
}
static interface Bar<T> extends BaseBar<T, Bar<T>>, Foo<T> {
void bar1();
}
}
run javac X.java
I get the error message:
X.java:15: error: BaseFoo cannot be inherited with different arguments: <T,X.Bar<T>> and <T,X.Foo<T>>
static interface Bar<T> extends BaseBar<T, Bar<T>>, Foo<T> {
^
Anyone has any solution?
Disclaim: I am trying to use the pattern to implement the fluent interface across a container class inheritance hierarchy.
Background: to make it easier for people to understand why I need this, here is the story. I want to create a container family: Traversal
<- Sequence
<- List
. So Traversal
has a method Traveral<T> accept(Visitor<T>)
(no PECS for short), this method should always return this
after iterating the visitor through the elements. When I have a List
type, I want the method return List<T>
instead of Traversal<T>
because I want to make it possible to call something like myList.accept(v).head(15)
, where head(int)
is a method of List
not Traversal
A class or interface cannot implement or extend from different instantiation of a generic interface. Your Bar
interface is breaking this rule. Let's examine the interface declaration:
static interface Bar<T> extends BaseBar<T, Bar<T>>, Foo<T>
So, Bar<T>
extends two interfaces:
BaseBar<T, Bar<T>>
Foo<T>
In addition to that, those two interfaces extend from different instantiation of the same interface BaseFoo
.
BaseBar<T, S extends BaseBar<T, S>> extends BaseFoo<T, S>
Foo<T> extends BaseFoo<T, Foo<T>>
Those inherited interfaces are eventually also the super interfaces of Bar
interface. Thus your Bar
interface tries to extend from 2 different instantiation of BaseFoo
, which is illegal. Let's understand the reason using a simple example:
// Suppose this was allowed
class Demo implements Comparable<Demo> , Comparable<String> {
public int compareTo(Demo arg) { ... }
public int compareTo(String arg) { ... }
}
then after type erasure, compiler would generate 2 bridge methods, for both the generic method. The class is translated to:
class Demo implements Comparable<Demo> , Comparable<String> {
public int compareTo(Demo arg) { ... }
public int compareTo(String arg) { ... }
// Bridge method added by compiler
public int compareTo(Object arg) { ... }
public int compareTo(Object arg) { ... }
}
So, that results in creation of duplicates bridge method in the class. That is why it is not allowed.
这篇关于BaseFoo不能用不同的参数继承:< T,X.Bar< T>>和< T,X.Foo< T>>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!