8203184: List.copyOf() fails to copy sublists
authorsmarks
Thu, 21 Jun 2018 08:45:57 -0700
changeset 50698 c1f7ece09b84
parent 50697 3ef0862bbb3d
child 50699 cc7fc46cc8c1
child 50825 aa0a35b071fb
8203184: List.copyOf() fails to copy sublists Reviewed-by: psandoz
src/java.base/share/classes/java/util/ImmutableCollections.java
src/java.base/share/classes/java/util/List.java
test/jdk/java/util/List/ListFactories.java
--- a/src/java.base/share/classes/java/util/ImmutableCollections.java	Thu Jun 21 08:25:03 2018 -0700
+++ b/src/java.base/share/classes/java/util/ImmutableCollections.java	Thu Jun 21 08:45:57 2018 -0700
@@ -83,6 +83,16 @@
 
     // ---------- List Implementations ----------
 
+    // make a copy, short-circuiting based on implementation class
+    @SuppressWarnings("unchecked")
+    static <E> List<E> listCopy(Collection<? extends E> coll) {
+        if (coll instanceof AbstractImmutableList && coll.getClass() != SubList.class) {
+            return (List<E>)coll;
+        } else {
+            return (List<E>)List.of(coll.toArray());
+        }
+    }
+
     @SuppressWarnings("unchecked")
     static <E> List<E> emptyList() {
         return (List<E>) ListN.EMPTY_LIST;
--- a/src/java.base/share/classes/java/util/List.java	Thu Jun 21 08:25:03 2018 -0700
+++ b/src/java.base/share/classes/java/util/List.java	Thu Jun 21 08:45:57 2018 -0700
@@ -1057,12 +1057,7 @@
      * @throws NullPointerException if coll is null, or if it contains any nulls
      * @since 10
      */
-    @SuppressWarnings("unchecked")
     static <E> List<E> copyOf(Collection<? extends E> coll) {
-        if (coll instanceof ImmutableCollections.AbstractImmutableList) {
-            return (List<E>)coll;
-        } else {
-            return (List<E>)List.of(coll.toArray());
-        }
+        return ImmutableCollections.listCopy(coll);
     }
 }
--- a/test/jdk/java/util/List/ListFactories.java	Thu Jun 21 08:25:03 2018 -0700
+++ b/test/jdk/java/util/List/ListFactories.java	Thu Jun 21 08:45:57 2018 -0700
@@ -48,7 +48,7 @@
 
 /*
  * @test
- * @bug 8048330
+ * @bug 8048330 8203184
  * @summary Test convenience static factory methods on List.
  * @run testng ListFactories
  */
@@ -330,6 +330,24 @@
         assertSame(copy1, copy2);
     }
 
+    @Test
+    public void copyOfSubList() {
+        List<Integer> orig = List.of(0, 1, 2, 3);
+        List<Integer> sub = orig.subList(0, 3);
+        List<Integer> copy = List.copyOf(sub);
+
+        assertNotSame(sub, copy);
+    }
+
+    @Test
+    public void copyOfSubSubList() {
+        List<Integer> orig = List.of(0, 1, 2, 3);
+        List<Integer> sub = orig.subList(0, 3).subList(0, 2);
+        List<Integer> copy = List.copyOf(sub);
+
+        assertNotSame(sub, copy);
+    }
+
     @Test(expectedExceptions=NullPointerException.class)
     public void copyOfRejectsNullCollection() {
         List<Integer> list = List.copyOf(null);