8203670: unmodifiable List iterator() implementations should not be ListIterators
authorsmarks
Tue, 26 Jun 2018 19:45:59 -0700
changeset 50809 6ff774d73176
parent 50808 7ea794b6ead6
child 50810 0358dad944c7
8203670: unmodifiable List iterator() implementations should not be ListIterators Reviewed-by: redestad, igerasim, plevart
src/java.base/share/classes/java/util/ImmutableCollections.java
test/jdk/java/util/List/ListFactories.java
--- a/src/java.base/share/classes/java/util/ImmutableCollections.java	Wed Jun 27 09:44:46 2018 +0800
+++ b/src/java.base/share/classes/java/util/ImmutableCollections.java	Tue Jun 26 19:45:59 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -213,16 +213,23 @@
         @Stable
         private final int size;
 
+        @Stable
+        private final boolean isListIterator;
+
         private int cursor;
 
         ListItr(List<E> list, int size) {
-            this(list, size, 0);
+            this.list = list;
+            this.size = size;
+            this.cursor = 0;
+            isListIterator = false;
         }
 
         ListItr(List<E> list, int size, int index) {
             this.list = list;
             this.size = size;
             this.cursor = index;
+            isListIterator = true;
         }
 
         public boolean hasNext() {
@@ -245,10 +252,16 @@
         }
 
         public boolean hasPrevious() {
+            if (!isListIterator) {
+                throw uoe();
+            }
             return cursor != 0;
         }
 
         public E previous() {
+            if (!isListIterator) {
+                throw uoe();
+            }
             try {
                 int i = cursor - 1;
                 E previous = list.get(i);
@@ -260,10 +273,16 @@
         }
 
         public int nextIndex() {
+            if (!isListIterator) {
+                throw uoe();
+            }
             return cursor;
         }
 
         public int previousIndex() {
+            if (!isListIterator) {
+                throw uoe();
+            }
             return cursor - 1;
         }
 
--- a/test/jdk/java/util/List/ListFactories.java	Wed Jun 27 09:44:46 2018 +0800
+++ b/test/jdk/java/util/List/ListFactories.java	Tue Jun 26 19:45:59 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.ListIterator;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -357,4 +358,15 @@
     public void copyOfRejectsNullElements() {
         List<Integer> list = List.copyOf(Arrays.asList(1, null, 3));
     }
+
+    @Test
+    public void iteratorShouldNotBeListIterator() {
+        List<Integer> list = List.of(1, 2, 3, 4, 5);
+        Iterator<Integer> it = list.iterator();
+        it.next();
+        try {
+            ((ListIterator<Integer>) it).previous();
+            fail("ListIterator operation succeeded on Iterator");
+        } catch (ClassCastException|UnsupportedOperationException ignore) { }
+    }
 }