给出以下C#代码,如何将其转换为Java?
public class Stop : IComparable<Stop>
{
public int CompareTo(Stop other) { ... }
}
public class Sequence<T> : IEnumerable<T>
where T : IComparable<T>
{
public IEnumerator<T> GetEnumerator() { ... }
IEnumerator IEnumerable.GetEnumerator() { ... }
}
public class Line<T> : Sequence<T>, IComparable<Line<T>>
where T : Stop
{
public int CompareTo(Line<T> other) { ... }
}
我很难将Line类的定义转换为Java。我的第一次尝试是:
public class Line<T extends Stop> extends Sequence<T> implements Comparable<Line<T>> { ... }
但是,编译器针对extends Sequence<T>
报告以下错误:
Error: type argument T is not within bounds of type-variable T
将定义更改为
public class Line<T extends Comparable<T>> extends Sequence<T> implements Comparable<Line<T>> { ... }
修复了该错误,但不能准确反映其意图:我想强制所有与Line一起使用的类型参数必须是Stop的子类型。使用T extends Comparable<T>
将允许实现接口的任意类型。
我不明白该错误的原因。是否有某种方法可以表达这种关系而不改变类型的结构,或者这是Java泛型的局限性?
编辑:访问https://www.onlinegdb.com/S1u9wclnH以查看我的尝试的精简版本。
答案 0 :(得分:1)
问题在于您对class Sequence
的定义。
public class Sequence<T> : IEnumerable<T>
where T : IComparable<T> { ... }
此C#类利用IComparable
是反变量的事实,因此C#类不需要完全T: IComparable<T>
,但是如果T
与它的基类之一。因此,即使使用从T
派生的类实例化了Stop
,该代码仍然有效。
Java没有声明站点差异,但是有使用站点差异(通配符)。无法为Sequence
派生的类实例化Java Stop
类,但可以实例化Line
类。因此出现编译器错误。
要解决此问题,每当在边界中使用Comparable
时,都需要将C#的声明站点差异转换为Java的通配符:
class Sequence<T extends Comparable<? super T>> implements Iterable<T> { ... }