ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-10-28 11:14:31  阅读:183  来源: 互联网

标签:types generics java


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

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接口又由以下方式提供:

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界面中,已使方法复制通用,而不是接口本身.这意味着任何实现方法还必须是通用的,具有相同的边界,返回类型和签名,以避免编译器错误和编译器警告.您将需要在IAstNode中:

<T extends ICopy> T copy();

即使您打算在此处将T用作IAstNode,也是如此.您的当前代码会收到未经检查的转换警告,因为T可能是IAstNode.未经检查的转换警告是您已失去代码类型安全性的信号,即使编译器允许您编译代码.

维护类型安全的方法是将泛型类型参数的声明从copy方法移动到接口ICopy本身.

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

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

这是IAstNode现在的样子.它声明自己的类型参数并带有自己的范围,该范围适合ICopy施加的范围.扩展ICopy时,它将其用作类型参数.现在,复制方法签名更加简单.

我给getChildren的ImmutableList类型指定了类型参数T;在这种情况下,这是最有意义的.

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>

复制方法将返回MyAstNode,而getChildren将返回ImmutableList< MyAstNode>.

标签:types,generics,java
来源: https://codeday.me/bug/20191028/1951963.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有