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

Contents of Doc 4, Classes (1): members, this, constructors, packages


Reference


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


Listen Here!S-sept9 2mins, Q-sept10 2mins Doc 4, Classes (1): members, this, constructors, packages Slide # 2

Classes


We can define classes and objects using a language approach or a conceptual approach

The language approach deals with syntax

The conceptual approach deals with purpose if classes and objects

Language Definition



Conceptual Definition



Listen Here!S-sept9 1min Doc 4, Classes (1): members, this, constructors, packages Slide # 3

Basic Terms


Javafieldmethod
C++data membermember function
Smalltalkinstance variablemethod
C???function


Class member refers to either a field or method

public class  BankAccount 
{
   public  float  balance = 0.0F;      // field
   public void deposit( float amount )   // method
   {
      balance += amount ;
   }
}

Comparisons to C++

Similar class syntax and structure

No multiple inheritance, uses interfaces instead

Functions are virtual by default

Constructors are much simpler

Destructors are not need

Packages provide separate name spaces for classes

Listen Here!S-sept9 8mins, Q-sept10 5mins Doc 4, Classes (1): members, this, constructors, packages Slide # 4

Fields

Each object has its own copy of the fields defined in the class, that is richStudent and poorInstructor have different values for the field balance. In this regard, classes are like C/C++ structs.

The fields in an object exist as long as the object exists

public class  BankAccount 
{
   public  float  balance = 0.0F;
}
public class RunBank 
{
   public static void main( String args[] ) 
   {
      System.out.println( "Start main " );
      BankAccount richStudent  =  new BankAccount( );
      richStudent.balance = (float) 100000;
      BankAccount poorInstructor  =  new BankAccount( );
      poorInstructor.balance =  5.10F;
      System.out.println( "Student Balance: " + 
                           richStudent.balance );
      System.out.println( "Prof Balance: " + poorInstructor.balance );
   }
}
Output
Start main
Student Balance: 100000
Prof Balance: 5.1


Doc 4, Classes (1): members, this, constructors, packages Slide # 5
Multi-File Programs

Put class BankAccount in file BankAccount.java

Put class RunBank in file RunBank.java

Compile top level class - javac will compile needed classes

Run program with java.

Example

rohan 21-> ls
BankAccount.java        RunBank.java
rohan 22-> javac RunBank.java
rohan 23-> ls
BankAccount.class       RunBank.class
BankAccount.java        RunBank.java
rohan 24-> java RunBank
Start main
Student Balance: 100000.0
Prof Balance: 5.1


Listen Here!S-sept9 3mins, Q-sept10 2mins Doc 4, Classes (1): members, this, constructors, packages Slide # 6

Methods

public class  BankAccount 
{
   public  float  balance = 0.0F;
   public void deposit( float amount )
   {
      balance += amount ;
   }
   public String toString()
   {
      return "Account Balance: " + balance;
   }
}
public class RunBank 
{
   public static void main( String args[] ) 
   {
      BankAccount richStudent  =  new BankAccount( );
      BankAccount poorInstructor;
      poorInstructor  =  new BankAccount( );
      richStudent.deposit( 10000F);
      poorInstructor.deposit( 5.10F );
      System.out.println( "Student Balance: " +
                                     richStudent.balance );
      System.out.println( "Prof: " + poorInstructor.toString() );
   }
}
Output
Student Balance: 10000
Prof: Account Balance: 5.1


Doc 4, Classes (1): members, this, constructors, packages Slide # 7
About The Previous Example

"balance" is a field of the class BankAccount
deposit() and toString() are methods of class BankAccount

A method of a class can access the fields of a class

"richStudent" and "poorInstructor" are references to objects

new BankAccount() creates a new object from the class BankAccount and returns a reference to the object

When a method change the value of a field, the change remains in effect after the method ends


