Obviously, the difference is that no cast is required in the last (working) example.
Can someone tell me what's going on here? Why doesn't the cast work? And is there any way to do this with ArrayList's built-in toArray function (which I believe requires a cast in any case)?
There are two overloaded versions of the Collection.toArray() method. The default one (no parameters) return everything in an Object array. An object array can hold any type of objects. However, just because all the items in the array are menu item objects, doesn't make the array a menu item array -- it is still an object array.
The other overloaded method is what you need. It takes an array that it will either use directly, or create another by type, and return an object array that IS-A type of array that you want. Basically....