SDSU CS 596 Java Programming
Fall Semester, 1998
Classes (2): References & Static
To Lecture Notes Index
© 1998, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 19-Sep-98

Reference


The Java Programming Language, 2 ed., Arnold & Gosling, Chapter 2



Listen Here!S-sept16 2mins, Q-sept17 2mins Doc 5, Classes (2): References & Static Slide # 2

Object Variables are References


This example shows two objects references, sam and samTwin, referencing the same object. This is demonstrated by using the samTwin reference to change the value of the field grade, and using the reference sam to display the new value.

public class  Student  
{
   public  char  grade;
}

public class PointerTest 
{
   public static void main( String args[] ) 
   {
      Student  sam  =  new  Student();
      sam.grade  =  'A';
      Student  samTwin  =  sam;
      samTwin.grade  =  'C';
      System.out.println( sam.grade );
   }
}
Output
C


Doc 5, Classes (2): References & Static Slide # 3
Parameter Passing - By value only

Parameter passing is by value only. Since we have only references to objects, it is possible for a method to permanently change the value of an object's state (that is the value of one or more of its fields). However, a method can not permanently change a parameter reference.

This is demonstrated on the next slide. The method changeReference() points the reference "unlucky" to a new object reference, which has the grade "A". However, the change is not reflected outside of the method. The method changeState() changes the value of the referenced object field. This change is reflected outside the method.


Listen Here!S-sept16 8secs Doc 5, Classes (2): References & Static Slide # 4
Parameter Passing & Objects

public class  Student  
{
   public  char  grade;
}
public class TestParameter   
{
   public static void main( String args[] ) 
   {
      Student    sam  =  new Student();
      sam.grade   =  'C';
      changeReference(  sam  );
      System.out.println(  sam.grade );
      changeState(  sam  );
      System.out.println(  sam.grade );
   }
   public  static void  changeState(  Student  lucky  )  
   {
      lucky.grade  =  'A';
   }
   public static void changeReference( Student unlucky )
   {
   unlucky = new Student();
   unlucky.grade = 'A';
   }
}
Output
C
A

Listen Here!S-sept16 5mins, Q-sept17 9mins Doc 5, Classes (2): References & Static Slide # 5

Static Members

Static Fields


There is only one copy of a static field

All objects created from the class reference the same copy of a static field

A static field exists before creating an object of the class

The following example shows how a static field can be referenced through an object (top.size) or through the class name (StaticFields.size). It also shows that the two objects, top and bottom, reference the same static field "size".

public class  StaticFields
{
   public  static  int  size  =  10;
   public void increaseSize( int increment )
   {
      size =  size + increment;
   }
}
public class  DemoStaticFields
{
   public  static  void  main( String[]  arguments )
   {
      System.out.println( "Size " + StaticFields.size );
      StaticFields top  =  new  StaticFields();
      StaticFields bottom  =  new  StaticFields();
      top.size = 20;
      System.out.println( "Size " + bottom.size );
   }
}
Output
Size 10
Size 20

Listen Here!S-sept16 7mins, Q-sept17 4mins Doc 5, Classes (2): References & Static Slide # 6

Static Methods (Class Methods)


Static methods can only access static fields and other static methods in the class

Static methods can be referenced via an object or the class

public class  StaticMethods
{
   public  static  int  size  =  10;
   public static void increaseSize( int increment )
   {
      size =  size + increment;
   }
}
public class  DemoStaticMethods
{
   public  static  void  main( String[]  arguments )
   {
      StaticMethods.increaseSize( 30 );      //Note use of class name
      System.out.println( "Size " + StaticMethods.size );
      StaticMethods top  =  new  StaticMethods();
      top.increaseSize( 20 );
      System.out.println( "Size " + StaticMethods.size );
   }
}
Output
Size 40
Size 60

Listen Here!S-sept16 2mins Doc 5, Classes (2): References & Static Slide # 7

Static Initialization Blocks


