Java 泛型:该类型不是有效的替代品

Posted

技术标签:

【中文标题】Java 泛型:该类型不是有效的替代品【英文标题】:Java generics: The type is not a valid substitute 【发布时间】:2021-10-19 11:07:50 【问题描述】:

我在使用 Java 泛型时有点纠结,并且在使用泛型类型时我开始遇到绑定不匹配错误。谁能指出我哪里出错了?

本质上,我正在尝试编写一个 K-Medoids 实现,它可以处理任何可以计算它们之间距离的对象类(例如,通用笛卡尔点,或使用大圆距离的纬度/经度点等。 )

我从这个开始(我承认,这本身可能是错误的):

public interface IDistanceMetric<T>

    public double distance(T that);

然后我有一个 GeoPoint 类来实现这个:

public class GeoPoint implements IDistanceMetric<GeoPoint>

    private final double lat;
    private final double lon;
    
    @Override
    public double distance(GeoPoint that)
    
        return GeoTools.greatCircleDistance(this, that);
    

然后还有几个类从这个链中继承,例如:

public abstract class GenericLocation extends GeoPoint


    private String prefix;

(现在,我知道GenericLocation 没有实现IDistanceMetric&lt;GenericLocation&gt;,但是如果我尝试在声明中明确实现它,我会得到一个单独的问题“不能用不同的参数多次实现”) .

无论如何,当我现在尝试实现 KMedoids 时,问题就来了:

public class KMedoids<P extends IDistanceMetric<P>>

    // ...

并尝试在代码中使用除GeoPoint 之外的任何其他 的基类来实例化它:

KMedoids<GenericLocation> kmeds; // bound mismatch error

这会导致绑定不匹配错误。

我在这里做错了什么?我看过几个类似的问题,但它们似乎不是完全相同的问题。我觉得这与我编写界面的方式有关,但我觉得我现在只是在猜测。

【问题讨论】:

KMedoids&lt;P extends IDistanceMetric&lt;? super P&gt;&gt;? 效果很好,谢谢!你刚刚所做的事情有什么花哨的术语吗?如果我知道这些术语,我将能够阅读更多关于这类事情的信息。 【参考方案1】:

KMedoids&lt;GenericLocation&gt; 会导致要求 GenericLocation 是 IDistanceMetric&lt;GenericLocation&gt;,当然不是,它是 IDistanceMetric&lt;GeoPoint&gt;

这就是为什么你会得到你所得到的错误。 修复它可能会变得非常混乱,就像多层嵌套泛型的情况一样。

Andy 建议了一个您说有效的修复 (KMedoids&lt;P extends IDistanceMetric&lt;? super P&gt;&gt;),但这就是您收到错误的原因。

【讨论】:

以上是关于Java 泛型:该类型不是有效的替代品的主要内容,如果未能解决你的问题,请参考以下文章

此 SQL 查询是不是有更有效的替代方法?

TypeScript 中具有泛型类型参数的泛型类型的替代方案

java泛型 通配符

Java中的泛型

Java中的泛型

IsBadReadPtr 的最有效替代品?