[Fwd: Code review request: 7072353 JNDI libraries do not build with javac -Xlint:all -Werror]
Joe Darcy
joe.darcy at oracle.com
Thu Aug 4 02:33:44 UTC 2011
David Holmes wrote:
> Joe Darcy said the following on 08/04/11 02:24:
>> On 8/3/2011 12:42 AM, David Holmes wrote:
>>> Alexandre Boulgakov said the following on 08/03/11 04:44:
>>>> On 8/2/2011 2:19 AM, Xuelei Fan wrote:
>>>>> 3017 Vector<Object> temp = (Vector)extractURLs(res.errorMessage);
>>>>> You may not need the conversion any more, the return value of
>>>>> extractURLs() has been updated to
>>>>> 2564 private static Vector<String> extractURLs(String
>>>>> refString)
>>>> The cast is needed to go from Vector<String> to Vector<Object>.
>>>
>>> Raw types should be avoided (here and elsewhere there are casts to
>>> raw Vector). I'm surprised (generics continue to surprise me) that
>>> despite all our advances in type-inference etc that the compiler can
>>> not tell that a Vector<T> is-a Vector<Object>. :(
>>
>> That is because in general a Vector<T> is not a Vector<Object>
>> because of the way subtyping works. As with arrays, it all looks
>> fine until you want to change the container; consider
>>
>> Vector<String> vs = new Vector<>();
>> ...
>> Vector<Object> vo = vs; // Assume this was okay to alias an object
>> vector and a string vector
>>
>> vo.add(new Integer(1)); // Add an Integer to a list of strings, boom!
>
> I see what you are saying but with arrays the boom would be an
> ArrayStoreException would it not? So the problem here is that there is
> no runtime checking for generics that could do the same. So we have to
> disallow this.
Exactly; since arrays are reified so the VM has the information needed
to check for an errant store and when appropriate throw the
ArrayStoreException. Since generics are implemented via erasure, the
analogous information is not available at runtime for collections. Note
that the behavior of arrays is statically unsafe and requires the
runtime check.
>
>> Using wildcards makes the subtyping work along the type argument axis.
>
> So what is the right fix here? To declare the underlying Vector as a
> Vector<?> and cast it to something concrete when needed? It seems very
> wrong to me to be inserting raw type casts all through this code.
It isn't entirely clear to be from a quick inspection of the code what
the actual type usage is. A writable general Vector should be a
Vector<Object> and Vector just meant for reading should be a Vector<?>
(or the equivalent Vector<? extends Object>).
If the type usage is "a sequence of X's and Y's" where X and Y don't
have some useful supertype, I would recommend using a somewhat different
set of data structures, like a list of type-safe heterogeneous
containers or a list of a new package-level XorY class.
-Joe
More information about the core-libs-dev
mailing list