Java Advanced Placement Study Guide:  Comparing Objects, Packages, Import Directives, and Some Common Exceptions

Sample question:  What happens if you exceed the boundaries of an array object?

Published: January 1,  2004
By Richard G. Baldwin

Questions

File JavaAP026.htm


Welcome

This is one in a miniseries of tutorial lessons designed to help you learn the essential features of Java object-oriented programming as identified by The College Board.

Purpose

The purpose of this miniseries is to help you study for the Advanced Placement Examinations designed by the College Board.

Once you understand everything in this miniseries, plus the material in the lessons that I published earlier on Java Data Structures, you should understand the Java programming features that the College Board considers essential for the first two semesters of object-oriented programming education at the university level.

Approach

These lessons provide questions, answers, and explanations designed to help you to understand the subset of Java features covered by the Java Advanced Placement Examinations (as of October, 2001).

Please see the first lesson in the miniseries entitled Java Advanced Placement Study Guide: Introduction to the Lessons, Primitive Types, for additional background information.  The previous lesson was entitled Java Advanced Placement Study Guide:  Interfaces and polymorphic behavior.

Supplementary material

In addition to the material in these lessons, I recommend that you also study the other lessons in my extensive collection of online Java tutorials, which are designed from a more conventional textbook approach.  You will find those lessons published at Gamelan.com.  However, as of the date of this writing, Gamelan doesn't maintain a consolidated index of my Java tutorial lessons, and sometimes they are difficult to locate there.  You will find a consolidated index at Baldwin's Java Programming Tutorials.

What is Included?

Click here for a preview of the Java programming features covered by this lesson.



1.  What output is produced by the following program?
public class Ap141{
  public static void main(
                        String args[]){
    new Worker().doIt();
  }//end main()
}//end class Ap141

class Worker{
  void doIt(){
    char[] anArray = {'J','o','e'};
    String Str1 = new String(anArray);
    String Str2 = new String(anArray);

    System.out.println( 
              Str1 + " " + Str2 + " " +
              (Str1 == Str2));
  }//end doIt()
}// end class Worker

Answer and Explanation

2.  What output is produced by the following program?

public class Ap142{
  public static void main(
                        String args[]){
    new Worker().doIt();
  }//end main()
}//end class Ap142

class Worker{
  void doIt(){
    char[] anArray = {'J','o','e'};
    String Str1 = new String(anArray);
    String Str2 = new String(anArray);

    System.out.println( 
              Str1 + " " + Str2 + " " +
              Str1.equals(Str2));
  }//end doIt()
}// end class Worker

Answer and Explanation

3.  What output is produced by the following program?

public class Ap143{
  public static void main(
                        String args[]){
    new Worker().doIt();
  }//end main()
}//end class Ap143

class Worker{
  void doIt(){
    java.util.ArrayList ref = 
            new java.util.ArrayList(1);
    ref.add("ABC ");
    ref.add("DEF ");
    ref.add("GHI");
    
    System.out.println(
                   (String)ref.get(0) + 
                   (String)ref.get(1) + 
                   (String)ref.get(2));
  }//end doIt()
}// end class Worker

Answer and Explanation

4.  What output is produced by the following program?

public class Ap144{
  public static void main(
                        String args[]){
    new Worker().doIt();
  }//end main()
}//end class Ap144

class Worker{
  void doIt(){
    ArrayList ref = 
            new ArrayList(1);
    ref.add("ABC ");
    ref.add("DEF ");
    ref.add("GHI");
    
    System.out.println(
                   (String)ref.get(0) + 
                   (String)ref.get(1) + 
                   (String)ref.get(2));
  }//end doIt()
}// end class Worker

Answer and Explanation

5.  What output is produced by the following program?

import java.util.ArrayList;

public class Ap145{
  public static void main(
                        String args[]){
    new Worker().doIt();
  }//end main()
}//end class Ap145