A static initialization block is an initialization block preceded with the quantifier "static". A static initialization block is normally executed only once each time your program is run. It will be executed before any object is created or any reference is to the class is actually made in your program. If more than one static block exists in the class, then they are executed in order, from top to bottom of the class. The static block can only reference static methods and static fields. Any static field referenced in the static block must be declared before the static block. This restriction does not hold for static methods.

public class  StaticFields   {
   public  static  int  size  =  10;
   static   {               // Run when class is first loaded 
      size  = classMethod( 20);
      System.out.println( size );
   }
   public  static  int  classMethod(  int  value  )  {
      System.out.println( "In class method" );
      return value + 10;
   }
}
public class TestStaticFields  {
   public static void main( String args[] ) {
      System.out.println( "Start Test" );      
      StaticFields     test  =  new  StaticFields  (  );
      StaticFields     secondObject  =  new  StaticFields  (  );
      StaticFields.size  =  100;
      System.out.println(  test.size  );   // Print 100
   }
}
Output
Start Test
In class method
30
100


Listen Here!S-sept16 4mins, Q-sept17 to end Doc 5, Classes (2): References & Static Slide # 8
Main revisited
There is nothing magic about the method "public static void main( String[] args )." When you execute a class with the command "java className" The JVM looks for a method called main with the exact signature and return type. If the main does not have the proper signature and return time, the JVM will report an error. So the main in OddMain below can not be used to start the class. However, the method "main" can be called from your code like any other static method, as is done in the next example. This does mean that your program can have multiple entry points, as the next example shows.

public class Top {
   public  static  void  main( String[]  arguments ) {
      System.out.println( "In top main" );
      Bottom.main( arguments );
   }
   public static void print() {
      System.out.println( "In top" );
   }
}
public class Bottom {
   public  static  void  main( String[]  arguments ) {
      System.out.println( "In bottom main" );
      Top.print( );
      OddMain.main( arguments );
   }
}
public class OddMain {
   public  static  int  main( String[]  arguments ) {
      System.out.println( "In odd main" );
      Top  hat  =  new Top();
      hat.print(  );
      return 5;
   }
}

Listen Here!S-sept16 2mins Doc 5, Classes (2): References & Static Slide # 9

Constant Fields


Declaring a field final means that it can only be set once

public class  Constants  
{
   protected  final  int  SIZE  =  10;
   protected  final  int[] CLASS_ARRAY  =  new int [ SIZE ];
   protected  final  int  NO_VALUE_YET;   // blank final
   public  void  aMethod( int input, final float FIXED)
   {
      final int NEW_FEATURE = 123;
      final int ALSO_FIXED = input;
      CLASS_ARRAY[ 3 ] = input;
   }
   
   public Constants( int aValue )
   {
      NO_VALUE_YET = aValue;
   }
   
   public static void main( String args[] ) 
   {
      Constants  test  =  new  Constants( 5);
      test.aMethod( 13, 2.2f);
      System.out.println(  test.NO_VALUE_YET   );   // Prints 5
   }
}


Doc 5, Classes (2): References & Static Slide # 10
Blank Final Rules

A blank final is a final variable declaration that lacks an initializer

A blank final must be assigned exactly once

A blank final class (static) variable must be assigned by one static initialization block

blank final class variable can not be assigned in more than one static initialization block

A blank final instance variable be assigned by one non-static initialization block or else by every constructor in the class

A blank final instance variable can not be assigned in a non-static initialization block and a constructor


Doc 5, Classes (2): References & Static Slide # 11
Blank Final Rules - Examples

public class  StaticConstants  
{
   protected static final  int  SIZE;
   static
   {
      SIZE = 123;
   }
}

public class  Constants  
{
   protected final  int  SIZE;
   {
      SIZE = 123;
   }
}


Doc 5, Classes (2): References & Static Slide # 12
Blank Final Rules - A JDK 1.1.6 Bug

