JDK-6515694 : (coll) Arrays.ArrayList.toArray() does not return Object[] always
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:collections
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-01-22
  • Updated: 2013-09-18
  • Resolved: 2007-01-22
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)

A DESCRIPTION OF THE PROBLEM :
Javadoc for Collection<E>.toArray<T>(T []) states that toArray(new Object[0]) is identical in function to toArray(). However Arrays.ArrayList.toArray() may return array that is not of type Object[]. This may cause unexpected ArrayStoreException.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
compile and run attached source code

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
class [Ljava.lang.Object;

ACTUAL -
class [Ljava.lang.String;
Exception in thread "main" java.lang.ArrayStoreException: java.lang.Object
        at Main.main(Main.java:7)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.*;

public class Main {
	public static void main(String[] args) {
		Object[] array = Arrays.asList("A").toArray();
		System.out.println(array.getClass());
		array[0] = new Object(); // cause ArrayStoreException
	}
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
use toArray(new Object[0])

Comments
I'm testing with @Override public Object[] toArray() { return Arrays.copyOf(a, a.length, Object[].class); } to see what, if anything, breaks. It may be best just to bite the bullet and fix this.
18-09-2013

The workaround Martin suggests isn't appropriate because Arrays.asList is intended to provide a view onto the array.
18-09-2013

WORK AROUND Here's the java.util.ArrayList(Collection) constructor: public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); size = elementData.length; // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); }
22-01-2007

EVALUATION The submitter is correct. The current behavior is a clear spec violation. This is a duplicate of 6260652: (coll) Arrays.asList(x).toArray().getClass() should be Object[].class which has a known fix. Unfortunately, Sun chose not to fix 6260652, for fear of breaking existing applications. Filing an escalation might change Sun's mind.
22-01-2007