Personal tools
You are here: Home Classes Fall 2004 - Spring 2005 Old CS 160 More on Objects; Arrays; Exceptions
Navigation
Log in


Forgot your password?
« May 2008 »
Su Mo Tu We Th Fr Sa
123
456789 10
11121314151617
18192021222324
25262728293031
 
Document Actions

More on Objects; Arrays; Exceptions

by admin last modified 2005-05-25 15:41

More about objects; Arrays; Exceptions

Object creation


What happens when the new operator is executed?

1.    Space is allocated in the memory of the Java Virtual Machine for the object.

2.    Its constructor is called.  A constructor is a segment of code used to initialize instance variables.

3.    A reference to the object (uniquely identifying it) is returned to the caller.


Constructors

A constructor is a method used to initialize an object.  It has the same name as the name of the class.  Unlike other methods, a constructor is declared without a return type.  The constructor does not return a value.

Like other methods, a constructor may have parameters.  It may also be overloaded; that is, several constructors may exist for the same class (and with the same name), as long as they have different parameter lists.  Consider the simple counter example:

example  A Simple Counter class

class SimpleCounter {

    private int count;

    SimpleCounter()
    {
        count = 0;
    }

    SimpleCounter(int n)
    {
        count = n;
    }

    public int timesCalled()
    {
        count++;
        return count;
    }
}



SimpleCounter has two constructors, one with no arguments and one with a single integer argument.  This gives us two ways to create a SimpleCounter:

SimpleCounter simple1 = new SimpleCounter();  // creates a counter initialized to 0

SimpleCounter simple2 = new SimpleCounter(50);  // creates a counter initialized to 50

Some additional details on constructors:

  • If the programmer does not write a constructor, Java provides a default constructor with no arguments, which does not initialize anything.

  • Within the constructor (or any other method), the reserved word this refers to the new object.  This is useful when a field name is the same as the name of one of the parameters.  For example, the second constructor for SimpleCounter could have been written

    SimpleCounter(int count)
    {
        this.count = count;
    }

  • Another use of this is to allow one of a class's constructors to call another.  For example, the no-argument constructor for SimpleCounter could have been written

    SimpleCounter()
    {
        this(0);  //  call the one-argument constructor with argument 0
    }

  • Default values.  If they are not explicitly initialized by a constructor, fields in a new object are given default values.  For a boolean, the default is false.  For a reference type, the default is null.  (This is why the null pointer exception is so common at run time.)  For all numeric fields, the default value is 0.  This is why the original version of SimpleCounter will work properly, even without a constructor.

  • Initializers.  Another way to initialize a field in a class the through the use of an intializer, written as part of the field declaration.  For example, the SimpleCounter could have been written

    class SimpleCounter {
        private int count = 0;
        public int timesCalled()
        {
           count++;
           return count;
        }
    }

    The code to perform this type of initialization is inserted into each constructor for the class, including the default constructor, if there is one.

Destroying and finalizing objects

Objects are automatically deleted from the JVM's memory when the object is no longer needed; that is, when there are no existing references to the object.  This is called garbage collection.  As a result, there is no statement to explicitly free or delete an object.

A class may have an instance method called a finalizer, which is executed whenever an object of the class is deleted by the JVM garbage collector.  This is analogous to the destructors of C++.  The purpose of a finalizer is normally to free resources held by the object being deleted.  The presence of automatic garbage collection makes a finalizer for most classes unnecessary, but it can still be useful for closing open files, deleting temporary files, closing network connections, etc.  A finalizer, if present, is a method with no arguments and no return value, called finalize .

Accessors and Mutators

It is customary in object-oriented programming that an object's data fields are private (accessible only to the object itself).  Its methods may be private or public, depending on the intended use.  Other objects can then communicate with the object only by sending it messages; that is, by calling its methods.  In some cases, an object may want to provide a public method which allows other objects to read or modify the value of one of its data fields.  It does so using methods called accessors or mutators.  The getText() and setText() methods of the TextField class are examples of an accessor and a mutator.

The SimpleCounter class could provide an accessor and a mutator for its count field as follows:

class SimpleCounter {

    private int count;

    SimpleCounter()
    {
        count = 0;
    }

    SimpleCounter(int n)
    {
        count = n;
    }

    public int getCount()
    {
        return count;
    }

    public void setCount(int x)
    {
        count = x;
    }

    public int timesCalled()
    {
        count++;
        return count;
    }
}


Arrays

An array is a contiguous block of memory cells used to store data.  For example, we might want to keep an array of integers, of names, of employee records containing name, SSN, address, etc.  Java arrays can be used for any of these purposes.
  • Each array must have a base data type, which can be a primitive type (like int or double) or an object type (like String).
  • Every element in the array must be of that base type.
  • Array elements are numbered sequentially, beginning with 0.