There is a bug in the JDK 1.1.6 compiler that allows a final field to be set in multiple constructors, as is done in the example below. This bug is fixed in JDK 1.2beta4. The Java 1.2 compiler will produce a compile error when it compiles the program below.

public class  Constants  
{
   protected final  int  SIZE;
   public Constants()
   {
      this( 5 );
      SIZE = 123;
   }
   
   public Constants( int newSize )
   {
      SIZE = newSize;
   }
   
   public  static  void  main( String  args[] )
   {
      Constants whichOne = new Constants();
      System.out.println( whichOne.SIZE );
   }
}

Output
123

Doc 5, Classes (2): References & Static Slide # 13
Objects and Constant Variables

When an object reference is final, as is "object" below, the reference can be assigned only once. The state of the object can change. This is shown below where the state of "object" is legally changed by directly accessing the field and using a method. However, assigning a new reference to the variable "object" is not allowed.

public class Test
   {
   public  static  void  main( String  args[] ) 
      {
      final Sample object = new Sample();
      object.data = 5;      // OK
      object.setData( 12 );   // OK
      object = new Sample();“// Compile Error
      }
   }
public class Sample
   {
   public int data = 3;
   
   public void setData( int newValue )
      {
      data = newValue;
      }
   }


Doc 5, Classes (2): References & Static Slide # 14

Initialization Order


A class is initialized when it is first "actively" used, i.e.

A method defined in the class is invoked
A constructor in the class is invoked
A non-constant field in the class is accessed

A class is initialized by performing direct assignments of static fields and static initialization blocks are done in order from top to bottom of the class


When an object is created, after the class in initialized, all instance field are initialized by:

performing direct assignments of non-static fields and instance initialization blocks are done in order from top to bottom of the class, then the constructor is executed


Doc 5, Classes (2): References & Static Slide # 15
Initialization Order and Forward References
Don't Mix

When you initialize a field you can not make a forward reference another field

public class ForwardReferenceAndInitialization
{
   public static int first = 1;
   public static int second =  first * 2;
   public static int third = fourth - 1;       // Compiler error
   public static int fourth = 4;
   public int fifth = 5;
   public int sixth = fifth + 1;
   public int seventh = eighth - 1;      // Compiler error
   public int eighth = 8;
}

Doc 5, Classes (2): References & Static Slide # 16
Function Calls & Forward Reference

When initializing a field you can make a forward reference to a method

public class ForwardReferenceAndFunctions
{
   public int fifth = getSixth();
   public int sixth = fifth + 1;
   public int seventh = getSixth();
   public int getSixth()
   {
      return sixth;
   }
}
public class Test
{
   public static void main( String[] arguments )
   {
   ForwardReferenceAndFunctions works;
   works = new ForwardReferenceAndFunctions();
   System.out.println( "fifth " + works.fifth );
   System.out.println( "sixth " + works.sixth );
   System.out.println( "seventh " + works.seventh );
   }
}
Output
fifth 0
sixth 1
seventh 1

Doc 5, Classes (2): References & Static Slide # 17
Forward References - A Review

A method or constructor can make a forward reference to another method or a field

An initialization block can not make a forward reference to a field, but can make a forward reference to a method

A direct assignment of a field can not make a reference to a field, but can make a forward reference to a method

Doc 5, Classes (2): References & Static Slide # 18
Initialization of Default Values

If a field is not explicitly assigned a value via a direct assignment when it is declared, it is assigned the default value for its type by the JVM.

A variable in a method is not assigned a default value. A variable in a method must be explicitly assigned a value in the program before you can use the variable. It is a compile error to try to use a variable in a method before assigning it a value.

Elements of arrays are assigned default values. The reference to an array in method is not given a default value. This is shown in the example below.

public class ArrayExample
{
   public static void main( String[] args )
   {
      int[] aReference;
         
      aReference[ 2 ] = 12; //Compile error
         
      aReference = new int[ 5];
         
      System.out.println( aReference[ 3 ] );
   }
}


Copyright © 1998 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
All rights reserved.

visitors since 19-Sep-98