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

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

@@ -3029,25 +3029,24 @@
         private static final long serialVersionUID = 1578914078182001775L;
 
         final Collection<E> c;
         final Class<E> type;
 
-        void typeCheck(Object o) {
+        E typeCheck(Object o) {
             if (o != null && !type.isInstance(o))
                 throw new ClassCastException(badElementMsg(o));
+            return (E) 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;
+            this.c = Objects.requireNonNull(c, "c");
+            this.type = Objects.requireNonNull(type, "type");
         }
 
         public int size()                 { return c.size(); }
         public boolean isEmpty()          { return c.isEmpty(); }
         public boolean contains(Object o) { return c.contains(o); }

@@ -3089,11 +3088,11 @@
                 (zeroLengthElementArray = zeroLengthArray(type));
         }
 
         @SuppressWarnings("unchecked")
         Collection<E> checkedCopyOf(Collection<? extends E> coll) {
-            Object[] a = null;
+            Object[] a;
             try {
                 E[] z = zeroLengthElementArray();
                 a = coll.toArray(z);
                 // Defend against coll violating the toArray contract
                 if (a.getClass() != z.getClass())

@@ -3485,14 +3484,21 @@
 
         public List<E> subList(int fromIndex, int toIndex) {
             return new CheckedList<>(list.subList(fromIndex, toIndex), type);
         }
 
+        /**
+         * {@inheritDoc}
+         *
+         * @throws ClassCastException if the class of an element returned by the
+         *         operator prevents it from being added to this collection
+         */
         @Override
         public void replaceAll(UnaryOperator<E> operator) {
-            list.replaceAll(operator);
+            list.replaceAll(e -> typeCheck(operator.apply(e)));
         }
+
         @Override
         public void sort(Comparator<? super E> c) {
             list.sort(c);
         }
     }