Professional Documents
Culture Documents
Java Manual
Java Manual
Introduction to
Java Programming
+
Chapter One
Chapter Two
Table of Contents
Overview of Programming
Computer System
Overview of Programming
Introduction to Java
Programming
Introduction to Java
Chapter Three
Chapter Four
Chapter Five
Chapter Six
ii
Objects
15
Basic Structures
15
20
Assignments
22
25
27
Data Types
Numbers
30
Integers
30
Floating-Point Numbers
31
Boolean
33
Characters
36
Expressions
Types of Expressions
39
39
Comparison Operators
40
Chapter Seven
Chapter Eight
Chapter Nine
Chapter Ten
Chapter Eleven
Chapter Twelve
Table of Contents
iii
44
44
else
45
If inside If
48
If-else-If
50
Program Style
Comments
53
Legal Characters
54
import
55
60
63
Special Operators
Bitwise Operators
65
Other Operators
65
68
Comments on switch
70
Order of Precedence
Precedence
72
Chapter Thirteen
Chapter Fourteen
Chapter Fifteen
Chapter Sixteen
Table of Contents
iv
Looping
While-loop
75
Do-while-loop
75
For-loop
75
80
Declaring
81
Calling
82
Object-Oriented Programming
82
Vocabulary
83
Classes
Concepts
89
Creating
90
Declaration
91
Strings
Overview
105
Comparison
106
Conversion
107
Concatenation
107
Chapter Seventeen
Chapter Eighteen
Table of Contents
Inheritance
Concepts
114
Abstract Classes
115
Polymorphism
116
Interfaces
118
Collections
119
Arrays
Introduction
122
Declaring
122
Initialization
124
Multi-dimensional
125
Overview of
Programming
CHAPTER
1
+
Computer System
Overview of Programming
+
Even the simplest computer classifies as a computer system, because at least two
components (hardware and software) have to work together. But the real meaning of
"computer system" comes with interconnection. Many computer systems can
interconnect, that is, join to become a bigger system. Interconnecting computer
systems can prove difficult due to incompatibilities, sometimes between differing
hardware and sometimes between different software suites.
Designers of individual different computer systems do not necessarily aim to
interconnect their product with any other system. But systems administrators can
often configure even disparate computers to communicate using a set of rules and
constraints known as protocols; these precisely define the "outside view" of the
system. This outside view effectively defines the way one system connects with
another. If two systems define the same "outside view", they can interconnect and
become a larger computer system.
This "outside view" usually comes in the form of a standard, that is, a document
explaining all of the rules a device or a program must follow. International bodies
such as the IETF or IEEE normally set up or endorse such standards. If an
individual system obeys all of the rules, systems designers say it "complies with"
the standard.
Programming is ...
... a craft. At its simplest, it comes down to getting a computer to do what you want it
to do (or what your user wants it to do). As a programmer, you are part listener, part
advisor, part interpreter, and part dictator.
The knowledge becomes out of date as new techniques, languages, and environments
are developed. Changing market forces may render the experience obsolete or
irrelevant. Given the speed at which Web-years fly by, this can happen pretty
quickly. Here's a small list of the guidelines to prevent this sad fact:
Learn at least one new language every year. Different languages solve
the same problems in different ways. By learning several different approaches,
you can help broaden your thinking and avoid getting stuck in a rut.
Read a technical book each quarter. Just to stay live :)
Take classes. Look for interesting courses at your local community college
or university.
Stay current. Subscribe to trade magazines and other journals.
It's important to continue investing. Once you feel comfortable with some new
language or bit of technology, move on. Learn another one.
Computer languages influence how we think about a problem, and how we think
about communicating. Every language comes with a list of features - buzzwords such
as static versus dynamic typing, early versus late binding, inheritance models (single,
multiple, or none) - all of which may suggest or obscure certain solutions. Designing
CHAPTER
Introduction to
Java Programming
Java
Objects
Basic Structures
Much of the syntax of Java is the same as C and C++. One major difference is that
Java does not have pointers. However, the biggest difference is that you must write
object oriented code in Java. Procedural pieces of code can only be embedded in
objects. In the following we assume that the reader has some familiarity with a
programming language. In particular, some familiarity with the syntax of C/C++ is
useful.
In Java we distinguish between applications, which are programs that perform the
same functions as those written in other programming languages, and applets, which
are programs that can be embedded in a Web page and accessed over the Internet.
Our initial focus will be on writing applications. When a program is compiled, a byte
code is produced that can be read and executed by any platform that can run Java.
When compiling you use javac <classname>.java and when interpreting java
bytecodes use java <classname>.
Steps in compiling and executing java programs:
1. Open a text editor
10
11
12
13
14
15
}
}
The first four lines is a comment on the application's function. Comments are not
required but are extremely useful as documentation within the source. Other notes
and doc files may get lost but these stay right where they are most useful. A long
comment starts with a /* or /** and ends with a */ Short one line comments begin
with // and end with the <return>.
The fifth line starts with the reserved word public. This indicates that objects
outside the object can invoke (or use) it. The reserved word class indicates that we
are building a new object with the name that follows. HelloWorldApp is the object
name (your choice) and is case sensitive. Java 'style' is to capitalize the first letter of
each word only. The line concludes with an opening curly bracket that marks the
start of the object definition.
Line six is an invocation of an initialization method (or procedure in older
languages). static indicates that it calls the class and not an 'instance' of the class.
The concept of 'instance' will be discussed later in the tutorials. The method's name
is main and the reserved word void indicates that no result is returned back. Main
has arguments (aka parameters) in round brackets. String[] indicates the variable
type is an array and args is a reserved word indicating that it is the command line
values that are being passed over to main. The line finishes with an opening bracket
for the main method.
Line eight invokes the println method of the system.out object. What is to be printed
is passed in the argument as a string parameter. Note that each Java statement
concludes with a semicolon.
Finally closing curly brackets are used for the main and for the object definition.
The Basic Structure of a Java Applet
Here is the explanation of the basic structure of a Java applet using the one that you
wrote to test your environment. Applets are placed in HTML documents and are
invoked (or executed) from within a Java aware browser such as MSIE, Netscape or
Opera.
/**
* The HelloWorld class implements an applet that
* displays "Hello World!" within an HTML document.
*/
import java.awt.Graphics;
import java.applet.Applet;
public class HelloWorld extends Applet
{
public void init() // Initialize the canvas
{
resize(150,10);
}
16
17
Exercises
1. Compile and execute the code below.
import java.io.*;
public class ExerOne{
public static void main(String [] args){
BufferedReader r=new BufferedReader(new
InputStreamReader(System.in));
System.out.println("Hello out there.");
System.out.println("Want to talk some more?");
System.out.println("Answer y for yes or n for no.");
char answerLetter;
try{
answerLetter=r.readLine().charAt(0);
}catch(Exception ex){};
if (answerLetter == 'y')
System.out.println("Nice weather we are having.");
System.out.println("Good-bye.");
}
}
2. Make a java program that print in the screen the following statements:
Java is great!!!
Java for one.
Java for all.
Follow the steps in compiling and executing java programs given earlier.
3. Here is another sample of a Java applet, try to compile and execute the
following code. Explore the code and take note of the objects used.
import javax.swing.*;
public class SampleApplet extends JApplet{
public void init(){
18
19
Variables and
Assignments
CHAPTER
3
+
Variables
Assignments
Variables
Variables are places in memory to store values. There are
different kinds of variables, and every language offers
slightly different characteristics.
Data Type specifies the kinds of data a variable an store. Java has two general kinds
of data types.
8 basic or primitive types (byte, short, int, long, float, double, char, boolean).
An unlimited number of object types (String, Color, JButton, ...). Java object
variables hold a reference (pointer) to the the object, not the object, which is
always stored on the heap.
Scope of a variable is who can see it. The scope of a variable is related program
structure: eg, block, method, class, package, child class.
Lifetime is the interval between the creation and destruction of a variable. The
following is basically how things work in Java. Local variables and parameters are
created when a method is entered and destroyed when the method returns. Instance
variables are created by new and destroyed when there are no more references to
them. Class (static) variables are created when the class is loaded and destroyed
when the program terminates.
Initial Value. What value does a variable have when it is created? There are several
possibilites.
1. No initial value. Java local variables have no initial value, however Java
compilers perform a simple flow analysis to ensure that every local variable is
assigned a value before it is used. These error messages are usually correct,
but the analysis is simple-minded, so sometimes you will have to assign an
initial value even tho you know that it isn't necessary.
2. User specified initial value. Java allows an assignment of intitial values in the
declaration of a variable.
3. Instance and static variables are given default initial values: zero for numbers,
null for objects, and false for booleans.
21
Declarations allow the compiler to find places where variables are misused,
eg, parameters of the wrong type. What is especially good is that these errors
are detected at compile time. Bugs that make it past the compiler are harder
to find, and may not be discovered until the program has been released to
customers. This fits the fail early, fail often philosophy.
Assignment Statements
Assignment statements use an assignment operator to store a value or the result
of an expression in a variable. Memory allocation is done at the time of
assignment. Primitive datatypes have static allocation with size determined by
their type. Simple examples include first_name = "Fred"; and count +=;
Variables may be assigned an initial value when declared. This is considered good
programming practice. Examples are boolean fileOpenFlag = true;, int
finalScore = null; and final float PI = 3.14159;
Local variables must be assigned a value prior to use. There is no default
assumption. Failure to initialize will cause a compiler error! Field variables (aka
properties) have defaults but initialization is good programming practice.
Arrays are allocated memory dynamically based on their array size through the
use of the new reserved word.
intArray = new int[5]; //previously declared
int markArray = new int[9]; //declaration and allocation at same time
int grades = new int[maxMarks]; //maxMarks must evaluate to positive
integer
Note: Since Java is a strongly typed language, required changes in data type must be
explicitly done with a cast operation. For example a = (int) b; (assumes a is of
type int and b is type char).
Exercises
1. Give the declaration for a variable called count of type int. The variable
should be initialized to zero in the declaration.
22
23
Input / Output
CHAPTER
4
+
10 }
11
12
13
14
Line 6 - import
One strength of Java is that it has many libraries or packages of predefined
classes and methods to help you do things. Some of these are automatically
known in every Java program, but you have to explicitly import others. This
import statement tells the compiler that you will be using part of the
Graphical User Interface (GUI) library - everything in javax.swing. Typical
programs have a few import statements.
Line 11 - Display a dialog box
This line displays this dialog box. The
predefined Java class, JOptionPane
contains methods to display dialog
boxes. A method is a group of Java
statements for doing one particular
thing. The "." following the class name
is followed by the name of the method,
showMessageDialog. Every method call
must be followed by a parenthesized
list of comma-separated arguments
(often called parameters) that specify
25
7
8
9
10
18
Line 11 - Declaring a local variable.
This tells the compiler to reserve some memory to hold a String. It's going to
hold a name, so we called the variable (a place in the computer's memory)
"humanName". The syntax for a simple declaration is to write the type of
thing that a variable will hold (String in this case), followed by the variable
name (humanName in this case).
26
27
Exercises
1. Give a Java statement that will display a window on the screen with the
message I Love You.
2. Write a complete Java program that will ask the user for the initials of the
users first and last name, and then output a greeting that says Hello
followed by the users initials and an exclamation mark. For example, if the
users initials are J and B, then the output greeting would be:
Hello J B!
If the users initials are stored in the two variables firstInitial and lastInitial,
both of type char, then the above output can be produced by the following
statement:
System.out.println(Hello + firstInitial + + lastInitial + !);
Be sure to note that the blank symbol is output after firstInitial. The use of the
plus sign in this way will be discussed later. In this exercise use the console to
accept input and display output.
28
Data Types
CHAPTER
5
+
Numbers
Integer
Floating-Point
Boolean
Characters
30
Numbers
There are two general kinds of numbers in Java and most other programming
languages: binary integers and binary floating-point numbers (sometimes called
real numbers). Although these numbers are stored in the computer as binary
numbers, you will usually use decimal numbers in your Java source program, and
the Java compiler will translate them to the correct binary form.
Numbers in Java
Integers
Floating-point
Strings to Numbers
Integers
Integers are whole numbers, for example, -35, 0, 2048, .... Integers are represented
in binary inside the computer, and in decimal in Java source programs. Java
automatically converts decimal numbers you write in your source program into
binary numbers internally.
Four (or five) kinds of primtive integers and two integer classes.
Primitive types. There are four types of integers in Java: byte, short, int, long. The
most common is int.
char! Technically, char is an unsigned integer type although it is almost exclusively
used to store characters. Making it integer is largely because of Java's legacy from
C++. Don't use char for integers unless you are sure of what you're doing.
Classes. In addition to the primitive types, there are two classes used for integers.
Integer - Primarily useful for utility methods and to put in the Collections
data structure classes.
Range
Maximum
+127
+32,767
int
32 -2,147,483,648
+2,147,483,647
long
64 -9,223,372,036,854,775,808 +9,223,372,036,854,775,807
int literals are written in the usual decimal notation, like 34 or -222.
long literals are written by adding an L (or lowercase l altho this is almost
There is no way to write a literal byte or short, altho sometimes Java will
automatically cast an int literal to the appropriate type.
Hexadecimal literals
You can write an int in hexadecimal by prefixing the hexadecimal number with the
digit zero followed by the letter x, "0x" or "0X". The hexadecimal digits are 0-9 and
the letters a-f in upper- or lowercase.
int i;
i = 0x2A; // assigns decimal 42 to i.
The shame of integer arithmetic
Operations may produce numbers which are too large (overflow) to be stored in an
int. No error is caused in this case; the result is simply an incorrect number (one of
the shames of modern computer arithmetic). Division by zero will cause an execution
exception (ArithmeticException). Use BigInteger to prevent arithmetic overflow.
Floating-point
Floating-point numbers are like real numbers in mathematics, for example, 3.14159,
-0.000001. Java has two kinds of floating-point numbers: float and double, both
stored in IEEE-754 format. The default type when you write a floating-point literal is
double.
Java floating-point types
type Size
Range
Precision
name bytes bits approximate in decimal digits
float 4
32 +/- 3.4 * 1038 6-7
double 8
64 +/- 1.8 * 10308 15
Limited precision
Because there are only a limited number of bits in each floating-point type, some
numbers are inexact, just as the decimal system can not represent some numbers
exactly, for example 1/3. The most troublesome of these is that 1/10 can not be
represented exactly in binary.
31
Floating-point literals
There are two types of notation for floating-point numbers. Any of these numbers
can be followed by "F" (or "f") to make it a float instead of the default double.
Standard
123450.0
1.2345e+5 123450.0
1.2345e-5
0.000012345
Example statement
Int
i = Integer.parseInt(s);
long
l = Long.parseLong(s);
float
f = Float.parseFloat(s);
double d = Double.parseDouble(s);
If s is null or not a valid representation of a number of that type, these methods will
throw (generate) a NumberFormatException. See below.
Handling NumberFormatExceptions
Put number conversions inside a try . . . catch statement so that you can do
something if bad input is entered. The conversion method will throw a
32
i = Integer.parseInt(s, radix);
long
l = Long.parseLong(s, radix);
33
Name
Meaning
i < j less than
6 < 24 is true.
i <= j less than or equal
6 <= 24 is true.
i == j equal
6 == 24 is false.
i >= j greater than or equal 10 >= 10 is true.
i > j greater than
10 > 10 is false.
i != j not equal
6 != 24 is true.
Logical operators
Op Name
Meaning
a && b and
The result is true only if both a and b are true.
a || b or
The result is true if either a or b is true.
!a
not
true if a is false and false if a is true.
Other operators and methods returning boolean values
Many methods return boolean values, eg, equals, and methods that begin
with "is". If you are writing your own boolean method, starting the name with
"is" is a good practice.
Less common logical operators: &, |, and ^ with boolean operands. These
are generally used with bits. || (or) and && (and) are preferred to | and &
because they are short-circuit operators that can stop the evaluation when
one of the operands determines the resulting value.
Boolean variables
You can declare boolean variables and test them. For example, this simple bubble
sort keeps looping until there were no exchanges, which means that everything must
be sorted. This is only an example, not a good way to sort.
void bubbleSort(int[] x, int n) {
boolean anotherPass; // true if something was out of order
do {
34
Unicode
Unicode is a system of encoding characters. All characters and Strings in Java use
the Unicode encoding, which allows truly international programming.
About Unicode
The Unicode effort is not coordinated with Java. At the time that Java was
started, all 50,000 defined Unicode characters could be reprensented with 16
bits (2 bytes). Consequently, Java used the 2-byte (sometimes called UTF-16)
representation for characters.
However, Unicode, now at version 4.0, has defined more characters than fit
into two bytes. To accommodate this unfortunate occurrance, Java 5 has
added facilities to work with surrogate pairs, which can represent characters
with multiple character codes. As a practical matter, most Java programs are
written with the assumption that all characters are two bytes. The characters
that don't fit into two bytes are largely unused, so it doesn't seem to be a
serious deficiency. We'll see how this works out in the future.
ASCII. Most programming languages before Java (C/C++, Pascal, Basic, ...)
use an 8-bit encoding of ASCII (American Standard Coding for Information
Interchange). ASCII only defines the first 128 characters, and the other 128
values are often used for various extensions.
The first 64 characters of Unicode have the same values as the equivalent
ASCII characters. The first 128 characters are the same as ISO-8895-1 Latin-1.
35
Unicode Fonts
Altho Java stores characters as Unicode, there are still some very practical operating
system problems in entering or displaying many Unicode characters. Most fonts
display only a very small subset of all Unicode characters, typically about 100
different characters.
Character
Character class static methods
Character Class Methods
Character class is used mostly for static methods to test char values.
b = Character.isDigit(c)
true if c is digit character.
b = Character.isLetter(c)
true if c is letter character.
b = Character.isLetterOrDigit(c)
true if c is letter or digit.
b = Character.isLowerCase(c)
true if c is lowercase char.
b = Character.isUpperCase(c)
true if c is uppercase char.
true if c is space, tab, ....
b = Character.isWhitespace(c)
c = Character.toLowerCase(c)
Lowercase version of c.
c = Character.toUpperCase(c)
Uppercase version of c.
ANSI/ASCII and Extended Latin Sections of Unicode
Unicode attempts to represent the characters in all current human languages, as well
as numerous special symbols. The most common implmentation of it uses 16 bits,
which is 65,536 characters (many are not yet assigned a graphic). The first 128 codes
are identical to ANSI/ASCII (American National Standards Institute / American
Standard Code for Information Interchange). Of the ASCII codes, the first 32 are
control codes. The first 256 codes are the same as ISO-8859-1 (Latin-1), which
includes ASCII of course. Below is a table which shows this common first part of the
Unicode character set. The table below is in HTML, so the actual characters that are
displayed are determined by your browser, not Java.
36
37
"
% &
'
48
<
>
64
@ A
80
Q R
W X
96
112 P
128
144
160
176
192
208
224
240
Exercises
1. Write a program that reads in a four digit number (like 1998) and that outputs
the number one digit per line, like so:
1
9
9
8
Your prompt should tell the user to enter a four-digit number and can then
assume that the user follows directions. Your program will not read the
number as a value of type int, but as four characters of type char.
2. Write a complete Java program that will read in two values of type double
and output the sum of the two numbers. Use the class JOptionPane to do
input and output using windows.
Expressions
CHAPTER
Types of Expressions
Expressions
Expressions within
Expressions
Comparison Operators
Types of Expressions
To put it simply, an expression is a line of code that can be reduced to a value or that
assigns a value. For example, you know that the addition operator adds one
expression to another, like this:
sum = expr1 + expr2;
In the preceding line, expr1 can be something as simple as the variable x or as
complex as (4 + 5) * 2 * 5 / 7 + x / y. The same goes for expr2, of course. And, in fact, the
first example containing expr1 and expr2 is an expression itself!
But no matter how complicated, all expressions can be classified into one of three
main categories:
39
(5 - x)
(2 + y)
And the above simplified expressions contain yet more sub-expressions. Those
expressions are:
5
x
2
y
Expressions are what programmers like to call recursive, meaning that the definition
of an expression keeps coming back on itself. An expression contains expressions
that contain other expressions, which themselves contain other expressions. How
deep you can dig depends on the complexity of the original expression. But, as you
saw demonstrated, even the relatively simple expression num = (5 - x) * (2 + y) has four
levels of depth.
Comparison Operators
Now that you've dug into the secrets of expressions, it's time to learn about a new
type of operator. So far, you've gotten some practice with mathematical operators,
which enable you to build various types of numerical and assignment expressions.
Another type of operator you can use to build expressions is the comparison
operator. Comparison operators are used to create logical expressions, which, if you
recall, result in a value of true or false. Table 8.1 lists the logical expressions used in
Java programming. C and C++ programmers will find these operators very familiar.
Table 8.1 Java's Logical Operators.
Operators
Description
==
Equal to
<
Less than
>
Greater than
<=
>=
!=
Not equal to
40
41
true
3 + 4 != 7
false
3 + 4 != 2 + 6
true
3 + 4 < 10
true
3 + 4 <= 10
true
3 + 4 == 4 + 4
false
3 + 4 > 10
false
3 + 4 >= 7
true
3 + 4 >= 8
false
Exercises
Suppose goals is a variable of type int. Fill in the if-else statement with an
expression that outputs the word Wow if the value of the variable goals is
greater than 10 and the words Oh Well if the value of goals is at most 10.
import java.io.*;
public class ExerTwo{
public static void main (String[] args){
System.out.println("Enter the number of goals:");
BufferedReader r=new BufferedReader(new
InputStreamReader(System.in));
String goalInput="";
int goals;
try{
goalInput=r.readLine();
}catch(Exception ex){};
goals=Integer.parseInt(goalInput);
if(___________)
System.out.println("Wow");
else
System.out.println("Oh Well");
}
}
42
Simple Flow
of Control
CHAPTER
General Forms
Condition is True or False
else
if inside if
If-else-if
if Statement - Overview
Purpose
The purpose of the if statement is to make decisions, and execute different parts of
your program depending on a boolean true/false value. About 99% of the flow
decisions are made with if. [The other 1% of the decisions use the switch/case
statement.]
General Forms
The if statement has this form:
do these statements
if (condition) {
do this clause if the condition is true
}
do these statements afterwards
or
do these statements
if (condition) {
do this clause if the condition is true
} else {
do this clause if the condition is false
}
do these statements afterwards
It is good programming style to always write the curly braces, {}, altho they are not
needed if the clause contains only a single statement.
Condition is true or false
The value of condition must be true or false (ie, a boolean value). It is often a
comparison.
...
if (marks < 60) {
JOptionPane.showMessageDialog(null, "This is terrible");
} else {
JOptionPane.showMessageDialog(null, "Not so bad");
}
44
...
The code above will display one of two dialogs, depending on teh value of marks.
'else' Not Required
'else' is not required
It is not necessary to have the else part of an if statement. Maybe only 50% of the time
there is an else part.
Form
The if statement without an else has this form:
if (condition) {
do this if the condition is true
}
Example
Here is a paintComponent() method with an if statement without an else clause.
public void paintComponent(Graphics g) {
super.paintComponent(g); // draw background etc.
if (marks < 50) {
g.setColor(Color.red);
}
g.drawString("Score = " + marks, 10, 50);
}
When the paintComponent() method begins, the Graphics context g uses Color.black by
default. Therefore there is no need to set the color to black.
'if' Statement - Braces
Braces { } not required for one statement
If the true or false part of and if statement has only one statement, you do not need
to use braces (also called "curly brackets").
Form
The if statement doesn't need braces if there is only one statement in a part. Here
both the true and false parts have only one statement:
if (condition)
one statement to do if condition is true
else
one statement to do if condition is false
45
46
if statement.
There are about ten kinds of statements. Many of them use braces for grouping
statements in the same way that the if statement uses braces.
'if' Statement - Indentation
Indent to make programs readable
There are several meathods to make programs readable. How can you easily make
the reader see which statements are inside the true part and false part of an if
statement.
The best way to show this is to indent the statements that are inside. To do this you
move the statements to the right by a few spaces. People commonly use two,
three, or four spaces. Choose one number (eg, I use 2 or 3), and use it for all
programs.
Java doesn't care about your indentation -- it is for humans (including yourself!).
Example 1 - No indentation - BAD BAD BAD
Here is the paintComponent() method from a previous page without indentation. This
is small, so it's easy to see which statements are in the true and false parts. If the if
statement is much larger, it will be unreadable without indentation.
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (marks < 50)
g.setColor(Color.red);
else
g.setColor(Color.black);
g.drawString("Score = " + marks, 10, 50);
}
47
48
c = Color.blue;
}
Because the true and false parts are both single statements, you might want to leave
out the braces and write:
if (age < 24)
if (height > 200)
c = Color.red;
else
c = Color.blue;
But this is WRONG, because 'else' always goes with the nearest 'if' when there are no
braces. This code is the same as:
if (age < 24) {
if (height > 200)
c = Color.red;
else
c = Color.blue;
}
Advice: Always use braces on if statements
These kinds of errors are very hard to find. This is another good reason to always
use braces.
Watch out for semicolons on your if statements
Why does the following code always say it thinks the user is lying?
String ageStr = JOptionPane.showInputDialog(null, "How old are
you?");
int age = Integer.parseInt(ageStr);
if (age > 120 || age < 0);
System.out.println("I think you're lying about your age!");
It's the semicolon! if you put a semicolon directly after the condition in an if
statement, Java thinks it's finished with the body of the statement. The indentation
of the next line, which is so important to human readers, is ignored by Java.
This is another error that's harder to make if you always follow the condition by an
opening brace.
49
50
Complaint
Some programming languages recognize this as a common kind
structured-programming construction, and have a special 'elseif'
statement. This would be a nice thing to add to Java.
Exercises
1. Suppose salary and deductions are variables of type double that have
been given values. Write an if-else-statement that outputs OK and sets the
variable net equal to salary minus deductions. If, however, salary is less
than deductions, the if-else-statement simply outputs the word Crazy, and
does not change the value of any variables.
2. Suppose number is a variable of type int that has been given a value. Write a
multibranch if-else-statement that outputs the word High if number is
greater than 10, outputs Low if number is less than 5 and output So-so if
number is anything else.
51
CHAPTER
Program Style
+
Comments
Legal Characters
import
Comments
Computer programs are read by both computes and humans. You write
Java instructions to tell the computer what to do. You must also write comments to
explain to humans what the program does. Of course, Java can't understand them
because they are written in English, or Spanish, or Thai, or ... .
Java ignores all comments. There is, however, a program called javadoc which
reads certain kinds of comments and produces HTML documentation (see below).
Spaces and blank lines
One of the most effective ways to make a program readable is to put spaces in at key
points. There are several styles for doing this. Even more important is to put blank
lines in your program. These should separate sections of code. There should be a
blank line between each "paragraph" of code. By paragraph, I mean a group of
statements that belong together logically; there is no Java concept of paragraph.
Java comments
// comments -- one line
After the two // characters, Java ignores everything to the end of the line. This
is the most common type of comment.
//--- local variables --int nquest; // number of questions.
int score; // count of number correct minus number wrong.
/* ... */ comments -- multiple lines
After the /* characters, Java will ignore everything until it finds a */. This kind
of comment can cross many lines, and is commonly used to "comment out"
sections of code -- making Java code into a comment while debugging a
program. For example,
/* Use comments to describe variables or sections of the
program.
They are very helpful to everyone who reads your programs:
your teacher, your boss, but especially yourself!
*/
javadoc comments
Comments that start with /** are used by the javadoc program to produce
HTML documentation for the program. The Java documentation from Sun
Microsystems is produced using javadoc. It is essential to use this kind of
comment for large programs.
53
Best Practices
Every comment has the potential to create an inconsistency between what the
comment says, and what the code does. One cause of "software rot" is that
code is changed over time, but comments are not updated. To avoid this, keep
comments next to the code that is documented so that they may be more
easily synchonized.
Identifier Names
Getting the names of things right is extremely important. It makes a huge difference
in readability. Many IDEs support refactoring, and specifically renaming. I will
sometimes rename classes several times before I hit on exactly the obvious name. It's
worth the effort.
Legal Characters
Every name is made from the following characters, starting with a letter:
Letters: a-z, A-Z, and other alphabetic characters from other languages.
Digits: 0-9
Special: _ (underscore)
No names can be the same as a Java keyword (eg, import, if, ...).
Examples
Apple
This is a legal name. Lowercase implies it's a variable or method.
Apple
This is a different legal name. Uppercase implies it's a class or interface.
APPLE Yet a different legal name. All uppercase implies it's a constant.
Topleft Legal, but multiple words should be camelcase.
top_left Better, but camelcase is preferred to _ in Java.
topLeft Good Java style
top left ILLEGAL - no blanks in a name
Import ILLEGAL - same as the Java keyword
Using Uppercase, Lowercase, and "Camelcase" Letters
The conventions for the use of upper- and lowercase is not enforced by compilers,
but it is so widely observed, that it should have been. Camelcase is the practice of
capitalizing the first letter of successive words in multi-word identifiers. Camelcase is
much preferred in the Java community over the use of underscores to separate
words, or even worse, no distinction made at word boundaries.
Class and interface names - Start with uppercase
54
A directory / folder is created with this project name. This directory name is
the name of your package.
When you build a main project, the double-clickable .jar file will use this
project/package/directory name.
55
Syntax
The package-path is a dot-separated series of nested packages, eg, java.awt or
java.awt.event. You can import (make visible) either a single class or all classes in
package with the "*" wildcard character.
Suggestion: Use only the first wildcard case below. It is by far the most common
usage.
import package-path.*; // Makes all classes in package visible.
import package-path.class; // Makes only class visible.
import static package-path.*; // Makes all static variables in all
classes in package visible.
import static package-path.class; // Makes all static variables in class
visible.
Example: import all classes in a package
The JOptionPane class is in the swing package, which is located in the javax
package.
import javax.swing.*; // Make all classes visible altho only one is used.
class ImportTest {
public static void main(String[] args) {
JOptionPane.showMessageDialog(null, "Hi");
System.exit(0);
}
}
Common imports
There are 166 packages containing 3279 classes and interfaces in Java 5. However,
there are only a few packages that are used in most programming. GUI programs
often use the first three imports.
import java.awt.*;
56
It's hard to remember to remove classes when they are no longer used,
so the import list is surprisingly often wrong. It can seriously slow
down reading because unusual or unexpected class imports make me
look for that class, only to discover that it must have been used in an
earlier version.
57
58
Using Logical
Expressions
CHAPTER
Logical Operators
Writing Logical Expressions
Logical Operators
The comparison operators enable you to compare two expressions. But another type
of operator-logical operators-supercharges comparison operators so that you can
combine two or more logical expressions into a more complex logical expression.
Even if you've never programmed a computer before, you're already familiar with
logical operators because you use them in everyday speech. For example, when you
say, "Do you have a credit card or ten dollars in cash?" you're using the logical
operator OR. Similarly, when you say, "I have a dog and a cat," you're using the AND
operator. Table 8.3 lists Java's logical operators and what they mean.
Table 8.3 Java's Logical Operators.
Operator
Description
&&
AND
||
OR
Exclusive OR
NOT
The AND (&&) operator requires all expressions to be true for the entire expression
to be true. For example, the expression
(3 + 2 == 5) && (6 + 2 == 8)
is true because the expressions on both sides of the && are true. However, the
expression
(4 + 3 == 9) && (3 + 3 == 6)
is false because the expression on the left of the && is not true. Remember this when
combining expressions with AND: If any expression is false, the entire expression is
false.
The OR operator (||) requires only one expression to be true for the entire expression
to be true. For example, the expressions
(3 + 6 == 2) || (4 + 4 == 8)
and
(4 + 1 == 5) || (7 + 2 == 9)
60
61
(4 == 4) && (5 == 5) && (6 == 6)
This expression gives a result of true because each expression to the left and right of
each AND operator is true. However, this expression yields a value of false:
(4 == 4) && (5 == 6) && (6 == 6)
Remember that, when using AND, if any sub-expression is false, the entire
expression is false. This is kind of like testifying in court. To be true, it's got to be the
truth, the whole truth, and nothing but the truth.
Example: Combining Different Comparison and Logical Operators
Again, just like mathematical operators, there's no restriction on how you can
combine the different comparison and logical operators, although if you build a very
complex expression, you may have trouble evaluating it yourself. Check out this
expression:
(3 < 5) && (2 == 2) && (9 > 6)
Here you've used four different comparison and logical operators in the same
complex expression. But because you're comparing the sub-expressions with the
AND operator, and because each of the sub-expressions is true, the result of the
above expression is true.
Now, look at this expression:
((3 < 5) && (2 == 1)) || (7 == 7)
Yep, things are getting tricky. Is the above expression true or false? (Hey, give it a
shot. You've got a fifty-fifty chance.) Ready for the answer? The above expression is
true. First, look at the parentheses. The outermost parentheses, on the left, group the
two expressions being compared by the AND operator into a single expression, so
evaluate it first. The value 3 is less than 5, but 2 does not equal 1, so the entire
expression on the left of the OR operator is false. On the right of the OR operator,
however, 7 does indeed equal 7, so this sub-expression is true. Because one of the
expressions in the OR comparison is true, the entire expression is true. Here's how
the expression breaks down, step-by-step:
((3 < 5) && (2 == 1)) || (7 == 7)
((true) && (false)) || (7 == 7)
62
false || (7 == 7)
false || true
true
Writing Logical Expressions
You wouldn't write expressions such as
(4 + 5 == 9) && !(3 + 1 == 3)
in your programs. They would serve no purpose because you already know how the
expressions evaluate. However, when you use variables, you have no way of knowing
in advance how an expression may evaluate. For example, is the expression
(num < 9) && (num > 15)
true or false? You don't know without being told the value of the numerical variable
num. By using logical operators, though, your program can do the evaluation, and,
based on the result-true or false-take the appropriate action. In the next chapter,
which is about if and switch statements, you'll see how your programs can use logical
expressions to make decisions.
63
10
CHAPTER
Special Operators
Bitwise Operators
Other Operators
65
Bitwise Operators
Java's bitwise operators operate on individual bits of integer (int and long) values. If
an operand is shorter than an int, it is promoted to int before doing the operations.
It helps to know how integers are represented in binary. For example the decimal
number 3 is represented as 11 in binary and the decimal number 5 is represented as
101 in binary. Negative integers are store in two's complement form. For example, -4
is 1111 1111 1111 1111 1111 1111 1111 1100.
The bitwise operators
Operator Name Example Result
Description
a&b
and
3&5
a|b
or
3|5
1 if either bit is 1.
a^b
xor
3^5
~a
not
~3
-4
n << p
left
shift
3 <<< 2
12
n >> p
right
shift
5 >> 2
n >>> p
right
shift
-4 >>> 28 15
// unpacking
height = packed_info & 0x7f;
gender = (packed_info >>> 7) & 1;
age = (packed_info >>> 8);
Use: Setting flag bits
Some library functions take an int that contains bits, each of which represents a
true/false (boolean) value. This saves a lot of space and can be fast to process. [needs
example]
Use: Shift left multiplies by 2; shift right divides by 2
On some older computers it was faster to use shift instead of multiply or divide.
y = x << 3;
// Assigns 8*x to y.
66
The switch
statement
11
CHAPTER
switch
comments on switch
68
69
It requires integers and doesn't allow useful types like String. Many other
languages do.
Exercises
1. Write a code that outputs One if the user inputs 1, Two if the user inputs 2,
Three if the user inputs 3, and outputs Go if the user inputs other numbers.
Use the switch statement.
2. Write a code that accepts a number from 1 to 12 as input. The code will output
January if the user inputs 1, February if the user inputs 2, March if the
user inputs 3 and so on. I f the user inputs a number not included in the given
range the code will output the statement Sorry, no such month.
70
Order of
Precedence
12
CHAPTER
Precedence
72
Order of Precedence
The operators in Java, shown in order of precedence - from highest to
lowest
Priority
1
Operators
Operation
[]
array index
()
method call
member access
++
--
+-
bitwise NOT
(type)
type cast
new
object creation
*/%
+-
addition, substraction
string concatenation
<<
>>
>>>
< <=
> >=
instanceof
reference test
Associativity
Left
Right
Left
Left
Left
Left
73
==
equal to
!=
not equal to
&
bitwise AND
&
bitwise XOR
bitwise OR
boolean (logical) OR
11
&&
Left
12
||
boolean (logical) OR
Left
13
?:
conditional
Right
assignment
*= /= += -= %=
<<= >>= >>>=
&= ^=
combinated assignment
(operation and assignment)
10
14
|=
Left
Left
Left
Left
Right
13
CHAPTER
Looping
+
while-loop
do-while loop
for-loop
75
}
Similar to the 'if' statement
There are three general ideas that you will see in many parts of Java.
indentation
76
count = count + 1;
}
g.drawString("Loop is finished. count="+count, 10, 300);
}//end paintComponent
This repeats the drawLine() call 50 times. The first time the while condition is tested,
it is true because the value of count is 0, which is less than 50. After the statements in
the body are done, the while loop comes back to the top of the loop and makes the
test again. Each time the value of count is larger. Finally, count is 50, and the value of
the condition will be false.
When the loop stops, the program continues with the statement after the end of the
loop (the drawLine() call). This will display the string "Loop is finished. count=50".
'for' Statement
Purpose
The purpose of the for statement is to repeat Java statements many times. It is
similar to the while statement, but it is often easier to use if you are counting or
indexing because it combines three elements of many loops: initialization, testing,
and incrementing.
General Form
The for statement has this form:
for (init-stmt; condition; next-stmt) {
do this each time
}
There are three parts in the for statement.
1. The init-stmt statement is done before the loop is started, usually to initial a
variable.
2. The condition expression is tested at the beginning of each time the loop is
done. The loop is stopped when this boolean expression is false (the same as
the while loop).
3. The next-stmt statement is done at the end of every time through the loop,
and usually increments a variable.
Example
Here is a loop written as both a while loop and a for loop. First using while:
count = 0;
while (count < 50) {
g.drawLine(20, count*5, 80, count*5);
count = count + 1;
}
77
Exercises
1. Write a program that asks the user to enter the size of triangle to print out (an
integer from 1 to 50) then print the triangle by printing a series of lines with
asterisks. The first line will have one asterisk, the next two, etc., each line
having one more asterisk than the previous line up to the number entered by
the user; on the next line print one less asterisk and continue by decreasing
the number of asterisks by one for each successive line until only one asterisk
is printed. Hint: use nested for loops; the outside loop controls the number of
lines to print and the inside loop controls the number of asterisks to print on a
line. For example, if the user enters 5 the output would be
*
**
***
****
*****
****
***
**
*
2. Create a program that lets the user enter a number greater than zero and
outputs the number given. This procedure will be performed as long as the
number is greater than zero. Use the while loop.
3. Create a program similar to the previous exercise but instead of using a while
loop use the do-while loop.
78
Programming
Using Methods
14
CHAPTER
Introduction
Declaring
Calling
Vocabulary
OOP
+
Methods - Introduction
Methods
The word method is commonly used in Object-Oriented Programming and is used in
Java. It means the same thing as function, procedure, or subroutine in other
programming languages. Many programmers use these other terms, especially
function, but these notes will use method
.
Why use methods?
For reusable code
If you need to do the same thing, or almost the same thing, many times, write
a method to do it, then call the method each time you have to do that task.
To parameterize code
In addition to making reusable code that is the same in all cases, you will
often want to use parameters that change the way the method works.
For top-down programming
A very useful style of programming is called top-down programming. You
solve a big problem (the "top") by breaking it down into little problems. To do
this in a program, you write a method for solving your big problem by calling
on other methods to solve the smaller parts of the problem. And these
methods for solving the simpler problems similarly call on other methods
until you get down to simple methods which solve simple problems
To create conceptual units
Create methods to do something that is one action in your mental view of the
problem. This will make it much easier for you to work with your programs.
To simplify
Because local variables and statements of a method can not been seen from
outside the method, they (and their complexity) are hidden from other parts
of the program, which prevents accidental errors or confusion.
Methods - Example
Example
This example shows a simple method that computes the area of a rectangle:
1. int computeArea(int width, int height) {
2.
3.
4.
return area;
5. }
80
The static keyword is used to declare class methods -- methods that don't
refer to a specific object. The only method that you will probably declare this
way is main.
type
Any Java type, including arrays, can be written here to tell what data type
value the method returns. Use void if the method doesn't return a value.
Note: There are also other, less frequent, modifiers that we won't discuss here
(protected, synchronized, final, abstract, native)
Parameters
Formal parameters are the parameters that are written in the method definition.
These are the names that you use in your method. Formal parameters are like local
variables that get an initial value at the time the method is called.
Actual parameters or arguments are the values that are written in the method
call. The actual parameter values are copied into the formal parameters, which are
then like initilialized local variables.
81
Local Variables
Variables that you declare in a method are called local variables. They are created on
a call stack when the method is entered, and they are destroyed when the method
returns. Because objects (eg Strings and arrays) are allocated in the heap, they are
never in the call stack and can be returned from the method.
Methods - Calling
What happens when a method is called
1. Space on the call stack is reserved for the return address, the local variables
and formal parameters, and perhaps other things in the current method that
must be saved.
2. The actual parameters are copied into the formal parameters.
3. Execution is transferred to the beginning of the called method.
4. When the method returns, the return address specifies where to continue
execution in the caller and the caller's state is restored. If the method returned
a value, that value is passed back to the caller.
Calling a method
When you call a method outside your class, you must put an object or class name in
front of it, then a dot, then the method call. For example,
g.drawRect(10, 20, 30, 40);
This calls the drawRect method in the class of g (Graphics) with 4 int parameters.
Internally there are five parameters: the Graphics object, and the four int
parameters. The method can then reference all of the fields in the Graphics object
without any special notation.
When you call methods which are defined in your own class, you don't need to write
an object in front of them if they are working on the same fields (the same object).
However, it is sometimes clearer to write this. in front of them to make it clear that
you are calling the method with the current object. [needs examples]
Methods - OOP
Static methods
If your method doesn't use an object of the class it is defined in, but does some work
only on it's parameters, then you can declare the method to be static. Except for
some utility methods and main(...), you should probably not be using static methods.
A good example of a static methods in Java is the Math or Character classes. For
example, the Math.cos(x) method calls the cosine method in the Math class. Cosine
takes only one (primitive) parameter, and it doesn't work on any object. Make a call
to a static method by putting a class name and a dot in front of the method call.
82
Signature
The signature of a method is its name and types of its parameters. The signature is
used to select which method is to be called in a class. When you define more than
one method by the same name in a class, there must be a difference in the number or
types of the parameters. When there is more than one method with the same name,
that name is overloaded.
Overriding
You override a method when you define a method that has the same name as in a
parent class. A good example of this is when you define a JApplet you write an init()
method. The JApplet class already has an init() method which you are overriding.
When the browser calls init(), it will then call your version of the method. In this case
you need to write init() because the init() in JApplet does nothing. Similarly, JPanel's
paintComponent() method is overridden when you declare a JPanel for drawing.
All calls go to your new method, and not to the method by the same name in the
parent class. To call the method in the parent class, as you must do in the first line of
paintComponent(), prefix the call with super..
Overloading
A method name is overloaded when there are two or more methods by the same
name in a class. At first it sounds like overloading methods would produce a lot of
confusion, but it really reduces the confusion.
You can also define a method in one class that has the same signature (name and
parameters) as the method in a different class. This is not called overloading, and
there can be no confusion because the object in front of the method identifies which
class the method is in.
Methods - Vocabulary
access modifier
There may be an access modifier at the front of a method header. The
access modifier tells which other methods can call this method.
keyword Access
none
public
Everyone can call it. You should use public if you want someone
outside your package to call the method. Some common methods
that are declared public are paint(), init(), actionPerformed(),
adjustmentValueChanged(), and main(). This is like making your phone
number public -- anyone can call you.
private
No one outside this class can call it. This is like only letting your
83
Everyone in this package and any child classes can use it. You won't
want to use this unless you are devoloping classes that you expect
others to use for inheritance.
actual parameter
The values in the method call are the actual parameters. When a call is
made, the values of the actual parameters are copied into the formal
parameters.
formal parameter
The parameters in the header of a method definition are the formal
parameters. Formal parameters are like local variables that get their values
from the actual parameters.
local variable
Local variables are variables that are declared in a method. Local variables
can only be used in that method (no other methods can access them). They
are created when a method is called, and destroyed when the method returns.
method
A method is a way to put a group of statements together to do something.
method body
Amethod body is the part of the method that contains the declarations of
local variables and the statements. For a non-void function, it must contain at
least one return statement.
method definition
A method definition has two parts: a method header, and a method body.
method header
A method header comes at the beginning and gives the following
information:
access modifier
return type
method name
formal parameters
Need to add: return type, return statement, signature, static/class methods, instance
methods, overriding, overloading, ... However, each entry should really be marked
both by area (methods, awt, ...), and by level (beginning, intermediate, or advanced).
Hmmm, that will have to come later.
Static/Class methods
There are two types of methods.
Instance methods are associated with an object and use the instance
variables of that object. This is the default.
84
Static methods use no instance variables of any object of the class they are
defined in. If you define a method to be static, you will be given a rude
message by the compiler if you try to access any instance variables. You can
access static variables, but except for constants, this is unusual. Static
methods typically take all they data from parameters and compute something
from those parameters, with no reference to variables. This is typical of
methods which do some kind of generic calculation. A good example of this
are the many utility methods in the predefined Math class. (See Math and
java.util.Random).
inputTF.setText("");
85
Documentation. Anyone seeing that a method is static will know how to call
it (see below). Similarly, any programmer looking at the code will know that a
static method can't interact with instance variables, which makes reading and
debugging easier.
86
Exercises
Write a program that allows the user to convert either from degrees Celcius to
Fahrenheit or degrees Fahrenheit to Celcius. Use the following formulas
degreesC=5(degreesF 32)/9
degreesF=(9(degreesC)/5) + 32
Prompt the user to enter a temperature and either a C or c for Celcius or an F
or f for Fahrenheit, if anything other than C, c, F, f is entered, print an error
message and ask the user to reenter a valid selection. Create two methods, one for
converting the temperature to Fahrenheit if Celcius is entered, and one for
converting Celcius if Fahrenheit is entered. Ask the user to enter 0 or q to quit
or any other key to repeat the loop and perform another conversion.
87
Classes
CHAPTER
15
+
Concepts
Creating
Declaration
89
90
If a class is defined within another class, it is an inner class. There are two
common reasons to do this: to attach an anonymous listener to a control at
the point where the control is being built, and to have access to the fields and
methods of the enclosing class.
override (applies to methods)
If a subclass redefines a method defined in a superclass, the method in the
superclass is overridden. A common use of this is in defining a subclass of
JPanel that you use for graphics. When you define the paintComponent method,
you are overriding the one that is already defined in JPanel. In
paintComponent, but not in most overriding methods, you should call the
method in the parent class with super.paintComponent. The "super" keyword is
how you refer to the overridden parent method. There is no way to explicitly
call the "grandparent's" method if it was overridden by the parent class.
overload (applies to methods)
A method in a class is overloaded if there is more than one method by the
same name. If the same name is used, the methods must different in the
number and/or types of the parameters so that there is no confusion. This
really has nothing to do with classes, only methods.
abstract class
A class which doesn't define all it's methods is called an abstract class. To be
useful, there must be a subclass which defines the missing methods. The "You
must declare this class abstract" error message from the Java compiler is
rather misleading. This usually means that you declared your class to
implement an interface, but failed to write all required methods -- or more
commonly that there's a spelling error in a method header.
interface
An interface is a list of methods that must be implemented. A class that
implements an interface must define all those methods. The method signatures
(prototypes) are listed in the interface. Interfaces may also define public static
final "constants". An interface is essentially the same as an completely
abstract class.
Creating Classes
Now that we've covered how to create and use objects, and how objects are cleaned
up, it's time to show you how to write the classes from which objects are created.
This section shows you the main components of a class through a small example that
implements a last-in-first-out (LIFO) stack. The following diagram lists the class and
identifies the structure of the code.
91
This implementation of a stack uses another object, a Vector, to store its elements.
Vector is a growable array of objects and does a nice job of allocating space for new
objects as space is required. The Stack class makes use of this code by using a Vector to
store its elements. However, it imposes LIFO restrictions on the Vector-- that is, you
can only add elements to and remove elements from the top of the stack.
The Class Declaration
The left side of the following diagram shows the possible components of a class
declaration in the order they should or must appear in your class declaration. The
right side describes their purposes. The required components are the class keyword
and the class name and are shown in bold. All the other components are optional,
and each appears on a line by itself (thus "extends Super" is a single component).
Italics indicates an identifier such as the name of a class or interface. If you do not
explicitly declare the optional items, the Java compiler assumes certain defaults: a
nonpublic, nonabstract, nonfinal subclass of Object that implements no interfaces.
92
The following list provides a few more details about each class declaration
component. It also provides references to sections later in this trail that talk about
what each component means, how to use each, and how it affects your class, other
classes, and your Java program.
public
By default, a class can be used only by other classes in the same package. The
public modifier declares that the class can be used by any class regardless of
its package. Look in Creating and Using Packages for information about
how to use modifiers to limit access to your classes and how it affects your
access to other classes.
abstract
final
Declares that the class cannot be instantiated. For a discussion about when
abstract classes are appropriate and how to write them, see Writing
Abstract Classes and Methods .
Declares that the class cannot be subclassed. Writing Final Classes and
Methods shows you how to use final and discusses the reasons for using it.
class NameOfClass
The class keyword indicates to the compiler that this is a class declaration and
that the name of the class is NameOfClass.
extends Super
The extends clause identifies Super as the superclass of the class, thereby
inserting the class within the class hierarchy.
How Do These Concepts Translate into Code? in the ObjectOriented Programming Concepts lesson, showed you a subclass of
Applet and talked briefly about the responsibilities and benefits of subclasses.
Managing Inheritance goes into further detail on this subject.
implements Interfaces
To declare that your class implements one or more interfaces, use the
keyword implements followed by a comma-separated list of the names of the
interfaces implemented by the class. How Do These Concepts Translate
into Code? explained how the ClickMe applet implements an interface.
Details about writing your own interfaces and how to use them can be found
in Getting Started .
93
94
new Stack();
When writing your own class, you don't have to provide constructors for it. The
default constructor is automatically provided by the runtime system for any class
that contains no constructors. The default provided by the runtime system doesn't do
anything. So, if you want to perform some initialization, you will have to write some
constructors for your class.
The constructor for the following subclass of Thread performs animation, sets up
some default values, such as the frame speed and the number of images, and then
loads the images:
class AnimationThread extends Thread {
int framesPerSecond;
int numImages;
Image[] images;
AnimationThread(int fps, int num) {
super("AnimationThread");
this.framesPerSecond = fps;
this.numImages = num;
this.images = new Image[numImages];
for (int i = 0; i <= numImages; i++) {
...
// Load all the images.
...
}
}
...
}
Note how the body of a constructor is like the body of a method; that is, it contains
local variable declarations, loops, and other statements. However, one line in the
AnimationThread constructor that you wouldn't see in a method is the second line:
super("AnimationThread");
This line invokes a constructor provided by the superclass of AnimationThread, namely,
Thread. This particular Thread constructor takes a String that sets the name of Thread.
Often a constructor wants to take advantage of initialization code written in a class's
superclass. Indeed, some classes must call their superclass constructor in order for
the object to work properly. If present, the superclass constructor must be the first
statement in the subclass's constructor: An object should perform the higher-level
initialization first.
You can specify what other objects can create instances of your class by using an
access specifier in the constructors' declaration:
private
95
No other class can instantiate your class. Your class may contain public class
methods (sometimes called factory methods), and those methods can
construct an object and return it, but no other classes can.
protected
Only subclasses of the class and classes in the same package can create
instances of it.
public
This is a relatively simple member variable declaration, but declarations can be more
complex. You can specify not only type, name, and access level, but also other
attributes, including whether the variable is a class or instance variable and whether
it's a constant. Each component of a member variable declaration is further defined
below:
accessLevel
Lets you control which other classes have access to a member variable by
using one of four access levels: public, protected, package, and private. You
control access to methods in the same way. Controlling Access to
Members of a Class covers access levels in detail.
static
final
Declares this is a class variable rather than an instance variable. You also use
static to declare class methods. Understanding Instance and Class
Members later in this lesson talks about declaring instance and class
variables.
96
Indicates that the value of this member cannot change. The following variable
declaration defines a constant named AVOGADRO, whose value is Avogadro's
number (6.022 * 1023) and cannot be changed:
final double AVOGADRO = 6.022e23;
It's a compile-time error if your program ever tries to change a final variable.
By convention, the name of constant values are spelled in uppercase letters.
transient
volatile
type
Like other variables, a member variable must have a type. You can use
primitive type names such as int, float, or boolean. Or you can use reference
types, such as array, object, or interface names.
name
A member variable's name can be any legal Java identifier and, by convention,
begins with a lowercase letter. You cannot declare more than one member
variable with the same name in the same class, but a subclass can hide a
member variable of the same name in its superclass. Additionally, a member
variable and a method can have the same name. For example, the following
code is legal:
public class Stack {
private Vector items;
// a method with same name as a member variable
public Vector items() {
...
}
}
Understanding Instance and Class Members
When you declare a member variable such as aFloat in MyClass:
class MyClass {
float aFloat;
}
you declare an instance variable. Every time you create an instance of a class, the
runtime system creates one copy of each class's instance variables for the instance.
You can access an object's instance variables from an object as described in Using
Objects .
Instance variables are in contrast to class variables (which you declare using the
static modifier). The runtime system allocates class variables once per class regardless
of the number of instances created of that class. The system allocates memory for
97
class variables the first time it encounters the class. All instances share the same
copy of the class's class variables. You can access class variables through an instance
or through the class itself.
Methods are similar: Your classes can have instance methods and class methods.
Instance methods operate on the current object's instance variables but also have
access to the class variables. Class methods, on the other hand, cannot access the
instance variables declared within the class (unless they create a new object and
access them through the object). Also, class methods can be invoked on the class, you
don't need an instance to call a class method.
By default, unless otherwise specified, a member declared within a class is an
instance member. The class defined below has one instance variable--an integer
named x--and two instance methods--x and setX--that let other objects set and query
the value of x:
class AnIntegerNamedX {
int x;
public int x() {
return x;
}
public void setX(int newX) {
x = newX;
}
}
Every time you instantiate a new object from a class, you get a new copy of each of
the class's instance variables. These copies are associated with the new object. So,
every time you instantiate a new AnIntegerNamedX object from the class, you get a new
copy of x that is associated with the new AnIntegerNamedX object.
All instances of a class share the same implementation of an instance method; all
instances of AnIntegerNamedX share the same implementation of x and setX. Note that
both methods, x and setX, refer to the object's instance variable x by name. "But", you
ask, "if all instances of AnIntegerNamedX share the same implementation of x and
setX isn't this ambiguous?" The answer is "no." Within an instance method, the name
of an instance variable refers to the current object's instance variable, assuming that
the instance variable isn't hidden by a method parameter. So, within x and setX, x is
equivalent to this.x.
Objects outside of AnIntegerNamedX that wish to access x must do so through a
particular instance of AnIntegerNamedX. Suppose that this code snippet was in another
object's method. It creates two different objects of type AnIntegerNamedX, sets their x
values to different values, then displays them:
...
AnIntegerNamedX myX = new AnIntegerNamedX();
AnIntegerNamedX anotherX = new AnIntegerNamedX();
myX.setX(1);
anotherX.x = 2;
98
99
For example, class variables are often used with final to define constants; this is more
memory efficient than final instance variables because constants can't change, so you
really only need one copy).
Similarly, when declaring a method, you can specify that method to be a class
method rather than an instance method. Class methods can only operate on class
variables and cannot access the instance variables defined in the class.
To specify that a method is a class method, use the static keyword in the method
declaration. Let's change the AnIntegerNamedX class such that its member variable x is
once again an instance variable, and its two methods are now class methods:
class AnIntegerNamedX {
int x;
static public int x() {
return x;
}
static public void setX(int newX) {
x = newX;
}
}
When you try to compile this version of AnIntegerNamedX, the compiler displays an
error like this one:
AnIntegerNamedX.java:4: Can't make a static reference to
nonstatic variable x in class AnIntegerNamedX.
return x;
^
This is because class methods cannot access instance variables unless the method
created an instance of AnIntegerNamedX first and accessed the variable through it.
Let's fix AnIntegerNamedX by making its x variable a class variable:
class AnIntegerNamedX {
static int x;
static public int x() {
return x;
}
static public void setX(int newX) {
x = newX;
}
}
Now the class will compile and the same code snippet from before that creates two
instances of AnIntegerNamedX, sets their x values, and then prints the x values
produces this output:
myX.x = 2
anotherX.x = 2
100
Again, changing x through myX also changes it for other instances of AnIntegerNamedX.
Another difference between instance members and class members is that class
members are accessible from the class itself. You don't need to instantiate a class to
access its class members. Let's rewrite the code snippet from before to access x and
setX directly from the AnIntegerNamedX class:
...
AnIntegerNamedX.setX(1);
System.out.println("AnIntegerNamedX.x = " + AnIntegerNamedX.x());
...
Notice that you no longer have to create myX and anotherX. You can set x and retrieve
x directly from the AnIntegerNamedX class. You cannot do this with instance members,
you can only invoke instance methods from an object and can only access instance
variables from an object. You can access class variables and methods either from an
instance of the class or from the class itself.
Initializing Instance and Class Members
You can use static initializers and instance initializers to provide initial values for
class and instance members when you declare them in a class:
class BedAndBreakfast {
static final int MAX_CAPACITY = 10;
boolean full = false;
}
This works well for members of primitive data type. Sometimes, it even works when
creating arrays and objects. But this form of initialization has limitations, as follows:
1. Initializers can perform only initializations that can be expressed in an
assignment statement.
2. Initializers cannot call any method that can throw a checked exception.
3. If the initializer calls a method that throws a runtime exception, then it
cannot do error recovery.
If you have some initialization to perform that cannot be done in an initializer
because of one of these limitations, you have to put the initialization code elsewhere.
To initialize class members, put the initialization code in a static initialization block.
To initialize instance members, put the initialization code in a constructor.
Using Static Initialization Blocks
Here's an example of a static initialization block:
101
102
All of the initialization code is in one place, thus making the code easier
to maintain and read.
Defaults are handled explicitly.
Constructors are widely understood by the Java community, including
relatively new Java programmers, while instance initializers are not
and may cause confusion to others reading your code.
Exercises
Create a class that graphs the grade distribution (number of As, Bs, Cs, Ds, Fs)
horizontally by printing lines with proportionate numbers of asterisks
corresponding to the percentage of grades in each category. Write methods to set
the number of each letter grade; read the number of each letter grade, return the
total number of grades, return the percent of each letter grade as a whole number
between 0 to 100, inclusive; and draw the graph. Set it up so that 50 asterisks
correspond to 100% (each one corresponds to 2%), include a scale on the
horizontal axis indicating each 10% increment from 0 to 100%, and label each
103
line with its letter grade. For example, if there are 1 As, 4 Bs, 6 Cs, 2 Ds, and 1 F,
the total number of grades is 14, the percentage of As is 7, percentage of Bs is 29,
percentage of Cs is 43, percentage of Ds is 14, and percentage of Fs is 7. The A
row would contain 4 asterisks (7% of 50 rounded to the nearest integer), the B
row 14, the C row21, the D row 7, and the F row 4, so the graph would look like
this.
0 10 20 30 40 50 60 70 80 90
|
|
|
|
|
|
|
|
|
|
**************************************************
****A
**************B
*********************C
*******D
****F
100%
|
Strings
16
CHAPTER
Overview
Comparison
Conversion
Concatenation
+
105
String Overview
Strings are sequences of Unicode characters. In many programming languages
strings are are stored in arrays of characters. However, in Java strings are a separate
object type, String. The "+" operator is used for concatenation, but all other
operations on strings are done with methods in the String class.
The basic class for strings. String objects can NOT be changed.
char
Primitive type for 16-bit Unicode characters.
Character
Primarily useful for its utility functions for working with characters.
StringBuffer
StringBuffers are used to build or change strings. Conversion between
String and StringBuffer is easy.
StringTokenizer Used to break a String into tokens (words).
BufferedReader Useful for reading and writing text files.
BufferedWriter
Pattern,
Matcher
String literals
To write a constant string, put the characters between double quotes, eg "abc".
Escape Character
There are some characters that can't be written directly in a string. The backslash
('\') character preceeds any of these special characters. For example, if a string
contains a double quotes, put a backslash ('\') in front of each internal double quote,
eg "abc\"def\"ghi". The other most common escape character is the newline
character, which is written as "n" following the backslash. For example, the following
string will produces two output lines. Note that the compiler replaces the backslash
plus character with the one desired character. Eg, "\n".length() is one.
System.out.println("This is the first\nand this is the second line.");
The "empty" string
The String equivalent of 0, is the string with no characters, "".
Concatenation
Expression Value
1+2
3
"1" + 2 "12"
1 + "2" "12"
106
"1" + 2 + 3 "123"
1 + 2 + "3" "33"
Putting two strings together to make a third string is called concatenation. In Java
the concatenation operator is '+', the same operator as for adding numbers. If either
operand is a String, Java will convert the other operand to a String (if possible) and
concatenate the two.
Upper- and lowercase
To change to uppercase (and similarly to lowercase), Java has two methods,
depending on whether you have a single character (eg, c) or a String (eg, s).
Converting a string to uppercase
s = s.toUpperCase();
Converting a character to uppercase
c = Character.toUpperCase(c);
Of course, you don't have to assign these values back to themselves -- you can use the
values where you want.
String Comparison
Strings can not be compared with the usual <, <=, >, or >= operators, and the ==
and != operators don't compare the characters in the strings.
Comparing objects vs. primitive types
[to be supplied]
Comparing Strings: ==, .equals(), .compareTo(), ...
To compare Strings for equality, don't use ==. The == operator checks to see if two
objects are exactly the same object. Two strings may be different objects, but
have the same value (have exactly the same characters in them). Use the .equals()
method to compare strings for equality. Similarly, use the .compareTo() method to
test for unequal comparisons. For example,
String s = "something", t = "maybe something else";
if (s == t)
// Legal, but usually WRONG.
if (s.equals(t)) // RIGHT
if (s > t) // ILLEGAL
if (s.compareTo(t) > 0) // CORRECT>
Comparing without regard to case
[to be supplied]
107
printf(), added in
No conversion required. Some common system methods will take any type
and convert it, eg, System.out.println().
Concatenation (+)
The most common idiom to convert something to a string is to concatenate it with a
string. If you just want the value with no additional text, concatenate it with the
empty string, one with no characters in it ("").
If either operand of a concatenation is a string, the other operand is converted to
string, regardless of whether it is a primitive or object type.
int x = 42;
String s;
s = x;
s = "" + x;
// ILLEGAL
// Converts int 42 to String "42"
// Assigns "3.5" to s
108
java.text.DecimalFormat
The java.text.DecimalFormat class provides many ways to format numbers into
strings, including number of fraction digits, using a currency symbol ($12.35),
scientific notation (3.085e24), percentage scaling (33%), locale which defines
national formatting options (3,000.50 or 3.000,50 or 3'000,50 or ...), patterns for
positive, zero, and negative numbers, etc. These notes show only how to specify the
number of fraction digits. Check the Java API documentation for other options.
First, create a DecimalFormat object which specifies the format of the number. The
zero before the decimal point means that at least one digit is produced, even if it is
zero. The zeros after the decimal point specify how many fraction digits are
produced. Then call the format() method of that object, passing the numeric value to
be converted.
The string that is returned by the format() will not contain additional text, other
than an optional currency or percent sign. Specifically, it can not be used to pad
numbers on the left with blanks for use in right alignment of a column of numbers.
Use printf() for this.
This program uses the same formatting object many times.
// File: formatTest/FormatTest.java
// Description: Test default and DecimalFormat formatting.
2 // Author: Michael Maus
3 // Date: 2000-10-27, 2000-11-07, 2005-02-13
1
4 import java.text.DecimalFormat;
5
public class FormatTest {
6
public static void main(String[] args) {
DecimalFormat twoPlaces = new DecimalFormat("0.00");
7
for (int i=1; i<=10; i++) {
8
double val = 1.0 / i;
9
System.out.println("1/" + i + " = " + twoPlaces.format(val) + ", "
+ val);
}
10
}
11 }
12
13
14
15
16
109
// Round down.
// Round up.
sb.append(", ");
110
sb.append(1.0/3.0);
String s = s.toString(); // s is "Answer = 42, 0.3333333333333333"
Numeric objects: Integer, Double, BigDecimal, BigInteger, ...
Concatenation works with all objects, not just numbers. When Java needs to convert
an object to a String, it calls the object's toString() method. Because every class (object
type) has the class Object as an ancestor, every class inherits Object's toString()
method. This will do something to generate a string from an object, but it will not
always be very useful. Many classes override toString() to do something better. When
you write a class whose objects might be converted to a String, write a toString
method.
Various numeric class conversion methods
[This will describe the Integer, etc wrapper class methods, as well as the BigInteger
and BigDecimal conversion methods.]
Converting Anything to String
Summary: Converting any data to strings is easy. You can do almost everything with
concatenation, but can get more control using some of the alternatives.
Converting numbers to strings - See Converting Numbers to Strings
There are many specialized issues with regard to converting numbers (precision,
exponents, currency, locale, ...), which are covered in Converting Numbers to
Strings.
Summary of conversion alternatives
toString() is universally
printf() was added in Java 5 to use a format for conversion. Altho it's primarily
No conversion required. Some common system methods will take any type
and convert it, eg, System.out.println().
string.
used with numbers, it also can be applied to objects of other classes. This isn't
discussed here.
Concatenation (+)
The most common idiom to convert something to a string is to concatenate it with a
string. If you just want the value with no additional text, concatenate it with the
empty string, one with no characters in it ("").
If either operand of a concatenation is a string, the other operand is converted to
string, regardless of whether it is a primitive or object type.
111
// ILLEGAL
// Might assign "Three of Hearts" to s
Exercises
1. Write a program that reads in a line of text and then outputs that line of text
with the first occurrence of hate changed to love. For example, a
possible sample dialog might be
Enter a line of text.
I hate you.
I have rephrased that line to read:
I love you.
You can assume that the word hate occurs in the input. If the word hate
occurs more than once in the line, then your program will only replace the
first occurrence of hate.
2. Write a program that asks the user to enter the first name of a friend or
relative, a favorite color, a favorite food, and a favorite animal, then print the
following two lines with the users input replacing the items in italics:
I had a dream that name ate a color animal
and said it tasted like food!
112
For example, if the user entered Jake for the persons name, blue for the color,
hamburger for the food, and dog for the animal, the output would be
I had a dream that Jake ate a blue dog
and said it tasted like hamburger!
Dont forget to put the exclamation mark at the end.
17
CHAPTER
Inheritance
+
Concepts
Abstract Classes
Interfaces
Collections
+
114
Inheritance
Inheritance is the capability of a class to use the properties and methods of
another class while adding its own functionality. An example of where this could be
useful is with an employee records system. You could create a generic employee
class with states and actions that are common to all employees. Then more specific
classes could be defined for salaried, commissioned and hourly employees. The
generic class is known as the parent (or superclass or base class) and the specific
classes as children (or subclasses or derived classes). The concept of inheritance
greatly enhances the ability to reuse code as well as making design a much simpler
and cleaner process.
Inheritance in Java
Java uses the extends keyword to set the relationship between a child class and a
parent class. For example:
public class GraphicsBox extends Box
The GraphicsBox class assumes or inherits all the properties of the Box class and
can now add its own properties and methods as well as override existing methods.
Overriding means creating a new set of method statements for the same method
signature (name and parameters). For example:
115
116
Polymorphism
Polymorphism is the capability of an action or method to do different things
based on the object that it is acting upon. This is the third basic principle of object
oriented programming. We have already used two types of polymorphism
(overloading and overriding). Now we will look at the third: dynamic method
binding.
Assume that three subclasses (Cow, Dog and Snake) have been created based on the
Animal abstract class, each having their own speak() method.
public class AnimalReference
{
public static void main(String[] args)
Animal ref
// set up var for an Animal
Cow aCow = new Cow("Bossy"); // makes specific objects
Dog aDog = new Dog("Rover");
Snake aSnake = new Snake("Earnie");
// now reference each as an Animal
ref = aCow;
ref.speak();
ref = aDog;
ref.speak();
ref = aSnake;
ref.speak();
}
117
Notice that although each method reference was to an Animal (but no animal objects
exist), the program is able to resolve the correct method related to the subclass
object at runtime. This is known as dynamic (or late) method binding.
Arrays of Subclasses
As with arrays of primitive types, arrays of objects allow much more efficient
methods of access. Note in this example that once the array of Animals has been
structured, it can be used to store objects of any subclass of Animal. By making the
method speak() abstract, it can be defined for each subclass and any usage will be
polymorphic (ie. adapted to the appropriate object type at runtime). It now becomes
very easy to rehearse the speak() method for each object by object indexing.
public class AnimalArray
{
public static void main(String[] args)
Animal[] ref = new Animal[3]; // assign space for array
Cow aCow = new Cow("Bossy"); // makes specific objects
Dog aDog = new Dog("Rover");
Snake aSnake = new Snake("Earnie");
// now put them in an array
ref[0] = aCow; ref[1] = aDog; ref[2] = aSnake;
// now demo dynamic method binding
for (int x=0;x<3;++x) { ref[x].speak(); }
}
Casting Objects
One of the difficulties of using a superclass array to hold many instances of subclass
objects is that one can only access properties and methods that are in the superclass
(ie. common to all). By casting an individual instance to its subclass form one can
refer to any property or method. But first take care to make sure the cast is valid buy
using the operation instanceof. Then perform the cast. As an example from above:
if (ref[x] instanceof Dog) // ok right type of object
{
Dog doggy = (Dog) ref[x]; // cast the current instance to its subclass
doggy.someDogOnlyMethod();
}
118
Interfaces
Java does not allow multiple inheritance (ie a subclass being the extension of
more than one superclass. To tie elements of different classes together Java uses an
interface. Interfaces are similar to abstract classes but all methods are abstract
and all properties are static final.As an example, we will build a Working
interface for the subclasses of Animal. Since this interface has the method called
work(), that method must be defined in any class using Working.
public interface Working
{
public void work();
}
When you create a class that uses an interface, you reference the interface with the
reserved word implements. Any class that implements an interface must include
code for all methods in the interface. This ensures commonality between interfaced
objects.
public class WorkingDog extends Dog implements Working
{
public WorkingDog(String nm)
{
super(nm); // builds ala parent
}
public void work() // this method specific to WorkingDog
{
speak();
System.out.println("I can herd sheep and cows");
}
}
119
Collections
Collections is a unifying philosophy that adds operational functionality, and
dynamic growth to object classes. The unification is through interfaces that each
collection object has. Functionality such as searches, sorts, insertion and deletion use
highly efficient algorithms. And mixtures of objects may be handled in a collection
class.
The collection interfaces are Collection, List, Set, and SortedSet. Collection is at
the top of this hierarchy and includes the methods add(), clear(), contains(0),
isEmpty(), remove(), size() as well as other less common ones. List extends
Collection for classes that are a sequence of elements (similar to an array). It also
overrides appropriate methods. Set extends Collection with methods that prevent
duplicate objects. SortedSet extends Set to keep all contained objects in a sorted
manner.
Classes which implement the appropriate interfaces include AbstractList, ArrayList,
LinkedList, HashSet, and TreeSet. ArrayList is very similar to arrays but with
methods for adding and removing items built-in. It is also dynamic(ie size does not
have to be declared at compile time). Other methods in ArrayList include
lastIndexOf(obj) to return position, get(index) to return object at a specific position,
and toArray() for converting a collection back to a regular array.
As an example of how specific objects can be located for access:
for (int x=0; x<emp.size; x++) // by index number
if (emp.get(x) instanceof Staff) // emp can be of several types
Staff s = (Staff) emp.get(x); // cast it to new Staff object
120
Exercises
1. Give the definition of a class named Doctor whose objects are records for a
clinics doctors. This class will be a derived class of the class Person given
below. A Doctor record has the doctors name (inherited from the class
Person), specialty (e.g. Pediatrician, Obstetrician, General Practitioner,
etc., so use type String, and office visit fee (use type double). Write a driver
program to test all your methods.
public class Person{
private String name;
public Person(){
Name=No name yet.;
}
public Person (String initialName){
name=initialName;
}
public void setName (String newName){
name=newName;
}
public String getName(){
return name;
}
public void writeOutput(){
System.out.println(Name: + name);
}
public boolean sameName(Person otherPerson){
return (this.name.equalsIgnoreCase(otherPerson.name));
}
}
2. Create a base class called Vehicle that has the manufacturers name (type
String), number of cylinders in the engine (type int), and owner (type
Person given in #1). Then create a class called Truck that is derived from
Vehicle and has additional properties, the load capacity in tons (type double
since it may contain a fractional part) and towing capacity in tons (type int).
Write a driver program that tests all your methods.
Arrays
18
CHAPTER
Introduction
Declaring
Initialization
Multi-dimensional
122
Arrays -- Introduction
Java arrays are similar to ideas in mathematics
An array can store many similar values in memory. The word "array" in Java means
approximately the same thing as array, matrix, or vector does in math.
Unlike math, you must declare the array and allocate a fixed amount of memory for
it.
Declaring an array
An array variable is like other variables -- you must declare it, which means you must
declare the type of elements that are in an array. All elements must be the same type.
Write the element type name, then "[]", then the name of the array variable. The
declaration only allocates space associated with a variable name for a reference to an
array, but doesn't create the actual array object.
String[] args;
int[] scores;
JButton[] bs;
// bs is an array of JButtons
Unlike some languages, never put the size of the array in the declaration because an
array declaration only tells Java that the variable is an array and the element type.
Allocating an array object
Create an array using new. This example creates an array of 100 int elements, from
a[0] to a[99].
int[] a;
123
124
b[1] = 0; // also changes a[1] because a and b are the same array.
// Both a and b point to same array with value {100, 0, 98}
Array Initialization
When you declare an array, you can can also allocate a preinitialized array object in
the same statement. In this case, do not give the array size because Java counts the
number of values to determine the size. For example,
// Java 1.0 style -- shorter, but can be used ONLY IN DECLARATIONS
String[] days = {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"};
The above way is the most common way to declare and initialize arrays.
Library methods for arrays
Static methods for manipulating arrays are available in the java.util.Arrays class (
asList(), binarySearch(), equals, fill(), and sort(). In addition there is System.arrayCopy().
Arrays -- Intermediate
Anonymous arrays
Java 2 added anonymous arrays, which allow you to create a new array of values
anywhere in the program, not just in an initialization in a declaration.
// This anonymous array style can also be used in other statements.
String[] days = new String[] {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"};
You can also use anonymous array syntax in other parts of the program. For
example,
// Outside a declaration you can make this assignment.
x = new String[] {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"};
You must be careful not to create these anonymous arrays in a loop or as local
variables because each use of new will create another array.
125
Dynamic allocation
Because arrays are allocated dynamically, the initialization values may arbitrary
expresssions. For example, this call creates two new arrays to pass as parameters to
drawPolygon.
g.drawPolygon(new int[] {n, n+45, 188}, new int[] {y/2, y*2, y}, 3);
C-style array declarations
Java also allows you to write the square brackets after the variable name, instead of
after the type. This is how you write array declarations in C, but is not a good style
for Java. C declaration syntax can get very ugly with part of the declaration before
the variable, and part after. Java has a much nicer style where all type information
can be written together without the use of a variable, and there are times when only
the Java notation is possible to use.
int[] a; // Java style -- good
int a[]; // C style -- legal, but not Java style
Common array problems
Some common array programming mistakes are:
Writing a.length() instead of a.length. The length() method is used with Strings,
not arrays.
Declaring an array with a size. Eg, int[100] a; instead of int[] a = new int[100];.
Arrays -- 2-dimensional
Multi-dimensional arrays
Java, as with most languages, supports multi-dimensional arrays - 1-dimensional, 2dimensional, 3-dimensional, ... This discusses 2-dimensional arrays, but the same
principles apply to higher dimensions.
2-dimensional arrays
2-dimensional arrays are usually represented in a row-column approach on paper,
and the terms "rows" and "columns" are used in computing.
Arrays of arrays
There are two ways to implement 2-dimensional arrays. Many languages reserve a
block of memory large enough to hold all elements of the full, rectangular, array
(number of rows times number of columns times the element size). Java doesn't do
this. Instead Java builds multi-dimensional arrays from many one-dimensional
arrays, the so-called "arrays of arrays" approach. [C++ supports both styles.]
There are a couple of interesting consequences of this: Rows may be different sizes.
Also, each row is an object (an array) that can be used independently.
126
Declaration
Declare a 2-dimensional array as follows:
int[][] a2; // Declares, but doesn't allocate, 2-dim array.
Allocation
As with all arrays, the new keyword must be used to allocate memory for an array.
For example,
int[][] a2 = new int[10][5];
This allocates an int array with 10 rows and 5 columns. As with all objects, the values
are initialized to zero (unlike local variables which are uninitialized).
This actually allocates 6 objects: a one-dimensional array of 5 elements for each of
the rows, and a one-dimensional array of ten elements, with each element pointing
to the appropriate row array.
Processing 2-dimensional arrays
Often 2-dimensional arrays are processed with nested for loops. Notice in the
following example how the rows are handled as separate objects. For example,
int[][] a2 = new int[10][5];
// print array in rectangular form
for (int r=0; r<a2.length; r++) {
for (int c=0; c<a2[r].length; c++) {
System.out.print(" " + a2[r][c]);
}
System.out.println("");
}
Uneven rows
One consequence of arrays of arrays is that each row can be a different size ("ragged"
arrays). For example, we could create a lower triangular array, allocating each row
"by hand" as follows.
int[][] tri;
tri = new int[10][]; // allocate array of rows
for (int r=0; r<tri.length; r++) {
tri[r] = new int[r+1];
}
127
128
Loop direction
Very rarely you will find a programmer who prefers to write loops that go from high
to low. Of course it makes no difference in this algorithm, however, there are
machines in which that can save a few nanoseconds. This is enough harder for
humans to read that it is generally considered antisocial without a good reason (and
it's not common to find a good reason).
Arrays -- Multi-dimensional
All arrays in Java are really linear, one-dimensional arrays. However, you can easily
build multi-dimensional arrays from these, and Java has features in the language to
help you do this.
These examples all use two-dimensional arrays, but the same syntax and coding can
easily be extended to arrays of any dimension. By convention two dimensional arrays
have rows (horizontal) and columns (vertical). The first subscript selects the row
(which is a one-dimensional array itself), and the second subscript selects the
element in that row/array.
Visualizing two-dimensional arrays
Assume we have an array, a, with three rows and four columns.
a[0][0] a[0][1] a[0][2] a[0][3] Two-dimensional arrays are usually visualized as
a matrix, with rows and columns. This diagram
a[1][0] a[1][1] a[1][2] a[1][3] shows the array a with its corresponding
a[2][0] a[2][1] a[2][2] a[2][3] subscripts.
+-----+
In Java two-dimensional arrays are implemented
| | +-----+-----+-----+-----+ is a one-dimensional array of one-dimensional
|a[0] | -> | [0] | [1] | [2] | [3] arrays -- like this.
|
| | +-----+-----+-----+-----+
+-----+
| | +-----+-----+-----+-----+
|a[1] | -> | [0] | [1] | [2] | [3]
|
| | +-----+-----+-----+-----+
+-----+
| | +-----+-----+-----+-----+
|a[2] | -> | [0] | [1] | [2] | [3]
|
| | +-----+-----+-----+-----+
+-----+
129
130