Listen Here!S-sept9 4mins, Q-sept10 5mins Doc 4, Classes (1): members, this, constructors, packages Slide # 8
The toString() Standard

  • When required Java sends toString() message to objects to convert them to strings
This happens in println() and when adding to strings
In println( richStudent ) the toString() method is used to convert richStudent to a string

public class RunBank 
{
   public static void main( String args[] ) 
   {
      BankAccount richStudent  =  new BankAccount( );
      BankAccount poorInstructor  =  new BankAccount( );
      richStudent.deposit( 10000F);
      poorInstructor.deposit( 5.10F );
      String profBalance = "Prof: " + poorInstructor;
      System.out.println( profBalance  );
      System.out.println( "Prof: " + poorInstructor );
      System.out.println( richStudent );
   }
}
Output
Prof: Account Balance: 5.1
Prof: Account Balance: 5.1
Account Balance: 10000

Listen Here!S-sept9 3mins, Q-sept10 1min Doc 4, Classes (1): members, this, constructors, packages Slide # 9

Initializing Fields


There are three ways in Java to give a field an initial value:
Direct Assignment
Instance Initialization Block
Constructors

Direct Assignment

public class  BankAccount 
{
   public  float  balance = 0.0F;
   public void deposit( float amount )
   {
      balance += amount ;
   }
   public String toString()
   {
      return "Account Balance: " + balance;
   }
}

Whenever a BankAccount object is created from the above class, the balance field will be set to 0.0F


Listen Here!S-sept9 2mins, Q-sept10 3mins Doc 4, Classes (1): members, this, constructors, packages Slide # 10
Initializing Fields

Instance Initialization Blocks

New to Java 1.1.x

Instance initialization blocks are indicated by blocks of code inside the class, but outside any method.

Whenever an object is created from a class the code in each instance initialization block is executed. If there is more than one instance initialization block they are executed in order, from top to bottom of the class. Use initialization blocks when the initialization cannot be done in a simple assignment and needs no extra input parameters. Direct assignment and constructors are used far more often than initialization blocks.

public class  TaxAccount
{
   public  double  balance;
   
   {   //Instance Initialization block
      float baseTaxRate = .33F;
      float companySize = 1.24F;
   
      balance = baseTaxRate * companySize - 
            Math.sin( baseTaxRate ) + .013f;
   }
   public static void main( String[] args )   //Test method
   {
      TaxAccount x = new TaxAccount();
      System.out.println( x.balance);
   }
}
Output
0.09815697215174707

Doc 4, Classes (1): members, this, constructors, packages Slide # 11

Initializing Fields - Constructors


Constructors have the same name as their class

Constructors have no return type

Constructors have zero or more arguments

Constructors are not methods! You can only call a constuctor using "new ClassName"

Constructors are called when objects are created (using "new")

new BankAccount( arg1, arg2 ) will call the BankAccount constructor with two arguments

Like methods, the argument list used (actual parameters) must match the constructors definition (formal parameters)


Listen Here!S-sept9 5mins, Q-sept10 5mins Doc 4, Classes (1): members, this, constructors, packages Slide # 12
Constructor Example

public class  BankAccount 
{
   public  float  balance;
   public BankAccount( float initialBalance ) //Constructor
   {
      balance = initialBalance;
   }
   public void deposit( float amount )
   {
      balance += amount ;
   }
   public String toString()
   {
      return "Account Balance: " + balance;
   }
}
public class RunBank 
{
   public static void main( String args[] ) 
   {
      BankAccount richStudent  =  new BankAccount( 10000F );
      BankAccount poorInstructor  =  new BankAccount( 5.10F );
      System.out.println( "Prof: " + poorInstructor );
      System.out.println( "Student: " + richStudent );
   }
}
Output
Prof: Account Balance: 5.1
Student: Account Balance: 10000.0

Listen Here!S-sept9 to end, S-sept14 17mins Doc 4, Classes (1): members, this, constructors, packages Slide # 13
Multiple Constructors