An array is declared as follows:

Basetype[]  arrayname;
Basetype arrayname[];

An array is considered to be an object in Java.  It is also necessary to instantiate an array.  For example, to declare and instantiate an array of 100 integers or Strings, we would write

int []  intArray =  new int[100];
String []  names = new String[100];

By default, the integers in the array are initialized to 0; the Strings are initialized to null.

Note that the size of an array is determined when it is instantiated, not when it is declared.

Two-dimensional arrays use pairs of brackets:

int [][] matrix = new int[10][10];

Array operations

The two basic array operations are to get the element at a given index, and to store an element at a given index.  These operations use the common [] indexing notation.  For example,
intArray[5] = 20;
intArray[i] = 30;
x = intArray[10];
intArray[i] = intArray[i+1];
matrix[i][j] = 100;
System.out.println(matrix[i][j]);
Every array also has a public "length" property, which indicates the size of the array.  (length is a read-only property.)  

example.  Print the contents of an array of Strings called names:

for(int i = 0; i < names.length; i++)
    System.out.println(names[i]);

example.  Reverse the order of the elements in names.

int len = names.length;

for(int i = 0; i < len/2; i++){
    String temp = names[i];
    names[i] = names[len - i - 1];
    names[len - i - 1] = temp;
}

example.  Use a bubble sort to sort names in increasing order.

for(int i = 0; i < len; i++)
    for(int j = 0; j < len; j++)
        if(names[j].compareTo(names[j+1]) > 0){
            String temp = names[j];
            names[j] = names[j+1];
            names[j+1] = temp;
            }

example.  Make a copy of names called names2.

String []  names2 = new String[names.length];

for(int i = 0; i < names.length; i++)
    names2[i] = names[i];


Once an array has been instantiated, its size cannot be increased or decreased.  However, the effect of increasing the array's size can be achieved by instantiating a larger array and copying the data from the old array to the new one.

example.  Double the size of names.

String [] temp = new String[2 * names.length];

for(int i = 0; i < names.length; i++)
    temp[i] = names[i];

names = temp;


Errors and Exception Handling

A critical problem in software development is the handling of run-time errors, such as
  • division by zero
  • nonexistent or inaccessible files
  • array index out of range
  • class not found
  • null pointer checking error
How should a program deal with these?
  1. Let the Java interpreter or the operating system kill the program.
  2. Pass error codes back from each method.  Calling method must check the return code and take appropriate action.  (Note:  this can't be done with constructors, which do not have return values.)
  3. Java exceptions.
Java supports exceptions, which are objects representing well-defined run-time errors.  (The full name of the exception class is java.lang.Exception.)  Programs can include code to:
  • indicate what should happen in response to a given exception
  • pass an exception off to some other part of the code, possibly the Java interpreter itself
  • initiate an exception after detecting an error
  • define new exception types by subclassing java.lang.Exception

Initiating exceptions

If a program detects an error, it can initiate an exception with the throw statement:

example

if(index < 0 || index >= array.length)
    throw new ArrayOutOfBoundsException();

Passing off an exception

Suppose method A calls method B, which executes some code that may result in an exception.  Suppose that B chooses not to handle the exception itself.  It may pass the exception off to A by using a "throws" clause in the method declaration.

example

public void B() throws IOException {

    open a file; // may trigger an I/O exception

}

From A's point of view, it appears that its call to B caused the exception.  A may then handle the exception or "throw" it back to the method which called A.

Catching exceptions

This technique is used when a method executes code which may result in an exception, and the method wants to provide code to handle such an exception if it occurs.  The exception-handling code gives the program a way to try to recover from the error and continue executing.  A try-catch-finally statement is used to program an exception handler.

syntax:

try {
    statements
}
catch(exception-type e){
    statements
}
catch(exception-type e){
    statements
}
.
.
.
finally {
    statements
}


That is, a try-catch-finally statement consists of a try clause, one or more catch clauses, and an optional finally clause.  Each clause contains a block of statements.  The statement is executed as follows:
  1. Execute the code in the try clause until it is completed, or until an exception occurs.  If no exception occurs, proceed to the finally clause.
  2. If an exception occurs during execution, look for the first catch clause with a matching exception type.
  3. If a catch clause is found which can handle the exception, execute it.  (Only the first matching catch block is executed.)
  4. Execute the code in the finally clause.  (This is done whether or not an exception occurs.)
If an uncaught exception occurs, the exception is thrown to the method which called this one, which may catch or throw it.


 

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: