【问题标题】:Creating an instance of the base class of a class using generics使用泛型创建类的基类的实例
【发布时间】:2013-10-29 14:58:20
【问题描述】:

在我的 Java 项目中,我有一个使用泛型类型的抽象类。我的类由一些具体的子类扩展和实现。我的源代码是这样的:

class Metrics<T extends Dataset>
{
    public float evaluate(T dataset, Entity x, Entity y);
}

class MetricsType1 extends Metrics<DatasetType1>
{
    public float evaluate(DatasetType1 dataset, Entity x, Entity y);
}

class MetricsType2 extends Metrics<DatasetType2>
{
    public float evaluate(DatasetType2 dataset, Entity x, Entity y);
}

在我的主应用程序中,我以这种方式使用我的类:

Metrics<DatasetType1> metrics1 = new MetricsType1();
Metrics<DatasetType2> metrics2 = new MetricsType2();

我想使用相同的引用“metrics”而不是使用两个不同的引用“metrics1”和“metrics”,这样我就可以使用 MetricsType1 或 MetricsType2 类来实例化我的“metrics”引用,而不必编写两个单独的参考文献。

我特别想写这样的东西:

Metrics metrics = null;
metrics = new MetricsType1();
// ...
metrics = new MetricsType2();

显然,Java 解释器给了我一个警告,告诉我应该为 Metrics 类的泛型使用参数。

我该如何处理?

谢谢!

【问题讨论】:

    标签: java generics subclass abstract superclass


    【解决方案1】:

    使用通配符:

    Metrics<?> metrics;
    

    或者,如果你想更具体:

    Metrics<? extends Dataset> metrics;
    

    在这种特殊情况下,它们都是同义词,因为 Metrics 被定义为 T extends Dataset

    但是请注意,使用此定义,evaluate 方法不能直接调用。您必须将对象转换为具体的子类才能执行此操作。

    【讨论】:

    • OP 应该能够转换引用并使用正确的评估方法,对吧?擦除未知,但子类是直接子类,可以使用 instanceof 进行检查。
    • 是的,当然,转换为子类型允许调用evaluate。已更新答案以反映这一点。
    • 啊,谢谢。我需要从另一个类的方法中调用我的指标的评估方法。我有类似的东西:public Network build(T dataset, Metrics metrics)。我怎么能在这个方法中调用metrics.evaluate而不引用Metrics子类?
    • 如果您有Metrics&lt;T&gt;,则evaluate 没有问题。问题来自通配符。有关更多信息,请参阅此内容:docs.oracle.com/javase/tutorial/extra/generics/wildcards.html
    • 好的,我看看。谢谢!
    【解决方案2】:

    你想要Metrics&lt;?&gt;
    如果有通用的基类型,也可以使用Metrics&lt;? extends CommonType&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-30
      • 1970-01-01
      相关资源
      最近更新 更多