Lecture 3

In this lecture we'll look at how to declare and initialize variables, and how to assign new values to variables using expressions.  We'll also introduce DrJava and its interactions window.

Declaring a Variable

A variable is a named location in memory that stores a particular type of value.  The syntax for declaring a variable is

type identifier;

type can be any of the Java primitive types, or any class.  For now, let's review the primitive types:

  Primitive type Range of values
  boolean true or false
Integer
types
byte -128 to 127
char any Unicode character
short -215 to 215-1
int -231 to 231-1
long -263 to 263-1
Floating-point
types
float approx. +/- 10-46 to 1038
double approx. +/- 10-324 to 10308

identifier is a Java identifier that specifies a name for the variable.

Let's look at a concrete example.

int x;

This variable declaration specifies a variable of type int called x.  One way to visualize the meaning of a variable declaration is that it adds an entry to a table of variables.  The table records the type, name, and current value of each declared variable.  After declaring the variable x, the table might look like this:

Type Name Value
int x ?

Note that we've specified the value of this variable with a question mark, to show that it's value is indeterminate.  Until a variable has been assigned a value, you generally should not attempt to use the value stored in the variable.  In some situations, the Java compiler will issue an error if you attempt to use a variable before a value has been stored in it.

Assignments

An assignment statement assigns a new value to a previously declared variable.  For example:

x  = 3;

The variable named on the left hand side of the assignment operator---the "=" symbol---is assigned the value of the expression on the right hand side.  In this case, the variable x is assigned the value of the literal integer value 3.  After the assignment, the table of variables looks like this:

Type Name Value
int x 3

DrJava

We will be using a Java development environment called DrJava.  DrJava has a very useful feature: it allows individual Java statements and expressions to be executed and evaluated, without needed to specify a complete program.  This feature allows you to perform experiments to understand Java language features.  To immediately evaluate an expression or statement, type it in the interactions window.

Here is a screenshot showing DrJava with several statements and expressions typed in the interactions window:

When typing a statement (such as a variable declaration or a variable assignment) in the interactions window, you should terminate it with a semicolon.  When typing an expression, leave out the semicolon: this lets DrJava know that you want to see the value resulting from evaluating the expression.  In the screenshot above, you can see that the variable x has been declared and assigned the value 3.  Evaluating the expression x reads the value out of the variable, and DrJava then prints out the value stored (which of course is 3).

Variables are Independent

We can declare as many variables as we would like.  For example: we can declare another int variable called y and assign it a value:

int y;
y = 4;

Now the table of variables looks like this:

Type Name Value
int x 3
int y 4

We can assign the value of one variable to another---for example, to read the value of y and assign it to x:

x = y;

Now the variable table looks like this:

Type Name Value
int x 4
int y 4

Note that after this assignment, x and y are still separate variables: each names a different location in memory.  For example, if we change x back to 3, it does not affect the value of y:

x = 3;

This assignment restores the variables to their original values:

Type Name Value
int x 3
int y 4

Expressions

Expressions take one or more values (such as literals and variables) and combine them to perform a computation.

For example, we can use the standard arithmetic operators to compute new values:

int z;
z = (x * y) + 30;

The table of variables now contains:

Type Name Value
int x 3
int y 4
int z 42

Variable Initializers

It is possible (and common) to initialize a variable at the same time that it is declared: for example:

int p = 17;

Any legal expression may be used to provide the value that initializes the variable.

Operator Precedence

Consider the following assignment statement:

q = 30 + x * y;

Assuming that x has the value 3 and y has the value 4, will q be assigned the value 132 (33 times 4) or the value 42 (30 + 12)?  The question boils down to whether the addition or the multiplication is evaluated first.

Answering this question involves operator precedence.  In this particular case, the value 42 is the correct one, because multiplication (the * operator) has a higher precedence than addition (the + operator).

Precedence of arithmetic and assignment operators in Java:

Operator Function Precedence
( ) Parenthesis Highest
- or + Unary minus or plus  
* Multiplication  
/ Division  
% Modulus  
+ Addition  
- Subtraction  
= Assignment Lowest

Rather than memorizing the precedence of Java operators, use parentheses to ensure that each part of an expression is evaluated in the correct order.

Mixed Expressions, Promotions, and Casts

When an expression contains operands of the same type (such as an addition with two int operands), then the result of the expression is the same type as the operands.  However, what happens when we have operands of two different types?

Say we have an int variable a and a double variable b:

int a = 3;
double b = 4.0;

What is the result of multiplying a and b?

a * b

The answer is double: the int value is promoted to a double before the multiplication, so the result of the expression is the double value 12.0.

The idea behind promotions is that some numeric types can represent a larger range of values than others.  In the example above, the double type can represent a much larger range of values than the int type.  Therefore, by converting the int to a double, Java avoids losing precision.

There is a hierarchy of numeric types:

Type Precision
byte Least precise
char/short  
int  
long  
float  
double Most precise

In a mixed expression, the less precise type is promoted to the more precise type.

Sometimes you may need to convert a value of a more precise type to a less precise type.  For example, you might have an int value that you need to convert to a short:

int i = 200;
short s = i;

If you try adding the statements above to a Java program, or typing them in the DrJava interactions window, you will find that an error is reported in the assignment of the int value to the short variable.  The reason for the error is that the int type has a larger range of values than the short variable can represent.  Java does not allow implicit conversions from a more precise type to a less precise type.  So, you need to perform an explicit conversion.  In Java, a type cast may be used to convert one type of numeric value to another:

int i = 200;
short s = (short) i;

To perform a type cast, just write the name of the type you want to convert to in parentheses just before the value that should be converted.

When you convert a more precise type to a less precise type, surprising results can occur.  For example, try typing the following statements in a DrJava interactions window:

int i = 128;
byte b = (byte) i;
b

You will see that the value stored in the byte variable b at the end of these statements is -128.  The reason is that the largest positive value that can be represented by a byte value is 127.  Trying to represent a value one greater than this results in the value of the byte wrapping around to become the smallest negative value, -128.

The main method

So far, we've only talked about small fragments of Java code: statements and expressions.  So, how to we define complete programs?

A complete Java program, or Java application, consists of a class that defines a main method.  The main method defines where execution for the application starts.  Here is a simple example:

public class Hello {
  public static void main(String[] args) {
    int answer = 42;
    System.out.println("The answer to life, the universe, and everything is " + answer);
  }
}

The main method is the part of the program that reads:

public static void main(String[] args) {
  int answer = 42;
  System.out.println("The answer to life, the universe, and everything is " + answer);
}

What does this method mean?  The part that reads

public static void main(String[] args)

Defines the visibility, modifiers, return type, name, and parameters of the method.  For a main method, these must all appear more or less exactly as shown here.  Roughly, public static void main(String[] args) means that

Don't worry about the exact meaning of all of these features.  By the end of the course you will know exactly what they mean.  For now, just take it on faith that by defining the main method in this way, we are telling Java that this is where we want execution of our program to start.

The part of the main method between the curly braces ("{" and "}") is a sequence of statements that define the behavior of the method.  In this case, we are assigning the literal value 42 to a variable called answer, and then making a call to the System.out.println method to write this value (along with a String) to the program's standard output.

We can execute a program in the interactions window by typing the command java followed by the name of the class whose main method we want to execute.  Here is the result of running the main method of our Hello class: