src/share/classes/java/util/Collections.java

Print this page
rev 10180 : 8047795: Collections.checkedList checking bypassed by List.replaceAll
Reviewed-by: psandoz, chegar


3014      */
3015     public static <E> Collection<E> checkedCollection(Collection<E> c,
3016                                                       Class<E> type) {
3017         return new CheckedCollection<>(c, type);
3018     }
3019 
3020     @SuppressWarnings("unchecked")
3021     static <T> T[] zeroLengthArray(Class<T> type) {
3022         return (T[]) Array.newInstance(type, 0);
3023     }
3024 
3025     /**
3026      * @serial include
3027      */
3028     static class CheckedCollection<E> implements Collection<E>, Serializable {
3029         private static final long serialVersionUID = 1578914078182001775L;
3030 
3031         final Collection<E> c;
3032         final Class<E> type;
3033 
3034         void typeCheck(Object o) {

3035             if (o != null && !type.isInstance(o))
3036                 throw new ClassCastException(badElementMsg(o));

3037         }
3038 
3039         private String badElementMsg(Object o) {
3040             return "Attempt to insert " + o.getClass() +
3041                 " element into collection with element type " + type;
3042         }
3043 
3044         CheckedCollection(Collection<E> c, Class<E> type) {
3045             if (c==null || type == null)
3046                 throw new NullPointerException();
3047             this.c = c;
3048             this.type = type;
3049         }
3050 
3051         public int size()                 { return c.size(); }
3052         public boolean isEmpty()          { return c.isEmpty(); }
3053         public boolean contains(Object o) { return c.contains(o); }
3054         public Object[] toArray()         { return c.toArray(); }
3055         public <T> T[] toArray(T[] a)     { return c.toArray(a); }
3056         public String toString()          { return c.toString(); }
3057         public boolean remove(Object o)   { return c.remove(o); }
3058         public void clear()               {        c.clear(); }
3059 
3060         public boolean containsAll(Collection<?> coll) {
3061             return c.containsAll(coll);
3062         }
3063         public boolean removeAll(Collection<?> coll) {
3064             return c.removeAll(coll);
3065         }
3066         public boolean retainAll(Collection<?> coll) {
3067             return c.retainAll(coll);
3068         }


3074             return new Iterator<E>() {
3075                 public boolean hasNext() { return it.hasNext(); }
3076                 public E next()          { return it.next(); }
3077                 public void remove()     {        it.remove(); }};
3078         }
3079 
3080         public boolean add(E e) {
3081             typeCheck(e);
3082             return c.add(e);
3083         }
3084 
3085         private E[] zeroLengthElementArray; // Lazily initialized
3086 
3087         private E[] zeroLengthElementArray() {
3088             return zeroLengthElementArray != null ? zeroLengthElementArray :
3089                 (zeroLengthElementArray = zeroLengthArray(type));
3090         }
3091 
3092         @SuppressWarnings("unchecked")
3093         Collection<E> checkedCopyOf(Collection<? extends E> coll) {
3094             Object[] a = null;
3095             try {
3096                 E[] z = zeroLengthElementArray();
3097                 a = coll.toArray(z);
3098                 // Defend against coll violating the toArray contract
3099                 if (a.getClass() != z.getClass())
3100                     a = Arrays.copyOf(a, a.length, z.getClass());
3101             } catch (ArrayStoreException ignore) {
3102                 // To get better and consistent diagnostics,
3103                 // we call typeCheck explicitly on each element.
3104                 // We call clone() to defend against coll retaining a
3105                 // reference to the returned array and storing a bad
3106                 // element into it after it has been type checked.
3107                 a = coll.toArray().clone();
3108                 for (Object o : a)
3109                     typeCheck(o);
3110             }
3111             // A slight abuse of the type system, but safe here.
3112             return (Collection<E>) Arrays.asList(a);
3113         }
3114 


3470                     typeCheck(e);
3471                     i.set(e);
3472                 }
3473 
3474                 public void add(E e) {
3475                     typeCheck(e);
3476                     i.add(e);
3477                 }
3478 
3479                 @Override
3480                 public void forEachRemaining(Consumer<? super E> action) {
3481                     i.forEachRemaining(action);
3482                 }
3483             };
3484         }
3485 
3486         public List<E> subList(int fromIndex, int toIndex) {
3487             return new CheckedList<>(list.subList(fromIndex, toIndex), type);
3488         }
3489 






3490         @Override
3491         public void replaceAll(UnaryOperator<E> operator) {
3492             list.replaceAll(operator);
3493         }

3494         @Override
3495         public void sort(Comparator<? super E> c) {
3496             list.sort(c);
3497         }
3498     }
3499 
3500     /**
3501      * @serial include
3502      */
3503     static class CheckedRandomAccessList<E> extends CheckedList<E>
3504                                             implements RandomAccess
3505     {
3506         private static final long serialVersionUID = 1638200125423088369L;
3507 
3508         CheckedRandomAccessList(List<E> list, Class<E> type) {
3509             super(list, type);
3510         }
3511 
3512         public List<E> subList(int fromIndex, int toIndex) {
3513             return new CheckedRandomAccessList<>(




3014      */
3015     public static <E> Collection<E> checkedCollection(Collection<E> c,
3016                                                       Class<E> type) {
3017         return new CheckedCollection<>(c, type);
3018     }
3019 
3020     @SuppressWarnings("unchecked")
3021     static <T> T[] zeroLengthArray(Class<T> type) {
3022         return (T[]) Array.newInstance(type, 0);
3023     }
3024 
3025     /**
3026      * @serial include
3027      */
3028     static class CheckedCollection<E> implements Collection<E>, Serializable {
3029         private static final long serialVersionUID = 1578914078182001775L;
3030 
3031         final Collection<E> c;
3032         final Class<E> type;
3033 
3034         @SuppressWarnings("unchecked")
3035         E typeCheck(Object o) {
3036             if (o != null && !type.isInstance(o))
3037                 throw new ClassCastException(badElementMsg(o));
3038             return (E) o;
3039         }
3040 
3041         private String badElementMsg(Object o) {
3042             return "Attempt to insert " + o.getClass() +
3043                 " element into collection with element type " + type;
3044         }
3045 
3046         CheckedCollection(Collection<E> c, Class<E> type) {
3047             this.c = Objects.requireNonNull(c, "c");
3048             this.type = Objects.requireNonNull(type, "type");


3049         }
3050 
3051         public int size()                 { return c.size(); }
3052         public boolean isEmpty()          { return c.isEmpty(); }
3053         public boolean contains(Object o) { return c.contains(o); }
3054         public Object[] toArray()         { return c.toArray(); }
3055         public <T> T[] toArray(T[] a)     { return c.toArray(a); }
3056         public String toString()          { return c.toString(); }
3057         public boolean remove(Object o)   { return c.remove(o); }
3058         public void clear()               {        c.clear(); }
3059 
3060         public boolean containsAll(Collection<?> coll) {
3061             return c.containsAll(coll);
3062         }
3063         public boolean removeAll(Collection<?> coll) {
3064             return c.removeAll(coll);
3065         }
3066         public boolean retainAll(Collection<?> coll) {
3067             return c.retainAll(coll);
3068         }


3074             return new Iterator<E>() {
3075                 public boolean hasNext() { return it.hasNext(); }
3076                 public E next()          { return it.next(); }
3077                 public void remove()     {        it.remove(); }};
3078         }
3079 
3080         public boolean add(E e) {
3081             typeCheck(e);
3082             return c.add(e);
3083         }
3084 
3085         private E[] zeroLengthElementArray; // Lazily initialized
3086 
3087         private E[] zeroLengthElementArray() {
3088             return zeroLengthElementArray != null ? zeroLengthElementArray :
3089                 (zeroLengthElementArray = zeroLengthArray(type));
3090         }
3091 
3092         @SuppressWarnings("unchecked")
3093         Collection<E> checkedCopyOf(Collection<? extends E> coll) {
3094             Object[] a;
3095             try {
3096                 E[] z = zeroLengthElementArray();
3097                 a = coll.toArray(z);
3098                 // Defend against coll violating the toArray contract
3099                 if (a.getClass() != z.getClass())
3100                     a = Arrays.copyOf(a, a.length, z.getClass());
3101             } catch (ArrayStoreException ignore) {
3102                 // To get better and consistent diagnostics,
3103                 // we call typeCheck explicitly on each element.
3104                 // We call clone() to defend against coll retaining a
3105                 // reference to the returned array and storing a bad
3106                 // element into it after it has been type checked.
3107                 a = coll.toArray().clone();
3108                 for (Object o : a)
3109                     typeCheck(o);
3110             }
3111             // A slight abuse of the type system, but safe here.
3112             return (Collection<E>) Arrays.asList(a);
3113         }
3114 


3470                     typeCheck(e);
3471                     i.set(e);
3472                 }
3473 
3474                 public void add(E e) {
3475                     typeCheck(e);
3476                     i.add(e);
3477                 }
3478 
3479                 @Override
3480                 public void forEachRemaining(Consumer<? super E> action) {
3481                     i.forEachRemaining(action);
3482                 }
3483             };
3484         }
3485 
3486         public List<E> subList(int fromIndex, int toIndex) {
3487             return new CheckedList<>(list.subList(fromIndex, toIndex), type);
3488         }
3489 
3490         /**
3491          * {@inheritDoc}
3492          *
3493          * @throws ClassCastException if the class of an element returned by the
3494          *         operator prevents it from being added to this collection
3495          */
3496         @Override
3497         public void replaceAll(UnaryOperator<E> operator) {
3498             list.replaceAll(e -> typeCheck(operator.apply(e)));
3499         }
3500 
3501         @Override
3502         public void sort(Comparator<? super E> c) {
3503             list.sort(c);
3504         }
3505     }
3506 
3507     /**
3508      * @serial include
3509      */
3510     static class CheckedRandomAccessList<E> extends CheckedList<E>
3511                                             implements RandomAccess
3512     {
3513         private static final long serialVersionUID = 1638200125423088369L;
3514 
3515         CheckedRandomAccessList(List<E> list, Class<E> type) {
3516             super(list, type);
3517         }
3518 
3519         public List<E> subList(int fromIndex, int toIndex) {
3520             return new CheckedRandomAccessList<>(