Inheritance & Constructors,
Vector & java.lang Classes


Peter Komisar ©  Conestoga College  latest version  5.6 /  2010

This class follows off of last week's discussion of Inheritance, this
time bringing attention to details of overriding and overloading
constructors. It goes on to survey Java's built in lang package
classes.


Review of Class Members



In object-oriented programming, data and operations are
formally coupled in the
data structure called the 'class'.
The class acts as a container for it's members. Class
members include 'fields', which are also called 'variables'.
Variables hold values that describe characteristics or
properties of an object. The class member that describes
behavior is the 'method'.

Methods have counterparts in other languages known as
functions, procedures, routines or operations. Methods
are the verbs or action parts of a class.

Java classes also hold 'constructors'. These are special
methods whose sole job is to create what are called new
instances or objects of a given class. This study covers
aspects of constructors that are tied to
inheritance.


Class members

// * constructors are not considered 'real' members of a class as they
// are used from outside the class
, in fact, to create the class objects.


Constructors & Overloading



Review: Invoking a Constructor 

A constructor is a unique and privileged method which is
used to create and initialize new objects. Creating a class
instance using the constructor with the new operator is
called instantiation. In the following example,  declaration,
instantiation and assignment are all combined.

Example   

AClass  reference = new AClass( );
// a constructor being invoked 

The above example shows a constructor being deployed
in the instantiation process.

Defining a Constructor

When defining a constructor in a class definition the
constructor has three distinguishing elements. A
constructor:


The implied return type of the constructor is the class
object that is set up in memory. Constructors are like
methods in that they use of round braces to receive
arguments and the use of curly braces to define the
scope of their actions. Following is the general form
of the constructor.
 

General Form of a Constructor inside a Class Definition

class  Name{
          Name( ){
        // the constructor with same name as class,
        //  no return type and round braces

            }
         } 

First consider a class called Car defined without any
constructors defined.

 Example

class Car{
          // variables   
         int speed = 7;
         int braking = 7;
         int handling = 7;

         // method
         int getRating( ) { return speed + braking + handling; }
       }


Now lets look at a Car class and define a constructor
in it. First notice the constructor has the same name
as the class, Car, and has no return type, unlike it's
sibling, the method.

   class Car{
// variables defined in class scope initialized to the default value 0
         int speed;
         int braking;
         int handling;

          //   an no-args constructor
 Car( ){
           speed =7;
           braking= 7;
           handling = 7;
          }

           // class method
           int getRating( ) { return speed + braking + handling; }
       }

The no-args Default Constructor

If we test the above classes we see they work the same.
You might ask what was accomplished using the form
with the constructor. Beyond being perhaps of better form,
nothing!

This is because, in the absence of a constructor being
supplied explicitly, a 'no-argument' default constructor
is supplied implicitly by the Java compiler. This supplied
constructor does the same work of initialization that the
explicitly defined constructor does.

// in the absence of an overtly supplied constructor
// the default no-args constructor is supplied


Constructor Non-Participation In Inheritance

We have seen that inheritance allows a class to extend
another class in such a way as to have access to the
members of the parent class. We are able to assign
values to the parent variables as if they had been
defined in the child class. 

Constructors, on the other hand, are not really considered
to be class members though they are ostensibly defined
within the class definition. This follows from the fact that
they are used to create class objects rather than being
a participating member of the class object.

// constructors are not true class members as they cannot
// participate in an object's operations


When Implicit No-args Constructor Is Not Provided

There is a special case that pertains to this discussion. If
you define a class with a constructor that takes arguments
then the compiler doesn't supply the no-args default
constructor automatically.  The following code doesn't compile
for this reason.


Example

class Construct{
      Construct(String s){
              System.out.println(s);
              }

public static void main(String[] args){
      new Construct( );
      // doesn't compile as the no-args constructor is not
      // provided in the case that any
constructors are defined
      }
   }

OUTPUT

>javac Construct.java
Construct.java:7: cannot find symbol
symbol  : constructor Construct()
location: class Construct
      new Construct( );
      ^
1 error

  

If a child class is built that attempts to invoke the no-args
constructor of the parent, the compile will fail as that version
of the constructor in the parent is not defined. The solution
here is to provide a no-args constructor explicitly whenever
you decide to define constructors for a class. 

This is shown in the next example which may be saved as
'Run.java', the class that contains the main( ) method.

// The no-args constructor is supplied automatically only
// if other constructors are not explicitly defined in a class
.  


Constructor Code Sample


class Parent
     {
// if you comment out the no-args constructor  you will
// get a compiler error as the compiler has not supplied
// the no-args constructor for the child to invoke

// a no args constructor, to comment in and out
// and a constructor that takes a String object

  //   /*
Parent( )
       {
       System.out.println
       ("The no-args parent constructor is expressed");
       }
  //   */   
 
 Parent(String name)
       {
       System.out.println
       ("Hello " + name + "! A constructor that takes a String is expressed."); 
       }
     }
  
// child class 

class Child extends Parent
     {
       Child( ){
       System.out.println
       ("This is followed by the child's constructor being invoked.");
       } 
     }
  
    
class Run
    {
public static void main(String[]args)
      {
      new Child( );
      }     
    }  

OUTPUT   // without the no-args constructor defined in parent

