Constructing an Array – Declarations

Constructing an Array

An array can be constructed for a fixed number of elements of a specific type, using the new operator. The reference value of the resulting array can be assigned to an array variable of the corresponding type. The syntax of the array creation expression is shown on the right-hand side of the following assignment statement:

Click here to view code image

array_name
 = new
element_type
[
array_size
];

The minimum value of array_size is 0; in other words, zero-length arrays can be constructed in Java. If the array size is negative, a NegativeArraySizeException is thrown at runtime.

Given the declarations

Click here to view code image

int anIntArray[], oneInteger;
Pizza[] mediumPizzas, largePizzas;

the three arrays in the declarations can be constructed as follows:

Click here to view code image

anIntArray   = new int[10];          // array for 10 integers
mediumPizzas = new Pizza[5];         // array of 5 pizzas
largePizzas  = new Pizza[3];         // array of 3 pizzas

The array declaration and construction can be combined.

Click here to view code image

element_type
1
[]
array_name
 = new
element_type
2
[
array_size
];

In the preceding syntax, the array type element_type2[] must be assignable to the array type element_type1[] (§5.8, p. 261). When the array is constructed, all of its elements are initialized to the default value for element_type2. This is true for both member and local arrays when they are constructed.

In the following examples, the code constructs the array, and the array elements are implicitly initialized to their default values. For example, all elements of the array anIntArray get the value 0, and all elements of the array mediumPizzas get the value null when the arrays are constructed.

Click here to view code image

int[] anIntArray = new int[10];                  // Default element value: 0
Pizza[] mediumPizzas = new Pizza[5];             // Default element value: null

The value of the field length in each array is set to the number of elements specified during the construction of the array; for example, mediumPizzas.length has the value 5.

Once an array has been constructed, its elements can also be explicitly initialized individually—for example, in a loop. The examples in the rest of this section make use of a loop to iterate over the elements of an array for various purposes.

Static Members in Classes – Declarations

Static Members in Classes

Static members belong to the class in which they are declared and are not part of any instance of the class. The declaration of static members is prefixed by the keyword static to distinguish them from instance members.

Static code inside a class can access a static member in the following three ways:

  • By the static member’s simple name
  • By using the class name with the static member’s name
  • By using an object reference of the static member’s class with the static member’s name

Depending on the access modifier of the static members declared in a class, clients can only access these members by using the class name or using an object reference of their class.

The class need not be instantiated to access its static members. This is in contrast to instance members of the class which can only be accessed by references that actually refer to an instance of the class.

Static Fields in Classes

Static fields (also called static variables and class variables) exist only in the class in which they are defined. When the class is loaded, static fields are initialized to their default values if no explicit initialization is specified. They are not created when an instance of the class is created. In other words, the values of these fields are not a part of the state of any object. Static fields are akin to global variables that can be shared with all objects of the class and with other clients, if necessary.

Example 3.6 Accessing Static Members in a Class

Click here to view code image

// File: StaticTest.java
import static java.lang.System.out;
class Light {
  // Static field:
  static int counter;                  // (1) No initializer expression
  // Static method:
  public static void printStatic() {
    Light myLight = null;
    out.printf(“%s, %s, %s%n”, counter, Light.counter, myLight.counter); // (2)
long counter = 10;                 // (3) Local variable shadows static field
    out.println(“Local counter: ” + counter);       // (4) Local variable accessed
    out.println(“Static counter: ” + Light.counter);// (5) Static field accessed
//  out.println(this.counter);         // (6) Cannot use this in static context
//  printNonStatic();                  // (7) Cannot call non-static method
  }
  // Non-static method:
  public void printNonStatic() {
   out.printf(“%s, %s, %s%n”, counter, this.counter, Light.counter);     // (8)
  }
}
//______________________________________________________________________________
public class StaticTest {              // Client of class Light
  public static void main(String[] args) {
    Light.counter++;                   // (9) Using class name
    Light dimLight = null;
    dimLight.counter++;                // (10) Using object reference
    out.print(“Light.counter == dimLight.counter: “);
    out.println(Light.counter == dimLight.counter);//(11) Aliases for static field
    out.println(“Calling static method using class name:”);
    Light.printStatic();               // (12) Using class name
    out.println(“Calling static method using object reference:”);
    dimLight.printStatic();            // (13) Using object reference
  }
}

Output from the program:

Click here to view code image

Light.counter == dimLight.counter: true
Calling static method using class name:
2, 2, 2
Local counter: 10
Static counter: 2
Calling static method using object reference:
2, 2, 2
Local counter: 10
Static counter: 2

In Example 3.6, the static field counter at (1) will be initialized to the default value 0 when the class is loaded at runtime, since no initializer expression is specified. The print statement at (2) in the static method printCount() shows how this static field can be accessed in three different ways, respectively: simple name counter, the class name Light, and object reference myLight of class Light, although no object has been created.

Shadowing of fields by local variables is different from hiding of fields by field declarations in subclasses. In Example 3.6, a local variable is declared at (3) that has the same name as the static field. Since this local variable shadows the static field, the simple name at (4) now refers to the local variable, as shown by the output from the program. The shadowed static field can of course be accessed using the class name, as shown at (5). It is the local variable that is accessed by its simple name as long as it is in scope.

Trying to access the static field with the this reference at (6) results in a compile-time error, since the this reference cannot be used in static code. Invoking the non-static method at (7) also results in a compile-time error, since static code cannot refer to non-static members by its simple name in the class.

The print statement at (8) in the method printNonStatic() illustrates referring to static members in non-static code: It refers to the static field counter by its simple name, with the this reference, and using the class name.

In Example 3.6, the class StaticTest is a client of the class Light. The client must use the class name or an object reference of class Light at (9) and (10), respectively, to access the static field counter in the class Light. The result from the print statement at (11) shows that these two ways of accessing a static field are equivalent.