Initialization and Cleanup


(来源:http://www.artima.com)

Objects and Java Seminar by Bill Venners
Lecture Handout

Agenda

  • Introduce constructors
  • Talk about method and constructor overloading
  • Discuss default constructors, this, and variable and array initialization
  • Look at object and class initialization order
  • Discuss finalization and cleanup

Constructors

 1 // In file initandcleanup/ex1/Account.java
 2 
 3 public class Account {
 4 
 5     // balance: in American pennies
 6     private long balance;
 7 
 8     public Account() {
 9         balance = 0;
10     }
11 
12     //...
13 }

 1 // In file initandcleanup/ex1/Example1.java
 2 
 3 public class Example1 {
 4 
 5     public static void main(String[] args) {
 6 
 7         // Create an empty account
 8         Account acct = new Account();
 9     }
10 }

Method Overloading

  • Overloaded methods share same name, differ in number, types of parameters:

    public int indexOf(int ch) {
        //...
    }
    public int indexOf(String str) {
        //...
    }
    

Overloading and Return Value

  • Can't overload just on return value...
    public char[] substring(int beginIndex) {
        //...
    }
    public String substring(int beginIndex) {
        //...
    }
    
  • Because then this would be ambiguous:
    s.substring(5);
    

Overloading Constructors

 1 // In file initandcleanup/ex2/Account.java
 2 
 3 public class Account {
 4 
 5     // balance: in American pennies
 6     private long balance;
 7 
 8     public Account() {
 9         balance = 0;
10     }
11 
12     public Account(long initDeposit) {
13         balance = initDeposit;
14     }
15 
16     //...
17 }

 1 // In file initandcleanup/ex2/Example2.java
 2 
 3 public class Example2 {
 4 
 5     public static void main(String[] args) {
 6 
 7         // Create an empty account
 8         Account acct1 = new Account();
 9 
10         // Create an account with $ 1 Billion
11         Account acct2 = new Account(100000000000L);
12     }
13 }

Default Constructor

  • If you don't define any constructors...
     1 // In file initandcleanup/ex3/Account.java
     2 
     3 public class Account {
     4 
     5     // balance: in American pennies
     6     private long balance;
     7 
     8     // No constructor declared
     9 
    10     // amount: in American pennies
    11     public boolean okToWithdraw(long amount) {
    12         return (amount <= balance);
    13     }
    14 
    15     // ...
    16 }
    
  • The compiler generates a default constructor for you:
     1 // In file initandcleanup/ex4/Account.java
     2 
     3 public class Account {
     4 
     5     // balance: in American pennies
     6     private long balance;
     7 
     8     public Account() {
     9     }
    10 
    11     // amount: in American pennies
    12     public boolean okToWithdraw(long amount) {
    13         return (amount <= balance);
    14     }
    15 
    16     // ...
    17 }
    

The this Reference

  • this is a reference to the current object:
     1 // In file initandcleanup/ex5/Account.java
     2 
     3 public class Account {
     4 
     5     // balance: in American pennies
     6     private long balance;
     7 
     8     public Account() {
     9         balance = 0;
    10     }
    11 
    12     public Account(long balance) {
    13         this.balance = balance;
    14     }
    15 
    16     // amount: in American pennies
    17     public boolean okToWithdraw(long amount) {
    18         return (amount <= this.balance);
    19     }
    20 
    21 
    22     //...
    23 }
    

The this Constructor Invocation 

  • this() calls a constructor from a constructor
  • Must be first
  • Can only have one per constructor
  • Can't call this() from methods
     1 // In file initandcleanup/ex6/Account.java
     2 
     3 public class Account {
     4 
     5     // balance: in American pennies
     6     private long balance;
     7     private long minBal;
     8 
     9     public Account() {
    10         this(0, 200000);
    11     }
    12 
    13     public Account(long initDeposit) {
    14         this(initDeposit, 200000);
    15     }
    16 
    17     public Account(long initDeposit, long minBal) {
    18         balance = initDeposit;
    19         this.minBal = minBal;
    20     }
    21 
    22     //...
    23 }
    

Variable Initialization

  • Instance (and class) variables get default values:
     1 // In file initandcleanup/ex7/Account.java
     2 
     3 public class Account {
     4 
     5     // balance: in American pennies
     6     private long balance;
     7 
     8     // amount: in American pennies
     9     public void deposit(long amount) {
    10 
    11         balance += amount;
    12     }
    13 
    14     // ...
    15 }
    
  • Local variables must be explicitly initialized:
     1 // In file initandcleanup/ex7/Example7.java
     2 
     3 // THIS WON'T COMPILE
     4 public class Example7 {
     5 
     6     public static void main(String[] args) {
     7 
     8         Account acct;
     9         // acct = new Account();
    10         acct.deposit(15000);
    11     }
    12 }
    

Object Initialization Order

  • Constructor compiled to <init>() method
  • First, <init>() calls another <init>()
  • Second, initializers and instance initialization blocks are executed in textual order (These can't forward reference)
  • Third, constructor body is executed
     1 // In file initandcleanup/ex8/Account.java
     2 
     3 public class Account {
     4 
     5     // balance: in American pennies
     6     private long balance = 200;
     7     private long minBal = 100;
     8 
     9     {
    10         balance = 400;
    11         minBal = 200;
    12     }
    13 
    14     // initDeposit, minBal: in American pennies
    15     public Account(long initDeposit, long minBal) {
    16 
    17         balance = initDeposit;
    18         this.minBal = minBal;
    19     }
    20 
    21     // ...
    22 }
    
    1 // In file initandcleanup/ex8/Example8.java
    2 
    3 public class Example8 {
    4 
    5     public static void main(String[] args) {
    6 
    7         Account acct = new Account(800, 400);
    8     }
    9 }
    

Class Initialization Order

  • Static initialization code compiled to <clinit>() method
  • Static initializers and static initialization blocks are executed in textual order (These can't forward reference)
    class CoffeeCup {
    
        private static int cupCount = 355;
    
        static {
            cupCount =
                PersistentStorage.getLastCupCount();
        }
    
        //...
    }
    
  • Classes are initialized primarily on their first active use

Array Initialization

  • Two ways to declare arrays (this declares only the array reference variable):
    int[] value;
    int value[];
    
  • To get an array object, must be explicit:
    private int[] value = new int[10];
    
    {
        for (int i = 0; i < value.length; ++i) {
            value[i] = i;
        }
    }
    
  • Can also use curly braces:
    private int[] value1 = { 0, 1, 2, 3, 4 };
    
    private Integer[] value2 = {
        new Integer(0),
        new Integer(1)
    };
    
  • arrayVar.length gives you the length of the array
  • Multi-dimensional arrays are implemented as arrays of arrays

Finalization and Cleanup

  • Memory for unused objects automatically reclaimed by garbage collector
  • finalize() automatically invoked by garbage collector before freeing memory
  • Objects may not get garbage collected
  • Can't rely on finalize() to release finite resources

Exercises

Problem 1.

Create a class named Problem1 that has a no-arg constructor that prints out the message "No-arg constructor invoked!". Add a main() method in class Problem1 that creates an instance of the Problem1 class.

Problem 2.

Create a class named Problem2 that has two constructors: a no-arg constructor and a constructor that takes a String as its only input parameter. Have the no-arg constructor print out the message "No-arg constructor invoked!". Have the other constructor do two things: first, invoke the no-arg constructor with this(); second, print out the String passed in as the input parameter. Add a main() method in class Problem2 that creates an instance of the Problem2 class using the constructor that takes a String. To the constructor, pass in the String, "String constructor invoked!".

Problem 3.

Create a Java application named Problem3 that creates an array of type Problem1 and length five. Then initialize the first three members of the array with references to three separate instances of class Problem1.

Problem 4.

Create a Java application named Problem4 that has a private static float variable named coefficient. Place the coefficient variable first in the class. Second in the class, place a main() method that prints out the value of coefficient. Third in the class, place a static initialization block that sets coefficient to 2.0.

Problem 5.

Create a Java application named Problem5 that creates a two dimensional array of ints named lincoln. Initialize each array element with the sum of its indices. For example, lincoln[1][2] should be initialized to 1 + 2, or 3. Print out all the values stored in the lincoln array.