4802647: Throw required NPEs from removeAll()/retainAll()
authormduigou
Tue, 07 May 2013 12:05:52 -0700
changeset 17441 5ae43433d158
parent 17440 fb37aa6b305e
child 17442 1444a769a68a
child 17477 09aab50cf738
4802647: Throw required NPEs from removeAll()/retainAll() Reviewed-by: mduigou, chegar, dholmes Contributed-by: Brandon Passanisi <brandon.passanisi@oracle.com>
jdk/src/share/classes/java/util/AbstractCollection.java
jdk/src/share/classes/java/util/AbstractSet.java
jdk/src/share/classes/java/util/ArrayList.java
jdk/test/java/util/Collection/MOAT.java
--- a/jdk/src/share/classes/java/util/AbstractCollection.java	Tue May 07 11:31:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/AbstractCollection.java	Tue May 07 12:05:52 2013 -0700
@@ -368,6 +368,7 @@
      * @see #contains(Object)
      */
     public boolean removeAll(Collection<?> c) {
+        Objects.requireNonNull(c);
         boolean modified = false;
         Iterator<?> it = iterator();
         while (it.hasNext()) {
@@ -401,6 +402,7 @@
      * @see #contains(Object)
      */
     public boolean retainAll(Collection<?> c) {
+        Objects.requireNonNull(c);
         boolean modified = false;
         Iterator<E> it = iterator();
         while (it.hasNext()) {
--- a/jdk/src/share/classes/java/util/AbstractSet.java	Tue May 07 11:31:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/AbstractSet.java	Tue May 07 12:05:52 2013 -0700
@@ -166,6 +166,7 @@
      * @see #contains(Object)
      */
     public boolean removeAll(Collection<?> c) {
+        Objects.requireNonNull(c);
         boolean modified = false;
 
         if (size() > c.size()) {
--- a/jdk/src/share/classes/java/util/ArrayList.java	Tue May 07 11:31:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/ArrayList.java	Tue May 07 12:05:52 2013 -0700
@@ -671,6 +671,7 @@
      * @see Collection#contains(Object)
      */
     public boolean removeAll(Collection<?> c) {
+        Objects.requireNonNull(c);
         return batchRemove(c, false);
     }
 
@@ -691,6 +692,7 @@
      * @see Collection#contains(Object)
      */
     public boolean retainAll(Collection<?> c) {
+        Objects.requireNonNull(c);
         return batchRemove(c, true);
     }
 
--- a/jdk/test/java/util/Collection/MOAT.java	Tue May 07 11:31:08 2013 -0700
+++ b/jdk/test/java/util/Collection/MOAT.java	Tue May 07 12:05:52 2013 -0700
@@ -26,6 +26,7 @@
  * @bug     6207984 6272521 6192552 6269713 6197726 6260652 5073546 4137464
  *          4155650 4216399 4294891 6282555 6318622 6355327 6383475 6420753
  *          6431845 4802633 6570566 6570575 6570631 6570924 6691185 6691215
+ *          4802647 7123424
  * @summary Run many tests on many Collection and Map implementations
  * @author  Martin Buchholz
  * @run main MOAT
@@ -58,6 +59,8 @@
 public class MOAT {
     public static void realMain(String[] args) {
 
+        testCollection(new NewAbstractCollection<Integer>());
+        testCollection(new NewAbstractSet<Integer>());
         testCollection(new LinkedHashSet<Integer>());
         testCollection(new HashSet<Integer>());
         testCollection(new Vector<Integer>());
@@ -753,6 +756,14 @@
         // The "all" operations should throw NPE when passed null
         //----------------------------------------------------------------
         {
+            clear(c);
+            try {
+                c.removeAll(null);
+                fail("Expected NullPointerException");
+            }
+            catch (NullPointerException e) { pass(); }
+            catch (Throwable t) { unexpected(t); }
+
             oneElement(c);
             try {
                 c.removeAll(null);
@@ -761,6 +772,14 @@
             catch (NullPointerException e) { pass(); }
             catch (Throwable t) { unexpected(t); }
 
+            clear(c);
+            try {
+                c.retainAll(null);
+                fail("Expected NullPointerException");
+            }
+            catch (NullPointerException e) { pass(); }
+            catch (Throwable t) { unexpected(t); }
+
             oneElement(c);
             try {
                 c.retainAll(null);
@@ -1205,4 +1224,35 @@
     static <T> T serialClone(T obj) {
         try { return (T) readObject(serializedForm(obj)); }
         catch (Exception e) { throw new Error(e); }}
+    private static class NewAbstractCollection<E> extends AbstractCollection<E> {
+        ArrayList<E> list = new ArrayList<>();
+        public boolean remove(Object obj) {
+            return list.remove(obj);
+        }
+        public boolean add(E e) {
+            return list.add(e);
+        }
+        public Iterator<E> iterator() {
+            return list.iterator();
+        }
+        public int size() {
+            return list.size();
+        }
+    }
+    private static class NewAbstractSet<E> extends AbstractSet<E> {
+        HashSet<E> set = new HashSet<>();
+        public boolean remove(Object obj) {
+            return set.remove(obj);
+        }
+        public boolean add(E e) {
+            return set.add(e);
+        }
+        public Iterator<E> iterator() {
+            return set.iterator();
+        }
+        public int size() {
+            return set.size();
+        }
+    }
+
 }