C:\Documents and Settings\Peter\My Documents\J2\Examples>javac Run.java
Run.java:29: cannot find symbol
symbol  : constructor Parent()
location: class Parent
       Child( ){
               ^
1 error

      
Constructor Overloading

Recall from tours of the documentation that more than one
constructor
can be supplied for a class. In the following
example we can build the Car class with
three constructors.
We are defining the class without variables and methods to
simplify
the view.

 Example  

class Car{
        Car( ) {
        // the no args constructor supplied explicitly

                 }
        Car(String options){
       // a constructor defined taking a String argument
                }
        Car(String options, String customization){
        // a constructor defined taking two string arguments
                }

The compiler doesn't mind several constructors being built
with the same name. This is called constructor overloading.
This is similar to method overloading where the compiler is
able to distinguish each constructor based on the order,
type and number of arguments. 



Using 'this' & 'super' in Constructors


Recall that the keyword 'this' could be used to reference
variables
or method defined in the scope of a container
class, that is, the class that contains those variables and
methods. The 'this' keyword
also has a special form that
is used to reference constructors defined inside a class.

In the case of constructors, the 'this' keyword is used
as an identifier together with the form of the
constructor
that it is being used to invoke. For instance the following
example shows
how to invoke a constructor in the current
class that has an argument list consisting of a String,
and an int value.
  (Another way of to say this is that the
form matches a constructor defined in the current class

with a matching constructor signature.)


Example
 

this( "x", 9 );

//  invokes a constructor in the current class
// that takes a String value and  an int


This is demonstrated in code in the following example.

Example   

class Limo{
         Limo(String stretch, int spec1, int spec2, int spec3){
         // some complex processing
          }
         Limo(String stretch, String tinted ){
             this(stretch , 1, 2, 3 );
             // go on to use the added argument

// calls the adjacent constructor with matching argument list
// then do further construction, using tinted directive

          }
     }

Where the 'this' keyword used with constructors references
constructors defined in the containing class, the 'super'
keyword can be used in constructors to reference a target
constructor defined in a parent class.

The super keyword is used in a similar way that the 'this'
keyword
, in a form that imitates a constructor that needs
to be invoked. The difference is the 'super' keyword is
used to
invoke a matching constructor in the parent class.

To example this we need to create a constructor where a
child class subclasses
a parent. First we define Car class
with two constructors.


Example

   class Car{
           Car(String options){
              // build car with standard options
                }
            Car(String options, String customization){
              // build car with custom options
                }
             // potential problem as the no-args
             // good practice to start with a no-args
             // constructor or supply an empty one

                }


Now we create a SportsCar class that extends the parent
class, Car. Notice how we use 'super' to specifically invoke
one of the parent constructors by matching the argument
lists.

Example

  class SportsCar extends Car{
         SportsCar(String options ){
                        super(options);
   // passes control to the parent
  // constructor with matching signature

                        }
                 }

Notice now if we tried to use the no-args super( ) we would
get a compiler error
because now that constructors have
been defined in the Car class the no-args
constructor has
not been supplied.


The 'this' and 'super' Keywords Both Want to Be First

A final point on 'this' and 'super'. If the constructor form
of these keywords are used
, Java programming rules
state that each must be the first statement in the
constructor code block. This leads to the obvious,
conundrum, 'In a constructor that uses both, how can
they both be first?  Both insist on being the first call
in a constructor.


Example
  // won't compile

class P {
      P( ) {
           }
           }
 
class C{
        C( ){
// putting either this( ) or super( ) before the other won't compile
         super( );
      
  this( );     
          }
public static void main(String[]args){
      new C( );
      }
   }  

To use use both, one must do so in stages by first
defining a constructor that uses super and then build
a constructor that invokes that constructor using this.

Following is another complete example showing super
and this used inside constructors


Second Constructor Example

class Old{
      Old( ){
      System.out.println("No-args Old");
      }
      Old(String name){
      System.out.println("Hi " + name + "! I am Old's one arg constructor being invoked.");
      }
      }

class Young extends Old{
      Young(String name){
      super(name);
      System.out.println("Young having called String constructor of Old");
      }
      Young(String name, String day, String month){
      this(name);
      System.out.println("Young calls 'this' and adds it's own properties");
      System.out.println(" Day is: " + day + " and " + " Month is: " + month + "\n"); 
      }
      }

public class OY{
      public static void main(String[] args){

      System.out.println( " \n**** No arg Old ****\n " );
      new Old();

      System.out.println( " \n**** Single arg Young ****\n " );
      new Young("Bentley");

      System.out.println( " \n**** One arg Old ****\n " );
      new Old("Syvester");

      System.out.println( " \n**** Three args Young ****\n " );
      new Young("Melissa","Thursday","April");

      }
     
    }

OUTPUT

 **** No arg Old ****

 
No-args Old
 
**** Single arg Young ****
 
Hi Bentley! I am Old's one arg constructor being invoked.
Young having called String constructor of Old
 
**** One arg Old ****
 
Hi Syvester! I am Old's one arg constructor being invoked.
 
**** Three args Young ****
 
Hi Melissa! I am Old's one arg constructor being invoked.
Young having called String constructor of Old
Young calls 'this' and adds it's own properties
 Day is: Thursday and  Month is: Apri
l


The following code sample demonstrates the invocation
of parent and grandparent constructors. Notice how the
constructors are invoked recursively up the inheritence
chain. This invocation happens by implicit calls to super( )
all the way back to Object class.


Sample Demonstrating Invocation of Ancestor Constructors

class Dark{
    Dark(){
    System.out.println("1. Dark");
    }

 public static void main(String[] args){
    new Dark();
    new Dawn();
    new Day();
   
    }
 }

class Dawn extends Dark{
  Dawn(){
     System.out.println("2. Dawn");
     }
   }

class Day extends Dawn{
    Day(){
     System.out.println("3. Day");
     }
  }


Output

1. Dark
1. Dark
2. Dawn
1. Dark
2. Dawn
3. Day

The redundancy in the output demonstrates how parent
constructors are invoked recursively.

Garbage Collector Replaces C++'s Destructors

A last word about Java constructors, if this was a C++ course 
we would go onto a discussion of destructors,
the counterpart
of a  constructor. Java saves us the need to deallocate memory
by providing the
'gc' thread where 'gc' abbreviates garbage
collector.

The 'gc' thread is a daemon or service thread that works in the
background taking advantage of slow times in CPU usage
deallocating memory locations that are no longer referenced.

 


Classes of the java.lang Package



The Java library of classes is enormous and growing! Java has
a set of 'built-in'
classes that are automatically imported for the
programmer that do basic 'bread and butter' activities. These
classes provide support that is so fundamental that they are

supplied automatically. These classes are found in the
java.lang package. 

Primary classes in this package are the String class and the
Math class. There is also the set of Wrapper classes, one for

each primitive type.

There are other neccessary classes like System, class Class
and
ClassLoader. Object class is defined in the lang package
as is the Thread class. Java's
SecurityManager is also defined
in the java.lang package.

The lang package is also where two dozen Exception classes
and twenty-one error classes are defined. In this section
we look
at the String, Math and Wrapper classes.


Common Classes Found In the java.lang Package


Vector in the java.util Package

Though in a different package, the util package, Vector is included
too, because it has been used so much throughout the Java libraries.

Though Vector is often replaced by classes such as ArrayList,
contained in the collection package, it remains a classic Java
workhorse.

// ArrayList adds some nice features however ArrayLists operations are not
// synchronized
as are Vector's methods. In a multi-threaded environment,
// you would need to make sure
calls on ArrayList are synchronized.



The String Class



In Java when you need a string of characters in your programs,
you use an instance of the String class. String objects hold a
series of adjacent characters in a way similar to an array.
However, where with an array you would reference an element
of the array to get a character, with String you use one of the
class methods to manipulate the string.

String Literals

A String literal is created when zero or more characters are
enclosed in double quotes.


Example 

"A String literal"     // String literal


String literals are normally used in some context. For instance
as an argument to a method.


Example
  

setText(" String literal as a method argument " );


String literals are also used in assignments.


Example
  

String string;
string = "A String literal assigned to a reference variable";

String is a class so an object of String class can also
be created using a String class constructor.


Example

String s = new String("A string" );
 

Strings as Immutable Objects

Strings are said to be immutable. This means a String
object is unchangeable. This description makes it sound
as though a String object is somehow final like a variable
that has been marked final and can no longer be changed.
What is actually unchangeable is the String object that has
been stored in memory.

So how do we make changes to a String object? What
occurs when Java methods are used to change a String
object is that the string is copied into an instance of the
mutable StringBuffer class. StringBuffer has a memory
area that can be used to modify and rearrange strings.

Changes are made to the StringBuffer representation and
then a new immutable String object is built in memory.
The old reference is then reassigned the new object while
the old dereferenced object is discarded.

Once no longer referenced, it is a matter of time before
the background gc thread deallocates the object and the
memory once associated with the old immutable String
object is freed.

//  When a change on a string is executed the string is written to a
// StringBuffer the
modifications are effected and then a new immutable
// String object is created.
The reference to the string object is made to
// point to the new string object in memory and and the old
object in
// memory is dicarded
 

The Overloaded Addition Operator

There is one case of operator overloading in Java. The
addition operator, represented by the '+' symbol, is
overloaded to do String concatenation.  (Overloading in
this context is when a symbol is able to do more than
one kind of operation in a language.) If one of the operands
to the operator, + is a String object, the other type will
either be promoted to String type (as in the case of
primitives) or the toString( ) method will be called on it
(in the case of object types.) In the following case each
primitive value represented by x and y will be supplied
in their String form.

Example      

System.out.println(" x is " + x + "y is " + y );  


Common String class Construction

Following are two common constructions of a String
object. The first uses a constructor
while the second
is a String literal assignment.

Example1

String s1 = new String( "common constructor"); 

// via  a  constructor

Example 2   

String s2 = "a string literal";          

// assigning a string literal

There are several String constructors ( 9 ) and String
objects can be created in a number of ways. The following
example shows a String object constructed from an array
of char type.

Example

String ball = "balloon";    // is equivalent to:

char parts[] = {'b', 'a', 'l','l','o','o','n'};
String ball2 = new String(parts);


Deep and Shallow Comparisons



When reference types are compared via the equality
operator, ==, the addresses stored in the references are
compared. This is called a shallow comparison. If the
equals( ) method is used, the contents pointed to by the
address stored in the reference is compared. This is a
deep comparison
. The following two cases cover the
different unique circumstances that may occur.

Comparisons of Same Addresses & Same Stored Values

To complicate matters, the Java environment maintains
'a pool of string literals'. Each string literal is represented
in the pool. Identical string literals are only represented
once  in the pool of literals
during a Java program's run.

// the string literal pools complicates matters

If an identical literal is used twice in a program, it is only
represented once in the literal pool. When deep and
shallow
comparison are made on the two references representing
the same string literal value
the result is consistent with
this fact. The addresses will be the same and the deep
comparison of value will also be the same. 


Example 

String xx = "X";
String xy = "X";

if (xx.equals(xy))        

// a 'deep' comparison ( of values stored ) resolves to true

// . . .

if (xx = = xy)     

// a 'shallow' comparison for these references also resolves to true

The second "shallow" comparison also resolves to true
as the addresses where the string literal, "X" is stored,
is the same location. 


Comparisons of  Different Addresses but Same Values

On the other hand, when a reference is created via a
constructor that points to a String literal, first the
literal
is recorded in the literal pool and then a new string is
created in memory, copied from the one in
the literal
pool. This copy is stored at a different location and so,
will not share the same address
as the one in the literal
pool.


Example 2

String yy = "X";
String yx = new String("X");
if (yy.equals(yx))               
 
// a 'deep' comparison (of stored values) resolves to true

// however the shallow comparison resolves to false

if (yy = = yx)                       
 

Code Sample Demonstating Deep and Shallow Comparison

class sTz{
public static void main(String[] args){

  // First Scenario

  String xx = "X";
  String xy = "X";
   if (xx.equals(xy))
     System.out.println
     ("\n"+"A deep comparison tests true for comparison on literal assignmnents");
  if (xx == xy)
     System.out.println
     ("A shallow test yields true indicating one value is stored at one address \n");

   // Second Scenario

  String yy = "X";
  String yx = new String("X");

    if (yy.equals(yx))
       System.out.println
       ("Values are the same when assigned by literal or by literal-supplied constructor");
    if (yy == yx)
    ;
    else
    System.out.println
   ("Shallow tests false showing the two values are stored at different addresses");
    }
  }


OUTPUT

> java sTz

A deep comparison tests true for comparison on literal assignmnents
A shallow test yields true indicating one value is stored at one address

Values are the same when assigned by literal or by literal-supplied constructor
Shallow tests false showing the two values are stored at different addresses



String Class Documentation    //    documentation just for reference   


Following is a summary of the String class constructors
and methods.
This lift is from an older JDK and more
may have been added by now.
This is provided to overview String class capabilities.


Constructor Summary

Here are 9 String constructors that show String instances can be created
from an
empty character sequence, a provided String object (where in fact
a copy is created
and encapsulated in the new instance), a  StringBuffer
instance, and arrays. (or parts
of arrays), of byte and char type, with or
without specified character encodings.

 
 

 String( ) 

 Initializes a newly created String object so
that it represents
an empty character sequence.

 String(byte[] bytes) 

 converts array of bytes using the platform's
 default character encoding to String.

 String(byte[] bytes, 
 int offset,  int length) 

 convert specified subarray of bytes using  the
platform's default character encoding to String.

 String(byte[] bytes, int offset, 
 int length, String enc) 

 convert the specified subarray of bytes using
 the specified character encoding to String.

 String(byte[] bytes,
 String enc) 

 converts the specified array of bytes using
 the specified character encoding to String.

 String(char[] value) 

 creates a new String representing the character
 sequence contained in the character array

 String(char[] value,
 int offset, int count) 

 creates a new String representing the character
 sequence contained in the character sub-array

 String(String value) 

 Initializes a newly created String object that
 is a copy of
the argument  string.

 String(StringBuffer buffer) 

 creates a new String based on the character
 sequence
contained in the String buffer.

   //  constructors deprecated because they didn't work properly are left out

 
Method Summary
   // the short summary from the JDK API documentation
 

 char charAt(int index) 

 Returns the character at the specified index.
 // index is offset i.e. first character is at 0

 int compareTo(Object o) 

 Compares this String to another Object.

 int compareTo(String StringB ) 

 Compares two strings lexicographically.
// returns a negative int if string is less than
// argument, 0 if the same, and a positive int
// if greater than (See API for details) 

 int compareToIgnoreCase
 (String str)

Compares two strings lexicographically,
ignoring case considerations.

String concat(String str)

 Concatenates the specified string to the end
 of this string.

 static String copyValueOf
 (char[] data)

 Returns a String equivalent to the given
 character array.

static String copyValueOf
(char[] data, int offset, int count)

 Returns a String equivalent to the given
 character sub-array.

boolean endsWith(String suffix)

Tests if this string ends with the specified suffix.

boolean equals(Object anObject)

 Compares this string to the specified object.

boolean equalsIgnoreCase
(String anotherString)

 Compares this String to another String, ignoring
 case considerations.

byte[] getBytes( )

 Converts String to bytes according to the
 platform's default  character encoding, storing
 the result into a new byte array.

byte[] getBytes(String enc)

convert String to bytes according to the
specified character
encoding, storing the
result into a new byte array.

void getChars(int srcBegin, int  srcEnd, char[] dst, int dstBegin)

Copies characters from this string into the
destination character array.

 int hashCode( )

Returns a hashcode for this string.

 int indexOf(int ch)

Returns the index within this string of the
first occurrence of the specified character.

 int indexOf(int ch, int fromIndex)

Returns the index within this string of the first occurrence of the specified character, starting
the search at the specified index.

 int indexOf(String str)

 Returns the index within this string of the
first occurrence of the specified substring.

 int indexOf
 (String str, int fromIndex)

Returns the index within this string of the first occurrence of the specified substring, starting
at the specified index.

 String intern( )

Returns a canonical representation for the
string object.

 int lastIndexOf(int ch)

Returns the index within this string of the
last occurrence of the specified character.

 int lastIndexOf
 (int ch, int fromIndex)

Returns the index within this string of the
last occurrence of the specified character,
searching backward starting at given index.

 int lastIndexOf(String str)

Returns the index within this string of the
rightmost occurrence of the specified substring.

 int lastIndexOf
 (String str, int fromIndex)

 Returns the index within this string of the last occurrence of the specified substring.

 int length( )

Returns the length of this string.

 boolean regionMatches (boolean 
 ignoreCase, int toffset, String other,  int ooffset, int len)

Tests if two string regions are equal.

boolean regionMatches(int toffset,
String other, int ooffset, int len)

Tests if two string regions are equal.

 String  replace
 (char oldChar, char newChar)

Returns the string that result from replacing
all occurrences of oldChar with newChar.

boolean startsWith(String prefix)

Tests if this string starts with the specified prefix.

 boolean startsWith
 (String prefix, int toffset)

Tests if this string starts with the specified prefix beginning a specified index.

 String substring(int beginIndex)

Returns a new string that is a substring of
this string.

 String substring
 (int beginIndex, int endIndex)

Returns a new string that is a substring of
this string.

 char[] toCharArray()

Converts this string to a new character array.

 String toLowerCase( )

 Converts all of the characters in this String
to lower case using the rules of the default
locale, which is returned by Locale.getDefault.

 String toLowerCase
 (Locale locale)

 Converts all of the characters in this String to
lower case using the rules of the given Locale.

 String toString()

This object (which is already a string!) is itself returned.

 String toUpperCase()

Converts all of the characters in this String to
upper case using the rules of the default locale, which is returned by Locale.getDefault.

 String toUpperCase(Locale locale)

Converts all of the characters in this String to upper case using the rules of the given locale.

 String trim()

Removes white space from both ends of this string.

 static String valueOf(boolean b)

 Returns the string representation of the
boolean argument.

 static String valueOf(char c)

Returns the string representation of the char argument.

 static String valueOf(char[] data)

Returns the string representation of the char array argument.

 static String valueOf
 (char[] data, int offset, int count)

Returns the string representation of a specific subarray of the char array argument.

 static String valueOf(double d)

Returns the string representation of the
double argument.

 static String valueOf(float f)

Returns the string representation of the float argument.

 static String valueOf(int i)

Returns the string representation of the int argument.

 static String valueOf(long l)

Returns the string representation of the long argument.

 static String valueOf(Object obj)

Returns the string representation of the
Object argument.


String Class Code Example

The following code example shows that the methods of
the String class are pretty straight forward to use.
 

import java.io.*;

class StringT{
public static void main(String[] args){

  char[] sa = {'S', 'a', 't', 'u', 'r','n'};
  String string = new String(sa);                             
// one of String's constructors

  System.out.println("\n 1. string has the value " +string );

  String sb = " Rings"; // added a space!
  int i = string.compareTo(sb);                                                        
// compareTo( )

  System.out.println(" 2. The lexigraphical comparison yields " + i );

  String cat=string.concat(sb);                                                         
// concat( );

  System.out.println(" 3. sb concatenated to string is: " + cat + "\n");

try{
  byte[] b= new byte[string.length( )];
  System.out.println(" 4. string length is " +string.length( )+"\n");
  for(int k=0;k<b.length;k++){
      b = string.getBytes("8859_1");
//  getBytes("8859_1") with character encoding

      System.out.println(b[k]);
      }
    }
    catch(UnsupportedEncodingException uee){ 
// have to catch unsupported encoding

    System.out.println("Unsupported Encoding");
    }

int j = string.indexOf("St");                                                                         
// indexOf( )

System.out.println("\n 5. The first occurence of ring is at index " + j );
// This reports index 0 so think of the index like an offset starting at zero
int z = (int)'T';                                                              
// casting a char type to an int

System.out.println(" 6. The char literal T cast to an int is "+ z);

System.out.println(" 7. before and after trim() \n");                                            
// trim( )

System.out.println("    before length: " + "   xyz   ".length()); 
// calling on string literals

System.out.println("    after length: " + "   xyz   ".trim().length());
String string2=string.valueOf(sa);                                      
// valueOf used on a char array

System.out.println("\n 8. This is sa array returned as a string " + string2);
 }
}

OUTPUT

> java StringT

 1. string has the value Saturn
 2. The lexigraphical comparison yields 51
 3. sb concatenated to string is Saturn Rings

 4. string length is 6

83
97
116
117
114
110

 5. The first occurence of ring is at index -1
 6. The char literal T cast to an int is 84
 7. before and after trim()

    before length: 9
    after length: 3

 8. This is sa array returned as a string Saturn



Wrapper Classes



Sometime you will need to treat a primitive type, such as an int
or boolean type as an object. For example, a primitive type cannot
be added directly to a Vector. Often though, number data would
need to be added to a Vector. Vector can only receive Object

types.

Wrapper classes serve in this role, to encapsulate primitive types
in class objects so they can be treated like object types. For instance,
Integer
is the wrapper class for integers. A wrapper class exists for
each of the primitive types.

The Wrapper class name for each primitive can be deduced by
starting the unabbreviated version of the primitive type name with
capitals. F
or example, int type's wrapper class is the Integer class,
while the char type's wrapper is the Character class. All the primitives
and their corresponding wrapper classes are listed in the following
table.
 

 Wrapper Class for each Primitive Type
 

 Wrapper 

 Primitive

 Boolean

 boolean

 Character

 char

 Byte

 byte

 Short

 short

 Integer

 int

 Long

 long

 Float

 float

 Double

 double


Besides providing objects types for primitives, wrapper classes
store useful constants and methods to convert to and from String
and other types. In the following example one of the important roles
wrapper classes serve is shown.
 

Wrapper Classes Represent Immutable Values Like the String Class

Another important point about the wrapper classes, they are like
the String class and represent immutable values.  There is a similarity
between the wrapper classes and the String class in that the String
class represents a wrapper for a collection of primitive 'char' type and
the wrapper classes serve as containers for the other numerical
primitive types.   

// String though is an array of chars while wrappers represent single numbers


Wrappers Have Important Type Conversion Methods

The Integer wrapper class static parseInt( ) method converts a
String value to an int value. In fact each of the wrappers has an
equivalent method. This is important as numbers are often provided
as String type and need to be converted.

In the case of the Integer wrapper class, the object is built
by passing an int value as an argument to the Integer class
constructor.

Example

Integer integer = new Integer(2012);

Object classes toString( ) method can be implicitly invoked
to render a String version of the object.

Example

public class _2012{
    
  static Integer integer = new Integer(2012);
  public static void main(String[]args){
  System.out.println(integer);
  }
}

Following is some code that examples some of the methods
that the wrapper classes offer. A String value is received
from the command line and converted to an int by the
static parseInt( ) method of the Integer class. This int
is wrapped in it's own Integer wrapper class. A conversion
method is called on this object and the initial value is
returned as a float. W
e don't have to catch the runtime
NumberFormatException but nothing stops us from doing
so.

 
Wrapper Class Code Example                                                                      

 /* parseInt() is a static method called here on the class  * name  */

class Wrap{
public static void main(String[] args){
if(args.length < 1){
System.out.println("Enter a number at the command line");
System.exit(0);
}
try{
int i=Integer.parseInt(args[0]);
Integer theWrapperClass= new Integer(i);
float f = theWrapperClass.floatValue( );
// intValue( ) returns enclosed wrappers int value
System.out.println("Here's your number as a float: " + f);
}
catch(NumberFormatException nfe){
System.out.println("Your number is too big or has a format problem");
System.exit(0);
 }
}
}
//  The number output converts to exponential floating point
// form at 10 million. A
NumberFormatException is thrown
// when the range of an int is exceeded,
~  +/-  2.147 billion.
                


The Math Class     



Math contains a collection of mathematical methods and
two constants. The constants are
Math.PI and Math.E.
Both are public, static, final and double. The Math class

itself is made final so cannot be sub-classed.  It's
constructor is private so it cannot be
instantiated. It's
methods and constants are static so can be accessed
through the
class name. This results in a rigid class
definition, with tight security controls.

The way the Math class has been created makes it
very easy to use.  Static method invocations are made
on the class name.

Example   Math.random( );


A Brief look at Math class Methods

abs( )
There are four versions of abs( ), each which returns an
absolute value for a value
provided which may be int, long,
float, or double. 
// resolves a -2 to a 2


ceil( )
& floor( )

These methods take and return doubles corresponding to
the nearest int value above
or below the double provided 
// ceil( ) will resolve a 1.1 to a 2 


max( )
& min( )

There are four versions of each max( ) and min( ) for int,
long, float and double types.
These methods take two
values and return the greater or the lesser of two,
respectively.


random( )

random( ) returns a random number between 0.0 and just
less than 1.0. This method
acts as a wrapper for the
creation of an instance of the Random class which is
one of
the utility methods supplied in the java.util package.

// Random # formula: random number = (int)( Math.random( )*number_range) + 1

round( )
Two forms of this method are available to round a float (to
an int) or a double (to a long)


sin( ), cos( )
& tan( ) 
// there are also asin acos atan & atan2
These methods take doubles and return the sine, cosine,
and tangent as doubles.


sqrt(
double d )

sqrt( ) returns the square root of a double provided as an
argument


pow(
double number, double power)

pow( ) returns a number evaluated to a given power


log( )

Returns the natural logarithm (base e) of a double value.


exp( )

Returns the exponential number e (i.e., 2.718...) raised to
the power of a double value.


rint( )

takes a double, rounds to an int then returns this value
as a double


IEEEremainder(double f1, double f2 )

returns an IEEE formulated remainder of a division

// supplemental information The remainder value is mathematically
// equal to f1 - f2 × n, where n
is the mathematical integer closest
// to the exact mathematical value of the quotient f1/f2, and if
two
// mathematical integers are equally close to f1/f2, then n is the
// integer that is even.)


toDegrees( )
// new since  JDK1.2
Converts an angle measured in radians to the equivalent
angle measured in degrees.


toRadians( ) // new since  JDK1.2
Converts an angle measured in degrees to the equivalent
angle measured in radians.

// these methods may through a runtime NumberFormatException
// Try entering something like 5y5 and see the error report

 

Math Code Example

   class MathMethods{
      public static void main(String[] args){
         if(args.length <6){
             System.out.println("Enter 6 numbers at the command line");
             System.exit(0);
             }
      int a=Integer.parseInt(args[0]);
      int b=Integer.parseInt(args[1]);
      int c=Integer.parseInt(args[2]);
      int d=Integer.parseInt(args[3]);
      int e=Integer.parseInt(args[4]);
       int f=Integer.parseInt(args[5]);
      double t;
      int[] intArray=new int[ ]{a,b,c,d,e,f};

          for ( int i=0; i < intArray.length - 1; i++ ){
              int z=Math.min(intArray[i],intArray[i+1] );
              intArray[i+1]=z;
              }
      int small=intArray[intArray.length-1];
      System.out.println("The smallest number in this set is "+small);
      System.out.println
      (" The square root of this number is " + Math.sqrt(small ) +
      "\n which when rounded is " +Math.round( Math.sqrt(small) )  );
      }
   }


New Math  // just for Reference


New Math Class, StrictMath

StrictMath is a parallel class that offers roughly the
same methods as the Math class but offers 'bit by bit
same results.' The added strictness comes at the cost
of performance. In many cases both classes are using
the same functions.

New Math Methods    // for refererence

New Math methods have snuck in in later versions
of the JDK. ( 1.4.x and 1.5.x )


cbrt(double a) 

Returns the cube root of a double value

cosh( double x)
Returns the hyperbolic cosine of a double value.

expm1(double x)
Returns ex -1.
Note that for values of x near 0, the exact
sum of
expm1(x) + 1 is much closer to the true result of
ex than exp(x)
hypot(double x,double y)
Returns sqrt(x2 +y2)without intermediate overflow or
underflow.

log1p(double x)

Returns the natural logarithm of the sum of the
argument and 1.

signum(float f)

Returns the signum function of the argument; zero
if the argument is zero, 1.0f if the argument is greater
than zero, -1.0f if the argument is less than zero.

ulp(float f)

Returns the size of an ulp of the argument. An ulp of
a
float value is the positive distance between this
floating-point value and the
float value next larger in
magnitude.


Had to try ulp( ) !

class Gulp{
public static void main(String args[]){
for(float f = 0.0F; f < 0.000000000001F ; f= f + .0000000000001F){
System.out.println(Math.ulp(f) + " ");

// Also works with no difference in this example
// System.out.println(StrictMath.ulp(f) + " ");


}
}
}
OUTPUT

> java Gulp
1.4E-45
6.7762636E-21
1.3552527E-20
2.7105054E-20
2.7105054E-20
5.421011E-20
5.421011E-20
5.421011E-20
5.421011E-20
5.421011E-20
1.0842022E-19


The Vector Class



One of the principle drawbacks of using arrays is they
need to be fixed in length. They don't lend themselves
to dynamically changing size. A Vector is a Java class
that acts as a container similar to an array but one which
can grow or shrink in size to allow objects to be added or
removed after the Vector has been created. While arrays
are a built-in feature of the Java language the Vector class
is a regular Java library class and will be referenced via
the java.util package.

// Vector is in the java.util package, unlike an array it is growable

Unlike arrays, which can be specified for any type defined
in Java (primitives, arrays, and Object types ), Vectors
store one generic type, that of Object. It is easy to add
an item to a Vector but to get it back it has to be cast
to the appropriate type.

Vector, unlike the String, Math and the wrapper classes
are not in the java.lang package. To use the Vector class
the java.util package needs to be imported or Vector's
fully qualified name needs to be used,  java.util.Vector.

Example   

import java.util.Vector;

// or import java.util.*; or use fully qualified name

Following is the class signature of the Vector class and
it's hierarchy.
 

Vector Class Signature

public class Vector
extends AbstractList implements List, Cloneable, Serializable

Vector Class Hierarchy

 java.lang.Object
   |
  +--java.util.AbstractCollection
         |
        +--java.util.AbstractList
               |
              +--java.util.Vector

// the inheritance tree shows Vector is a type of List and also implements
// the List interface
A list is an ordered collection (also known generically
// as a sequence).

A Vector is created via one of it's four constructors. Vector has
an empty constructor and a constructor that takes a Collection
object. It also has a constructor that allows setting the initial
capacity of the Vector. A fourth constructor allows specifying
the initial capacity and the capacity increment. The capacity
increment decides the size that the vector will grow by and is
automatically set to the size of the vector.

// capacity is automatically set to the size of the vector

Vector implements the methods of the List interface plus about
15 other methods for a total of about 40 methods. This shows
you that Vector has quite a bit of versatility absent in the array.

Classic Instantiation Form

Vector v=new Vector( 5 );  
// this is a Vector with it's initial capacity set to 5.

You can use add( ) and addElement( ) methods to add items to
the Vector and
remove( ) or removeElement( ) methods to remove
items. Primitive types need to
be 'wrapped' in appropriate wrapper
classes to be stored in a Vector. The
elements( ) method will return
an Enumeration object which you can iterate with
Enumeration's
hasMoreElements( ) and nextElement( ) methods. elementAt( )

returns a component at a specified index.

Evidence of Underlying Object Array

It is interesting to note that the Vector object will allow more items
to be added than was declared to the constructor
as the initial
capacity. But if an access is attempted beyond the last element 
added
a runtime exception ArrayOutOfBoundsException is thrown.
This, together with the fact that Vector only takes Object type, 
indicates that an Object array is used at the heart of a Vector

class. This array is copied to a bigger array when the stated
capacity of the
Vector is exceeded.

// The fact an ArrayOutofBoundsException may be thrown indicates that
//
Vector is a wrapper for an array accessorized with 'growable' algorithms


Vector Code Sample Classic Version // with casting

import java.util.*;

class VectorTest{
public static void main(String[]args){
  Vector v=new Vector(3);
  Integer i1=new Integer(1);
  Integer i2=new Integer(2);
  Integer i3=new Integer(3);
  Integer i4=new Integer(4);

  v.add(i1);
  v.add(i2);
  v.add(i3);
  v.add(i4); // not like array. Vector adds past capacity.
  Integer five=(Integer)(v.elementAt(3));
  System.out.println(five.intValue());
  }
}

Attack of the Generics!  // as of JDK 1.5

Stop right there. That was the way we would instantiate
a collection class like a vector. This whole idea of allowing
a general Object type to be stored made those who wanted
stricter type safety uncomfortable.

As a result in JDK 1.5 Generics were introduced. This
allowed specifying precisely the
type of objects that
would be stored in classes like Vector. This can include
Object type which allows the classic behaviour to remain.

The above instantiation in the brave new world of JDK1.5
might take the look of the following.

New Generic Instantiation Form

Vector<Integer> v=new Vector<Integer>(3);

The 1.5 equivalent of the old form is:

Vector<Object> = new Vector<Object>(5) ;

Following the code is rewritten with Generics. Notice
a benefit is we no longer need to cast our values back.


Vector Code Sample With Generics // don't need the cast back

import java.util.*;

class VectorTest{
public static void main(String[]args){
  Vector<Integer> v=new Vector<Integer>(3);
  Integer i1=new Integer(1);
  Integer i2=new Integer(2);
  Integer i3=new Integer(3);
  Integer i4=new Integer(4);

  v.add(i1);
  v.add(i2);
  v.add(i3);
  v.add(i4); // not like array. Vector adds past capacity.
  Integer five=v.elementAt(3);
  System.out.println(five.intValue());
  }
}

Constructor Summary      // from the jdk documentation
 

Vector( ) 

 Constructs an empty vector so that its internal data array 
 has size 10 and its standard capacity increment is zero.

Vector
(Collection c) 

 Constructs a vector containing the elements of the 
 specified collection, in the order they are returned by
 the collection's iterator.

 Vector
(int initialCapacity)

 Constructs an empty vector with the specified initial
 capacity and with its capacity increment equal to zero.

 Vector(int initialCapacity,
   int capacityIncrement)

Constructs an empty vector with the specified initial
 capacity and capacity  increment. 


Method List

 

 void  add (int index, 
        Object element)

 Inserts the specified element at the specified position 
 in this Vector.

 boolean add(Object o)

 Appends the specified element to the end of this Vector.

 boolean addAll
 (Collection c)

 Appends all of the elements in the specified Collection
 to the end of this Vector, in the order that they are 
 returned by the specified Collection's Iterator.

 boolean addAll
 (int index, Collection c)

 Inserts all of the elements in in the specified Collection
 into this Vector at the specified position.

 void  addElement 
 (Object obj)

 Adds the specified component to the vector end, 
 increasing its size by one.

int capacity()

 Returns the current capacity of this vector.

void clear ( )

 Removes all of the elements from this Vector.

Object clone( )

 new Returns a clone of this vector.

 boolean contains
 (Object elem)

 Tests if the specified object is a component in 
 this vector.

 boolean containsAll 
 (Collection c) 

 Returns true if this Vector contains all of the 
 elements in the specified Collection.

 void copyInto
 (Object[] anArray)

 Copies the components of this vector into
 the specified array.

Object elementAt(int index)

Returns the component at the specified index.

Enumeration elements()

 Returns an enumeration of the components of 
 this vector.

void ensureCapacity
(int minCapacity)

 Increases the capacity of this vector, if necessary,
 to ensure that it can hold at  least the number of 
 components specified by the minimum capacity 
 argument.

boolean equals(Object o)

 Compares the specified Object with this Vector
 for equality. 

Object firstElement( )

 Returns the first component (the item at index 0) 
 of this vector.

Object get(int index)

 Returns the element at the specified position in 
 this Vector.

int hashCode()

Returns the hash code value for this Vector.

int  indexOf(Object elem)

Searches for the first occurence of the given argument, 
testing for equality using the equals method.

 int  indexOf
 (Object elem, int index)

 Searches for the first occurence of the given argument, 
beginning the search at index, and testing for equality 
 using the equals method.

void  insertElementAt
(Object obj, int index)

 Inserts the specified object as a component in this 
 vector at the specified index.

boolean isEmpty()

 Tests if this vector has no components.

Object lastElement( )

 Returns the last component of the vector.

int lastIndexOf(Object elem)

 Returns the index of the last occurrence of the 
 specified object in this vector.

int lastIndexOf
(Object elem, int index)

 Searches backwards for the specified object, starting
 from the specified index, and returns an index to it.

Object remove(int index)

 Removes the element at the specified position in this 
 Vector.

boolean  remove(Object o)

 Removes the first occurrence of the specified element
 in this Vector If the Vector does not contain the element,
 it is unchanged.

 boolean  removeAll 
 (Collection c) 

 Removes from this Vector all of its elements that are 
 contained in the specified Collection.

 void removeAllElements()

 Removes all components from this vector and 
 sets its size to zero.

 boolean  removeElement
 (Object obj)

 Removes the first (lowest-indexed) occurrence of
 the argument from this vector.

 void removeElementAt
 (int index)

 Deletes the component at the specified index.

protected void removeRange
(int fromIndex, int toIndex)

 Removes from this List all of the elements whose index 
 is between fromIndex, inclusive and toIndex, exclusive.

 boolean retainAll
 (Collection c)

Retains only the elements in this Vector that are
 contained in the specified Collection.

 Object set
 (int index, Object element)

 Replaces the element at the specified position in this 
 Vector with the specified element.

 void setElementAt
 (Object obj, int index)

 Sets the component at the specified index of this 
 vector to be the specified object.

 void setSize(int newSize)

 Sets the size of this vector.

 int size() 

 Returns the number of components in this vector.

 List subList
 (int fromIndex, int toIndex)

 Returns a view of the portion of this List between 
 fromIndex, inclusive, and toIndex, exclusive.

 Object[] toArray()

 Returns an array containing all of the elements in
 this Vector in the correct order.

 Object[] toArray(Object[] a)

 Returns an array containing all of the elements in
 this Vector in the correct order.

 String toString()

 Returns a string representation of this Vector, 
 containing the String representation of each element.

 void trimToSize( )

 Trims the capacity of this vector to be the vector's 
 current size.




Self Test                                       Self Test With Answers



1) If used inside one of the constructors of a class called Cat which
    of the following would the constructor this( 1.1, 2.2 ) call?

a ) Cat (double x, double y ) { /* */ }
b)  Cat( int j, int k ) { /* */ }
c)  Cat(  ) { /* */ }
d)  Cat  ( float u, int p ) { /* */ }


