This appendix summarizes the syntax of the Java language and serves as a quick reference guide to look up specific points of language usage.
Java programs are organized into packages that contain the source code declarations of Java classes and interfaces. Packages are identified by the package statement. It is the first statement in a source code file:
package packageName;
If a package statement is omitted, the classes and interfaces declared within the package are put into the default no-name package. The package name and the CLASSPATH are used to find a class. Only one class or interface may be declared as public for a given source code file (compilation unit). For example, you can define classes X and Y and interface Z within a compilation unit, but only one of these three can be declared public. The name of the compilation unit must be the name of the public class or interface followed by the .java extension.
The import statement is used to reference classes and interfaces that are declared in other packages. There are three forms of the import statement:
import packageName.className; import packageName.interfaceName; import packageName.*;
The first and second forms allow the identified classes and interfaces to be referenced without specifying the name of their package. The third form allows all classes and interfaces in the specified package to be referenced without specifying the name of their package.
Java provides three styles of comments:
/* This is a multiline comment. */
// This is a single line comment.
/** This is a multiline javadoc comment */
The first comment style supports traditional C-language comments. All text appearing between /* and */ is treated as a comment. Comments of this style can span multiple lines.
The second comment style supports single-line C++ comments. All text following the // until the end of the line is treated as a comment.
The third comment style is used by the javadoc documentation-generation tool. All text between the /** and */ is treated as a javadoc comment. javadoc comments may span multiple lines. The use of javadoc comments is covered in Appendix D, "Generating Documentation and Help Files."
Comments cannot be nested and cannot appear within string and character literals.
Identifiers are used to name Java language entities. They begin with a letter, underscore character (_), or dollar sign ($). Subsequent characters consist of these characters and digits. Identifiers are case sensitive and cannot be the same as a reserved word. Avoid using the dollar sign character; it is used for compiler-generated identifiers.
The following words are reserved by the Java language, and cannot be used as identifiers:
abstract
boolean
break
byte
case
catch
char
class
const
continue
default
do
double
else
extends
final
finally
float
for
goto
if
implements
import
instanceof
int
interface
long
native
new
package
private
protected
public
return
short
static
super
switch
synchronized
this
throw
throws
transient
try
void
volatile
while
Java defines eight primitive types. Variables that are declared as a primitive type are not objects. They are only placeholders to store primitive values. The eight primitive types are byte, short, int, long, float, double, char, and boolean.
The byte, short, int, and long types represent 8-, 16-, 32-, and 64-bit integer values. The literal values of these types are written using positive or negative decimal, hexadecimal, or octal integers. Hexadecimal values are preceded by 0x or 0X and use the letters a through f (upper- or lowercase) to represent the digits 10 through 15. Octal numbers are preceded by 0. Long decimal values have an l or L appended to the end of the number.
The float and double types represent 32- and 64-bit IEEE 754 floating-point numbers. float numbers have the f or F suffix. double numbers have d or D. If no suffix is provided, the default double type is assumed. Floating-point numbers may be written in any of the following four forms:
digits . optionalDigits optionalExponentPart suffix . digits optionalExponentPart suffix digits exponentPart suffix NaN
The suffix is optional. It consists of f, F, d, or D, as described previously.
The exponent part is optional in the first two forms but required in the third form. It consists of an e or E followed by a signed integer. It is used to identify the exponent of 10 of the number written in scientific notation. For example, 1000000.0 could be represented as 1.0E6.
The special value NaN is used to represent the value "not a number," which occurs as the result of undefined mathematical operations such as division by zero.
The char type represents 16-bit Unicode characters. Unicode is a 16-bit superset of the ASCII character set that provides many foreign-language characters. A single character is specified by putting the character within single quotes (`). There are three exceptions: single quote (`), double quote ("), and backslash (\). The backslash character (\) is used as an escape code to represent special character values. The character escape codes are shown in Table A.1.
Escape Code | Character |
\b | Backspace |
\t | Tab |
\n | Linefeed |
\f | Form feed |
\r | Carriage return |
\" | Double quote |
\' | Single quote |
\\ | Backslash |
The backslash can also be followed by an 8-bit octal value, or by a u or U followed by a four-digit hexadecimal value. The four-digit value is used to specify the value of Unicode characters.
The boolean type represents the logical values true and false.
String literals are also provided by Java, although strings are not primitive values. Strings consist of characters enclosed by double quotes ("). The character escape codes may be used within strings.
The literal value null is used to identify the fact that an object is not assigned to a value. It may be used with any variable that is not of a primitive data type.
Class literals were introduced with Java 1.1. A class literal is formed by appending .class to the name of a primitive or reference type. It evaluates to an object of type Class, which is the Class object for the identified type. The expression void.class evaluates to void. You can use class literals to directly refer to the class of a variable. For example, suppose Test is a class that you've declared. The following statement displays the name of the Test class:
System.out.println(Test.class);
Objects are the basic elements of Java programs. They are executable entities that contain data and provide methods for manipulating that data. Every object is an instance of a class. Classes are the templates from which objects are created. They define the type of data that an object contains and the methods for manipulating that data. Objects are created (or instantiated) via constructors. An object is instantiated by assigning specific values to the field variables defined by the class.
Class declarations allow new classes to be defined for use in Java programs. Classes are declared as follows:
classModifiers class className extendsClause implementsClause classBody
The class modifiers, extends clause, and implements clause are optional.
The class modifiers are abstract, public, and final. An abstract class provides an abstract class declaration that cannot be instantiated. In general, abstract classes are used as building blocks for the declaration of subclasses. A class that is declared as public can be referenced outside its package. If a class is not declared as public, it can be referenced only within its package. A final class cannot be subclassed. A class cannot be declared as both final and abstract.
The extends clause is used to identify the immediate superclass of a class and thereby position the class within the overall class hierarchy. It is written as follows:
extends immediateSuperclass
The implements clause identifies the interfaces that are implemented by a class. It is written as follows:
implements interfaceNames
The interface names consist of one or more interface names separated by commas.
The class body declares the members of a class. It is written as follows:
{ memberDeclarations }
The member declarations consists of zero or more of the following declarations:
Object initializers and inner classes were introduced with Java 1.1. Object initializers are used to initialize a non-static field variable as part of a class's declaration. Inner classes are classes that are declared within the body of another class. Inner classes may also be declared local to a statement block. They are used to declare classes for use within a limited local scope.
Java also allows inner classes to be declared anonymously within an expression. These classes are referred to as anonymous classes.
Variables are used to refer to objects and primitive data types. They are declared as follows:
variableModifiers type extendedVariableName variableInitialization ;
The variable modifiers and variable initialization are optional. A variable's type may be a primitive data type, class type, or interface type. The extended variable name is a variable name followed by zero or more bracket sets ([]) indicating that the variable is an array.
The variable initialization consists of an equal sign (=) followed by an expression yielding a value of the variable's type. If the variable being declared is an array, it can be assigned to an array initializer. Array initializers are written as follows:
{elementInitializers}
The element initializers are expressions that yield values that are consistent with the element type of the array.
There are seven variable modifiers: public, protected, private, static, final, transient, and volatile.
The public, protected, and private modifiers are used to designate the specific manner in which a variable can be accessed. Variables that are declared as public can be accessed anywhere that the class in which they are declared can be accessed. Variables that are declared as protected can be accessed within the package in which they are declared and in subclasses of the class in which they are declared. Variables that are declared as private are only accessible in the class in which they are defined and not in any of its subclasses. If a variable isn't declared as public, protected, or private, it can be accessed only within the package in which it is declared.
A variable that is declared as static is associated with its class and is shared by objects that are instances of its class. A static variable is also known as a class variable.
A variable that is declared as final is a constant and cannot be modified. final variables must be initialized before they are used. Java 1.1 allows the initialization of a final variable to be separated from its declaration.
A variable that is declared as transient is not saved as part of an object when the object is serialized. The transient keyword identifies a variable that does not maintain a persistent state.
A variable that is declared as volatile refers to objects and primitive values that can be modified asynchronously by separate threads of execution. They are treated in a special manner by the compiler to control the manner in which they can be updated.
Constructors are methods that are used to initialize newly created objects of a class. They are declared as follows:
constructorModifiers constructorName(ParameterList) throwsClause constructorBody
The constructor modifiers are public, protected, and private. They control access to the constructor and are used in the same manner as they are for variables.
The constructor name is the same as the class name in which it is declared. It is followed by a parameter list, consisting of an opening parenthesis, followed by zero or more parameter declarations, followed by a closing parenthesis. The parameter declarations are separated by commas. Parameter declarations are written as follows:
type parameterName
Each parameter declaration consists of a type followed by a parameter name. A parameter name may be followed by sets of matched brackets ([]) to indicate that it is an array.
The throws clause identifies all uncaught exceptions that are thrown within the constructor. It is written as follows:
throws uncaughtExceptions
The exceptions are separated by commas.
The body of a constructor specifies the manner in which an object of the constructor's class is to be initialized. It is written as follows:
{constructorCallStatement blockBody}
The constructor call statement and block body are optional, but the opening and closing braces must be supplied.
The constructor call statement allows another constructor of the class or its superclass to be invoked before the constructor's block body. It is written using one of the two following forms:
this(argumentList); super(argumentList);
The first form results in a constructor for the current class being invoked with the specified arguments. The second form results in the constructor of the class's superclass being invoked. The argument list consists of expressions that evaluate to the allowed values of a particular constructor.
If no constructor call statement is specified, a default super() constructor is invoked before the constructor block body.
Methods are used to perform operations on the data contained in an object. They are written as follows:
methodModifiers returnType methodName(ParameterList) throwsClause methodBody
The parameters and throws clause are declared in the same method as in constructor declarations.
The method body differs from the constructor body in that it does not allow a constructor call statement.
The method modifiers include the public, protected, and private modifiers defined for constructors, as well as the final, static, abstract, native, and synchronized modifiers.
The final modifier identifies a method that cannot be overridden.
The static modifier identifies a class method. Class methods are only allowed to access static class variables. static methods are final.
An abstract method is used to identify a method that cannot be invoked and must be overridden by any non-abstract subclasses of the class in which it is declared. An abstract method does not have a method body. Instead, it has a semicolon (;).
A native method is a method written in a language other than Java. It is like an abstract method in that its body is replaced by a semicolon.
A synchronized method is a method that must acquire a lock on an object or on a class before it can be executed.
A static initializer is a block of code that is used to initialize the static variables of a class. It is written as follows:
static block
Static initializers can only access static class variables. They are executed in the order in which they appear in a class declaration.
Object initializers do not have the static keyword. They are used to initialize non-static variables of a class and are executed immediately after a class's superclass constructor is invoked.
An interface specifies a collection of abstract methods that must be overridden by classes that implement the interface. Interfaces are declared as follows:
interfaceModifiers interface interfaceName extendsClause interfaceBody
The interface modifiers are public and abstract. public interfaces can be accessed in other packages. All interfaces are abstract. The abstract modifier is superfluous.
The optional extends clause is used to identify any interfaces that are extended by an interface. It is written as follows:
extends interfaceNames
The interface names are separated by commas. An interface inherits all the methods of all interfaces that it extends.
The interface body is enclosed within braces and consists of zero or more variable (constant) and abstract method declarations. Variables declared within an interface are public, static, and final. Methods are public and abstract. These variable and method modifiers need not be specified.
Blocks consist of sequences of local variable declarations and statements. They are written as follows:
{ blockBody }
The block body is a sequence of local variable or class declarations or statements. A block can also consist of a single statement without the enclosing braces.
Local variables are declared in the same manner that field variables are declared, except that local variables do not include modifiers. They are accessible within the block in which they are declared. The this and super variables are predefined. They refer to the current object for which a method is invoked and the superclass of the current object being invoked.
The programming statements supported by Java are described in the following subsections.
The empty statement performs no processing. It consists of a single semicolon.
A block statement consists of a sequence of statements and declarations that are treated as a single statement block. The statements are enclosed within braces ({ and }).
A method invocation invokes a method for an object or class. Method invocations may be used within an expression or as a separate statement. Method invocation statements take the following forms:
objectName.methodName(argumentList);
className.methodName(argumentList);
The argumentList consists of a comma-separated list of zero or more expressions that are consistent with the method's parameters.
When an object is allocated, it is typically assigned to a variable. However, it is not required to be assigned when it is allocated. An allocation statement is of the following form:
new constructor(argumentList);
The new operator is used to allocate an object of the class specified by the constructor. The constructor is then invoked to initialize the object using the arguments specified in the argumentList.
The assignment statement assigns an object or value to a variable. Its general form is
variableName = expression;
where the expression yields a value that is consistent with the variable's type.
Other assignment operators may be used in addition to the = operator. See the section titled "Operators" later in this appendix.
The if statement is used to select among alternative paths of execution. It is written in the following two forms:
if ( booleanExpression ) statement if ( booleanExpression ) statement1 else statement2
In the first form, statement is executed only if the booleanExpression is true. In the second form, statement1 is executed if the booleanExpression is true and statement2 is executed if the booleanExpression is false.
A statement can be labeled by prefixing an identifier to the statement as follows:
label: statement
The label can be a name or integer.
The switch statement is similar to the if statement in that it enables a selection from alternative paths of execution. It is written as follows:
switch (expression) caseBlock
The expression must evaluate to a byte, char, short, or int value. Control is transferred to the next statement in the block that is labeled with a value that matches the expression.
The case block contains a sequence of case-labeled statements. These statements are written as follows:
case value: statement
An optional default-value statement may also appear in the case block. It is written as follows:
default: statement
If no value matches the expression and a default-value statement is provided, control is transferred to this statement. If there is no default-value statement, the next statement following the switch statement is executed.
The break statement is used to transfer control to a labeled statement or out-of-statement block. It takes the following forms:
break;
break label;
The first form transfers control to the first statement following the current statement block. The second form transfers control to the statement with the identified label.
The for statement is used to iteratively execute a statement. It takes the following form:
for (initializationStatement ; booleanExpression ; incrementStatement) iteratedStatement
The initialization statement is executed at the beginning of the for statement, and then the boolean expression is tested. If the expression is true, the iterated statement is executed. The increment statement is executed after the iterated statement and then the boolean expression is retested. The iterated statement-increment-statement loop continues until the boolean expression evaluates to false. The increment statement does not end with a semicolon.
The while statement is used to execute a statement while a boolean expression is true. It is written as follows:
while (booleanExpression) iteratedStatement
The boolean expression is evaluated; if it is true, the iterated statement is executed. It continues to execute until the boolean expression is false.
The do statement, like the while statement, is used to execute a statement until a boolean expression becomes false. The only difference is that the expression is tested after the statement is executed. The do statement is written as follows:
do iteratedStatement while (booleanExpression);
The continue statement is used to continue execution of a loop (for, do, or while) without completing execution of the iterated statement. The continue statement may take an optional label. It is written as follows:
continue label;
If a label is supplied, the loop continues at the labeled loop.
The synchronized statement is used to execute a statement after acquiring a lock on an object. It is written as follows:
synchronized ( expression ) statement
The expression yields the object for which the lock must be acquired.
The try statement executes a block of statements while setting up exception handlers. If an exception occurs, the appropriate handler, if any, is executed to handle the exception. A finally clause may also be specified to perform absolutely required processing.
The try statement is written as follows:
try block catchClauses finallyClause
At least one catch clause or a finally clause must be provided.
The format of the catch clause is as follows:
catch (exceptionDeclaration) block
If an exception is thrown within the block executed by the try statement and it can be assigned to the type of exception declared in the catch clause, the block of the catch clause is executed.
The finally clause, if it is provided, is always executed regardless of whether an exception is generated.
The return statement is used to return an object or value as the result of a method's invocation. It is written as follows:
return expression;
The value of the expression must match the return value identified in the method's declaration.
Java defines arithmetic, relational, logical, bit-manipulation, caste, class, selection, and assignment operators. Table A.2 summarizes these operators.
Operator Type | Operator | Description | Example |
Arithmetic | + | Addition | a + b |
- | Subtraction | a - b | |
* | Multiplication | a * b | |
/ | Division | a / b | |
% | Modulus | a % b | |
Relational | > | Greater than | a > b |
< | Less than | a < b | |
>= | Greater than or equal | a >= b | |
<= | Less than or equal | a <= b | |
!= | Not equal | a != b | |
== | Equal | a == b | |
Logical | ! | Not | !a |
&& | AND | a && b | |
|| | OR | a || b | |
Bit-manipulation | ~ | Complement | ~a |
& | AND | a & b | |
| | OR | a | b | |
^ | Exclusive or | a ^ b | |
<< | Left-shift | a << b | |
>> | Right-shift | a >> B | |
>>> | Zero-filled right-shift | a >>> b | |
Assignment | = | Assignment | a = b |
++ | Increment and assign | a++ | |
-- | Decrement and assign | a-- | |
+= | Add and assign | a += b | |
-= | Subtract and assign | a -= b | |
*= | Multiply and assign | a *= b | |
/= | Divide and assign | a /= b | |
%= | Take modulus and assign | a %= b | |
|= | OR and assign | a |= b | |
&= | AND and assign | a &= b | |
^= | XOR and assign | a ^= b | |
<<= | Left-shift and assign | a <<= b | |
>>= | Right-shift and assign | a >>= b | |
>>>= | Zero-filled left-shift and assign | a >>>= b | |
Caste | (type) | Convert to type | (char) b |
Instance | instanceof | Is instance of class? | a instanceof b |
Allocation | new | Create a new object of a class | new A() |
Selection | ? : | If...Then selection | a ? b : c |
Java's multithreading support is provided through the Thread class of the java.lang package. Objects of the Thread class have their own separate flow of control.
Java provides two approaches to creating threads. In the first approach, you create a subclass of class Thread and override the run() method to provide an entry point into the thread's execution. When you create an instance of your Thread subclass, you invoke its start() method to cause the thread to execute as an independent sequence of instructions. The start() method is inherited from the Thread class. It initializes the Thread object using your operating system's multithreading capabilities and invokes the run() method.
Subclassing the Thread class is a simple and direct approach to multithreading. However, there are times when you may want your thread to be an object of a class that is outside of the Thread class hierarchy. This is often the case when you develop components for multithreaded applets. Java's other approach to creating threads does not limit your threads to the Thread class hierarchy. In this approach, your class implements the Runnable interface of java.lang. The Runnable interface consists of a single method, the run() method, which must be overridden by your class. The run() method provides an entry point into your thread's execution. In order to run an object of your class as an independent thread, you pass it as an argument to a constructor of class Thread.
The stop(), suspend(), and resume() methods of the Thread class have been deprecated in JDK 1.2, which means that they'll be phased out of future versions of Java. These methods have been deprecated because of inherent problems that cannot easily be remedied. Chapter 1, "What's New in JDK 1.2," summarizes these problems.
© Copyright, Macmillan Computer Publishing. All rights reserved.