8203670: unmodifiable List iterator() implementations should not be ListIterators
Reviewed-by: redestad, igerasim, plevart
--- 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) { }
+ }
}