2) What will the following print out? Select the correct answer.

String x1 = "X";
String x2 = "X";
if (x1.equals(x2))
System.out.println( "Positive")
else
System.out.println("Negative")

a ) Positive
b ) Negative


3) What will the following print out? Select the correct answer.
String x1 = "X";
String x2 = "X";
 

if (x1==x2)
System.out.println( "Positive")
else
System.out.println("Negative")

a )
b)


4) One of the following is not a valid wrapper class. Which is it?

a) Float
b) Int
c) Double
d) Long


5)  Which of the following statements is not correct?

a) The Math class itself is final so can only be extended once
b) Math's constructor is private so it cannot be instantiated.
c) Math methods and constants are static
d) Math methods are only accessible through the Math class name
 

6) Math.floor(44.4) returns
a) 45
b) 45.0
c) 44
d) 44.0


7) Which of the following is not in the java lang package

a) Vector
b) Boolean
c) Math
d) String

8 ) Which of the following statements is not correct?

a) The number of objects added may exceed the capacity.
b) The no-args Vector constructor defaults to an initial capacity set to 5.
c) To return an element to it's original type typically requires a cast.
d) Vector can throw an exception is an element index is addressed
    higher than the number of elements that have been added to the
    Vector.



Exercise



Using Constructors

1 ) Create a parent class with three different constructors. Include one
no-arg constructor. The other two constructors will be overloaded and
takes different arguments, distinguished either by type, number or order.

