gpt4 book ai didi

java - ?扩展 TSubject 扩展主题 - 类型不安全,或者只是 Java 无法处理它?

转载 作者:太空宇宙 更新时间:2023-11-04 08:28:14 25 4
gpt4 key购买 nike

编译时

import java.util.List;

public class Test {
public static class Subject {
}

public static class MySubject extends Subject {
}

public static class Step<TSubjectA extends Subject> {
public void doWork(TSubjectA subject) {
}
}

public static class Worker {
public static <TSubjectB extends Subject> void doWork(TSubjectB subject, List<Step<? extends TSubjectB>> steps) {
for (Step<? extends TSubjectB> step : steps) {
step.doWork(subject);
}
}
}

public static void main(String[] args) {
MySubject subject;
List<Step<? extends Subject>> steps;

Worker.doWork(subject, steps);
}
}

我收到错误

Test.java:18: doWork(capture#95 of ? extends TSubjectB) in Test.Step cannot be applied to (TSubjectB)

据我所知,subject 的类型为 TSubjectB,它扩展了 Subject。类型TSubjectA 是扩展TSubjectB 的类型,而TSubjectB 又扩展了Subject。所以我应该能够将 subject 传递给 doWork 并且它应该都是类型安全的。

我是否遗漏了一些东西,它实际上不是类型安全的,或者这只是 Java 泛型的限制?

最佳答案

虽然类型参数 TSubjectATSubjectB 都保证是扩展 Subject 的某种类型,但它们不一定是同一类型 - 一个可能是 MySubject,另一个可能是 MyOtherSubject。这就是编译器不认为当前代码类型安全的原因。

如果您需要的功能严格依赖于 Subject 基本实现,只需删除类型参数并依赖多态性即可:

public static class Step {
public void doWork(Subject subject) {
//do Subject stuff
}
}

public static class Worker {
public static void doWork(Subject subject, List<Step> steps) {
for (Step step : steps) {
step.doWork(subject);
}
}
}

public static void main(String[] args) {

List<Step> steps = ...;

//all valid
Worker.doWork(new Subject(), steps);
Worker.doWork(new MySubject(), steps);
Worker.doWork(new MyOtherSubject(), steps);
}

如果不是,也就是说,如果 doWork 实现根据 Subject 的子类型而有所不同,那么泛型将无法帮助您,您需要进行一些设计更改。请记住,Java 中的泛型不是动态魔法,而是有助于编译时类型安全的语法糖。阅读type erasure如果您尚未了解此限制。

关于java - ?扩展 TSubject 扩展主题 - 类型不安全,或者只是 Java 无法处理它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8098868/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com