Wow; I think I figured out the answer to my own question. I'm just not sure it's worth it! :)
The problem is the cast isn't checked. So, you have to check it yourself. You can't just check a parameterized type with instanceof, because the parameterized type information is unavailable at runtime, having been erased at compile time.
But, you can perform a check on each and every item in the hash, with instanceof, and in doing so, you can construct a new hash that is type-safe. And you won't provoke any warnings.
Thanks to mmyers and Esko Luontola, I've parameterized the code I originally wrote here, so it can be wrapped up in a utility class somewhere and used for any parameterized HashMap. If you want to understand it better and aren't very familiar with generics, I encourage viewing the edit history of this answer.
That's a lot of work, possibly for very little reward... I'm not sure if I'll use it or not. I'd appreciate any comments as to whether people think it's worth it or not. Also, I'd appreciate improvement suggestions: is there something better I can do besides throw AssertionErrors? Is there something better I could throw? Should I make it a checked Exception?
In this case, it is perfectly okay to suppress the unchecked cast warning.
It's an unchecked cast because is not known at runtime. So the runtime check can only check the cast up to (the erasure of ), but not actually up to itself. (So for example, if were , then if the object's actual runtime class was , it would not be caught by the check even though it's not .)
returns , and not (where would be the type argument of the parameter), because it can be used to create both arrays of primitives and arrays of references. Type variables like cannot represent primitive types, and the only supertype of array-of-primitive types is . objects representing primitive types are parameterized with its wrapper class as the type parameter, e.g. has type . But if you pass to , you will create an , not (which would be ). But if you pass a representing a reference type, will return an .
So basically, calling with a will always return either an , or an array of primitives. An array-of-primitives type is not a subtype of , so it would fail a runtime check for . In other words, if the result is an , it is guaranteed to be an . So even though this cast only checks up to at runtime, and it doesn't check the part from up to , in this case, the check up to is sufficient to guarantee that it is an , and so the unchecked part is not an issue in this case, and it is effectively a fully checked cast.
By the way, from the code you have shown, you do not need to pass a class object to initialize or to use . That would only be necessary if your class actually used the class at runtime. But it doesn't. All it does is create an array (that is not exposed to the outside of the class), and get elements from it. That can be achieved using an . You just need to cast to when you take an element out (which is unchecked by which we know to be safe if we only put s into it):