In a child class constructor invoke one of the parent constructors that
takes arguments using the keyword 'super'. Then in the child, use the
'this' keyword in another constructor to invoke the constructor that has
used the 'super' keyword. Add some symbolic accessory features to the
second constructor, even just comments or actions represented by
System.out.println statements.


Using Lang Classes

2) Create a class that takes a name in at the command line. Use methods
of the String class to convert the name to uppercase and pre- and postfix
the name with exclamation marks. Then write to the command line the
'dressed' name in conjunction with a statement something like  "!!! BOB !!!
You have won a new car!"


3) Create two wrapper classes that store a height and width of a right-
angled triangle.
Pass these values in at the command line when the
program is invoked. Store these
two classes in a Vector. Access the
Vector elements and retrieve the wrapped values.

Figure out the hypotenuse using Math methods and store this value in
another wrapper
class. Access the third wrapper class and write the
three values in a statement to
screen. (i.e. A triangle with a width of
___ and a height of ____ has a hypontenuse
value of ______ )


// it would be tempting to just store the final value in the Vector but for exercise
// we take the long way around and store the two entered values in the Vector
// before accessing them to compute the hypotenuse.



PS. If you forgot the Pythagorean theorem, it states that the sum of
the squares of
of the sides of a right angled triangle is equal to the
square of the hypotenuse.