public class  ConstructorExample  {
   public  ConstructorExample( )  {
      System.out.println(  "In constructor - no argument"  );
   }; // the ; is legal but does nothing
   public  ConstructorExample( int  size)  {
      System.out.println(  "In constructor - one argument" );
   }
   public  void  ConstructorExample( )  {
      System.out.println(  "return type means it is ");
      System.out.println(  "not a constructor "  );
   }
}
public class TestConstructor  {
   public static void main( String args[] ) {
      System.out.println( "Start main " );
      ConstructorExample  test  =  new ConstructorExample( );
      ConstructorExample  x  =  new ConstructorExample(5);
      System.out.println( "Done with Constructors " );
      test.ConstructorExample ();
   }
}
Output
Start main 
In constructor - no argument
In constructor - one argument
Done with Constructors 
return type means it is 
not a constructor 

Listen Here!S-sept9 6mins, Q-sept10 8mins Doc 4, Classes (1): members, this, constructors, packages Slide # 14
Implicit Constructors
If a class has no constructor the compiler generates an implicit constructor with no arguments for the class. If a class has any constructor, the compiler will not generate the implicit constructor. This can cause some confusion. Start with a working class with no constructor. Now add a constructor to the class. It compiles with no problem. But code that uses the class will no longer compile since it used the implicit constructor, which is no longer provided. If you add a constructor to an existing class, you may need to also add a constructor with no arguments.

public class  ImplicitConstructorOnly  {
   int  size  =  5;
}
public class  OneConstructor  {
   OneConstructor(  String  message  )  {
      System.out.println(  message  );
   }
}
public class  TwoConstructors  {
   TwoConstructors  (  String  message  )  {
      System.out.println(  message  );
   }
   TwoConstructors  (  )  {
      System.out.println(  "No argument Constructor"  );
   }
}
public class  Constructors  {
   public static void main( String args[] ) {
   ImplicitConstructorOnly  ok  =  new  ImplicitConstructorOnly();
   TwoConstructors  alsoOk  =  new  TwoConstructors();
   OneConstructor  compileError  =  new  OneConstructor();
   }
}

Listen Here!S-sept14 2mins Doc 4, Classes (1): members, this, constructors, packages Slide # 15

Order of Initialization

When you create an object the direct assignment of fields and instance initialization blocks are done in order from top to bottom of class, then the constructor is executed

public class  OrderExample
{
   int aField = 1;
   {
      System.out.println( "First block: " + aField );
      aField++;
   }
   public OrderExample()
   {
      System.out.println( "Start Constructor: " + aField );
      aField++;
      System.out.println( "End Constructor: " + aField );
   }
   
   {
      System.out.println( "Second block: " + aField );
      aField++;
   }
   
   
   public  static  void  main( String  args[] ) 
      {
      OrderExample test = new OrderExample();
      }
}
Output
First block: 1
Second block: 2
Start Constructor: 3
End Constructor: 4


Doc 4, Classes (1): members, this, constructors, packages Slide # 16
Order of Class Elements
Layout

The compiler will let you order the element of a class nearly any order!

Fields must be declared before they are used in an initialization block

Human readers require some consistency

Guidelines suggest placing all field declaration in one location
place all fields at the beginning of the class
or
place all fields at the end of the class


Listen Here!Q-sept10 3mins, S-sept14 3mins Doc 4, Classes (1): members, this, constructors, packages Slide # 17
Layout Example

public class  OrderExample
{
   public OrderExample()
   {
      a = 8;      // OK
   }
   
   {
      a = 4;      // Compile Error
   }
   
   int a = 1;
   
   public int getC()   
   {
      return c;
   }
      
   int c = 3;
   
   {
      a = 4;
   }
}


Listen Here!S-sept14 3mins Doc 4, Classes (1): members, this, constructors, packages Slide # 18

Overloading Methods


The signature of a method is its name with number, type and order of its parameters.

