Casting, instanceof, and @SuppressWarnings("unchecked") are noisy. It would be nice to stuff them down into a method where they won't need to be looked at. is an attempt to do that.
is making some assumptions:
- (1) The map can't be trusted to be homogeneous
- (2) Redesigning to avoid need for casting or instanceof is not viable
- (3) Ensuring type safety in an fail early manner is more important than the performance hit
- (4) Returningis sufficient (rather than returning)
- (5) The key and value type args are not generic (like )
(1), (2) and (3) are symptoms of my work environment, beyond my control. (4) and (5) are compromises I've made because I haven't found good ways to overcome them yet.
(4) Is difficult to overcome because even if a was passed into a I haven't been able to figure out how to return a . So I return a .
(5) Is probably an inherent limitation of using . I'd love to hear alternative ideas.
Despite those limitations can you see any problems with this java 1.5 code? Am I making any assumptions I haven't identified? Is there a better way to do this? If I'm reinventing the wheel please point me to the wheel. :)
Usage code block:
Methods code block:
Some reading I found helpful:
Generic factory with unknown implementation classes
Generic And Parameterized Types
I'm also wondering if a TypeReference / super type tokens might help with (4) and (5) and be a better way to approach this problem. If you think so please post an example.
A raw type is the name of a generic class or interface without any type arguments. For example, given the generic class:
To create a parameterized type of , you supply an actual type argument for the formal type parameter :
If the actual type argument is omitted, you create a raw type of :
Therefore, is the raw type of the generic type . However, a non-generic class or interface type is not a raw type.
Raw types show up in legacy code because lots of API classes (such as the classes) were not generic prior to JDK 5.0. When using raw types, you essentially get pre-generics behavior — a gives you s. For backward compatibility, assigning a parameterized type to its raw type is allowed:
But if you assign a raw type to a parameterized type, you get a warning:
You also get a warning if you use a raw type to invoke generic methods defined in the corresponding generic type:
The warning shows that raw types bypass generic type checks, deferring the catch of unsafe code to runtime. Therefore, you should avoid using raw types.
The Type Erasure section has more information on how the Java compiler uses raw types.
Unchecked Error Messages
As mentioned previously, when mixing legacy code with generic code, you may encounter warning messages similar to the following:
This can happen when using an older API that operates on raw types, as shown in the following example:
The term "unchecked" means that the compiler does not have enough type information to perform all type checks necessary to ensure type safety. The "unchecked" warning is disabled, by default, though the compiler gives a hint. To see all "unchecked" warnings, recompile with .
Recompiling the previous example with reveals the following additional information:
To completely disable unchecked warnings, use the flag. The annotation suppresses unchecked warnings. If you are unfamiliar with the syntax, see Annotations.
« Previous • Trail • Next »