具有 return 列表的方法的通用接口
Generic interface with a method that return a list
我有一个通用接口 (Pack<A extends PackAnimal>
),其中一种方法 returns List<A>
。今天我发现如果在实现接口的 class 中我忘记指定 class (class XXX implements PackAnimal
) return 类型在编译时未检查并失败执行期间
interface PackAnimal {
}
class Buffalo implements PackAnimal {
}
interface LonelyAnimal {
}
class Puma implements LonelyAnimal {
}
interface Pack<A extends PackAnimal> {
List<A> getMembers();
}
class PumaPack implements Pack {
@Override
public List<Puma> getMembers() {
return null;
}
}
这是为什么?如果声明中存在任何类型的错误,编译将失败,我该如何强制?
您的列表声明为未知类型。使用 class 类型:
interface Pack<A extends PackAnimal> {
List<A> getMembers();
}
// won't compile because Puma not within bound
class PumaPack implements Pack<Puma> {
List<Puma> getMembers() {return null;}
}
// compiles OK
class BuffaloPack implements Pack<Buffalo> {
List<Buffalo> getMembers() {return null;}
}
但是你无法阻止某人像你的 PumpPack 示例那样编写 raw(缺失类型)实现,但是你会得到一个编译器 warning:
// compile warning
class PumaPack implements Pack {
List getMembers() {return null;}
}
如果您将编译设置为在出现警告时失败:
javac -Werror ...
那么即使对于原始类型,您也将实现您的目标。
您正在体验使用 Raw Types 的可怕和奇怪的结果。
本质上,如果您错过了 <...>
任何应该出现的地方,编译器会将您的代码视为遗留代码,并且不会做很多它应该做的正常类型检查。大多数编译器尽了最大努力,但在检查过程中留下了漏洞。
interface PackAnimal {
}
class Buffalo implements PackAnimal {
}
interface LonelyAnimal {
}
class Puma implements LonelyAnimal {
}
interface Pack<A extends PackAnimal> {
// Obviously fine.
List<A> getMembers();
}
// Raw type so no checking.
class PumaPack implements Pack {
@Override
public List<Puma> getMembers() {
// Raw typed class so Puma isn't checked for PackAnimal super.
return Arrays.asList(new Puma());
}
}
class Six {
}
// Properly typed so Raw Types not happening.
class SixPack implements Pack<Six> {
@Override
// NOT ALLOWED: Attempt to use incompatible return type!!!
public List<Six> getMembers() {
return null;
}
}
我有一个通用接口 (Pack<A extends PackAnimal>
),其中一种方法 returns List<A>
。今天我发现如果在实现接口的 class 中我忘记指定 class (class XXX implements PackAnimal
) return 类型在编译时未检查并失败执行期间
interface PackAnimal {
}
class Buffalo implements PackAnimal {
}
interface LonelyAnimal {
}
class Puma implements LonelyAnimal {
}
interface Pack<A extends PackAnimal> {
List<A> getMembers();
}
class PumaPack implements Pack {
@Override
public List<Puma> getMembers() {
return null;
}
}
这是为什么?如果声明中存在任何类型的错误,编译将失败,我该如何强制?
您的列表声明为未知类型。使用 class 类型:
interface Pack<A extends PackAnimal> {
List<A> getMembers();
}
// won't compile because Puma not within bound
class PumaPack implements Pack<Puma> {
List<Puma> getMembers() {return null;}
}
// compiles OK
class BuffaloPack implements Pack<Buffalo> {
List<Buffalo> getMembers() {return null;}
}
但是你无法阻止某人像你的 PumpPack 示例那样编写 raw(缺失类型)实现,但是你会得到一个编译器 warning:
// compile warning
class PumaPack implements Pack {
List getMembers() {return null;}
}
如果您将编译设置为在出现警告时失败:
javac -Werror ...
那么即使对于原始类型,您也将实现您的目标。
您正在体验使用 Raw Types 的可怕和奇怪的结果。
本质上,如果您错过了 <...>
任何应该出现的地方,编译器会将您的代码视为遗留代码,并且不会做很多它应该做的正常类型检查。大多数编译器尽了最大努力,但在检查过程中留下了漏洞。
interface PackAnimal {
}
class Buffalo implements PackAnimal {
}
interface LonelyAnimal {
}
class Puma implements LonelyAnimal {
}
interface Pack<A extends PackAnimal> {
// Obviously fine.
List<A> getMembers();
}
// Raw type so no checking.
class PumaPack implements Pack {
@Override
public List<Puma> getMembers() {
// Raw typed class so Puma isn't checked for PackAnimal super.
return Arrays.asList(new Puma());
}
}
class Six {
}
// Properly typed so Raw Types not happening.
class SixPack implements Pack<Six> {
@Override
// NOT ALLOWED: Attempt to use incompatible return type!!!
public List<Six> getMembers() {
return null;
}
}