Java - 从通用方法返回正确的类型

发布于 2024-10-12 07:56:18 字数 986 浏览 7 评论 0原文

我有以下类结构:

public class Team {
    ...
}

public class Event {

}

public abstract class Fixture<T extends Team> implements Event {
   ...
}

public abstract class Forecast<Event> {

}

public class MyPrediction<T extends Fixture<? extends Team>> extends Forecast<Fixture<? extends Team>>{

}

我正在尝试对各种体育赛事进行建模(即“固定装置”用于两个参与者之间相互对抗的特定游戏,而另一种类型的“事件”可能有许多参与者),对特定“事件”结果的预测。我有一个通用方法:

public <T> MyPrediction<Fixture<? extends Team>> getMyPrediction(Fixture<? extends Team> fixture) {

}

我希望能够返回一个 MyPrediction 实例,该实例具有 fixture 参数的通用类型,但我似乎无法这样做。例如,如果我执行如下操作,则会收到编译错误:

SoccerFixture<EnglishSoccerTeams> soccerMatch = new ScoccerFixture<EnglishSoccerTeams>();
MyPrediction<SoccerFixture<EnglishSoccerTeams>> = getMyPrediction(soccerMatch);

我愿意更改我的类结构以合并此功能。我怎样才能这样做呢?

I have the following class structure:

public class Team {
    ...
}

public class Event {

}

public abstract class Fixture<T extends Team> implements Event {
   ...
}

public abstract class Forecast<Event> {

}

public class MyPrediction<T extends Fixture<? extends Team>> extends Forecast<Fixture<? extends Team>>{

}

I am trying to model sports events of all kinds (i.e. a 'Fixture' is for a particular game between two participants play against each other, whereas another type of 'Event' may have many participants), along with predictions for the outcome of particular 'Events'. I have a generic method:

public <T> MyPrediction<Fixture<? extends Team>> getMyPrediction(Fixture<? extends Team> fixture) {

}

I want to be able to return a MyPrediction instance which has the generic type of the fixture argument, but I can't seem to do so. For example, if I do something like the following, then I get a compilation error:

SoccerFixture<EnglishSoccerTeams> soccerMatch = new ScoccerFixture<EnglishSoccerTeams>();
MyPrediction<SoccerFixture<EnglishSoccerTeams>> = getMyPrediction(soccerMatch);

I am willing to change my class structure to incorporate this feature. How can I do so?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

随波逐流 2024-10-19 07:56:18

getMyPrediction 的签名更改为

public <T extends Fixture<? extends Team>> MyPrediction<T> getMyPrediction(T fixture)

这告诉编译器参数和结果中的固定类型相同,从而允许类型检查通过。

这是一个完整的示例,还进行了一些其他细微的更改以使其能够编译。它引入了类 Predictor 来保存 getMyPrediction 方法和 doit 方法来显示示例使用:

public interface Team {
}

public interface Event {
}

public abstract class Fixture<T extends Team> implements Event {
}

public abstract class Forecast<T> {
}

public class MyPrediction<T extends Fixture<? extends Team>> extends
        Forecast<Fixture<? extends Team>> {
}

public class SoccerFixture<T extends SoccerTeam> extends Fixture<T> {
}

public class SoccerTeam implements Team {
}

public class EnglishSoccerTeam extends SoccerTeam {
}

public class Predictor {

    public <T extends Fixture<? extends Team>> MyPrediction<T> getMyPrediction(T fixture) {
        return new MyPrediction<T>();
    }

    public void doit() {
        SoccerFixture<EnglishSoccerTeam> soccerMatch = new SoccerFixture<EnglishSoccerTeam>();
        MyPrediction<SoccerFixture<EnglishSoccerTeam>> myPrediction = getMyPrediction(soccerMatch);
    }
}

如其他地方所述,您可能需要引入一个或更多工厂对象来在 MyPrediction 实现中执行有意义的工作。

Change the signature of getMyPrediction to

public <T extends Fixture<? extends Team>> MyPrediction<T> getMyPrediction(T fixture)

This tells the compiler that the fixture types in the argument and result are the same, allowing type-checking to pass.

Here is a complete example, with some other minor changes to get it to compile. It introduces the class Predictor to hold the getMyPrediction method and a doit method to show sample use:

public interface Team {
}

public interface Event {
}

public abstract class Fixture<T extends Team> implements Event {
}

public abstract class Forecast<T> {
}

public class MyPrediction<T extends Fixture<? extends Team>> extends
        Forecast<Fixture<? extends Team>> {
}

public class SoccerFixture<T extends SoccerTeam> extends Fixture<T> {
}

public class SoccerTeam implements Team {
}

public class EnglishSoccerTeam extends SoccerTeam {
}

public class Predictor {

    public <T extends Fixture<? extends Team>> MyPrediction<T> getMyPrediction(T fixture) {
        return new MyPrediction<T>();
    }

    public void doit() {
        SoccerFixture<EnglishSoccerTeam> soccerMatch = new SoccerFixture<EnglishSoccerTeam>();
        MyPrediction<SoccerFixture<EnglishSoccerTeam>> myPrediction = getMyPrediction(soccerMatch);
    }
}

As noted elsewhere, you might need to introduce one or more factory objects to perform meaningful work in the MyPrediction implementation.

卸妝后依然美 2024-10-19 07:56:18

Java 的类型系统不够强大,无法直接执行您建议的操作,因为类型擦除(泛型参数在运行时不可用。

通常的解决方案是创建一个单独的 EventFactory 类,然后您可以将其传递给需要的任何方法创建特定的事件子类型实例。

Java's type system is not powerful enough to do directly what you propose, because of type erasure (the generic parameters are not available at runtime.

The usual solution is to create a separate EventFactory class, which you can then pass in to any method which needs to create a specific Event subtype instance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文