|
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
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
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.
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
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
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
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
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;
}
}
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
}
}
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
Blank
Final Rules - Examples
public class StaticConstants
{
protected static final int SIZE;
static
{
SIZE = 123;
}
}
public class Constants
{
protected final int SIZE;
{
SIZE = 123;
}
}
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
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;
}
}
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
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;
}
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
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
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