gpt4 book ai didi

java - 使用泛型时失去类型安全

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:10:09 24 4
gpt4 key购买 nike

我有一个用于深度复制列表的实用程序类 (ListUtils)。该类中重要的方法是copy,定义如下:

public static <T  extends ICopy> List<T> copy(List<T> xs) {
LinkedList<T> newList = new LinkedList<>() ;
for(T x : xs) {
newList.add(x.<T> copy()) ;
}
return xs;
}

反过来,ICopy 接口(interface)由:

public interface ICopy {
<T extends ICopy> T copy() ;
}

然后,强制每个AST节点实现ICopy,IAstNode定义如下:

public interface IAstNode extends ICopy {

ImmutableList<? extends IAstNode> getChildren() ;

int getStartLine() ;
int getEndLine() ;

IAstNode copy() ;
}

在这一点上,我失去了类型安全性,因为 Java 编译器指示我应该编写带有抑制警告注释的副本?

对正在发生的事情有任何见解吗?

最佳答案

在你的ICopy界面,你已经制作了方法copy通用的,而不是接口(interface)本身。这意味着任何实现方法也必须是通用的,具有相同的边界、返回类型和签名,以避免编译器错误和编译器警告。你需要在 IAstNode :

<T extends ICopy> T copy();

即使您打算 T 也是如此成为IAstNode这里。由于 T,您会收到当前代码的未经检查的转换警告可能是 IAstNode .未经检查的转换警告表明您的代码已失去类型安全性,即使编译器允许您编译代码。

为了保护类型安全,您可以做的是将泛型类型参数的声明从 copy 中移走。接口(interface)方法 ICopy本身。

public interface ICopy<T extends ICopy<T>> {
T copy();
}

然后任何子接口(interface)(或实现类)都可以提供类型参数,或者它声明自己的类型参数,用于扩展或实现接口(interface)。

这是IAstNode看起来像现在。它用自己的边界声明自己的类型参数,符合 ICopy 强加的边界。 .它在扩展 ICopy 时将其用作类型参数. copy方法签名现在更简单了。

我给了类型参数 TImmutableList输入 getChildren ;它在这种情况下最有意义。

public interface IAstNode<T extends IAstNode<T>> extends ICopy<T> {

ImmutableList<T> getChildren() ;

int getStartLine() ;
int getEndLine() ;

T copy();
}

任何想要指定什么的类 T其实是可以这样做的:

public class MyAstNode implements IAstNode<MyAstNode>

copy方法将返回 MyAstNode , 和 getChildren会返回 ImmutableList<MyAstNode> .

关于java - 使用泛型时失去类型安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30040927/

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