The return type is not part of the signature of a method.

Two methods in the same class can have the same name if their signatures are different.

public class OverLoad
{
   public void same() {
      System.out.println( "No arguments" );
   }
   public void same( int firstArgument ) {
      System.out.println( "One int arguments" );
   }
   public void same( char firstArgument ) {
      System.out.println( "One char arguments" );
   }
   public int same( int firstArgument ) {      // Compile Error
      System.out.println( "One char arguments" );
      return 5;
   }
   public void same( char firstArgument, int secondArgument) {
      System.out.println( "char + int arguments" );
   }
   public void same( int firstArgument, char secondArgument ) {
      System.out.println( "int + char arguments" );
   }
}

Listen Here!Q-sept10 4mins, S-sept14 4mins, Q-sept17 2mins Doc 4, Classes (1): members, this, constructors, packages Slide # 19

this

(not that)
"this" refers to the current object. It is normally used to return self from method and pass the current object as a parameter from the current object. Java's "this" differs from C++'s "this". The difference occurs with inheritance.

In the example below there are two uses of "this". The first use of this "this.balance = initialBalance" is not needed. "this.balance" refers to the field named "balance". In the first constructor, replacing "this.balance" with "balance" would not change the behavior of the code. The second use of this "this.balance = balance" is required. Since the second constructor has a parameter named "balance", in the second constructor the name "balance" refers to the argument, not the field. So "balance = balance" in this constructor would not set the value of the field. Since "this.balance" refers to the field, the statement "this.balance = balance" does set the value of the field to the value of the parameter.

public class  BankAccount 
{
   public  float  balance;
   public BankAccount( float initialBalance )
   {
      this.balance = initialBalance;
   }
   public BankAccount( int balance )
   {
      this.balance = balance;
   }
   public void deposit( float amount )
   {
      balance += amount ;
   }
   public String toString()
   {
      return "Account Balance: " + balance;
   }
}

Listen Here!Q-sept10 3mins, S-sept14 4mins Doc 4, Classes (1): members, this, constructors, packages Slide # 20
Returning this
Since the deposit method returns "this" which is the current object, we can nest calls to deposit. richStudent.deposit( 100F ).deposit( 200F) is read from left to right. First deposit( 100F ) is sent to the object referred to by richStudent. This method returns "this", the richStudent object with the increased balance. Then deposit( 200F ) is sent to the object returned by the first deposit method, i.e. the richStudent object. This would not work if deposit did not return "this".

public class  BankAccount 
{
   public  float  balance;
   public BankAccount( float initialBalance )
   {
      this.balance = initialBalance;
   }
   public BankAccount deposit( float amount )
   {
      balance += amount ;
      return this;
   }
}

public class RunBank 
{
   public static void main( String args[] ) 
   {
      BankAccount richStudent  =  new BankAccount( 10000F );
      richStudent.deposit( 100F ).deposit( 200F ).deposit( 300F );
      System.out.println( "Student: " + richStudent.balance );
   }
}
Output
Student: 10600.0

Listen Here!Q-sept10 to end, S-sept14 4mins Doc 4, Classes (1): members, this, constructors, packages Slide # 21
this as Parameter
A Convoluted Contrived Example
This example shows how a BankAccount object can sent itself as a parameter of a method to another object. In this case the BankAccount object adds itself to a list of customers with bad balances.

public class CustomerList {
   public BankAccount[] list = new BankAccount[ 100 ];
   public int nextFreeSlot = 0;
   public void add( BankAccount newItem ){
      list[ nextFreeSlot++ ] =  newItem;
   }
}
public class  BankAccount  {
   public  float  balance;
   public BankAccount( float initialBalance ) {
      this.balance = initialBalance;
   }
   public void badBalanceCheck( CustomerList badAccounts ) {
      if ( balance <= 0F ) badAccounts.add( this );
   }
}
public class RunBank {
   public static void main( String args[] ) {
      BankAccount richStudent  =  new BankAccount( 10000F );
      CustomerList customersToDrop = new CustomerList();
      richStudent.badBalanceCheck( customersToDrop );
   }
}


