给定以下 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>> { ... }
修复了错误,但没有准确反射(reflect)意图:我想强制与 Line 一起使用的所有类型参数必须是 Stop 的子类型。使用T extends Comparable<T>
将允许实现该接口(interface)的任意类型。
我不明白错误的原因。有没有某种方法可以在不改变类型结构的情况下表达这种关系,或者这是 Java 泛型的限制吗?
编辑:访问https://www.onlinegdb.com/S1u9wclnH查看我的尝试的精简版本。
最佳答案
问题是你对 class Sequence
的定义.
public class Sequence<T> : IEnumerable<T>
where T : IComparable<T> { ... }
这个 C# 类利用 IComparable
的事实是逆变的,因此 C# 类不需要完全 T: IComparable<T>
,但如果T
也很高兴与其基类之一相当。因此,即使 T
,代码也能工作。使用派生自 Stop
的类进行实例化.
Java 没有声明站点差异,但有使用站点差异(通配符)。你的Java Sequence
无法为从 Stop
派生的类实例化该类,但是你的Line
类可能是。因此编译器错误。
要解决此问题,每当您使用 Comparable
时,您都需要将 C# 的声明站点差异转换为 Java 的通配符在范围内:
class Sequence<T extends Comparable<? super T>> implements Iterable<T> { ... }
关于java - 如何将这段 C# 泛型转换为 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58902790/