如何使用Java泛型映射不同的值类型

发表于:2015-4-02 09:34

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:shutear    来源:51Testing软件测试网采编

  一般来说,开发人员偶尔会遇到这样的情形: 在一个特定容器中映射任意类型的值。然而Java 集合API只提供了参数化的容器。这限制了类型安全地使用HashMap,如单一的值类型。但如果想混合苹果和梨,该怎样做呢?
  幸运的是,有一个简单的设计模式允许使用Java泛型映射不同的值类型,Joshua Bloch在其《Effective Java》(第二版,第29项)中将其描述为类型安全的异构容器(typesafe hetereogeneous container)。
  关于这个主题,最近碰到一些不太合适的解决方案。它给了我在这篇文章中解释这个问题域,并阐述一些实现细节的想法。
  使用Java泛型映射不同的值类型
  考虑一个例子,你需要提供某种应用程序的上下文,它可以将特定的键绑定到任意类型的值。利用String作为键的HashMap,一个简单的、非类型安全(type safe)的实现可能是这样的:
  public class Context {
  private final Map<String,Object> values = new HashMap<>();
  public void put( String key, Object value ) {
  values.put( key, value );
  }
  public Object get( String key ) {
  return values.get( key );
  }
  [...]
  }
  接下来的代码片段展示了怎样在程序中使用Context :
  Context context = new Context();
  Runnable runnable = ...
  context.put( "key", runnable );
  // several computation cycles later...
  Runnable value = ( Runnable )context.get( "key" );
  可以看出,这种方法的缺点是在第6行需要进行向下转型(down cast)。如果替换键值对中值的类型,显然会抛出一个ClassCastException异常:
  Context context = new Context();
  Runnable runnable = ...
  context.put( "key", runnable );
  // several computation cycles later...
  Executor executor = ...
  context.put( "key", executor );
  // even more computation cycles later...
  Runnable value = ( Runnable )context.get( "key" ); // runtime problem
  产生这种问题的原因是很难被跟踪到的,因为相关的实现步骤可能已经广泛分布在你的程序各个部分中。
  为了改善这种情况,貌似将value和它的key、它的value都进行绑定是合理的。
  在我看到的、按照这种方法的多种解决方案中,常见的错误或多或少归结于下面Context的变种:
  public class Context {
  private final <String, Object> values = new HashMap<>();
  public <T> void put( String key, T value, Class<T> valueType ) {
  values.put( key, value );
  }
  public <T> T get( String key, Class<T> valueType ) {
  return ( T )values.get( key );
  }
  [...]
  }
31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号