class Worker{
  void doIt(){
    ArrayList ref = null;
    ref = new ArrayList(1);
    ref.add("ABC ");
    ref.add("DEF ");
    ref.add("GHI");
    
    System.out.println(
                   (String)ref.get(0) + 
                   (String)ref.get(1) + 
                   (String)ref.get(2));
  }//end doIt()
}// end class Worker

Answer and Explanation

6.  What output is produced by the following program?

import java.util.ArrayList;

public class Ap146{
  public static void main(
                        String args[]){
    new Worker().doIt();
  }//end main()
}//end class Ap146

class Worker{
  void doIt(){
    ArrayList ref = null;
    ref.add("ABC ");
    ref.add("DEF ");
    ref.add("GHI");
    
    System.out.println(
                   (String)ref.get(0) + 
                   (String)ref.get(1) + 
                   (String)ref.get(2));
  }//end doIt()
}// end class Worker

Answer and Explanation

7.  What output is produced by the following program?

public class Ap147{
  public static void main(
                        String args[]){
    new Worker().doIt();
  }//end main()
}//end class Ap147

class Worker{
  void doIt(){
    ArrayList ref = null;
    ref = new ArrayList(1);
    ref.add("ABC ");
    ref.add("DEF ");
    
    System.out.println(
                   (String)ref.get(0) + 
                   (String)ref.get(1) + 
                   (String)ref.get(2));
  }//end doIt()
}// end class Worker

Answer and Explanation

8.  What output is produced by the following program?

public class Ap148{
  public static void main(
                        String args[]){
    new Worker().doIt();
  }//end main()
}//end class Ap148

class Worker{
  void doIt(){
    System.out.println(1.0/0);
  }//end doIt()
}// end class Worker

Answer and Explanation

9.  What output is produced by the following program?

public class Ap149{
  public static void main(
                        String args[]){
    new Worker().doIt();
  }//end main()
}//end class Ap149

class Worker{
  void doIt(){
    System.out.println(1/0);
  }//end doIt()
}// end class Worker

Answer and Explanation

10.  What output is produced by the following program?

public class Ap150{
  public static void main(
                        String args[]){
    new Worker().doIt();
  }//end main()
}//end class Ap150

class Worker{
  void doIt(){
    String[] ref = {"AB ","CD ","EF "};
    for(int i = 0; i <= 3; i++){
      System.out.print(ref[i]);
    }//end forloop
    System.out.println("");
  }//end doIt()
}// end class Worker

Answer and Explanation



Copyright 2002, Richard G. Baldwin.  Reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.

About the author

Richard Baldwin is a college professor (at Austin Community College in Austin, TX) and private consultant whose primary focus is a combination of Java and XML. In addition to the many platform-independent benefits of Java applications, he believes that a combination of Java and XML will become the primary driving force in the delivery of structured information on the Web.

Richard has participated in numerous consulting projects involving Java, XML, or a combination of the two.  He frequently provides onsite Java and/or XML training at the high-tech companies located in and around Austin, Texas.  He is the author of Baldwin's Java Programming Tutorials, which has gained a worldwide following among experienced and aspiring Java programmers. He has also published articles on Java Programming in Java Pro magazine.

Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.

baldwin.richard@iname.com


What is Included?

According to the subset document,



Answers and Explanations

Answer 10

Both of the following occur.

C.  AB CD EF
B.  Runtime Error

Back to Question 10

Explanation 10

Another index out of bounds

This is another example of a program that throws an index out of bounds exception.  In this case, since the container is an array object, the name of the exception is ArrayIndexOutOfBoundsException.

Populate a three-element array object

