如何正确实现java.util.Collection类?解决泛型参数隐藏警告问题
这个警告的根源很明确:你在toArray方法上声明的泛型参数<T>,和你的LinkedList<T>类本身的泛型参数T重名了——方法级别的T把类级别的T给“隐藏”了,编译器自然会提示你这个命名冲突。
最简单的解决方案:给方法的泛型参数换个名字
Collection接口中toArray方法的泛型参数是独立于类泛型的,它的作用是指定返回数组的元素类型(可以是集合元素类型的父类),和你的LinkedList<T>的T(集合元素类型)本来就不是同一个概念。所以你完全不需要修改类上Collection<T>的泛型参数,只需要把方法的泛型参数换成其他字母,比如<E>:
@Override public <E> E[] toArray(E[] arg0) { // 你的自定义实现代码 }
这样一来,方法的E和类的T就不会有命名冲突,警告自然消失。而且这完全符合Collection接口的方法定义——你可以传入任意类型的数组(只要E是T的父类型或本身),比如对于LinkedList<String>,你可以传入Object[]返回Object[],也可以传入String[]返回String[],逻辑完全通顺。
为什么不能用类的泛型参数代替?
可能你会想,能不能直接用类的T来定义方法?比如写成public T[] toArray(T[] arg0)。但这不符合Collection接口的方法签名——接口的toArray方法是泛型方法,允许返回比集合元素类型更宽泛的数组类型,而如果直接用类的T,就限制了只能返回T[],违背了接口的设计意图。
不推荐的方案:压制警告
当然你也可以用@SuppressWarnings("unchecked")注解来压制警告,但这只是“掩盖问题”而不是“解决问题”,不建议这么做——命名冲突本身会降低代码可读性,万一后续维护时混淆了两个T的含义,反而容易出bug。
内容的提问来源于stack exchange,提问作者Davis8988

