JDK-5048399 : (coll) please fix anachronisms in collections internal generification
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.util:collections
  • Affected Version: 5.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: solaris_8
  • CPU: generic
  • Submitted: 2004-05-17
  • Updated: 2012-10-08
  • Resolved: 2005-09-04
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availabitlity Release.

To download the current JDK release, click here.
JDK 6
6 b51Fixed
Description
The collections implementations are a template of our suggested practices
for people writing generic code or generifying their existing code, so it
should be as clean as possible both externally and internally.

======================================================
Date: Mon, 17 May 2004 09:38:01 -0700
From: ###@###.###
Subject: Re: Double fisted casting?
To: ###@###.###
Cc: ###@###.###

###@###.### wrote:
> 
>> My code wouldn't compile without the double cast.
>>
>> Note that the code below is YOUR code, that I just found in the 
>> library sources. It wouldn't compile without the double cast either.
>>  
>>
> It's Sun's code, but I believe ###@###.### parameterized it.  That's why I 
> asked him about the double cast.

OK, there are two things going on here.

First, the double cast is necessary because doing it as a single cast would 
provoke a compile-time error.  The compile-time error is correct: the compiler 
has detected a cast from one type (EntrySet) to another (Set<Map.Entry<K,V>>) 
that could not ever be correct (because EntrySet extends a different, 
non-parameterized version of Set).  The double cast hides from the compiler the 
fact that we are doing a cast that is not merely unsafe, but incorrect.

So why do we have an incorrect cast in the code?  The answer is: it was added to 
work around a compiler bug that has long since been fixed.  The following code 
in HashMap.java:

     public Set<Map.Entry<K,V>> entrySet() {
         Set<Map.Entry<K,V>> es = entrySet;
         return (es != null ? es : (entrySet = (Set<Map.Entry<K,V>>) (Set) new 
EntrySet()));
     }

     private class EntrySet extends AbstractSet/*<Map.Entry<K,V>>*/ {
         public Iterator/*<Map.Entry<K,V>>*/ iterator() {
             return newEntryIterator();
         }
         public boolean contains(Object o) {
             if (!(o instanceof Map.Entry))
                 return false;
             Map.Entry<K,V> e = (Map.Entry<K,V>) o;
             Entry<K,V> candidate = getEntry(e.getKey());
             return candidate != null && candidate.equals(e);
         }
         public boolean remove(Object o) {
             return removeMapping(o) != null;
         }
         public int size() {
             return size;
         }
         public void clear() {
             HashMap.this.clear();
         }
     }

should be replaced by its correct version:

     public Set<Map.Entry<K,V>> entrySet() {
         Set<Map.Entry<K,V>> es = entrySet;
         return (es != null ? es : (entrySet = new EntrySet()));
     }

     private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
         public Iterator<Map.Entry<K,V>> iterator() {
             return newEntryIterator();
         }
         public boolean contains(Object o) {
             if (!(o instanceof Map.Entry))
                 return false;
             Map.Entry<K,V> e = (Map.Entry<K,V>) o;
             Entry<K,V> candidate = getEntry(e.getKey());
             return candidate != null && candidate.equals(e);
         }
         public boolean remove(Object o) {
             return removeMapping(o) != null;
         }
         public int size() {
             return size;
         }
         public void clear() {
             HashMap.this.clear();
         }
     }

However, since this is all private code, and we are past Tiger beta2 freeze, 
there is not sufficient urgency to do it now.  You'll find a number of 
anachronisms hiding inside the implementation of collections due to recent 
language changes, and I hope we have the time to address them soon after Tiger.

###@###.###


Comments
EVALUATION In progress. ###@###.### 2004-05-18 Will be integrated as part of jsr166x improvements. ###@###.### 2005-05-10 18:07:24 GMT
2004-05-18