Listen Here!S-sept14 4mins, Q-sept17 7mins Doc 4, Classes (1): members, this, constructors, packages Slide # 22
this and Chaining Constructors
"this" with an argument list as first line of a constructor will call another constructor of the same class with the given parameters. The call to "this" must be the first statement in the constructor. The example below has the first two constructors calling another constructor. The changing done here (the first constructor calling the second, which calls the third) is common. The last constructor does all the work. The other constructors just determine default values for some of the parameters. This keeps all the actual work in one place and avoids cutting-and-pasting code between the constructors.

public class  ThisAndConstructors
{
   public ThisAndConstructors()
   {
      this( 5 );
      System.out.println( "No argument");
   }
   
   public ThisAndConstructors( int a)
   {
      this( a, 10 );
      System.out.println( "One argument");
   }
   public ThisAndConstructors( int a, int b)
   {
      System.out.println( "Two arguments");
   }
   public  static  void  main( String  args[] ) 
   {
      new ThisAndConstructors();
   }
}
Output
Two arguments
One argument
No argument

Listen Here!S-sept14 2mins Doc 4, Classes (1): members, this, constructors, packages Slide # 23
Calling Methods before calling a "this" Constructor
You can call a static method before calling a constructor with "this". A bit restrictive at times, but it is the rule of the language.

public class MethodCallInConstructor
   {
   private int value;
   
   public MethodCallInConstructor( int first, int second, int third )
      {
      this( nonstaticAdd( first, second, third ) );  // compiler error
      }
   public MethodCallInConstructor( int first, int second )
      {
      this( add( first, second ) );       // OK, can call static method
      System.out.println( "2 arguments: Value = " + value );
      }
   
   public MethodCallInConstructor( int first )
      {
      value = first;
      System.out.println( "1 argument: Value = " + value );
      }
   
   public int nonstaticAdd( int a, int b, int c )
      {
      return a + b + c;
      }
      
   public static int add( int a, int b )
      {
      return a + b;
      }
   }


Listen Here!S-sept14 25secs Doc 4, Classes (1): members, this, constructors, packages Slide # 24

Finalize - A Destructor of Sorts


Automatic storage management handles reclaiming objects and arrays that are no longer needed by a running program. When an object is determined to no longer be needed it may be reclaimed, unless it has a finalize method. If a class has a finalize method, the method is executed. The object is reclaimed the next time it is determined the object is no longer needed. The finalize method is never called more than once for an object.

In Java 1.0.2 it was hard to insure that finalize would be called.

Java 1.1 introduced the method:

System.runFinalizersOnExit(boolean)
default value is false - do not run finalize on exit

You can now force finalize to run when your program exits

Java 1.2 introduces different levels of references, which gives more control over garbage collection and finalization. This is an advanced topic, which would cause much confusion at this point.

Finalize is rarely used in practice. Either you don't care when the object is collected by garbage or you need to insure that resources used by the object are released as soon as possible. Finalize does not help in the latter case.


Listen Here!S-sept14 5mins, Q-sept17 5mins Doc 4, Classes (1): members, this, constructors, packages Slide # 25
Finalize Example
There is no output since there was no need to run garbage collection in this program, so finalize() is never called.

public class  Death  
{
   int  myId;
   public  Death  ( int  sequenceNumber)  
   {
      myId  =  sequenceNumber;  
   }
   public  void  finalize( )  
   {
      System.out.println(  myId  );    
   }
}
public class  Finalization  
{
   public static void main( String args[] ) 
   {
      Death  sampleObject;
      for (  int  k = 0;  k < 5;  k++ )
         sampleObject  =  new Death(  k  );
   }
}
No Output

