Java中的类型安全的空集合

之前曾在Java Collections类的实用程序上进行过博客撰写,并且特别地在使用Usings Collections Methods上的博客emptyList(),emptyMap()和emptySet()上进行了博客撰写。 在本文中,我研究了使用Collections类的相关字段访问空集合与使用Collections类的相关方法访问空集合之间有时细微但重要的区别。

以下代码演示了直接访问Collections的字段以指定空集合。

将集合的字段用于空集合

/**
    * Instantiate my collections with empty versions using Collections fields.
    * This will result in javac compiler warnings stating 'warning: [unchecked]
    * unchecked conversion'.
    */
   public void instantiateWithEmptyCollectionsFieldsAssigment()
   {
      this.stringsList = Collections.EMPTY_LIST;
      this.stringsSet = Collections.EMPTY_SET;
      this.stringsMap = Collections.EMPTY_MAP;      
   }

上面的代码使用javac进行编译 ,但是导致出现警告消息(在这种情况下,该消息由NetBeans和Ant生成):

-do-compile:
    [javac] Compiling 1 source file to C:\java\examples\typesafeEmptyCollections\build\classes
    [javac] Note: C:\java\examples\typesafeEmptyCollections\src\dustin\examples\Main.java uses unchecked or unsafe operations.
    [javac] Note: Recompile with -Xlint:unchecked for details.

-Xlint:unchecked指定 javac的参数(在这种情况下,通过NetBeans project.properties文件中的javac.compilerargs=-Xlint:unchecked )有助于获取更具体的警告消息,用于前面列出的代码:

[javac] Compiling 1 source file to C:\java\examples\typesafeEmptyCollections\build\classes
    [javac] C:\java\examples\typesafeEmptyCollections\src\dustin\examples\Main.java:27: warning: [unchecked] unchecked conversion
    [javac]       this.stringsList = Collections.EMPTY_LIST;
    [javac]                                     ^
    [javac]   required: List<String>
    [javac]   found:    List
    [javac] C:\java\examples\typesafeEmptyCollections\src\dustin\examples\Main.java:28: warning: [unchecked] unchecked conversion
    [javac]       this.stringsSet = Collections.EMPTY_SET;
    [javac]                                    ^
    [javac]   required: Set<String>
    [javac]   found:    Set
    [javac] C:\java\examples\typesafeEmptyCollections\src\dustin\examples\Main.java:29: warning: [unchecked] unchecked conversion
    [javac]       this.stringsMap = Collections.EMPTY_MAP;      
    [javac]                                    ^
    [javac]   required: Map<String,String>
    [javac]   found:    Map

如果在其选项中选中了适当的提示框,则NetBeans还将显示这些警告。 接下来的三个图像演示如何确保设置适当的提示以查看NetBeans中的这些警告,并提供一个示例,说明NetBeans如何将上面显示的代码与警告一起呈现。

幸运的是,很容易利用Collections类的实用程序并以类型安全的方式访问空集合,而不会导致这些javac警告和相应的NetBeans提示。 这种方法是使用Collections方法而不是其字段 。 下一个简单的代码清单对此进行了演示。

对空集合使用集合的方法

/**
    * Instantiate my collections with empty versions using Collections methods.
    * This will avoid the javac compiler warnings alluding to 'unchecked conversion'.
    */
   public void instantiateWithEmptyCollectionsMethodsTypeInferred()
   {
      this.stringsList = Collections.emptyList();
      this.stringsSet = Collections.emptySet();
      this.stringsMap = Collections.emptyMap();
   }

上面的代码将编译而不会发出警告,并且也不会显示任何NetBeans提示。 Collections类的每个字段的Javadoc文档都没有解决为什么这些字段会出现这些警告的问题,但是每个类似方法的文档都对此进行了讨论。 具体来说,有关Collections.emptyList()Collections.emptySet()Collections.emptyMap()的文档每个状态为“((不同于此方法,该字段不提供类型安全性。)”

对最后一个代码清单中显示的空集合使用Collections方法可提供类型安全性,而无需显式指定存储在该集合中的类型,因为类型是通过在显式分配给已知和已经声明的实例属性时使用Collections方法来推断的指定的元素类型。 如果无法推断类型,则使用没有显式指定类型的Collections方法时将导致编译器错误 。 下一个尝试在NetBeans中执行此操作的屏幕快照中显示了这一点。

具体的编译器错误消息是:

[javac] C:\java\examples\typesafeEmptyCollections\src\dustin\examples\Main.java:62: error: method populateList in class Main cannot be applied to given types;
    [javac]       populateList(Collections.emptyList());
    [javac]       ^
    [javac]   required: List<String>
    [javac]   found: List<Object>
    [javac]   reason: actual argument List<Object> cannot be converted to List<String> by method invocation conversion
    [javac] C:\java\examples\typesafeEmptyCollections\src\dustin\examples\Main.java:63: error: method populateSet in class Main cannot be applied to given types;
    [javac]       populateSet(Collections.emptySet());
    [javac]       ^
    [javac]   required: Set<String>
    [javac]   found: Set<Object>
    [javac]   reason: actual argument Set<Object> cannot be converted to Set<String> by method invocation conversion
    [javac] C:\java\examples\typesafeEmptyCollections\src\dustin\examples\Main.java:64: error: method populateMap in class Main cannot be applied to given types;
    [javac]       populateMap(Collections.emptyMap());
    [javac]       ^
    [javac]   required: Map<String,String>
    [javac]   found: Map<Object,Object>
    [javac]   reason: actual argument Map<Object,Object> cannot be converted to Map<String,String> by method invocation conversion
    [javac] 3 errors

通过在代码中显式指定集合元素的类型,可以避免这些编译器错误并实现类型安全。 这显示在下一个代码清单中。

使用Collections的Empty方法显式指定元素类型

/**
    * Pass empty collections to another method for processing and specify those
    * empty methods using Collections methods. This will result in javac compiler
    * ERRORS unless the type is explicitly specified.
    */
   public void instantiateWithEmptyCollectionsMethodsTypeSpecified()
   {
      populateList(Collections.<String>emptyList());
      populateSet(Collections.<String>emptySet());
      populateMap(Collections.<String, String>emptyMap());
   }

出于相同的目的,使用Collections类的用于获取空集合的方法比使用Collections的类似命名的字段更可取,因为这些方法提供了类型安全性。 这样可以更好地利用Java的静态类型系统,这是诸如Effective Java这类书籍的关键主题。 一个不错的副作用是消除了混乱的警告和标记的NetBeans提示,但是更重要的结果是更好,更安全的代码。

参考: JCG合作伙伴 Dustin Marx在Inspired by Actual Events博客中提供的Java类型安全空集合

翻译自: https://www.javacodegeeks.com/2012/11/type-safe-empty-collections-in-java.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值