[jdom-interest] How will JDOM be updated for Java Generics (JDK 1.5)?

Geoff Rimmer geoff.rimmer at sillyfish.com
Sat Jul 20 06:43:26 PDT 2002


Michael Salmon <ms at formulae.org> writes:
>
> I do not agree with adding Generics to Java. Let me list many of my
> reasons.
>
> Java is stable, changes to the syntax and use of the language
> assumes that something is wrong with the existing language. Don't
> fix what aint broke.
>
> Generics dont accomplish anything that you couldnt do with Java
> already.

The main benefit of generics for me is the compile-time type safety;
not only for simple types like:

    List<String>

but also for complex types like:

    Map<String,List<Map<String,String>>> map;

which you would *traditionally* iterate as follows:

    for ( Iterator iter1 = map.entrySet().iterator(); iter1.hasNext(); )
    {
        Map.Entry entry1 = (Map.Entry)iter1.next();
        String key1 = (String)entry1.getKey();
        List list = (List)entry1.getValue();
        
        for ( Iterator iter2 = list.iterator(); iter2.hasNext(); )
        {
            Map map2 = (Map)iter2.next();
            for ( Iterator iter3 = map2.entrySet().iterator();
                  iter3.hasNext(); )
            {
                Map.Entry entry3 = (Map.Entry)iter3.next();
                String key3 = (String)entry3.getKey();
                String value3 = (String)entry3.getValue();
            }
        }
    }

Now, the above code contains 7 casts which will only be checked at
runtime.  If there are any mistakes in the casting, you might not
found out about it for weeks.

The generics version looks like this:
            
    for ( Iterator<Map.Entry<String,List<Map<String,String>>>> iter1
          = map.entrySet().iterator(); iter1.hasNext(); )
    {
        Map.Entry<String,List<Map<String,String>>> entry1 = iter1.next();
        String key1 = entry1.getKey();
        List<Map<String,String>> list = entry1.getValue();
        
        for ( Iterator<Map<String,String> iter2 = list.iterator();
              iter2.hasNext(); )
        {
            Map<String,String> map2 = iter2.next();
            for ( Iterator<Map.Entry<String,String>> iter3
                  = map2.entrySet().iterator(); iter3.hasNext(); )
            {
                Map.Entry<String,String> entry3 = iter3.next();
                String key3 = entry3.getKey();
                String value3 = entry3.getValue();
            }
        }
    }

and if any of the parameterised types was incorrect, the compiler
would refuse to even generate the .class file.  This is without doubt
a major benefit for code maintenance.

I understand there are also proposals to introduce a 'foreach'
construct, which would make the code look something like this:

    for ( entry1 : map.entrySet() )
    {
        String key1 = entry1.getKey();
        for ( map2 : entry1.getValue() )
        {
            for ( entry3 : map2.entrySet() )
            {
                String key3 = entry3.getKey();
                String value3 = entry3.getValue();
            }
        }
    }

> It is very easy to subclass the list type you want to allow only
> particular types of values for.

Erm, which is easier out of these two?

1. List<Fish> fishList = new ArrayList<Fish>();

2. public class FishList extends ArrayList
   {
       public FishList() {}
       public FishList( Collection c ) { super( c ); }
       public FishList( int initialCapacity ) { super( initialCapacity ); }
       public Fish[] toArray( Fish[] a ) { return (Fish[])super.toArray( a ); }
       public boolean add( Fish f ) { return super.add( f ); }
       public void add( int i, Fish f ) { return super.add( i, f ); }
       public Fish getFish( int i ) { return (Fish)super.getFish( i ); }
       public Fish remove( int i ) { return (Fish)super.remove( i ); }
       public Fish set( int i, Fish f ) { return (Fish)super.set( i, f ); }
   }

   FishList fishList = new FishList();

You would have to write one of these classes for every new type that
comes along.  A maintenance nightmare.  Note also that creating a
"type-safe" List by extending ArrayList is not safe, as you can still
bypass the "type-safe" methods you have introduced, and to call the
base class methods instead (with the wrong types).

> Is changing the language really going to make it any easier for
> everyone?

It certainly is if they use generics sensibly (and not just do
List<Object>, Map<Object,Object> etc, which would defeat the point).

> I strongly disagree to adding generics code to jdom until; its
> released in the jdk, has full backwards compatibility and most
> people seem to understand how they would use it properly and also
> how they can accomplish the same thing without it.

I would say that JDOM should probably not contain any Generics code
(parameterised types) until the first beta of 1.5 is released; but
that does not stop the JDOM developers from doing some preparatory
changes *now* in readiness for when 1.5 is released.  For example the
two I mentioned in my earlier post: creating a Node interface, and
changing the way filters work.

> I dont want to support Java changing things like PERL does whenever
> someone comes up with some "bright idea".

Generics are not just some new trendy idea that happens to be in
favour at the moment; their equivalent in C++ (Templates) has been
around for years, with proven success.

-- 
Geoff Rimmer <> geoff.rimmer at sillyfish.com <> www.sillyfish.com
www.sillyfish.com/phone - Make savings on your BT and Telewest phone calls
UPDATED 07/06/2002: 521 destinations, 14 schemes (incl. 10p/min to mobiles)



More information about the jdom-interest mailing list