gpt4 book ai didi

java - 避免使用泛型进行不安全的转换

转载 作者:行者123 更新时间:2023-11-29 05:36:35 26 4
gpt4 key购买 nike

假设我有一个抽象类:

public abstract class Trainer<T extends Animal>{
...
}

我希望所有子类都有一个通用方法来检查训练员对给定动物的训练状态。所以我在我的培训师定义中有:

public abstract class Trainer<T extends Animal>{
public double getStatus(Animal a){
...
}
}

这样任何人都可以查询培训师,无论其具体类型如何。但是,为了让个别培训师负责报告他们自己的状态,我要求个别培训师实现 internalGetStatus 方法,然后我希望我的 getStatus 方法调用.所以我目前正在做的是:

public abstract class Trainer<T extends Animal>{
protected abstract internalGetStatus(T theAnimal);
public double getStatus(Animal a){
return internalGetStatus((T) a);
}
}

当然,问题是 return internalGetStatus((T) a); 涉及未经检查的类型转换,它会引发我想避免的警告。

有办法吗?

由于一些超出我控制的设计限制,当查询特定动物的状态时,它作为父类 Animal 的对象提供,而不是为训练器创建的特定动物类型。

最佳答案

这取决于类的使用方式。但是,你并没有说太多。让我们从以下代码开始:

abstract class Animal { }

final class Lion extends Animal { }

abstract class Trainer<T extends Animal> {
public abstract double getStatus(T animal);
}

final class LionTrainer extends Trainer<Lion> {
public double getStatus(Lion lion) {
return 4.2;
}
}

您提到 getStatus 的调用方方法不知道动物类型。这意味着他没有使用 Trainer<Lion> ,但原始类型Trainer<Animal>通配符类型。让我们来看看这三个案例。

原始类型:类型参数对原始类型无关紧要。您可以调用方法 getStatusAnimal .只要 Trainer 的子类型,这就有效和 Animal匹配。否则,您将看到 ClassCastException在运行时。

void raw(Trainer trainer, Animal animal) {
trainer.getStatus(animal);
}

Trainer<Animal>: 显然,您可以调用方法 getStatusTrainer<Animal>Animal .它类似于上述情况。静态类型系统不会识别,如果类型不匹配,在运行时您会看到异常。

void base(Trainer<Animal> trainer, Animal animal) {
trainer.getStatus(animal);
}

请注意,您可以传递 LionTrainer到此方法(带强制转换),因为在运行时 Trainer<Animal> 之间没有区别和 Trainer<Lion> .

通配符类型: 好吧,这在调用方不起作用 - 不强制转换 Trainer<?>到别的东西。 ?代表 Animal 的未知子类型(包括基类本身)。

void wildcard(Trainer<?> trainer, Animal animal) {
trainer.getStatus(animal); // ERROR
}

结果是,如果框架使用原始类型基本类型,那么应该没有问题。否则,将强制转换添加到您的代码、使用注释抑制警告并记录您决定这样做的原因会更简单。

关于java - 避免使用泛型进行不安全的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19342319/

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