答案是可以的!也就是说泛型可以实现的功能,用Object也是可以实现的。
那为什么还要使用泛型呢?因为泛型有如下优点:
1、无须类型强转,提高效率,避免了强转出错。
2、通配符"?"的使用提高了程序的阅读性。
3、限制通配符(<? extends T>、<? super T>)提高了程序的健壮性。
所以,可以使用泛型就尽量使用泛型吧!
下面举例说明一下第2条和第3条:
例子1:Collection<E>泛型接口的removeAll()方法:
boolean removeAll(Collection<?> c);
我们知道Collection是众多集合的顶层接口(List、Set等),Collection容器中包含的元素类型是任意的,也就是说removeAll方法必须是与类型无关的一个方法。所以这个问号"?"是不是很形象呢!
例子2:ArrayList泛型类的addAll()方法:
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
看到上面的参数Collection<? extends E>,说明这个c必须是E类型或者E的子类。如果你很粗心,什么都往ArrayList里面加,编译器可不会答应。
ArrayList<String> stringArrayList = new ArrayList<>();
ArrayList<Object> objectArrayList = new ArrayList<>();
stringArrayList.addAll(objectArrayList);//编译器直接给你报错了
objectArrayList.addAll(stringArrayList);//可以
如果是用Object实现的ArrayLis而不是使用泛型,需要等到运行期间才会报类型强转错误了。因此使用了泛型,好处多多,程序很健壮!!
细节补充:
1、有没有发现通配符"?"出现的地方基本都是在方法的参数中!!因为通配符"?"负责接收信息。
2、类型擦除是泛型出现以后才有的。List<T>中,List<Object>和List<String>都是List.class,Object和String被擦除了。
3、泛型方法是需要<T>进行声明的,泛型方法可以独立于泛型类和泛型接口而存在的。
//<T>的作用:1、声明的此方法为泛型方法;2、定义了参数中的T
public <T> void genericsMethod(T t){
//do something with t
}
4、可以用Collection<T>代替Collection<?>吗?答案是可以的,改为泛型方法!
//将boolean removeAll(Collection<?> c);改为泛型方法。
<T> boolean removeAll(Collection<T> c);
如果对您有用的话赞一下呗!谢谢啦!