A 2  =    B 2    +  C 2


Optional Approaches    



Using Command Line IO


You can use the String[ ] supplied by main to enter
values to your program. There
are a couple examples
of this technique shown in the above note. This
functionality
would typically be used to configure
your application.  For instance, if your program
was
creating a net connection, you could enter a port
number other than the default.


You may wish to use an 'inline' approach based classes
in the io package as in the
following partial excerpt. Either
way is good to practice. The following code is pretty
primitive. Making it more sophisticated has the
disadvantage of making it complex.
It does show a
formula for entering values at the command line.



import java.io.*;

class AverageTwoNumbers
{
  
public static void main(String[]args)
   {
   String value = "";
   int sum = 0;
   int average = 0;

   BufferedReader in = new BufferedReader
   (new InputStreamReader(System.in));
 
   System.out.println( " Enter a mark " );
   try{
        value = in.readLine( );
        int holding = 0;
      
        try{
             holding = Integer.parseInt(value);
             sum = sum + holding;
            }
        catch(NumberFormatException ne){
             System.out.println( "Your number was not well formed");
             }
        
   
        System.out.println( "You have entered: " + value);
        System.out.println(" Type in another value ");
   
        value = in.readLine( );

       
         try{
             holding = Integer.parseInt(value);
             sum = sum + holding;
             }      
          catch(NumberFormatException ne){
               System.out.println( "Your number was not well formed. Run again.");
               return;
               }
        
       
        average = sum /2;
        System.out.println("The average of the two numbers is: " + average);
     }
      catch(IOException io){System.out.println("IOException thrown");}

   }
 }    


Using JOptionPane

You can also use the handy JOptionPane to do input and
output at the keyboard. JOptionPane supplies a handy
lightweight GUI for entering and displaying data. Followng
is sample code showing JOptionPane being used. The
Double wrapper class is also used. To add a degree of
robustness, we add exception catching for the exception,
NumberFormatException.

JOptionPane Sample Code


import javax.swing.*;


public class LightGUI {
public static void main(String[]args){

try{

  double base;
  double height;

  String baseInput = JOptionPane.showInputDialog
  ("What is the length of the base of the triangle?");

  base = Double.parseDouble(baseInput);

  String heightInput = JOptionPane.showInputDialog
  ("And what is the height of the triangle?");

  height = Double.parseDouble(heightInput);

  double areaTriangle =  base * height  / 2 ;

  JOptionPane.showMessageDialog
  (null, "The area of your triangle is " + areaTriangle);

}
catch(NumberFormatException nfe){
 JOptionPane.showMessageDialog
 (null, "Your number is too large or incorrectly formatted.");

 }
System.exit(0);
}
}