Listen Here!S-sept14 38secs Doc 4, Classes (1): members, this, constructors, packages Slide # 26
Finalize Example - On Exit

This example shows how to force finalization on exit.

public class  FinalizationOnExit  
{
   public static void main( String args[] ) 
   {
      System.runFinalizersOnExit(true);
      Death  sampleObject;
      for (  int  k = 0;  k < 5;  k++ )
         sampleObject  =  new Death(  k  );
   }
}
Output
0
1
2
3
4


Listen Here!S-sept14 2mins Doc 4, Classes (1): members, this, constructors, packages Slide # 27
Finalize Example - Forced

This example shows how to force finalization. Why is finalize only called on the first four objects and not the fifth object?

public class  FinalizationForced  
{
   public static void main( String args[] ) 
   {
      Death  sampleObject;
      for (  int  k = 0;  k < 5;  k++ )
         sampleObject  =  new Death(  k  );
      System.gc();
      System.runFinalization();  
   }
}
Output
0
1
2
3

Listen Here!S-sept14 5mins Doc 4, Classes (1): members, this, constructors, packages Slide # 28

Access Levels for Fields and Methods


public
Members declared public are accessible anywhere the class is accessible

protected
Members declared protected are directly accessible to any subclasses, and directly accessible by code in the same package
Different from C++'s protected

private
Members declared private are accessible only in the class itself

package
A member is declared package level access by not explicitly declaring the member any access level
Members with package access are directly accessible only to code in the same package
Subclasses in different packages can not directly access the member directly

Note that until we cover packages access levels package, protected and public will seem to be the same.


Listen Here!S-sept14 2mins, Q-sept17 11mins Doc 4, Classes (1): members, this, constructors, packages Slide # 29
Public, Protected, Private

public class AccessLevels 
{
   public  int  publicObjectVariable ;
   protected  float  protectedObjectVariable  =  10;
   private  int[]  privateObjectVariable;
   int  packageAcceess =  publicObjectVariable;
   public  AccessLevels (  int  startValue  )  
   {
      System.out.println(  " Start Constructor"  );
      privateObjectVariable  =  new  int[ startValue ];
   }
   public  void  sampleMethod(  int  value  )  
   {
      System.out.println( " In method" );
      privateObjectVariable[ 1 ]  =  value;
   }
}
public class TestAccessLevels 
{
   public static void main( String args[] ) 
   {
      AccessLevels   test  =  new AccessLevels ( 11 );
      test.publicObjectVariable  =  100;   // Ok
      test.protectedObjectVariable=  100;   // Ok
      test.privateObjectVariable[ 1 ]  =  100;   // Compile Error
      test.packageAcceess =  100;   // Ok
   }
}

Doc 4, Classes (1): members, this, constructors, packages Slide # 30
Look Ma, Hidden Methods
This example shows that one can have private methods

public class  Hide
{
   public void publicAccess()
   {
      System.out.println( "Start public access " );
      internalWorker();
      realPrivateWorker();
   }
   protected void internalWorker()
   {
      System.out.println( "In internal worker " );
   }
   private void realPrivateWorker()
   {
      System.out.println( "In Private worker " );
   }
   public static void main( String[] args )
   {
      Hide me = new Hide();
      me.publicAccess();
   }
}
Output
Start public access 
In internal worker 
In Private worker 


Listen Here!S-sept14 4mins Doc 4, Classes (1): members, this, constructors, packages Slide # 31
Better BankAccount

Making balance private improves the BankAccount class.

We can now restrict access to the balance.

public class  BankAccount 
{
   private  float  balance;
   public BankAccount( float initialBalance ) 
   {
      balance = initialBalance;
   }
   public void deposit( float amount )
   {
      balance += amount ;
   }
   public String toString()
   {
      return "Account Balance: " + balance;
   }
}

Doc 4, Classes (1): members, this, constructors, packages Slide # 32
Modular Design Rules

Measure Twice, Cut Once


