Java
  Home arrow Java arrow Page 3 - Generics of Java 1.5 Tiger
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
JAVA

Generics of Java 1.5 Tiger
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 16
    2005-05-26

    Table of Contents:
  • Generics of Java 1.5 Tiger
  • Using Type-Safe Maps
  • Iterating Over Parameterized Types
  • Accepting Parameterized Types as Arguments
  • Returning Parameterized Types
  • Checking for Lint
  • Generics and Type Conversions
  • Using Type Wildcards
  • Writing Generic Types
  • Restricting Type Parameters

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Generics of Java 1.5 Tiger - Iterating Over Parameterized Types


    (Page 3 of 10 )

    Although the for/in loop provides a means of almost completely avoiding the java.util.Iterator class, that particular feature of Tiger isn’t covered until Chapter 7. But until you get to that chapter (and probably occasionally after that), it’s still useful to know how generic collection types affect Iterator. You’ll need to perform an extra step to get the full power of generics.

    How do I do that?

    It would seem that once you’ve parameterized your collections, grabbing an Iterator and using it would be trivial:

      List<String> listOfStrings = new LinkedList<String>();
      listOfStrings.add("Happy");
      listOfStrings.add("Birthday");
      listOfStrings.add("To");
      listOfStrings.add("You");
      for (Iterator i = listOfStrings.iterator(); i.hasNext(); ) {
        String s = i.next();
        out.println(s);
      }

    However, all is not well. Here’s what the compiler spits back to you:

      [javac] code\src\com\oreilly\tiger\ch02\GenericsTester.java:54:
                incompatible types
      [javac] found : java.lang.Object
      [javac] required: java.lang.String
      [javac]     String s = i.next();
      [javac]                      ^
      [javac] Note: code\src\com\oreilly\tiger\ch02\GenericsTester.java
                uses unchecked or unsafe operations.
      [javac] Note: Recompile with -Xlint:unchecked for details.
      [javac] 1 error

    The problem here is that while you’ve parameterized your List, you haven’t parameterized your Iterator. It’s still spitting out Objects, and doesn’t know that it should only expect to receive and respond with String types. Just like the collections, Iterator is a generic type in Java, and is declared as public interface Iterator<E>. Its next() method, then, returns E (which is a placeholder, as detailed in “Using Type-Safe Lists“). To parameterize it, you use the same syntax as you did for collection classes:

      List<String> listOfStrings = new LinkedList<String>();
      listOfStrings.add("Happy");
      listOfStrings.add("Birthday");
      listOfStrings.add("To");
      listOfStrings.add("You");
      for (Iterator<String> i = listOfStrings.iterator(); i.hasNext(); ) {
        String s = i.next();
        out.println(s);
      }

    Now this Iterator only works with String types, and your code compiles (and runs) normally. You should always pair your Iterators with your collections like this—if the collection is parameterized, the Iterator should use the same parameter.

    What about...

    ...if you define a typesafe Iterator, for a collection that isn’t typesafe. Well, you’re basically playing with fire, and assuming that someone filled the collection correctly. The following code, for example, compiles and runs without a problem (although you’ll get lint warnings, detailed in “Checking for Lint“:

      public void testTypeSafeIterators(PrintStream out) throws IOException {
        List listOfStrings = new LinkedList();  
        listOfStrings.add("Happy");
        listOfStrings.add("Birthday");
        listOfStrings.add("To");
       
    listOfStrings.add("You");
        for (Iterator<String> i = listOfStrings.iterator(); i.hasNext(); ) {
          String s = i.next();
          out.println(s);
        }
      }

    In this case, it was probably just an oversight that List wasn’t also parameterized. However, the following code also compiles fine, but fails horribly at runtime:

      public void testTypeSafeIterators(PrintStream out) throws IOException {
        List listOfStrings = getList();
        for (Iterator<String> i = listOfStrings.iterator(); i.hasNext(); ) {
          String s = i.next();
          out.println(s);
        }
      }
      private List getList() {
        List list = new LinkedList();
        list.add(3);
        list.add("Blind");
        list.add("Mice");
        return list;
      }

    The getList() method, which presumably could have been coded by a trusted (or even a non-trusted) source, is supposed to return only String objects (at least, that’s inferred by the use of Iterator<String>). However, it adds a numeric object (an int that gets boxed into an Integer), and at runtime a nasty ClassCastException pops up. This is why you should always parameterize your collections if you want to parameterize your Iterators. If you took that step, you’d get an error at compile-time when trying to assign the List returned from getList() (which is not parameterized) to a List<String>. That error protects you from problems just like this one.

    More Java Articles
    More By O'Reilly Media


       · List<Integer> ints = new ArrayList<Integer>();ints.add(1);ints.add(2);// This...
       · public static int biggest(Box<T> box1, Box<U> box2) { int box1Size =...
     

    Buy this book now. This article was taken from chapter two of Java 1.5 Tiger: A Developer's Notebook, written by Brett McLaughlin and David Flanagan (O'Reilly, 2004; ISBN: 0596007388). Check it out at your favorite bookstore. Buy this book now.

    JAVA ARTICLES

    - Deploying Multiple Java Applets as One
    - Deploying Java Applets
    - Understanding Deployment Frameworks
    - Database Programming in Java Using JDBC
    - Extension Interfaces and SAX
    - Entities, Handlers and SAX
    - Advanced SAX
    - Conversions and Java Print Streams
    - Formatters and Java Print Streams
    - Java Print Streams
    - Wildcards, Arrays, and Generics in Java
    - Wildcards and Generic Methods in Java
    - Finishing the Project: Java Web Development ...
    - Generics and Limitations in Java
    - Getting Started with Java Web Development in...







    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 3 Hosted by Hostway
    Stay green...Green IT