CHAPTER 4: Types, Values, and Variables Previous
Previous
Java Language
Java Language
Index
Index
Next
Next

4.5 Variables

4.5.1 Variables of Primitive Type , 4.5.2 Variables of Reference Type , 4.5.3 Kinds of Variables , 4.5.4 Initial Values of Variables , 4.5.5 Variables Have Types, Objects Have Classes

A variable is a storage location and has an associated type, sometimes called its compile-time type, that is either a primitive type (S4.2) or a reference type (S4.3). A variable always contains a value that is assignment compatible (S5.2) with its type. A variable's value is changed by an assignment (S15.25) or by a prefix or postfix ++ (increment) or -- (decrement) operator (S15.13.2, S15.13.3, S15.14.1, S15.14.2).

Compatibility of the value of a variable with its type is guaranteed by the design of the Java language. Default values are compatible (S4.5.4) and all assignments to a variable are checked for assignment compatibility (S5.2), usually at compile time, but, in a single case involving arrays, a run-time check is made (S10.10).


4.5.1 Variables of Primitive Type

A variable of a primitive type always holds a value of that exact primitive type.


4.5.2 Variables of Reference Type

A variable of reference type can hold either of the following:


4.5.3 Kinds of Variables

There are seven kinds of variables:

  1. A class variable is a field declared using the keyword static within a class declaration (S8.3.1.1), or with or without the keyword static within an interface declaration (S9.3). A class variable is created when its class or interface is loaded (S12.2) and is initialized to a default value (S4.5.4). The class variable effectively ceases to exist when its class or interface is unloaded (S12.8), after any necessary finalization of the class or interface (S12.6) has been completed.
  2. An instance variable is a field declared within a class declaration without using the keyword static (S8.3.1.1). If a class T has a field a that is an instance variable, then a new instance variable a is created and initialized to a default value (S4.5.4) as part of each newly created object of class T or of any class that is a subclass of T (S8.1.3). The instance variable effectively ceases to exist when the object of which it is a field is no longer referenced, after any necessary finalization of the object (S12.6) has been completed.
  3. Array components are unnamed variables that are created and initialized to default values (S4.5.4) whenever a new object that is an array is created (S15.9). The array components effectively cease to exist when the array is no longer referenced. See Chapter 10 for a description of arrays.
  4. Method parameters (S8.4.1) name argument values passed to a method. For every parameter declared in a method declaration, a new parameter variable is created each time that method is invoked (S15.11). The new variable is initialized with the corresponding argument value from the method invocation. The method parameter effectively ceases to exist when the execution of the body of the method is complete.
  5. Constructor parameters (S8.6.1) name argument values passed to a constructor. For every parameter declared in a constructor declaration, a new parameter variable is created each time a class instance creation expression (S15.8) or explicit constructor invocation (S8.6.5) invokes that constructor. The new variable is initialized with the corresponding argument value from the creation expression or constructor invocation. The constructor parameter effectively ceases to exist when the execution of the body of the constructor is complete.
  6. An exception-handler parameter is created each time an exception is caught by a catch clause of a try statement (S14.18). The new variable is initialized with the actual object associated with the exception (S11.3, S14.16). The exception-handler parameter effectively ceases to exist when execution of the block associated with the catch clause is complete.
  7. Local variables are declared by local variable declaration statements (S14.3). Whenever the flow of control enters a block (S14.2) or for statement (S14.12), a new variable is created for each local variable declared in a local variable declaration statement immediately contained within that block or for statement. A local variable declaration statement may contain an expression which initializes the variable. The local variable with an initializing expression is not initialized, however, until the local variable declaration statement that declares it is executed. (The rules of definite assignment (Chapter 16) prevent the value of a local variable from being used before it has been initialized or otherwise assigned a value.) The local variable effectively ceases to exist when the execution of the block or for statement is complete.

Were it not for one exceptional situation, a local variable could always be regarded as being created when its local variable declaration statement is executed. The exceptional situation involves the switch statement (S14.9), where it is possible for control to enter a block but bypass execution of a local variable declaration statement. Because of the restrictions imposed by the rules of definite assignment (Chapter 16), however, the local variable declared by such a bypassed local variable declaration statement cannot be used before it has been definitely assigned a value by an assignment expression (S15.25). The following example contains several different kinds of variables:


class Point {
	static int numPoints;								// numPoints is a class variable
	int x, y;								// x and y are instance variables
	int[] w = new int[10];								// w[0] is an array component
	int setX(int x) {								// x is a method parameter
		int oldx = this.x;							// oldx is a local variable
		this.x = x;
		return oldx;
	}
}


4.5.4 Initial Values of Variables

Every variable in a Java program must have a value before its value is used:

The example program:


class Point {
	static int npoints;
	int x, y;
	Point root;
}


class Test {
	public static void main(String[] args) {
		System.out.println("npoints=" + Point.npoints);
		Point p = new Point();
		System.out.println("p.x=" + p.x + ", p.y=" + p.y);
		System.out.println("p.root=" + p.root);
	}
}

prints:


npoints=0
p.x=0, p.y=0
p.root=null

illustrating the default initialization of npoints , which occurs when the class Point is prepared (S12.3.2), and the default initialization of x , y , and root , which occurs when a new Point is instantiated. See Chapter 12 for a full description of all aspects of loading, linking, and initialization of classes and interfaces, plus a description of the instantiation of classes to make new class instances.


4.5.5 Variables Have Types, Objects Have Classes

Every object belongs to some particular class: the class that was mentioned in the creation expression that produced the object, the class whose class object was used to invoke the newInstance method (S20.3.6) to produce the object, or the String class for objects implicitly created by the string concatenation operator + (S15.17.1). This class is called the class of the object. (Arrays also have a class, as described at the end of this section.) An object is said to be an instance of its class and of all superclasses of its class.

(Sometimes a variable or expression is said to have a "run-time type" but that is an abuse of terminology; it refers to the class of the object referred to by the value of the variable or expression at run time, assuming that the value is not null . Properly speaking, type is a compile-time notion. A variable or expression has a type; an object or array has no type, but belongs to a class.)

The type of a variable is always declared, and the type of an expression can be deduced at compile time. The type limits the possible values that the variable can hold or the expression can produce at run time. If a run-time value is a reference that is not null , it refers to an object or array that has a class (not a type), and that class will necessarily be compatible with the compile-time type.

Even though a variable or expression may have a compile-time type that is an interface type, there are no instances of interfaces. A variable or expression whose type is an interface type can reference any object whose class implements (S8.1.4) that interface.

Here is an example of creating new objects and of the distinction between the type of a variable and the class of an object:


public interface Colorable {
	void setColor(byte r, byte g, byte b);
}

class Point { int x, y; }

class ColoredPoint extends Point implements Colorable {

	byte r, g, b;


	public void setColor(byte rv, byte gv, byte bv) {
		r = rv; g = gv; b = bv;
	}

}


class Test {
	public static void main(String[] args) {
		Point p = new Point();
		ColoredPoint cp = new ColoredPoint();
		p = cp;
		Colorable c = cp;
	}
}

In this example:

Every array also has a class; the method getClass (S20.1.1), when invoked for an array object, will return a class object (of class Class ) that represents the class of the array. The classes for arrays have strange names that are not valid Java identifiers; for example, the class for an array of int components has the name "[I " and so the value of the expression:

new int[10].getClass().getName()

is the string "[I" ; see S20.1.1 for details.

Top© 1996 Sun Microsystems, Inc. All rights reserved.