Object-Oriented programming requires more planning earlier then procedural programming


Supports:

Decomposability
Composability
Protection
Continuity
Understandability



Poker Rule: Hide Your Cards
or
Information Hiding

All information about a module should be private unless it is specifically declared public

Only the methods in the definition of the abstraction should be declared public

Supports:

Decomposability
Composability
Continuity
Understandability


Listen Here!S-sept14 to end Doc 4, Classes (1): members, this, constructors, packages Slide # 33
Two Views on Hidden fields

  • All fields should be protected or private to outside access
  • All fields should be hidden from methods in same class
This second view is the more extreme of the two. The example below shows how it is done. Each field has methods that are used to access the field. If others need to access the field, the method can be made non-private like getBalance(). The claim is that now it is easy to change the representation of the fields of the class. To change how balance is stored, we just need to change two methods. However, unless great care and some skill is used to start with good abstractions it can be much harder to change the representation of the field than this example indicates.

public class  BankAccount  {
   private  float  balance;
   public float getBalance() {
      return balance;
   }
   private void setbalance( float newBalance) {
      balance = newBalance;
   }
   public BankAccount( float initialBalance )  {
      setbalance( initialBalance );
   }
   public void deposit( float amount ) {
      setbalance( getBalance() + amount );
   }
   public String toString() {
      return "Account Balance: " + getBalance();
   }
}

Listen Here!S-sept16 6mins, Q-sept17 6mins Doc 4, Classes (1): members, this, constructors, packages Slide # 34

Class Names, Packages, Import, CLASSPATH


Each class belongs to a "package".

Packages are used to group related classes. A package creates a name space. Classes in different packages can have the same name.

To put a class in a package, place the statement:

package packageName;

at the beginning of the source file containing the class.

Example

package  EDU.sdsu.roger;
public  class  Sample  {
   public  void  hello()  {
      System.out.println( "Hello for package sdsu.roger" );
   }
}

If a class has no declared package, it is in the unnamed package.

Package names are separated into components, which are separated by "."

In the above example the components are "EDU", "sdsu", and "roger"


Doc 4, Classes (1): members, this, constructors, packages Slide # 35
Classpath & Packages

For the JVM to find a class in a package at runtime, the binaries of the class must be in the correct spot and your CLASSPATH must be correctly set.

The name of the package determines the directory structure that contains the binaries of your classes in the package. Each component of the package name is mapped to a directory of the same name.

The next slide shows an example. In this example the source code and the binary (.class file) are in the same directory. This is not required. The instructions for the example are required for the .class file. The .java file can be placed where you like. If you place the source files in a different location, you must compile them before using them.

Warning

I have double checked the instructions on the next slide. They do work.

Using packages and classpaths for the first time can be very confusing and error prone. Beginners often have trouble using packages for the first time. You may be tempted to just avoid using packages. You must be able to create and use packages. If you do not master this and claim to know Java, at best you will be laughed at by Java programmers.



Listen Here!S-sept16 4mins, Q-sept17 8mins Doc 4, Classes (1): members, this, constructors, packages Slide # 36
Package Example
package  EDU.sdsu.roger;
public  class  Sample  {
   public  void  hello()  {
      System.out.println( "Hello for package sdsu.roger" );
   }
}
The class must be in a file named "Sample.java"

Place file "Sample.java" in a directory called "roger"

Place directory "roger" in a directory called "sdsu"

Place directory "sdsu" in a directory "EDU"

The directory "EDU" can be placed anywhere, for completeness of the example I place it in the directory "/home/ma/whitney/java"

Make sure that "/home/ma/whitney/java" in the CLASSPATH environment variable

   setenv CLASSPATH  '.:/home/ma/whitney/java'

Place the following class anywhere you like and compile & run, the JVM will use the CLASSPATH to find the class Sample. If you did not compile Sample.java, on a UNIX machine Java will compile it for you when you compile TestPackage

