Good question. Regarding your added question about why casting as (T[]) gives a warning--the JVM can indeed check if an array is, say, of type String[] in runtime, but it can't check if it's of type T[] because it doesn't know what T is.
To elaborate on Dave's response to your original question:
I find the first response here to be rather concise and well-written (I believe it to be by Neal Gafter, one of the Java gurus at Sun until recently):
http://forum.java.sun.com/thread.jspa?forumID=316&threadID=457033(note: 'statically' means during compile-time, and 'dynamically' means during run-time)
Notice the reason he writes "BOOM!" on the last line of code.
1. If generic arrays were allowed, everything until that line would work--even
oa[0] = new Box<Integer>(3);!. That's because Java checks if this assignment is valid dynamically, and at runtime, oa points to a Box[] (remember generic type information is lost), and you're assigning a Box to it, so all's good.
2. If the JVM were able to determine that the assignment was invalid (e.g. if you try to put an Integer in an array of runtime type String[]), it would perform the well-specified behavior of throwing an ArrayStoreException, but here this error would be missed, and you'd have a vicious problem on the final line.
Notice another difference between arrays and classes is that the generic List equivalent of
Object[] oa = bsa; gives a compile error (i.e. you can't assign a List<Box<String>> to a List<Object>). That allows the compiler to statically check the type safety of generic class operations.
The post mentions a proposal to introduce variance on arrays in Java; here's a draft of such a proposal
http://www.daimi.au.dk/~plesner/variance/docs/variance-whitepaper.pdf. See section 3.
Casting is not necessarily bad, but you might want to reconsider if it is really best to use an array for whatever you are doing. Speak with your TA about your particular case.