The code in the following fragment creates and populates a three-element array object containing reference to three String objects.
 
  void doIt(){
    String[] ref = {"AB ","CD ","EF "};

Access an out-of-bounds element

The next fragment attempts to access an element in the array at index value 3.
 
    for(int i = 0; i <= 3; i++){
      System.out.print(ref[i]);
    }//end forloop

Since index value 3 is outside the bounds of the array, the program throws the following exception and aborts:

AB CD EF java.lang.ArrayIndexOutOfBoundsException
 at Worker.doIt(Ap150.java:22)
 at Ap150.main(Ap150.java:14)

Note however that the program displays the contents of the three String objects referred to by the contents of the first three elements in the array before the problem occurs.  That's the way it often is with runtime errors.  Often, a program will partially complete its task before getting into trouble and aborting with a runtime error.

Answer 9

B.  Runtime Error

Back to Question 9

Explanation 9

A setup

If you feel like you've been had, chances are you have been had.  The only purpose for Question 8 was to set you up for this question.

Division by zero for integer types

This program deals with the process of dividing by zero for int types.  The code in the following fragment divides the int value 1 by the int value 0.
 
  void doIt(){
    System.out.println(1/0);
  }//end doIt()

Not the same as double divide by zero

However, unlike with type double, this process doesn't return a very large value and continue running.  Rather, for type int, attempting to divide by zero will result in a runtime error of type ArithmeticException that looks something like the following under JDK 1.3:

java.lang.ArithmeticException: / by zero
 at Worker.doIt(Ap149.java:20)
 at Ap149.main(Ap149.java:14)

An exercise for the student

I won't attempt to explain the difference in behavior for essentially the same problem between type int and type double.  As the old saying goes, I'll leave that as an exercise for the student.

Answer 8

C.  Infinity

Back to Question 8

Explanation 8

A double divide by zero operation

This program deals with the process of dividing by zero for floating values of type double.

The following code fragment attempts to divide the double value 1.0 by the double value 0.
 
  void doIt(){
    System.out.println(1.0/0);
  }//end doIt()

The program runs successfully, producing the output Infinity.

What is Infinity?

Suffice it to say that Infinity is a very large number.

(Any value divided by zero is a very large number.)
At this point, I'm not going to explain it further.  If you are interested in learning what you can do with infinity, see the language specifications.

Answer 7

B.  Runtime Error

Back to Question 7

Explanation 7

This program illustrates an IndexOutOfBounds exception.

Instantiate and populate an ArrayList object

By now, you will be familiar with the kind of container object that you get when you instantiate the ArrayList class.

The code in the following fragment instantiates such a container, having an initial capacity of one element.

Then it adds two elements to the container.  Each element is a reference to an object of the class String.
 
  void doIt(){
    ArrayList ref = null;
    ref = new ArrayList(1);
    ref.add("ABC ");
    ref.add("DEF ");

Increase capacity automatically

Because two elements were successfully added to a container having an initial capacity of only one element, the container was forced to increase its capacity automatically.

Following execution of the code in the above fragment, String object references were stored at index locations 0 and 1 in the ArrayList object.

Get reference at index location 2

The next fragment attempts to use the get() method to fetch an element from the container at index value 2.

Index values in an ArrayList object begin with zero.  Therefore, since only two elements were added to the container in the earlier fragment, there is no element at index value 2.
 
    
    System.out.println(
                   (String)ref.get(0) + 
                   (String)ref.get(1) + 
                   (String)ref.get(2));

An IndexOutOfBounds exception

As a result, the program throws an IndexOutOfBounds exception.  The error produced under JDK 1.3 looks something like the following:

Exception in thread "main" java.lang.IndexOutOfBoundsException:
Index: 2, Size: 2
at java.util.ArrayList.RangeCheck
  (Unknown Source)
at java.util.ArrayList.get
  (Unknown Source)
at Worker.doIt(Ap147.java:27)
at Ap147.main(Ap147.java:16)

Attempting to access an element with a negative index value would produce the same result.

An ArrayIndexOutOfBounds exception

A similar result occurs if you attempt to access an element in an ordinary array object outside the bounds of the index values determined by the size of the array.  However, in that case, the name of the exception is ArrayIndexOutOfBounds.

Answer 6

B.  Runtime Error

Back to Question 6

Explanation 6

The infamous NullPointerException

Interestingly, one of the first things that you read when you start reading Java books, is that there are no pointers in Java.  It is likely that shortly thereafter when you begin writing, compiling, and executing simple Java programs, one of your programs will abort with an error message looking something like that shown below:

Exception in thread "main" java.lang.NullPointerException
        at Worker.doIt(Ap146.java:23)
        at Ap146.main(Ap146.java:16)

What is a NullPointerException?

Stated simply, a NullPointerException occurs when you attempt to perform some operation on an object using a reference that doesn't refer to an object.

That is the case in this program

The following code fragment declares a local reference variable and initializes its value to null.

(A reference variable in Java must either refer to a valid object, or specifically refer to no object (null).  Unlike a pointer in C and C++, a Java reference variable cannot refer to something arbitrary.)
In this case, null means that the reference variable doesn't refer to a valid object.
 
  void doIt(){
    ArrayList ref = null;

No ArrayList object

Note that the code in the above fragment does not instantiate an object of the class ArrayList and assign that object's reference to the reference variable.

(The reference variable doesn't contain a reference to an object instantiated from the class named ArrayList, or an object instantiated from any class for that matter.)
Invoke a method on the reference

However, the code in the next fragment attempts to add a String object's reference to a nonexistent ArrayList object by invoking the add method on the reference containing null.
 
    ref.add("ABC ");

This results in the NullPointerException shown earlier.

What can you do with a null reference?

The only operation that you can perform on a reference variable containing null is to assign an object's reference to the variable.  Any other attempted operation will result in a NullPointerException.

Answer 5

C.  ABC DEF GHI

Back to Question 5

Explanation 5

The purpose of this program is to Program contains an import directive

This program is the same as the program in Question 4 with a major exception.  Specifically, the program contains the import directive shown in the following fragment.
 
import java.util.ArrayList;

A shortcut

The designers of Java recognized that having to type a fully-qualified name for every reference to a class in a Java program can become burdensome.  Therefore, they provided us with a shortcut that can be used, so long as we don't need to refer to two or more class files having the same name.

Import directives

The shortcut is called an import directive.

As can be seen above, the import directive consists of the word import followed by the fully-qualified name of a class file that will be used in the program.

A program may have more than one import directive, with each import directive specifying the location of a different class file.

The import directive(s) must appear before any class or interface definitions in the source code.

The alternative wild-card syntax

An alternative form of the import directive replaces the name of the class with an asterisk.

The asterisk behaves as a wild-card character.  It tells the compiler to use any class file that it finds in that package that matches a class reference in the source code.

The wild-card form should be used with care, because it can sometimes cause the compiler to use a class file that is different from the one that you intended to use (if it finds the wrong one first).

Class file name collisions

If your source code refers to two different class files having the same name, you must forego the use of the import directive and provide fully-qualified names for those class files.

Answer 4

A.  Compiler Error

Back to Question 4

Explanation 4

The purpose of this program is to continue to illustrate the use of java packages.

No fully-qualified class names

This program is the same as the program in Question 3 with a major exception.  Neither of the references to the ArrayList class use fully-qualified names in this program.  Rather, the references are as shown in the following fragment.
 
    ArrayList ref = 
            new ArrayList(1);

Compiler errors

As a result, the JDK 1.3 compiler produces two error messages similar to the following:

Ap144.java:20: cannot resolve symbol
symbol  : class ArrayList
location: class Worker
    ArrayList ref =

Doesn't know how to find the class file

This error message indicates that the compiler didn't know where to look on the disk to find the file named ArrayList.class

Answer 3

C.  ABC DEF GHI

Back to Question 3

Explanation 3

Illustrate the use of java packages

Since it was necessary to make use of a class to illustrate packages, this program also previews the use of the ArrayList class.  We will be very interested in this class later when we study Java data containers.

What is an ArrayList object?

Some of this terminology may not make much sense to you at this point, but I'll go ahead and tell you anyway, just as a preview.

According to Sun, the ArrayList class provides a

"Resizable-array implementation of the List interface. Implements all optional list operations, and permits all elements, including null. In addition to implementing the List interface, this class provides methods to manipulate the size of the array that is used internally to store the list. (This class is roughly equivalent to Vector, except that it is unsynchronized.)"
Stated more simply ...

Stated more simply, an object of the ArrayList class can be used as a replacement for an array object.  An ArrayList object knows how to increase its capacity on demand, whereas the capacity of a simple array object cannon change once it is instantiated.

An ArrayList object

The following statement instantiates a new object of the ArrayList class, with an initial capacity for one element.  The initial capacity is determined by the int value passed to the constructor when the object is instantiated.
 
    java.util.ArrayList ref = 
            new java.util.ArrayList(1);

Back to the primary purpose ...

Getting back to the primary purpose of this program, what is the meaning of the term java.util that appears ahead of the name of the class, ArrayList?

Avoiding name conflicts

One of the age-old problems in computer programming has to do with the potential for name conflicts.  The advent of OOP and reusable code didn't cause that problem to go away.  If anything, it made the problem worse.

For example, you and I may work as programmers for separate companies named X and Y.  A company named Z may purchase our two companies and attempt to merge the software that we have written separately.  Given that there are only a finite number of meaningful class names, there is a good possibility that you and I may have defined different classes with the same names.  Furthermore, it may prove useful to use both of the class definitions in a new program.

Put class files in different directories

Sun's solution to the problem is to cause compiled class files to reside in different directories.  Simplifying things somewhat, if your compiled file for a class named Joe is placed in a directory named X, and my compiled file for a different class named Joe is placed in a directory named Y, then source code in the same Java program can refer to those two class files as X.Joe and Y.Joe.  This scheme makes it possible for the Java compiler and the Java virtual machine to distinguish between the two files having the name Joe.class.

The java and util directories

Again, simplifying things slightly, the code in the above fragment refers to a file named ArrayList.class, which is stored in a directory named util, which is a subdirectory of a directory named java.

The directory named java is the root of a directory tree containing a very large number of standard Java class files.

(As an aside, there is another directory named javax, which forms the root of another directory tree containing class files considered to be extensions to the standard class library.)
Many directories (packages)

Stated simply, a Java package is nothing more or less than a directory containing class files.

The standard and extended Java class libraries are scattered among a fairly large number of directories or packages (a quick count of the packages in the JDK 1.3 documentation indicates that there are approximately 65 standard and extended packages).

A fully-qualified class name

With one exception, whenever you refer to a class in a Java program, you must provide a fully-qualified name for the class, including the path through the directory tree culminating in the name of the class.  Thus, the following is the fully-qualified name for the class whose name is ArrayList.

java.util.ArrayList

(Later we will see another way to accomplish this that requires less typing effort.)

The exception

The one exception to the rule is the use of classes in the java.lang package, (such as Boolean, Class, and Double).  Your source code can refer to classes in the java.lang package without the requirement to provide a fully-qualified class name.

An ArrayList object

Now back to the use of the object previously instantiated from the class named ArrayList.  This is the kind of object that is often referred to as a container.

(A container in this sense is an object that is used to store references to other objects.)
Many methods available

An object of the ArrayList class provides a variety of methods that can be used to store object references and to fetch the references that it contains.

The add() method

One of those methods is the method named add().

The following code fragment instantiates three objects of the String class, and stores them in the ArrayList object instantiated earlier.

(Note that since the initial capacity of the ArrayList object was adequate to store only a single reference, the following code causes the object to automatically increase its capacity to at least three.)
    ref.add("ABC ");
    ref.add("DEF ");
    ref.add("GHI");

The get() method

The references stored in an object of the ArrayList class can be fetched by invoking the get(int value) method on a reference to the object.

The code in the following fragment invokes this method to fetch the references stored in index locations 0, 1, and 2.  These references are passed to the println() method, where the contents of the String objects referred to by those references are concatenated and displayed on the computer screen.
 
    System.out.println(
                   (String)ref.get(0) + 
                   (String)ref.get(1) + 
                   (String)ref.get(2));

The output

This results in the following being displayed:

ABC DEF GHI

Summary

The above discussion gave you a preview into the use of containers in general, and the ArrayList container in particular.

However, the primary purpose of this program was to help you to understand the use of packages in Java.

The ArrayList class was simply used as an example of a class file that is stored in a standard Java package.

Answer 2

D.  Joe Joe true

Back to Question 2

Explanation 2

Two String objects with identical contents

As in Question 1, the program instantiates two String objects containing identical character strings, as shown in the following code fragment.
 
    char[] anArray = {'J','o','e'};
    String Str1 = new String(anArray);
    String Str2 = new String(anArray);

Compare objects for equality

Also, as in Question 1, this program compares the two objects for equality and displays the result as shown by the boldface portion of the statement in the following fragment.
 
    System.out.println( 
              Str1 + " " + Str2 + " " +
              Str1.equals(Str2));

Compare using overridden equals() method

However, in this program, the == operator is not used to compare the two objects.  Rather, the objects are compared using an overridden version of the equals() method.  In this case, the equals() method returns true, indicating that the objects are of the same type and contain the same data values.

The equals() method

The equals() method is defined in the Object class, and can be overridden in subclasses of Object.  It is the responsibility of the author of the subclass to override the method so as to implement that author's concept of "equal" insofar as objects of the class are concerned.

The overridden equals() method

The reason that the equals() method returned true in this case was that the author of the String class provided an overridden version of the equals() method.

The default equals() method

If the author of the class does not override the equals() method, and the default version of the equals() method inherited from Object is invoked on an object of the class, then according to Sun:

"for any reference values x and y, this method returns true if and only if x and y refer to the same object (x==y has the value true)"
In other words, the default version of the equals() method inherited from the class Object provides the same behavior as the == operator when applied to object references.

Answer 1

C.  Joe Joe false

Back to Question 1

Explanation 1

The identity operator

This program illustrates the behavior of the == operator (referred to as identity in some College Board documents) when used to compare references to objects.

Two String objects with identical contents

As shown in the following fragment, this program instantiates two objects of the String class containing identical character strings.
 
class Worker{
  void doIt(){
    char[] anArray = {'J','o','e'};
    String Str1 = new String(anArray);
    String Str2 = new String(anArray);

The fact that the two String object contain identical character strings is confirmed by:

Compare object references using identity (==)

The references to the two String objects are compared using the == operator, and the result of that comparison is displayed.  This comparison will produce either true or false.  The code to accomplish this comparison is shown in the boldface portion of the following fragment.
 
    System.out.println( 
              Str1 + " " + Str2 + " " +
              (Str1 == Str2));

The statement in the above fragment produces the following display:

Joe Joe false

How can this be false?

We know that the two objects are of the same type (String) and that they contain the same character strings.  Why does the == operator return false?

Doesn't compare the objects

The answer lies in the fact that the above statement doesn't really compare the two objects at all.  Rather, it compares the values stored in the reference variables referring to the two objects.  That is not the same as comparing the objects.

References are not equal

Even though the objects are of the same type and contain the same character string, they are two different objects, located in different parts of memory.  Therefore, the contents of the two reference variables containing references to the two objects are not equal.

The correct answer is false

The == operator returns false as it should.  The only way that the == operator could return true is if both reference variables refer to the same object, (which is not the case).

The bottom line is ...

The == operator cannot be used to compare two objects for equality.  However, it can be used to determine if two reference variables refer to the same object.



Copyright 2002, Richard G. Baldwin.  Reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.

About the author

Richard Baldwin is a college professor (at Austin Community College in Austin, TX) and private consultant whose primary focus is a combination of Java and XML. In addition to the many platform-independent benefits of Java applications, he believes that a combination of Java and XML will become the primary driving force in the delivery of structured information on the Web.

Richard has participated in numerous consulting projects involving Java, XML, or a combination of the two.  He frequently provides onsite Java and/or XML training at the high-tech companies located in and around Austin, Texas.  He is the author of Baldwin's Java Programming Tutorials, which has gained a worldwide following among experienced and aspiring Java programmers. He has also published articles on Java Programming in Java Pro magazine.

Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.

baldwin.richard@iname.com

-end-