import  EDU.sdsu.roger.Sample;
public class TestPackage {
   public static void main( String args[] ) {
      Sample  me  =  new  Sample();
      me.hello();
   }
}

Listen Here!S-sept16 5mins, Q-sept17 17mins Doc 4, Classes (1): members, this, constructors, packages Slide # 37
Import Statement

The import statement allows you to use short class names

Both the examples below will compile and run

With Import, Short Name
import  EDU.sdsu.roger.Sample;
public class TestPackage {
   public static void main( String args[] ) {
      Sample  me  =  new  Sample();
      me.hello();
   }
}

Without Import, Full Name

public class TestPackage {
   public static void main( String args[] ) {
      EDU.sdsu.roger.Sample me  =  
         new EDU.sdsu.roger.Sample();
      me.hello();
   }
}
Implicit Import

All classes in the java.lang package are imported in all programs implicitly for you

Listen Here!S-sept16 2mins Doc 4, Classes (1): members, this, constructors, packages Slide # 38
Import on Demand

You can replace the class name in the import statement with an "*".

This will import all classes in that package and is called import on demand

The following import statement will import all classes in the EDU.sdsu.roger package

import  EDU.sdsu.roger.*;
Recommended Naming Convention

Sun recommends that you use your domain name in your package names.

The order of the domain is reversed & the top-level domain name is capitalized.

This will eliminate name clashes when other people use your packages.

This convention is being used more frequently now. Even Sun is starting to use the convention.


Listen Here!S-sept16 1min Doc 4, Classes (1): members, this, constructors, packages Slide # 39
Name Collision

Packages can be used to avoid name collisions of classes.

Two use the two Leaf classes below in the same code we can:

  • Use the full name of each class
  • Import one class and use the full name of the other class
  • Import both packages on demand to import other classes in each package and use the full name for the Leaf classes
Examples on next slide

File SearchTree/Leaf
package SearchTree;
public class Leaf
{
   public Leaf()
   {
      System.out.println( "Leaf in a binary search tree" );
   }
}
File Botany/Leaf
package Botany;
public class Leaf
{
   public Leaf()
   {
      System.out.println( "Leaf in a real tree" );
   }
}

Listen Here!S-sept16 1min, S-sept16 1min Doc 4, Classes (1): members, this, constructors, packages Slide # 40
Use Full Names
class Test 
{
   public static void main( String args[] )
   {
      Botany.Leaf green = new Botany.Leaf();
      SearchTree.Leaf node = new SearchTree.Leaf();
   }
}

Import One Leaf
import SearchTree.Leaf;
class Test 
{
   public static void main( String args[] )
   {
      Botany.Leaf green = new Botany.Leaf();
      Leaf node = new Leaf();
   }
}

Importing Both Leaf Classes - Error
import SearchTree.Leaf;
import Botany.Leaf;         // Compile error
class Test 
{
   public static void main( String args[] )
   {
      Botany.Leaf green = new Botany.Leaf();
      Leaf node = new Leaf();
   }
}


Listen Here!S-sept16 2mins Doc 4, Classes (1): members, this, constructors, packages Slide # 41
What should this do? And Why?

import SearchTree.Leaf;
import Botany.*;
class Test 
{
   public static void main( String args[] )
   {
      Botany.Leaf green = new Botany.Leaf();
      Leaf node = new Leaf();
   }
}

Listen Here!Q-sept17 2mins, Q-sept17 3mins Doc 4, Classes (1): members, this, constructors, packages Slide # 42
Class Access Levels

Public
Accessible to code in and outside a package

Package
Accessible to code in package only
No subclasses outside package allowed
Used as helper classes in package

package Botany;
public class Leaf
{
   
   public Leaf()
   {
      System.out.println( "Leaf in a real tree" );
   }
}


package Botany;
class BotanyHelper
{
   // Only code in package Botany can use this class
}

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

visitors since 09-Sep-98