Language Basics
Contents
- Variables
- BasicsDemo
- Operators
- Expressions
- Statements
- Blocks
- Data Types
- Control Flow Statements
- Java Language Keywords
- Arithmetic Operators
- Running the Sort Program
- Assignment Operators
- Shift and Logical Operators
- Branching Statements
- The break Statement
- The continue Statement
- The return Statement
- Exception Handling Statements
- Final Variables
- Control Flow Statements
- Decision-Making Statements
- Exception-Handling Statements
- Branching Statements
- The for Statement
- The if/else Statements
- Other Operators
- Shortcut if-else Statement
- The [ ] Operator
- The . Operator
- The () Operator
- The (type) Operator
- The new Operator
- The instanceof Operator
- Relational and Conditional Operators
- Scope
- The switch Statement
- Variable Initialization
- Variable Names
- The while and do-while Statements
Variables
An object stores its state in variables.You must explicitly provide a name and a type for each variable you want to use in your program. The variable's name must be a legal identifier --an unlimited series of Unicode characters that begins with a letter. One uses the variable name to refer to the data that the variable contains. The variable's type determines what values it can hold and what operations can be performed on it. To give a variable a type and a name, you write a variable declaration , which generally looks like this:
type nameThe section of code where the variable's simple name can be used is the variable's scope, which is determined implicitly by the location of the variable declaration, that is, where the declaration appears in relation to other code elements.
The MaxVariablesDemo program, shown below, declares eight variables of different types within its main method.
The output from this program is:public class MaxVariablesDemo { public static void main(String args[]) { // integers byte largestByte = Byte.MAX_VALUE; short largestShort = Short.MAX_VALUE; int largestInteger = Integer.MAX_VALUE; long largestLong = Long.MAX_VALUE; // real numbers float largestFloat = Float.MAX_VALUE; double largestDouble = Double.MAX_VALUE; // other primitive types char aChar = 'S'; boolean aBoolean = true; // display them all System.out.println("The largest byte value is " + largestByte); System.out.println("The largest short value is " + largestShort); System.out.println("The largest integer value is " + largestInteger); System.out.println("The largest long value is " + largestLong); System.out.println("The largest float value is " + largestFloat); System.out.println("The largest double value is " + largestDouble); if (Character.isUpperCase(aChar)) { System.out.println("The character " + aChar + " is upper case."); } else { System.out.println("The character " + aChar + " is lower case."); } System.out.println("The value of aBoolean is " + aBoolean); } }The largest byte value is 127 The largest short value is 32767 The largest integer value is 2147483647 The largest long value is 9223372036854775807 The largest float value is 3.40282e+38 The largest double value is 1.79769e+308 The character S is upper case. The value of aBoolean is true
BasicsDemo
The BasicsDemo program adds the numbers from 1 to 10 and displays the result.
public class BasicsDemo { public static void main(String[] args) { int sum = 0; for (int current = 1; current <= 10; current++) { sum += current; } System.out.println("Sum = " + sum); } }The output from this program is:
Sum = 55
Operators
An operator performs a function on one, two, or three operands. An operator that requires one operand is called a unary operator. For example, ++ is a unary operator that increments the value of its operand by 1. An operator that requires two operands is a binary operator. For example, = is a binary operator that assigns the value from its right-hand operand to its left-hand operand. And finally, a ternary operator is one that requires three operands. The Java programming language has one ternary operator, ?:, which is a short-hand if-else statement.The unary operators support either prefix or postfix notation. Prefix notation means that the operator appears before its operand:
Postfix notation means that the operator appears after its operand:operator op //prefix notationAll of the binary operators use infix notation, which means that the operator appears between its operands:op operator //postfix notationop1 operator op2 //infix notationThe ternary operator is also infix; each component of the operator appears between operands:
In addition to performing the operation, an operator returns a value. The return value and its type depend on the operator and the type of its operands. For example, the arithmetic operators, which perform basic arithmetic operations such as addition and subtraction, return numbers-the result of the arithmetic operation. The data type returned by an arithmetic operator depends on the type of its operands: If you add two integers, you get an integer back. An operation is said to evaluate to its result.op1 ? op2 : op3 //infix notation
Expressions
Expressions perform the work of a program. Among other things, expressions are used to compute and to assign values to variables and to help control the execution flow of a program. The job of an expression is twofold: to perform the computation indicated by the elements of the expression and to return a value that is the result of the computation.
An expression is a series of variables, operators, and method calls (constructed according to the syntax of the language) that evaluates to a single value.
Operators return a value, so the use of an operator is an expression.
... // other primitive types char aChar = 'S'; boolean aBoolean = true; // display them all System.out.println("The largest byte value is " + largestByte); ... if (Character.isUpperCase(aChar)) { ... }Each of these expressions performs an operation and returns a value.
Expression Action Value Returned aChar = 'S' Assign the character 'S' to the character variable aChar The value of aChar after the assignment ('S') "The largest byte value is " + largestByte Concatenate the string "The largest byte value is " and the value of largestByte converted to a string The resulting string: The largest byte value is 127 Character.isUpperCase(aChar) Call the method isUpperCase The return value of the method: true The data type of the value returned by an expression depends on the elements used in the expression. The expression aChar = 'S' returns a character because the assignment operator returns a value of the same data type as its operands and aChar and 'S' are characters. As you see from the other expressions, an expression can return a boolean value, a string, and so on.
The Java programming language allows you to construct compound expressions and statements from various smaller expressions as long as the data types required by one part of the expression matches the data types of the other. Here's an example of a compound expression:
In this particular example, the order in which the expression is evaluated is unimportant because the results of multiplication is independent of order--the outcome is always the same no matter what order you apply the multiplications. However, this is not true of all expressions. For example, the following expression gives different results depending on whether you perform the addition or the division operation first:x * y * zOne can specify exactly how you want an expression to be evaluated by using balanced parentheses ( and ). For example to make the previous expression unambiguous, you could write:x + y / 100 //ambiguousIf you don't explicitly indicate the order in which you want the operations in a compound expression to be performed, the order is determined by the precedence assigned to the operators in use within the expression. Operators with a higher precedence get evaluated first. For example, the division operator has a higher precedence than does the addition operator. Thus, the two following statements are equivalent:(x + y)/ 100 //unambiguous, recommendedWhen writing compound expressions, you should be explicit and indicate with parentheses which operators should be evaluated first. This will make your code easier to read and to maintain.x + y / 100 x + (y / 100) //unambiguous, recommendedThe following table shows the precedence assigned to the operators. The operators in this table are listed in precedence order: the higher in the table an operator appears, the higher its precedence. Operators with higher precedence are evaluated before operators with a relatively lower precedence. Operators on the same line have equal precedence.
postfix operators [] . ( params) expr++ expr-- unary operators ++ expr -- expr + expr - expr ~ ! creation or cast new ( type) expr multiplicative * / % additive + - shift << >> >>> relational < > <= >= instanceof equality == != bitwise AND & bitwise exclusive OR ^ bitwise inclusive OR | logical AND && logical OR || conditional ? : assignment = += -= *= /= %= &= ^= |= <<= >>= >>>= When operators of equal precedence appear in the same expression, a rule must govern which is evaluated first. All binary operators except for the assignment operators are evaluated in left-to-right order. Assignment operators are evaluated right to left.
Statements
Statements are roughly equivalent to sentences in natural languages. A statement forms a complete unit of execution. The following types of expressions can be made into a statement by terminating the expression with a semicolon (;):These kinds of statements are called expression statements. Here are some examples of expression statements:
- Assignment expressions
- Any use of ++ or --
- Method calls
- Object creation expressions
In addition to these kinds of expression statements, there are two other kinds of statements. A declaration statement declares a variable. You've seen many examples of declaration statements.aValue = 8933.234; //assignment statement aValue++; //increment statement System.out.println(aValue); //method call statement Integer integerObject = new Integer(4); //object creation statementA control flow statement regulates the order in which statements get executed. The for loop and the if statement are both examples of control flow statements.double aValue = 8933.234; // declaration statement
Blocks
A block is a group of zero or more statements between balanced braces and can be used anywhere a single statement is allowed. The following listing shows two blocks from the MaxVariablesDemo program, each containing a single statement:if (Character.isUpperCase(aChar)) { System.out.println("The character " + aChar + " is upper case."); } else { System.out.println("The character " + aChar + " is lower case."); }
Data Types
Every variable must have a data type. A variable's data type determines the values that the variable can contain and the operations that can be performed on it. For example, in the MaxVariablesDemo program, the declaration int largestInteger declares that largestInteger has an integer data type (int). Integers can contain only integral values (both positive and negative). One can perform arithmetic operations, such as addition, on integer variables.
The Java programming language has two categories of data types: primitive and reference. A variable of primitive type contains a single value of the appropriate size and format for its type: a number, a character, or a boolean value. For example, an integer value is 32 bits of data in a format known as two's complement, the value of a char is 16 bits of data formatted as a Unicode character, and so on.
The following table lists, by keyword, all of the primitive data types supported by Java, their sizes and formats, and a brief description of each. The MaxVariablesDemo program declares one variable of each primitive type.
Keyword Description Size/Format (integers) byte Byte-length integer 8-bit two's complement short Short integer 16-bit two's complement int Integer 32-bit two's complement long Long integer 64-bit two's complement (real numbers) float Single-precision floating point 32-bit IEEE 754 double Double-precision floating point 64-bit IEEE 754 (other types) char A single character 16-bit Unicode character boolean A boolean value (true or false) true or false
In other languages, the format and size of primitive data types may depend on the platform on which a program is running. In contrast, the Java programming language specifies the size and format of its primitive data types. Hence, you don't have to worry about system-dependencies.
One can put a literal primitive value directly in your code. For example, if you need to assign the value 4 to an integer variable you can write this:
The digit 4 is a literal integer value. Here are some examples of literal values of various primitive types:int anInt = 4;Examples of LiteralValues and Their Data Types
Literal Data Type 178 int 8864L long 37.266 double 37.266D double 87.363F float 26.77e3 double ' c ' char true boolean false boolean Generally speaking, a series of digits with no decimal point is typed as an integer. One can specify a long integer by putting an 'L' or 'l' after the number. 'L' is preferred as it cannot be confused with the digit '1'. A series of digits with a decimal point is of type double. One can specify a float by putting an 'f' or 'F' after the number. A literal character value is any single Unicode character between single quote marks. The two boolean literals are simply true and false.
Arrays, classes, and interfaces are reference types. The value of a reference type variable, in contrast to that of a primitive type, is a reference to (an address of) the value or set of values represented by the variable.
A reference is called a pointer, or a memory address in other languages. The Java programming language does not support the explicit use of addresses like other languages do. One uses the variable's name instead.
Control Flow Statements
When you write a program, you type statements into a file. Without control flow statements, the interpreter executes these statements in the order they appear in the file from left to right, top to bottom. One can use control flow statements in your programs to conditionally execute statements, to repeatedly execute a block of statements, and to otherwise change the normal, sequential flow of control. For example, in the following code snippet, the if statement conditionally executes the System.out.println statement within the braces, based on the return value of Character.isUpperCase(aChar):The Java programming language provides several control flow statements, which are listed in the following table.char c; ... if (Character.isUpperCase(aChar)) { System.out.println("The character " + aChar + " is upper case."); }
Statement Type Keyword looping while, do-while , for decision making if-else, switch-case exception handling try-catch-finally, throw branching break, continue, label:, return In the sections that follow, you will see the following notation to describe the general form of a control flow statement:
control flow statement details { statement(s) }Technically, the braces, { and }, are not required if the block contains only one statement. However, we recommend that you always use { and }, because the code is easier to read and it helps to prevent errors when modifying code.
Java Language Keywords
The following words are cannot be used as names in your program. wrue, false, and null are not keywords but they are reserved words, so you cannot use them as names in your programs either.
boolean else interface super break extends long switch case finally new this catch float package throw char for private throws class goto * protected transient const if public try continue implements return void default import short volatile do instanceof static while
Arithmetic Operators
The Java programming language supports various arithmetic operators for all floating-point and integer numbers. These operators are + (addition), - (subtraction), * (multiplication), / (division), and % (modulo).The following table summarizes the binary arithmetic operations in the Java programming language.
Operator Use Description + op1 + op2 Adds op1 and op2 - op1 - op2 Subtracts op2 from op1 * op1 * op2 Multiplies op1 by op2 / op1 / op2 Divides op1 by op2 % op1 % op2 Computes the remainder of dividing op1 by op2 Here's an example program, ArithmeticDemo, that defines two integers and two double-precision floating-point numbers and uses the five arithmetic operators to perform different arithmetic operations. This program also uses + to concatenate strings. The arithmetic operations are shown in red:
The output from this program is:public class ArithmeticDemo { public static void main(String[] args) { //a few numbers int i = 37; int j = 42; double x = 27.475; double y = 7.22; System.out.println("Variable values..."); System.out.println(" i = " + i); System.out.println(" j = " + j); System.out.println(" x = " + x); System.out.println(" y = " + y); //adding numbers System.out.println("Adding..."); System.out.println(" i + j = " + (i + j)); System.out.println(" x + y = " + (x + y)); //subtracting numbers System.out.println("Subtracting..."); System.out.println(" i - j = " + (i - j)); System.out.println(" x - y = " + (x - y)); //multiplying numbers System.out.println("Multiplying..."); System.out.println(" i * j = " + (i * j)); System.out.println(" x * y = " + (x * y)); //dividing numbers System.out.println("Dividing..."); System.out.println(" i / j = " + (i / j)); System.out.println(" x / y = " + (x / y)); //computing the remainder resulting from dividing numbers System.out.println("Computing the remainder..."); System.out.println(" i % j = " + (i % j)); System.out.println(" x % y = " + (x % y)); //mixing types System.out.println("Mixing types..."); System.out.println(" j + y = " + (j + y)); System.out.println(" i * x = " + (i * x)); } }Note that when an integer and a floating-point number are used as operands to a single arithmetic operation, the result is floating point. The integer is implicitly converted to a floating-point number before the operation takes place. The following table summarizes the data type returned by the arithmetic operators, based on the data type of the operands. The necessary conversions take place before the operation is performed.Variable values... i = 37 j = 42 x = 27.475 y = 7.22 Adding... i + j = 79 x + y = 34.695 Subtracting... i - j = -5 x - y = 20.255 Multiplying... i * j = 1554 x * y = 198.37 Dividing... i / j = 0 x / y = 3.8054 Computing the remainder... i % j = 37 x % y = 5.815 Mixing types... j + y = 49.22 i * x = 1016.58
Data Type of Result Data Type of Operands long Neither operand is a float or a double (integer arithmetic); at least one operand is a long. int Neither operand is a float or a double (integer arithmetic); neither operand is a long. double At least one operand is a double. float At least one operand is a float; neither operand is a double. In addition to the binary forms of + and -, each of these operators has unary versions that perform the following operations:
Operator Use Description + +op Promotes op to int if it's a byte, short, or char - -op Arithmetically negates op Two shortcut arithmetic operators are ++, which increments its operand by 1, and --, which decrements its operand by 1. Either ++ or -- can appear before (prefix) or after (postfix) its operand. The prefix version, ++op/--op, evaluates to the value of the operand after the increment/decrement operation. The postfix version, op++/op--, evaluates the value of the operand before the increment/decrement operation.
The following program, called SortDemo, uses ++ twice and -- once.
This program puts 10 integer values into an array-a fixed length structure that can hold multiple values of the same type-then sorts them. The line of code in red declares an array referred to by arrayOfInts, creates the array, and puts 10 integer values into it. The program uses arrayOfInts.length to get the number of elements in the array. Individual elements are accessed with this notation: arrayOfInts[index], where index is an integer indicating the position of the element within the array. Note that indices begin at 0.public class SortDemo { public static void main(String[] args) { int[] arrayOfInts = { 32, 87, 3, 589, 12, 1076, 2000, 8, 622, 127 }; for (int i = arrayOfInts.length; --i >= 0; ) { for (int j = 0; j < i; j++) { if (arrayOfInts[j] > arrayOfInts[j+1]) { int temp = arrayOfInts[j]; arrayOfInts[j] = arrayOfInts[j+1]; arrayOfInts[j+1] = temp; } } } for (int i = 0; i < arrayOfInts.length; i++) { System.out.print(arrayOfInts[i] + " "); } System.out.println(); } }The output from this program is a list of numbers sorted from lowest to highest:
Let's look at how the SortDemo program uses -- to control the outer of its two nested sorting loops. Here's the statement that controls the outer loop:3 8 12 32 87 127 589 622 1076 2000The for statement is a looping construct. What's important here is the code in red, which continues the for loop as long as the value returned by --i is greater than or equal to 0. Using the prefix version of -- means that the last iteration of this loop occurs when i is equal to 0. If we change the code to use the postfix version of --, the last iteration of this loop occurs when i is equal to -1, which is incorrect for this program because i is used as an array index and -1 is not a valid array index.for (int i = arrayOfInts.length; --i >= 0; ) { ... }The other two loops in the program use the postfix version of ++. In both cases, the version used doesn't really matter, because the value returned by the operator isn't used for anything. When the return value of one of these shortcut operations isn't used for anything, convention prefers the postfix version.
The shortcut increment/decrement operators are summarized in the following table.
Operator Use Description ++ op++ Increments op by 1; evaluates to the value of op before it was incremented ++ ++op Increments op by 1; evaluates to the value of op after it was incremented -- op-- Decrements op by 1; evaluates to the value of op before it was decremented -- --op Decrements op by 1; evaluates to the value of op after it was decremented
Running the Sort Program
Before you can run the SortDemo program, you need to compile it. Here's how:The following instructions show you how to run the SortDemo program and display the results.
- UNIX
% javac SortDemo.java- DOS shell (Windows 95/NT)
C:\> javac SortDemo.java
- UNIX
% java SortDemo 3 8 12 32 87 127 589 622 1076 2000- DOS shell (Windows 95/NT)
C:\> java SortDemo 3 8 12 32 87 127 589 622 1076 2000
Assignment Operators
One uses the basic assignment operator, =, to assign one value to another. The MaxVariablesDemo program uses = to initialize all of its local variables:The Java programming language also provides several shortcut assignment operators that allow you to perform an arithmetic, shift, or bitwise operation and an assignment operation all with one operator. Suppose you wanted to add a number to a variable and assign the result back into the variable, like this:// integers byte largestByte = Byte.MAX_VALUE; short largestShort = Short.MAX_VALUE; int largestInteger = Integer.MAX_VALUE; long largestLong = Long.MAX_VALUE; // real numbers float largestFloat = Float.MAX_VALUE; double largestDouble = Double.MAX_VALUE; // other primitive types char aChar = 'S'; boolean aBoolean = true;One can shorten this statement using the shortcut operator +=, like this:i = i + 2;The two previous lines of code are equivalent.i += 2;The following table lists the shortcut assignment operators and their lengthy equivalents:
Operator Use Equivalent to += op1 += op2 op1 = op1 + op2 -= op1 -= op2 op1 = op1 - op2 *= op1 *= op2 op1 = op1 * op2 /= op1 /= op2 op1 = op1 / op2 %= op1 %= op2 op1 = op1 % op2 &= op1 &= op2 op1 = op1 & op2 |= op1 |= op2 op1 = op1 | op2 ^= op1 ^= op2 op1 = op1 ^ op2 <<= op1 <<= op2 op1 = op1 << op2 >>= op1 >>= op2 op1 = op1 >> op2 >>>= op1 >>>= op2 op1 = op1 >>> op2
Shift and Logical Operators
A shift operator performs bit manipulation on data by shifting the bits of its first operand right or left. This table summarizes the shift operators available in the Java programming language.
Operator Use Operation >> op1 >> op2 shift bits of op1 right by distance op2 << op1 << op2 shift bits of op1 left by distance op2 >>> op1 >>> op2 shift bits of op1 right by distance op2 (unsigned) Each operator shifts the bits of the left-hand operand over by the number of positions indicated by the right-hand operand. The shift occurs in the direction indicated by the operator itself. For example, the following statement shifts the bits of the integer 13 to the right by one position:
The binary representation of the number 13 is 1101. The result of the shift operation is 1101 shifted to the right by one position-110, or 6 in decimal. The left-hand bits are filled with 0s as needed.13 >> 1;The following table shows the four operators the Java programming language provides to perform bitwise functions on their operands:
Operator Use Operation & op1 & op2 bitwise and | op1 | op2 bitwise or ^ op1 ^ op2 bitwise xor ~ ~op2 bitwise complement When its operands are numbers, the & operation performs the bitwise AND function on each parallel pair of bits in each operand. The AND function sets the resulting bit to 1 if the corresponding bit in both operands is 1, as shown in the following table.
op1 op2 Result 0 0 0 0 1 0 1 0 0 1 1 1 Suppose that you were to AND the values 13 and 12, like this: 13 & 12. The result of this operation is 12 because the binary representation of 12 is 1100, and the binary representation of 13 is 1101.
If both operand bits are 1, the AND function sets the resulting bit to 1; otherwise, the resulting bit is 0. So, when you line up the two operands and perform the AND function, you can see that the two high-order bits (the two bits farthest to the left of each number) of each operand are 1. Thus, the resulting bit in the result is also 1. The low-order bits evaluate to 0 because either one or both bits in the operands are 0. When both of its operands are numbers, the | operator performs the inclusive or operation, and ^ performs the exclusive or (XOR) operation. Inclusive or means that if either of the two bits is 1, the result is 1. The following table shows the results of inclusive or operations:1101 //13 & 1100 //12 ------ 1100 //12
op1 op2 Result 0 0 0 0 1 1 1 0 1 1 1 1 Exclusive or means that if the two operand bits are different the result is 1, otherwise the result is 0. The following table shows the results of an exclusive or operation.
op1 op2 Result 0 0 0 0 1 1 1 0 1 1 1 0 And finally, the complement operator inverts the value of each bit of the operand: if the operand bit is 1 the result is 0 and if the operand bit is 0 the result is 1.
Among other things, bitwise manipulations are useful for managing sets of boolean flags. Suppose, for example, that your program had several boolean flags that indicated the state of various components in your program: is it visible, is it draggable, and so on. Rather than define a separate boolean variable to hold each flag, you could define a single variable, flags, for all of them. Each bit within flags would represent the current state of one of the flags. You would then use bit manipulations to set and to get each flag. First, set up constants that indicate the various flags for your program. These flags should each be a different power of 2 to ensure that each bit is used by only one flag. Define a variable, flags, whose bits would be set according to the current state of each flag. The following code sample initializes flags to 0, which means that all flags are false (none of the bits are set).
To set the "visible" flag when something became visible you would use this statement:int flags = 0;To test for visibility, you could then write:flags = flags | VISIBLE;Here's the complete program, BitwiseDemo, that includes this code.if ((flags & VISIBLE) == VISIBLE) { ... }Here's the output from this program:public class BitwiseDemo { public static void main(String[] args) { int flags = 0; flags = flags | VISIBLE; flags = flags | DRAGGABLE; if ((flags & VISIBLE) == VISIBLE) { if ((flags & DRAGGABLE) == DRAGGABLE) { System.out.println("Flags are Visible and Draggable."); } } flags = flags | EDITABLE; if ((flags & EDITABLE) == EDITABLE) { System.out.println("Flags are now also Editable."); } } }Flags are Visible and Draggable. Flags are now also Editable.
Branching Statements
The Java programming language supports three branching statements: The break statement and the continue statement, which are covered next, can be used with or without a label. A label is an identifier placed before a statement. The label is followed by a colon (:):You'll see an example of a label within the context of a program in the next section.statementName: someJavaStatement;
The break Statement
The break statement has two forms: unlabeled and labeled. You saw the unlabeled form of the break statement used with switch earlier. As noted there, an unlabeled break terminates the enclosing switch statement, and flow of control transfers to the statement immediately following the switch. One can also use the unlabeled form of the break statement to terminate a for, while, or do-while loop. The following sample program, BreakDemo, contains a for loop that searches for a particular value within an array:The break statement terminates the for loop when the value is found. The flow of control transfers to the statement following the enclosing for, which is the print statement at the end of the program.public class BreakDemo { public static void main(String[] args) { int[] arrayOfInts = { 32, 87, 3, 589, 12, 1076, 2000, 8, 622, 127 }; int searchfor = 12; int i = 0; boolean foundIt = false; for ( ; i < arrayOfInts.length; i++) { if (arrayOfInts[i] == searchfor) { foundIt = true; break; } } if (foundIt) { System.out.println("Found " + searchfor + " at index " + i); } else { System.out.println(searchfor + "not in the array"); } } }The output of this program is:
The unlabeled form of the break statement is used to terminate the innermost switch, for, while, or do-while; the labeled form terminates an outer statement, which is identified by the label specified in the break statement. The following program, BreakWithLabelDemo, is similar to the previous one, but it searches for a value in a two-dimensional array. Two nested for loops traverse the array. When the value is found, a labeled break terminates the statement labeled search, which is the outer for loop:Found 12 at index 4The output of this program is:public class BreakWithLabelDemo { public static void main(String[] args) { int[][] arrayOfInts = { { 32, 87, 3, 589 }, { 12, 1076, 2000, 8 }, { 622, 127, 77, 955 } }; int searchfor = 12; int i = 0; int j = 0; boolean foundIt = false; search: for ( ; i < arrayOfInts.length; i++) { for (j = 0; j < arrayOfInts[i].length; j++) { if (arrayOfInts[i][j] == searchfor) { foundIt = true; break search; } } } if (foundIt) { System.out.println("Found " + searchfor + " at " + i + ", " + j); } else { System.out.println(searchfor + "not in the array"); } } }This syntax can be a little confusing. The break statement terminates the labeled statement; it does not transfer the flow of control to the label. The flow of control transfers to the statement immediately following the labeled (terminated) statement.Found 12 at 1, 0
The continue Statement
One uses the continue statement to skip the current iteration of a for, while , or do-while loop. The unlabeled form skips to the end of the innermost loop's body and evaluates the boolean expression that controls the loop, basically skipping the remainder of this iteration of the loop. The following program, ContinueDemo, steps through a string buffer checking each letter. If the current character is not a p, the continue statement skips the rest of the loop and proceeds to the next character. If it is a p, the program increments a counter, and converts the p to an uppercase letter.Here is the output of this program:public class ContinueDemo { public static void main(String[] args) { StringBuffer searchMe = new StringBuffer( "peter piper picked a peck of pickled peppers"); int max = searchMe.length(); int numPs = 0; for (int i = 0; i < max; i++) { //interested only in p's if (searchMe.charAt(i) != 'p') continue; //process p's numPs++; searchMe.setCharAt(i, 'P'); } System.out.println("Found " + numPs + " p's in the string."); System.out.println(searchMe); } }The labeled form of the continue statement skips the current iteration of an outer loop marked with the given label. The following example program, ContinueWithLabelDemo , uses nested loops to search for a substring within another string. Two nested loops are required: one to iterate over the substring and one to iterate over the string being searched. This program uses the labeled form of continue to skip an iteration in the outer loop:Found 9 p's in the string. Peter PiPer Picked a Peck of Pickled PePPersHere is the output from this program:public class ContinueWithLabelDemo { public static void main(String[] args) { String searchMe = "Look for a substring in me"; String substring = "sub"; boolean foundIt = false; int max = searchMe.length() - substring.length(); test: for (int i = 0; i <= max; i++) { int n = substring.length(); int j = i; int k = 0; while (n-- != 0) { if (searchMe.charAt(j++) != substring.charAt(k++)) { continue test; } } foundIt = true; break test; } System.out.println(foundIt ? "Found it" : "Didn't find it"); } }Found it
The return Statement
The return statement is used to exit from the current method, and return back to the calling method. It can return values:
return ++count;The data type of the value returned must match the data type of the method's declared return value. When a method is declared void, return nothing.
return;
Exception Handling Statements
The Java programming language provides a mechanism known as exceptions to help programs report and handle errors. When an error occurs, the program throws an exception. What does this mean? It means that the normal flow of the program is interrupted and that the runtime environment attempts to find an exception handler, a block of code that can handle a particular type of error. The exception handler can attempt to recover from the error or, if it determines that the error is unrecoverable, provide a gentle exit from the program.Three statements play a part in handling exceptions:
- The try statement identifies a block of statements within which an exception might be thrown.
- The catch statement must be associated with a try statement and identifies a block of statements that can handle a particular type of exception. The statements are executed if an exception of a particular type occurs within the try block.
- The finally statement must be associated with a try statement and identifies a block of statements that are executed regardless of whether or not an error occurs within the try block.
Here's the general form of these statements:
This has been a brief overview of the statements provided by the Java programming language used in reporting and handling errors. However, other factors and considerations, such as the difference between runtime and checked exceptions and the hierarchy of exceptions classes, which represent various types of exceptions, play a role in using the exception mechanism.try { statement(s) } catch (exceptiontype name) { statement(s) } finally { statement(s) }
Final Variables
One can declare a variable in any scope to be final. The value of a final variable cannot change after it has been initialized. Such variables are similar to constants in other programming languages.To declare a final variable, use the final keyword in the variable declaration before the type:
The previous statement declares a final variable and initializes it, all at once. Subsequent attempts to assign a value to aFinalVar result in a compiler error. You may, if necessary, defer initialization of a final local variable. Simply declare the local variable and initialize it later, like this:final int aFinalVar = 0;A final local variable that has been declared but not yet initialized is called a blank final. Again, once a final local variable has been initialized, it cannot be set, and any later attempts to assign a value to blankfinal result in a compile-time error.final int blankfinal; . . . blankfinal = 0;
Control Flow Statements
When you write a program, you type statements into a file. Without control flow statements, the interpreter executes these statements in the order they appear in the file from left to right, top to bottom. One can use control flow statements in your programs to conditionally execute statements, to repeatedly execute a block of statements, and to otherwise change the normal, sequential flow of control. For example, in the following code snippet, the if statement conditionally executes the System.out.println statement within the braces, based on the return value of Character.isUpperCase(aChar):The Java programming language provides several control flow statements, which are listed in the following table.char c; ... if (Character.isUpperCase(aChar)) { System.out.println("The character " + aChar + " is upper case."); }
Statement Type Keyword looping while, do-while , for decision making if-else, switch-case exception handling try-catch-finally, throw branching break, continue, label:, return In the sections that follow, you will see the following notation to describe the general form of a control flow statement:
Technically, the braces, { and }, are not required if the block contains only one statement. However, we recommend that you always use { and }, because the code is easier to read and it helps to prevent errors when modifying code.control flow statement details { statement(s) }
Although goto is a reserved word, currently the Java programming language does not support the goto statement.
Decision-Making Statements
The Java programming language has two decision-making statements: if-else and switch. The more general-purpose statement is if; use switch to make multiple-choice decisions based on a single integer value. The following is the most basic if statement whose single statement block is executed if the boolean expression is true:Here's an if statement with a companion else statement. The if statement executes the first block if the boolean expression is true; otherwise, it executes the second block:if (boolean expression) { statement(s) }One can use else if to construct compound if statements:if (boolean expression) { statement(s) } else { statement(s) }The switch statement evaluates an integer expression and executes the appropriate case statement.if (boolean expression) { statement(s) } else if (boolean expression) { statement(s) } else if (boolean expression) { statement(s) } else { statement(s) }switch (integer expression) { case integer expression: statement(s) break; ... default: statement(s) break; }
Exception-Handling Statements
Use the try, catch, and finally statements to handle exceptions.try { statement(s) } catch (exceptiontype name) { statement(s) } catch (exceptiontype name) { statement(s) } finally { statement(s) }
Branching Statements
Some branching statements change the flow of control in a program to a labeled statement. You label a statement by placing a legal identifier (the label) followed by a colon (:) before the statement:Use the unlabeled form of the break statement to terminate the innermost switch, for, while, or do-while statement.statementName: someJavaStatement;Use the labeled form of the break statement to terminate an outer switch, for, while, or do-while statement with the given label:break;A continue statement terminates the current iteration of the innermost loop and evaluates the boolean expression that controls the loop.break label;The labeled form of the continue statement terminates the current iteration of the loop with the given label:continue;Use return to terminate the current method.continue label;One can return a value to the method's caller, by using the form of return that takes a value.return;return value;
The for Statement
The for statement provides a compact way to iterate over a range of values. The general form of the for statement can be expressed like this:The initialization is an expression that initializes the loop-it's executed once at the beginning of the loop. The termination expression determines when to terminate the loop. This expression is evaluated at the top of each iteration of the loop. When the expression evaluates to false, the loop terminates. Finally, increment is an expression that gets invoked after each iteration through the loop. All these components are optional. In fact, to write an infinite loop, you omit all three expressions:for (initialization; termination; increment) { statement }for ( ; ; ) { // infinite loop ... }Often for loops are used to iterate over the elements in an array, or the characters in a string. The following sample, ForDemo, uses a for statement to iterate over the elements of an array and print them:
The output of the program is: 32 87 3 589 12 1076 2000 8 622 127.public class ForDemo { public static void main(String[] args) { int[] arrayOfInts = { 32, 87, 3, 589, 12, 1076, 2000, 8, 622, 127 }; for (int i = 0; i < arrayOfInts.length; i++) { System.out.print(arrayOfInts[i] + " "); } System.out.println(); } }Note that you can declare a local variable within the initialization expression of a for loop. The scope of this variable extends from its declaration to the end of the block governed by the for statement so it can be used in the termination and increment expressions as well. If the variable that controls a for loop is not needed outside of the loop, it's best to declare the variable in the initialization expression. The names i, j, and k are often used to control for loops; declaring them within the for loop initialization expression limits their life-span and reduces errors.
The if/else Statements
The if statement enables your program to selectively execute other statements, based on some criteria. For example, suppose that your program prints debugging information, based on the value of a boolean variable named DEBUG. If DEBUG is true, your program prints debugging information, such as the value of a variable, such as x. Otherwise, your program proceeds normally. A segment of code to implement this might look like this:This is the simplest version of the if statement: The block governed by the if is executed if a condition is true. Generally, the simple form of if can be written like this:if (DEBUG) { System.out.println("DEBUG: x = " + x); }What if you want to perform a different set of statements if the expression is false? One uses the else statement for that. Consider another example. Suppose that your program needs to perform different actions depending on whether the user clicks the OK button or another button in an alert window. Your program could do this by using an if statement along with an else statement:if (expression) { statement(s) }The else block is executed if the if part is false. Another form of the else statement, else if, executes a statement based on another expression. An if statement can have any number of companion else if statements but only one else. Following is a program, IfElseDemo , that assigns a grade based on the value of a test score: an A for a score of 90% or above, a B for a score of 80% or above, and so on:. . . // response is either OK or CANCEL depending // on the button that the user pressed . . . if (response == OK) { // code to perform OK action } else { // code to perform Cancel action }The output from this program is:public class IfElseDemo { public static void main(String[] args) { int testscore = 76; char grade; if (testscore >= 90) { grade = 'A'; } else if (testscore >= 80) { grade = 'B'; } else if (testscore >= 70) { grade = 'C'; } else if (testscore >= 60) { grade = 'D'; } else { grade = 'F'; } System.out.println("Grade = " + grade); } }You may have noticed that the value of testscore can satisfy more than one of the expressions in the compound if statement: 76 >= 70 and 76 >= 60. However, as the runtime system processes a compound if statement such as this one, once a condition is satisfied, the appropriate statements are executed (grade = 'C';), and control passes out of the if statement without evaluating the remaining conditions.Grade = CThe Java programming language supports an operator, ?:, that is a compact version of an if statement. Recall this statement from the MaxVariablesDemo program:
Here's how you could rewrite that statement using the ?: operator:if (Character.isUpperCase(aChar)) { System.out.println("The character " + aChar + " is upper case."); } else { System.out.println("The character " + aChar + " is lower case."); }The ?: operator returns the string "upper" if the isUpperCase method returns true. Otherwise, it returns the string "lower". The result is concatenated with other parts of a message to be displayed. Using ?: makes sense here because the if statement is secondary to the call to the println method. Once you get used to this construct, it also makes the code easier to read.System.out.println("The character " + aChar + " is " + (Character.isUpperCase(aChar) ? "upper" : "lower") + "case.");
Other Operators
The following table lists the other operators that the Java programming language supports.
Operator Description ?: Shortcut if-else statement [] Used to declare arrays, create arrays, and access array elements . Used to form qualified names ( params ) Delimits a comma-separated list of parameters ( type ) Casts (converts) a value to the specified type new Creates a new object or a new array instanceof Determines whether its first operand is an instance of its second operand
Shortcut if-else Statement
The ?: operator is a conditional operator that is short-hand for an if-else statement:The ?: operator returns op2 if op1 is true or returns op3 if op1 is false.op1 ? op2 : op3
The [ ] Operator
One uses square brackets to declare arrays, to create arrays, and to access a particular element in an array. Here's an example of an array declaration:The previous code declares an array that can hold ten floating point numbers. Here's how you would access the 7th item in that array:float[] arrayOfFloats = new float[10];Note that array indices begin at 0.arrayOfFloats[6];
The . Operator
The dot (.) operator accesses instance members of an object or class members of a class.
The () Operator
When declaring or calling a method, one lists the method's arguments between ( and ). One can specify an empty argument list by using () with nothing between them.
The (type) Operator
Casts (or "converts") a value to the specified type.
The new Operator
One uses the new operator to create a new object or a new array. Here's an example of creating a new Integer object from the Integer class in the java.lang package:Integer anInteger = new Integer(10);
The instanceof Operator
The instanceof operator tests whether its first operand is an instance of its second.op1 must be the name of an object and op2 must be the name of a class. An object is considered to be an instance of a class if that object directly or indirectly descends from that class.op1 instanceof op2
Relational and Conditional Operators
A relational operator compares two values and determines the relationship between them. For example, != returns true if the two operands are unequal. This table summarizes the relational operators:
Operator Use Returns true if > op1 > op2 op1 is greater than op2 >= op1 >= op2 op1 is greater than or equal to op2 < op1 < op2 op1 is less than op2 <= op1 <= op2 op1 is less than or equal to op2 == op1 == op2 op1 and op2 are equal != op1 != op2 op1 and op2 are not equal Following is an example, RelationalDemo, that defines three integer numbers and uses the relational operators to compare them. The relational operations are shown in red:
Here's the output from this program:public class RelationalDemo { public static void main(String[] args) { //a few numbers int i = 37; int j = 42; int k = 42; System.out.println("Variable values..."); System.out.println(" i = " + i); System.out.println(" j = " + j); System.out.println(" k = " + k); //greater than System.out.println("Greater than..."); System.out.println(" i > j = " + (i > j)); //false System.out.println(" j > i = " + (j > i)); //true System.out.println(" k > j = " + (k > j)); //false, they are equal //greater than or equal to System.out.println("Greater than or equal to..."); System.out.println(" i >= j = " + (i >= j)); //false System.out.println(" j >= i = " + (j >= i)); //true System.out.println(" k >= j = " + (k >= j)); //true //less than System.out.println("Less than..."); System.out.println(" i < j = " + (i < j)); //true System.out.println(" j < i = " + (j < i)); //false System.out.println(" k < j = " + (k < j)); //false //less than or equal to System.out.println("Less than or equal to..."); System.out.println(" i <= j = " + (i <= j)); //true System.out.println(" j <= i = " + (j <= i)); //false System.out.println(" k <= j = " + (k <= j)); //true //equal to System.out.println("Equal to..."); System.out.println(" i == j = " + (i == j)); //false System.out.println(" k == j = " + (k == j)); //true //not equal to System.out.println("Not equal to..."); System.out.println(" i != j = " + (i != j)); //true System.out.println(" k != j = " + (k != j)); //false } }Relational operators often are used with conditional operators to construct more complex decision-making expressions. The Java programming language supports six conditional operators-five binary and one unary--as shown in the following table.Variable values... i = 37 j = 42 k = 42 Greater than... i > j = false j > i = true k > j = false Greater than or equal to... i >= j = false j >= i = true k >= j = true Less than... i < j = true j < i = false k < j = false Less than or equal to... i <= j = true j <= i = false k <= j = true Equal to... i == j = false k == j = true Not equal to... i != j = true k != j = false
Operator Use Returns true if && op1 && op2 op1 and op2 are both true, conditionally evaluates op2 || op1 || op2 either op1 or op2 is true, conditionally evaluates op2 ! ! op op is false & op1 & op2 op1 and op2 are both true, always evaluates op1 and op2 | op1 | op2 either op1 or op2 is true, always evaluates op1 and op2 ^ op1 ^ op2 if op1 and op2 are different--that is if one or the other of the operands is true but not both One such operator is &&, which performs the conditional AND operation. One can use two different relational operators along with && to determine whether both relationships are true. The following line of code uses this technique to determine whether an array index is between two boundaries. It determines whether the index is both greater than or equal to 0 and less than NUM_ENTRIES, which is a previously defined constant value.
Note that in some instances, the second operand to a conditional operator may not be evaluated. Consider this code segment:0 <= index && index < NUM_ENTRIESThe && operator will return true only if both operands are true. So, if numChars is greater than or equal to LIMIT, the left-hand operand for && is false, and the return value of && can be determined without evaluating the right-hand operand. In such a case, the interpreter will not evaluate the right-hand operand. This has important implications if the right-hand operand has side effects, such as reading from a stream, updating a value, or making a calculation.(numChars < LIMIT) && (...)When both operands are boolean, the operator & performs the same operation as &&. However, & always evaluates both of its operands and returns true if both are true. Likewise, when the operands are boolean, | performs the same operation as ||. The | operator always evaluates both of its operands and returns true if at least one of its operands is true. When their operands are numbers, & and | perform bitwise manipulations.
Scope
A variable's scope is the region of a program within which the variable can be referred to by its simple name. Secondarily, scope also determines when the system creates and destroys memory for the variable. Scope is distinct from visibility, which applies only to member variables and determines whether the variable can be used from outside of the class within which it is declared. Visibility is set with an access modifier.The location of the variable declaration within your program establishes its scope and places it into one of these four categories:
- member variable
- local variable
- method parameter
- exception-handler parameter
A member variable is a member of a class or an object. It is declared within a class but outside of any method or constructor. A member variable's scope is the entire declaration of the class. However, the declaration of a member needs to appear before it is used when the use is in a member initialization expression.
You declare local variables within a block of code. In general, the scope of a local variable extends from its declaration to the end of the code block in which it was declared. In MaxVariablesDemo, all of the variables declared within the main method are local variables. The scope of each variable in that program extends from the declaration of the variable to the end of the main method --indicated by the first right curly bracket } in the program code.
Parameters are formal arguments to methods or constructors and are used to pass values into methods and constructors. The scope of a parameter is the entire method or constructor for which it is a parameter.
Exception-handler parameters are similar to parameters but are arguments to an exception handler rather than to a method or a constructor. The scope of an exception-handler parameter is the code block between { and } that follow a catch statement.
Consider the following code sample:
if (...) { int i = 17; ... } System.out.println("The value of i = " + i); // error
The switch Statement
Use the switch statement to conditionally perform statements based on an integer expression. Following is a sample program, SwitchDemo , that declares an integer named month whose value supposedly represents the month in a date. The program displays the name of the month, based on the value of month, using the switch statement:The switch statement evaluates its expression, in this case the value of month, and executes the appropriate case statement. Thus, the output of the program is: August. Of course, you could implement this by using an if statement:public class SwitchDemo { public static void main(String[] args) { int month = 8; switch (month) { case 1: System.out.println("January"); break; case 2: System.out.println("February"); break; case 3: System.out.println("March"); break; case 4: System.out.println("April"); break; case 5: System.out.println("May"); break; case 6: System.out.println("June"); break; case 7: System.out.println("July"); break; case 8: System.out.println("August"); break; case 9: System.out.println("September"); break; case 10: System.out.println("October"); break; case 11: System.out.println("November"); break; case 12: System.out.println("December"); break; } } }Deciding whether to use an if statement or a switch statement is a judgment call. One can decide which to use, based on readability and other factors. An if statement can be used to make decisions based on ranges of values or conditions, whereas a switch statement can make decisions based only on a single integer value. Also, the value provided to each case statement must be unique.int month = 8; if (month == 1) { System.out.println("January"); } else if (month == 2) { System.out.println("February"); } . . . // and so onAnother point of interest in the switch statement is the break statement after each case. Each break statement terminates the enclosing switch statement, and the flow of control continues with the first statement following the switch block. The break statements are necessary because without them, the case statements fall through. That is, without an explicit break, control will flow sequentially through subsequent case statements. Following is an example, SwitchDemo2, which illustrates why it might be useful to have case statements fall through:
The output from this program is:public class SwitchDemo2 { public static void main(String[] args) { int month = 2; int year = 2000; int numDays = 0; switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: numDays = 31; break; case 4: case 6: case 9: case 11: numDays = 30; break; case 2: if ( ((year % 4 == 0) && !(year % 100 == 0)) || (year % 400 == 0) ) numDays = 29; else numDays = 28; break; } System.out.println("Number of Days = " + numDays); } }out of the switch statement anyway. However, we recommend using a break for the last case statement just in case you need to add more case statements at a later date. This makes modifying the code easier and less error-prone.Number of Days = 29Finally, you can use the default statement at the end of the switch to handle all values that aren't explicitly handled by one of the case statements.
int month = 8; . . . switch (month) { case 1: System.out.println("January"); break; case 2: System.out.println("February"); break; case 3: System.out.println("March"); break; case 4: System.out.println("April"); break; case 5: System.out.println("May"); break; case 6: System.out.println("June"); break; case 7: System.out.println("July"); break; case 8: System.out.println("August"); break; case 9: System.out.println("September"); break; case 10: System.out.println("October"); break; case 11: System.out.println("November"); break; case 12: System.out.println("December"); break; default: System.out.println("Hey, that's not a valid month!"); break; }
Variable Initialization
Local variables and member variables can be initialized with an assignment statement when they're declared. The data type of the variable must match the data type of the value assigned to it. The MaxVariablesDemo program provides initial values for all its local variables when they are declared. The local variable declarations from that program follow, with the initialization code set in red:Parameters and exception-handler parameters cannot be initialized in this way. The value for a parameter is set by the caller.// integers byte largestByte = Byte.MAX_VALUE; short largestShort = Short.MAX_VALUE; int largestInteger = Integer.MAX_VALUE; long largestLong = Long.MAX_VALUE; // real numbers float largestFloat = Float.MAX_VALUE; double largestDouble = Double.MAX_VALUE; // other primitive types char aChar = 'S'; boolean aBoolean = true;
Variable Names
A program refers to a variable's value by the variable's name. For example, when it displays the value of the largestByte variable, the MaxVariablesDemo program uses the name largestByte. A name, such as largestByte, that's composed of a single identifier, is called a simple name. Simple names are in contrast to qualified names, which a class uses to refer to a member variable that's in another object or class.In the Java programming language, the following must hold true for a simple name:
- It must be a legal identifier. An identifier is an unlimited series of Unicode characters that begins with a letter.
- It must not be a keyword, a boolean literal (true or false), or the reserved word null.
- It must be unique within its scope. A variable may have the same name as a variable whose declaration appears in a different scope. In some situations, a variable may share the same name as another variable if it is declared within a nested block of code. (We will cover this in the next section, Scope.)
Variable names begin with a lowercase letter, and class names begin with an uppercase letter. If a variable name consists of more than one word, the words are joined together, and each word after the first begins with an uppercase letter, like this: isVisible. The underscore character (_) is acceptable anywhere in a name, but by convention is used only to separate words in constants (because constants are all caps by convention and thus cannot be case-delimited).
The while and do-while Statements
One uses a while statement to continually execute a block of statements while a condition remains true. The general syntax of the while statement is:First, the while statement evaluates expression, which must return a boolean value. If the expression returns true, then the while statement executes the statement(s) associated with it. The while statement continues testing the expression and executing its block until the expression returns false.while (expression) { statement }The example program shown below, called WhileDemo, uses a while statement to step through the characters of a string, appending each character from the string to the end of a string buffer until it encounters the letter g.
The value printed by the last line is: Copy this strin.public class WhileDemo { public static void main(String[] args) { String copyFromMe = "Copy this string until you " + "encounter the letter 'g'."; StringBuffer copyToMe = new StringBuffer(); int i = 0; char c = copyFromMe.charAt(i); while (c != 'g') { copyToMe.append(c); c = copyFromMe.charAt(++i); } System.out.println(copyToMe); } }The Java programming language provides another statement that is similar to the while statement--the do-while statement. The general syntax of the do-while is:
Instead of evaluating the expression at the top of the loop, do-while evaluates the expression at the bottom. Thus the statements associated with a do-while are executed at least once.do { statement(s) } while (expression);Here's the previous program rewritten to use do-while and renamed to DoWhileDemo:
The value printed by the last line is: Copy this strin.public class DoWhileDemo { public static void main(String[] args) { String copyFromMe = "Copy this string until you " + "encounter the letter 'g'."; StringBuffer copyToMe = new StringBuffer(); int i = 0; char c = copyFromMe.charAt(i); do { copyToMe.append(c); c = copyFromMe.charAt(++i); } while (c != 'g'); System.out.println(copyToMe); } }