您正在尝试做的事情非常有用,我发现我经常需要用自己编写的代码来做。一个示例用例:
假设我们有一个接口Foo
,并且有一个zorking
包,其中有一个ZorkingFooManager
创建和管理package-private实例的包ZorkingFoo implements Foo
。(一种非常常见的情况。)
因此,ZorkingFooManager
需要包含一个,private Collection<ZorkingFoo> zorkingFoos
但需要暴露一个public Collection<Foo> getAllFoos()
。
大多数Java程序员在实现getAllFoos()
一个新对象之前不会三思而后行,因为它分配了一个new ArrayList<Foo>
,并使用其中的所有元素填充zorkingFoos
并返回它。我很高兴地想到,在遍布全球的数百万台机器上运行的Java代码所消耗的所有时钟周期中,大约有30%只会创建无用的ArrayList副本,而这些副本在创建后就被垃圾回收了。
当然,解决此问题的方法是向下收集集合。这是最好的方法:
static <T,U extends T> List<T> downCastList( List<U> list )
{
return castList( list );
}
这带给我们castList()
功能:
static <T,E> List<T> castList( List<E> list )
{
@SuppressWarnings( "unchecked" )
List<T> result = (List<T>)list;
return result;
}
result
由于Java语言的变态,中间变量是必需的:
因此,即使不是@SuppressWarnings
在return
语句中使用它,也可以在赋值中使用它,这显然很好,因此额外的“结果”变量可以解决此问题。(无论如何,应该通过编译器或JIT对其进行优化。)