Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions

  




 

 

Thinking in Java
Prev Contents / Index Next

Container disadvantage:
unknown type

The “disadvantage” to using the Java containers is that you lose type information when you put an object into a container. This happens because the programmer of that container class had no idea what specific type you wanted to put in the container, and making the container hold only your type would prevent it from being a general-purpose tool. So instead, the container holds references to Object, which is the root of all the classes, so it holds any type. (Of course, this doesn’t include primitive types, since they aren’t real objects, and thus, are not inherited from anything.) This is a great solution, except:

  1. Because the type information is thrown away when you put an object reference into a container, there’s no restriction on the type of object that can be put into your container, even if you mean it to hold only, say, cats. Someone could just as easily put a dog into the container.
  2. Because the type information is lost, the only thing the container knows that it holds is a reference to an object. You must perform a cast to the correct type before you use it.

    Here’s an example using the basic workhorse container, ArrayList. For starters, you can think of ArrayList as “an array that automatically expands itself.” Using an ArrayList is straightforward: create one, put objects in using add( ), and later get them out with get( ) using an index—just like you would with an array, but without the square brackets.[57] ArrayList also has a method size( ) to let you know how many elements have been added so you don’t inadvertently run off the end and cause an exception.

    First, Cat and Dog classes are created:

    //: c11:Cat.java
    package c11;
    
    public class Cat {
      private int catNumber;
      public Cat(int i) { catNumber = i; }
      public void id() {
        System.out.println("Cat #" + catNumber);
      }
    } ///:~


    //: c11:Dog.java
    package c11;
    
    public class Dog {
      private int dogNumber;
      public Dog(int i) { dogNumber = i; }
      public void id() {
        System.out.println("Dog #" + dogNumber);
      }
    } ///:~


    Cats and Dogs are placed into the container, then pulled out:

    //: c11:CatsAndDogs.java
    // Simple container example.
    // {ThrowsException}
    package c11;
    import java.util.*;
    
    public class CatsAndDogs {
      public static void main(String[] args) {
        List cats = new ArrayList();
        for(int i = 0; i < 7; i++)
          cats.add(new Cat(i));
        // Not a problem to add a dog to cats:
        cats.add(new Dog(7));
        for(int i = 0; i < cats.size(); i++)
          ((Cat)cats.get(i)).id();
          // Dog is detected only at run time
      }
    } ///:~


    The classes Cat and Dog are distinct; they have nothing in common except that they are Objects. (If you don’t explicitly say what class you’re inheriting from, you automatically inherit from Object.) Since ArrayList holds Objects, you can not only put Cat objects into this container using the ArrayList method add( ), but you can also add Dog objects without complaint at either compile time or run time. When you go to fetch out what you think are Cat objects using the ArrayList method get( ), you get back a reference to an object that you must cast to a Cat. Then you need to surround the entire expression with parentheses to force the evaluation of the cast before calling the id( ) method for Cat; otherwise, you’ll get a syntax error. Then, at run time, when you try to cast the Dog object to a Cat, you’ll get an exception.

    This is more than just an annoyance. It’s something that can create difficult-to-find bugs. If one part (or several parts) of a program inserts objects into a container, and you discover only in a separate part of the program through an exception that a bad object was placed in the container, then you must find out where the bad insert occurred. Most of the time this isn’t a problem, but you should be aware of the possibility.
    Thinking in Java
    Prev Contents / Index Next


 
 
   Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire