When you load a class dynamically through reflection, you're not going to escape having to do some casts, since the compiler doesn't know what the type of the class is that you're going to load at runtime, so it can't check the types.
In your second solution you are using the raw type Validator (a raw type is a generic type where you don't specify the type arguments). Don't use raw types - the only reason raw types exist is for compatibility with old Java code (from Java 1.4 and older, when generics didn't yet exist in the language), and you shouldn't use raw types in new code.
So, let's look at your first solution. That doesn't work, because you use Validator<?> and you can't pass that a Map<String, ?>, because the compiler can't be sure that the "?" you used for Validator stands for the same type as you used for the "?" in the Map.
You probably made this mistake because of a common misunderstanding about generic wildcards: Validator<?> does not mean: a Validator that I can pass any kind of object to. It means: a Validator that needs objects of some specific, but unknown type. You can't pass anything to the validate() method because the compiler doesn't know what the unknown type is.
If you know the type in advance, you can cast the Validator with the right type:
This will still give you a warning ("unchecked cast"), which you can optionally suppress:
If you don't know the type in advance, then you can cast to Validator<Object>.
Campbell Ritchie wrote:Please tell us what the book says; the original poster (=OP) might not have access to it.
Well, I am still too much a beginner but I will give my best in trying to explain -
because I think, that my exposure of a possible misunderstanding will help me
as well. So please correct me - I am very thankful if I can learn something
As far as I understand it ...
The idea of wild cards is described earlier in the book is really important
to understand this problem here as already described by Jesper. What the
book explains is the following:
The wild card is NO type parameter, it is an actual type parameter
(as Joshua Bloch would name it, or a specialized type argument (as Angelika Langer would name it): The specialization is called wild
card type, what is probably not a good name for it (cause it is already
an "instantiation"). So as Jesper already said, the wildcard (?) stands for
the information: there exists an unknown type Tx for the given generic type
that makes it (the imagined parameterized generic type) a valid reference to the given
e.g. having List<?> list (that is nothing than List<? extends Object>) says
There exists one Tx out of T, for that List<Tx> is a valid parameterized type to the provided object. But Tx is unknown to the compiler - it just knows, that the list
contains only Tx type elements.
And now the first very important consequence: Each ? of the declarations generates
one separate compiler capture. This is I think, what Jesper said, when telling
the compiler can't be sure that the "?" you used for Validator stands for
the same type as you used for the "?" in the Map
But the example above has another speciality. The documentation of the
newInstance() claims to return T. This is different to the java.lang.reflect.Array.newInstance()
method, that claims to return Object (no, not Object as one would assume) -
this because of primitive type arrays that need to be treated also in this case.
Both variants need to be casted to the actual parameterized type - and this is an
unchecked (and therefore evil (holy me ;) cast). The point here is parameterized,
because at runtime this information is gone, so the given back instance is just
that one reflected by the class object - so in Petar's example, the Validator.
From the design point of view the book tells us, that in cast of unchecked casts, stay with
the rule of truth in advertising, that is:
The reified type of an array must be a subtype of the erasure of the static type
meaning, when using reflection whatever, make sure, that the function delivering the reference
to an object has the type of the instance. Inside this function you need to use unchecked casts,
what means *danger* but is necessary in case you want to develop e.g. a toArray method that
takes a List<Type> and gives back an array Type.
Uff ... so .. and please now slaughter ... for sure I missed something or used somewhere a
wrong terminus technicus.
Cheers and have a nice evening,
This tiny ad is guaranteed to be gluten free.
Free, earth friendly heat - from the CodeRanch trailboss