看到java.util.Collections代码时看到checked集合
static class CheckedCollection implements Collection, Serializable { }
看了代码的实现不知道是干嘛用的,
1. 光有java静态类型检查在有的时候是不够的,比如把这个list传给了别的调用者
起初我们定义这个List是
List<Integer> list = xxx;
在我们自己eclipse里面 由于有静态检查 我们一般不会
list.add("hello world")
但是如果传递给调用者 调用者使用
List newList = list;
就可以随意插入任何类型的对象,运行不会报错。因为这个newList已经是rawtype的.
避免这个结果们可以将比如原来的 getXXX()方法
public List getCards() {
return list;
}
改写为
public List getCards() {
return Collections.checkedList(list, Integer.class);
}
调用者插入其他类型,运行时就会遇到
Exception in thread "main" java.lang.ClassCastException: Attempt to insert class java.lang.String element into collection with element type class java.lang.Integer
at java.util.Collections$CheckedCollection.typeCheck(Collections.java:2276)
at java.util.Collections$CheckedCollection.add(Collections.java:2319)
at ds.PersonService.main(PersonService.java:11)
这样的错误
2. 还有一个作用就是为了debug 如果在程序中总是遇到这样的问题可以先用checked集合来代替
这样根据上面的错误信息来调试 调试完毕再弄回去
==================================================================================================
下面是checkedCollection的实现 其他具体实现(list/set/map)可以到Collections类里面查到
final Collection<E> c;
final Class<E> type;
void typeCheck(Object o) {
if (o != null && !type.isInstance(o))
throw new ClassCastException(badElementMsg(o));
}
private String badElementMsg(Object o) {
return "Attempt to insert " + o.getClass() +
" element into collection with element type " + type;
}
CheckedCollection(Collection<E> c, Class<E> type) {
if (c==null || type == null)
throw new NullPointerException();
this.c = c;
this.type = type;
}
public int size() { return c.size(); }
public boolean isEmpty() { return c.isEmpty(); }
public boolean contains(Object o) { return c.contains(o); }
public Object[] toArray() { return c.toArray(); }
public <T> T[] toArray(T[] a) { return c.toArray(a); }
public String toString() { return c.toString(); }
public boolean remove(Object o) { return c.remove(o); }
public void clear() { c.clear(); }
public boolean containsAll(Collection<?> coll) {
return c.containsAll(coll);
}
public boolean removeAll(Collection<?> coll) {
return c.removeAll(coll);
}
public boolean retainAll(Collection<?> coll) {
return c.retainAll(coll);
}
public Iterator<E> iterator() {
final Iterator<E> it = c.iterator();
return new Iterator<E>() {
public boolean hasNext() { return it.hasNext(); }
public E next() { return it.next(); }
public void remove() { it.remove(); }};
}
public boolean add(E e) {
typeCheck(e);
return c.add(e);
}
private E[] zeroLengthElementArray = null; // Lazily initialized
private E[] zeroLengthElementArray() {
return zeroLengthElementArray != null ? zeroLengthElementArray :
(zeroLengthElementArray = zeroLengthArray(type));
}
@SuppressWarnings("unchecked")
Collection<E> checkedCopyOf(Collection<? extends E> coll) {
Object[] a = null;
try {
E[] z = zeroLengthElementArray();
a = coll.toArray(z);
// Defend against coll violating the toArray contract
if (a.getClass() != z.getClass())
a = Arrays.copyOf(a, a.length, z.getClass());
} catch (ArrayStoreException ignore) {
// To get better and consistent diagnostics,
// we call typeCheck explicitly on each element.
// We call clone() to defend against coll retaining a
// reference to the returned array and storing a bad
// element into it after it has been type checked.
a = coll.toArray().clone();
for (Object o : a)
typeCheck(o);
}
// A slight abuse of the type system, but safe here.
return (Collection<E>) Arrays.asList(a);
}
public boolean addAll(Collection<? extends E> coll) {
// Doing things this way insulates us from concurrent changes
// in the contents of coll and provides all-or-nothing
// semantics (which we wouldn't get if we type-checked each
// element as we added it)
return c.addAll(checkedCopyOf(coll));
}