Introduction To Programming Using Java 7e Itebooks pdf download
Introduction To Programming Using Java 7e Itebooks pdf download
Itebooks download
https://ebookbell.com/product/introduction-to-programming-using-
java-7e-itebooks-23836692
https://ebookbell.com/product/introduction-to-programming-using-java-
version-9-swing-edition-david-j-eck-50625664
https://ebookbell.com/product/introduction-to-programming-using-java-
david-j-eck-2375550
https://ebookbell.com/product/multimedia-introduction-to-programming-
using-java-1st-edition-david-gries-2100192
https://ebookbell.com/product/introduction-to-programming-using-
python-daniel-y-liang-22039592
Introduction To Programming Using Visual Basics 10th Edition David I
Schneider
https://ebookbell.com/product/introduction-to-programming-using-
visual-basics-10th-edition-david-i-schneider-11768686
https://ebookbell.com/product/introduction-to-programming-using-
visual-basic-11e-11th-edition-david-i-schneider-11732072
https://ebookbell.com/product/introduction-to-programming-using-
fortran-9520032008-version-3051-ed-jorgensen-10466018
https://ebookbell.com/product/an-introduction-to-programming-using-
python-schneider-david-i-21354512
https://ebookbell.com/product/an-introduction-to-programming-using-
visual-basic-2008-with-visual-studio-expression-edition-dvd-7th-ed-
schneider-22041544
Introduction to Programming Using Java
Version 7.0, August 2014
David J. Eck
Hobart and William Smith Colleges
Preface xi
i
CONTENTS ii
3 Control 67
3.1 Blocks, Loops, and Branches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
3.1.1 Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
3.1.2 The Basic While Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
3.1.3 The Basic If Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
3.1.4 Definite Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
3.2 Algorithm Development . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
3.2.1 Pseudocode and Stepwise Refinement . . . . . . . . . . . . . . . . . . . . 74
3.2.2 The 3N+1 Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
3.2.3 Coding, Testing, Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . 80
3.3 while and do..while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
3.3.1 The while Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
3.3.2 The do..while Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
3.3.3 break and continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
3.4 The for Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
3.4.1 For Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
3.4.2 Example: Counting Divisors . . . . . . . . . . . . . . . . . . . . . . . . . . 91
3.4.3 Nested for Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
3.5 The if Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
3.5.1 The Dangling else Problem . . . . . . . . . . . . . . . . . . . . . . . . . . 96
3.5.2 Multiway Branching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
3.5.3 If Statement Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
3.5.4 The Empty Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
3.6 The switch Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
3.6.1 The Basic switch Statement . . . . . . . . . . . . . . . . . . . . . . . . . . 104
3.6.2 Menus and switch Statements . . . . . . . . . . . . . . . . . . . . . . . . . 106
3.6.3 Enums in switch Statements . . . . . . . . . . . . . . . . . . . . . . . . . 108
3.6.4 Definite Assignment and switch Statements . . . . . . . . . . . . . . . . . 108
3.7 Exceptions and try..catch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
3.7.1 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
3.7.2 try..catch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
3.7.3 Exceptions in TextIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
3.8 Introduction to Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
3.8.1 Creating and Using Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . 114
3.8.2 Arrays and For Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
CONTENTS iii
4 Subroutines 135
4.1 Black Boxes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
4.2 Static Subroutines and Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
4.2.1 Subroutine Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
4.2.2 Calling Subroutines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
4.2.3 Subroutines in Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
4.2.4 Member Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
4.3 Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
4.3.1 Using Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
4.3.2 Formal and Actual Parameters . . . . . . . . . . . . . . . . . . . . . . . . 147
4.3.3 Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
4.3.4 Subroutine Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
4.3.5 Array Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
4.3.6 Command-line Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
4.3.7 Throwing Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
4.3.8 Global and Local Variables . . . . . . . . . . . . . . . . . . . . . . . . . . 154
4.4 Return Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
4.4.1 The return statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
4.4.2 Function Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
4.4.3 3N+1 Revisited . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
4.5 APIs, Packages, and Javadoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
4.5.1 Toolboxes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
4.5.2 Java’s Standard Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
4.5.3 Using Classes from Packages . . . . . . . . . . . . . . . . . . . . . . . . . 163
4.5.4 Javadoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
4.5.5 Static Import . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
4.6 More on Program Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
4.6.1 Preconditions and Postconditions . . . . . . . . . . . . . . . . . . . . . . . 168
4.6.2 A Design Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
4.6.3 The Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
4.7 The Truth About Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
4.7.1 Initialization in Declarations . . . . . . . . . . . . . . . . . . . . . . . . . 175
4.7.2 Named Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
4.7.3 Naming and Scope Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Exercises for Chapter 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Quiz on Chapter 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
CONTENTS iv
Glossary 735
Preface
xi
Preface xii
Finally, Chapter 13 returns to the topic of graphical user interface programming to cover some
of Java’s more advanced capabilities.
∗ ∗ ∗
The Seventh Edition of “Introduction to Programming using Java” is not a huge update
from the sixth edition. In fact, my main motivation for the new version was to remove any use
of applets or coverage of applets from the book. Applets are Java programs that run on a web
page. When Java first came out, they were exciting, and it seemed like they would become a
major way of creating active content for the Web. Up until the sixth edition, the web pages
for this book included applets for running many of the sample programs. However, because
of security issues and the emergence of other technologies, applets are no longer widely used.
Furthermore, the most recent versions of Java made it fairly difficult and unpleasant to use the
applets in the book. In place of applets, I have tried to make it as easy as possible for readers
to download the sample programs and run them on their own computers.
Another significant change in the seventh edition is that arrays are now introduced in
Chapter 3 in a basic form that is used throughout the next three chapters. Previously, arrays
were not introduced until Chapter 7, after objects and GUI programming had already been
covered. Much of the more advanced coverage of arrays is still in Chapter 7.
Aside from that, there are many small improvements throughout, mostly related to features
that were new in Java 7.
∗ ∗ ∗
The latest complete edition of Introduction to Programming using Java is available on line
at http://math.hws.edu/javanotes/. The first version of the book was written in 1996, and
there have been several editions since then. All editions are archived at the following Web
addresses:
• First edition: http://math.hws.edu/eck/cs124/javanotes1/ (Covers Java 1.0.)
• Second edition: http://math.hws.edu/eck/cs124/javanotes2/ (Covers Java 1.1.)
• Third edition: http://math.hws.edu/eck/cs124/javanotes3/ (Covers Java 1.1.)
• Fourth edition: http://math.hws.edu/eck/cs124/javanotes4/ (Covers Java 1.4.)
• Fifth edition: http://math.hws.edu/eck/cs124/javanotes5/ (Covers Java 5.0.)
• Sixth edition: http://math.hws.edu/eck/cs124/javanotes6/ (Covers Java 5.0 and later.)
• Seventh edition: http://math.hws.edu/eck/cs124/javanotes7/ (Covers Java 7.)
Introduction to Programming using Java is free, but it is not in the pub-
lic domain. Version 7 is published under the terms of the Creative Commons
Attribution-NonCommercial-ShareAlike 3.0 License. To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-sa/3.0/. For example, you can:
• Post an unmodified copy of the on-line version on your own Web site (including the parts
that list the author and state the license under which it is distributed!).
• Give away unmodified copies of this book or sell them at cost of production, as long as
they meet the requirements of the license.
• Make modified copies of the complete book or parts of it and post them on the web or
otherwise distribute them non-commercially, provided that attribution to the author is
given, the modifications are clearly noted, and the modified copies are distributed under
the same license as the original. This includes translations to other languages.
Preface xiii
For uses of the book in ways not covered by the license, permission of the author is required.
While it is not actually required by the license, I do appreciate hearing from people who
are using or distributing my work.
∗ ∗ ∗
A technical note on production: The on-line and PDF versions of this book are created
from a single source, which is written largely in XML. To produce the PDF version, the XML
is processed into a form that can be used by the TeX typesetting program. In addition to XML
files, the source includes DTDs, XSLT transformations, Java source code files, image files, a
TeX macro file, and a couple of scripts that are used in processing. The scripts work on Linux
and on Mac OS.
I have made the complete source files available for download at the following
address:
http://math.hws.edu/eck/cs124/downloads/javanotes7-full-source.zip
These files were not originally meant for publication, and therefore are not very cleanly
written. Furthermore, it requires a fair amount of expertise to use them. However, I have had
several requests for the sources and have made them available on an “as-is” basis. For more
information about the sources and how they are used see the README file from the source
download.
∗ ∗ ∗
Professor David J. Eck
Department of Mathematics and Computer Science
Hobart and William Smith Colleges
300 Pulteney Street
Geneva, New York 14456, USA
Email: eck@hws.edu
WWW: http://math.hws.edu/eck/
Chapter 1
When you begin a journey, it’s a good idea to have a mental map of the terrain you’ll be
passing through. The same is true for an intellectual journey, such as learning to write computer
programs. In this case, you’ll need to know the basics of what computers are and how they
work. You’ll want to have some idea of what a computer program is and how one is created.
Since you will be writing programs in the Java programming language, you’ll want to know
something about that language in particular and about the modern computing environment for
which Java is designed.
As you read this chapter, don’t worry if you can’t understand everything in detail. (In fact,
it would be impossible for you to learn all the details from the brief expositions in this chapter.)
Concentrate on learning enough about the big ideas to orient yourself, in preparation for the
rest of the book. Most of what is covered in this chapter will be covered in much greater detail
later in the book.
1
CHAPTER 1. THE MENTAL LANDSCAPE 2
location. The CPU can also store information in memory by specifying the information to be
stored and the address of the location where it is to be stored.
On the level of machine language, the operation of the CPU is fairly straightforward (al-
though it is very complicated in detail). The CPU executes a program that is stored as a
sequence of machine language instructions in main memory. It does this by repeatedly reading,
or fetching , an instruction from memory and then carrying out, or executing , that instruc-
tion. This process—fetch an instruction, execute it, fetch another instruction, execute it, and so
on forever—is called the fetch-and-execute cycle. With one exception, which will be covered
in the next section, this is all that the CPU ever does.
The details of the fetch-and-execute cycle are not terribly important, but there are a few
basic things you should know. The CPU contains a few internal registers, which are small
memory units capable of holding a single number or machine language instruction. The CPU
uses one of these registers—the program counter , or PC—to keep track of where it is in the
program it is executing. The PC simply stores the memory address of the next instruction that
the CPU should execute. At the beginning of each fetch-and-execute cycle, the CPU checks the
PC to see which instruction it should fetch. During the course of the fetch-and-execute cycle,
the number in the PC is updated to indicate the instruction that is to be executed in the next
cycle. (Usually, but not always, this is just the instruction that sequentially follows the current
instruction in the program.)
∗ ∗ ∗
A computer executes machine language programs mechanically—that is without under-
standing them or thinking about them—simply because of the way it is physically put together.
This is not an easy concept. A computer is a machine built of millions of tiny switches called
transistors, which have the property that they can be wired together in such a way that an
output from one switch can turn another switch on or off. As a computer computes, these
switches turn each other on or off in a pattern determined both by the way they are wired
together and by the program that the computer is executing.
Machine language instructions are expressed as binary numbers. A binary number is made
up of just two possible digits, zero and one. Each zero or one is called a bit. So, a machine
language instruction is just a sequence of zeros and ones. Each particular sequence encodes
some particular instruction. The data that the computer manipulates is also encoded as binary
numbers. In modern computers, each memory location holds a byte, which is a sequence of
eight bits. (A machine language instruction or a piece of data generally consists of several bytes,
stored in consecutive memory locations.)
A computer can work directly with binary numbers because switches can readily represent
such numbers: Turn the switch on to represent a one; turn it off to represent a zero. Machine
language instructions are stored in memory as patterns of switches turned on or off. When a
machine language instruction is loaded into the CPU, all that happens is that certain switches
are turned on or off in the pattern that encodes that instruction. The CPU is built to respond
to this pattern by executing the instruction it encodes; it does this simply because of the way
all the other switches in the CPU are wired together.
So, you should understand this much about how computers work: Main memory holds
machine language programs and data. These are encoded as binary numbers. The CPU fetches
machine language instructions from memory one after another and executes them. It does
this mechanically, without thinking about or understanding what it does—and therefore the
program it executes must be perfect, complete in all details, and unambiguous because the CPU
can do nothing but execute it exactly as written. Here is a schematic view of this first-stage
CHAPTER 1. THE MENTAL LANDSCAPE 3
Memory
10001010 (Location 0)
00110100 (Location 1)
Data to Memory 01110111 (Location 2)
10100100 (Location 3)
∗ ∗ ∗
A computer system consisting of many devices is typically organized by connecting those
devices to one or more busses. A bus is a set of wires that carry various sorts of information
between the devices connected to those wires. The wires carry data, addresses, and control
signals. An address directs the data to a particular device and perhaps to a particular register
or location within that device. Control signals can be used, for example, by one device to alert
another that data is available for it on the data bus. A fairly simple computer system might
be organized like this:
Input/ Data
Output Address
Controller Control
Now, devices such as keyboard, mouse, and network interface can produce input that needs
to be processed by the CPU. How does the CPU know that the data is there? One simple idea,
which turns out to be not very satisfactory, is for the CPU to keep checking for incoming data
over and over. Whenever it finds data, it processes it. This method is called polling , since
the CPU polls the input devices continually to see whether they have any input data to report.
Unfortunately, although polling is very simple, it is also very inefficient. The CPU can waste
an awful lot of time just waiting for input.
To avoid this inefficiency, interrupts are generally used instead of polling. An interrupt
is a signal sent by another device to the CPU. The CPU responds to an interrupt signal by
putting aside whatever it is doing in order to respond to the interrupt. Once it has handled
the interrupt, it returns to what it was doing before the interrupt occurred. For example, when
you press a key on your computer keyboard, a keyboard interrupt is sent to the CPU. The
CPU responds to this signal by interrupting what it is doing, reading the key that you pressed,
processing it, and then returning to the task it was performing before you pressed the key.
Again, you should understand that this is a purely mechanical process: A device signals an
interrupt simply by turning on a wire. The CPU is built so that when that wire is turned on,
the CPU saves enough information about what it is currently doing so that it can return to
the same state later. This information consists of the contents of important internal registers
such as the program counter. Then the CPU jumps to some predetermined memory location
and begins executing the instructions stored there. Those instructions make up an interrupt
handler that does the processing necessary to respond to the interrupt. (This interrupt handler
is part of the device driver software for the device that signaled the interrupt.) At the end of
the interrupt handler is an instruction that tells the CPU to jump back to what it was doing;
it does that by restoring its previously saved state.
CHAPTER 1. THE MENTAL LANDSCAPE 5
Interrupts allow the CPU to deal with asynchronous events. In the regular fetch-and-
execute cycle, things happen in a predetermined order; everything that happens is “synchro-
nized” with everything else. Interrupts make it possible for the CPU to deal efficiently with
events that happen “asynchronously,” that is, at unpredictable times.
As another example of how interrupts are used, consider what happens when the CPU needs
to access data that is stored on a hard disk. The CPU can access data directly only if it is
in main memory. Data on the disk has to be copied into memory before it can be accessed.
Unfortunately, on the scale of speed at which the CPU operates, the disk drive is extremely
slow. When the CPU needs data from the disk, it sends a signal to the disk drive telling it
to locate the data and get it ready. (This signal is sent synchronously, under the control of
a regular program.) Then, instead of just waiting the long and unpredictable amount of time
that the disk drive will take to do this, the CPU goes on with some other task. When the disk
drive has the data ready, it sends an interrupt signal to the CPU. The interrupt handler can
then read the requested data.
∗ ∗ ∗
Now, you might have noticed that all this only makes sense if the CPU actually has several
tasks to perform. If it has nothing better to do, it might as well spend its time polling for input
or waiting for disk drive operations to complete. All modern computers use multitasking to
perform several tasks at once. Some computers can be used by several people at once. Since the
CPU is so fast, it can quickly switch its attention from one user to another, devoting a fraction
of a second to each user in turn. This application of multitasking is called timesharing . But a
modern personal computer with just a single user also uses multitasking. For example, the user
might be typing a paper while a clock is continuously displaying the time and a file is being
downloaded over the network.
Each of the individual tasks that the CPU is working on is called a thread . (Or a process;
there are technical differences between threads and processes, but they are not important here,
since it is threads that are used in Java.) Many CPUs can literally execute more than one
thread simultaneously—such CPUs contain multiple “cores,” each of which can run a thread—
but there is always a limit on the number of threads that can be executed at the same time.
Since there are often more threads than can be executed simultaneously, the computer has to be
able switch its attention from one thread to another, just as a timesharing computer switches
its attention from one user to another. In general, a thread that is being executed will continue
to run until one of several things happens:
• The thread might voluntarily yield control, to give other threads a chance to run.
• The thread might have to wait for some asynchronous event to occur. For example, the
thread might request some data from the disk drive, or it might wait for the user to press
a key. While it is waiting, the thread is said to be blocked , and other threads, if any, have
a chance to run. When the event occurs, an interrupt will “wake up” the thread so that
it can continue running.
• The thread might use up its allotted slice of time and be suspended to allow other threads
to run. Not all computers can “forcibly” suspend a thread in this way; those that can are
said to use preemptive multitasking . To do preemptive multitasking, a computer needs
a special timer device that generates an interrupt at regular intervals, such as 100 times
per second. When a timer interrupt occurs, the CPU has a chance to switch from one
thread to another, whether the thread that is currently running likes it or not. All modern
desktop and laptop computers, and even typical smartphones and tablets, use preemptive
CHAPTER 1. THE MENTAL LANDSCAPE 6
multitasking.
Ordinary users, and indeed ordinary programmers, have no need to deal with interrupts and
interrupt handlers. They can concentrate on the different tasks or threads that they want the
computer to perform; the details of how the computer manages to get all those tasks done are
not important to them. In fact, most users, and many programmers, can ignore threads and
multitasking altogether. However, threads have become increasingly important as computers
have become more powerful and as they have begun to make more use of multitasking and
multiprocessing. In fact, the ability to work with threads is fast becoming an essential job skill
for programmers. Fortunately, Java has good support for threads, which are built into the Java
programming language as a fundamental programming concept. Programming with threads
will be covered in Chapter 12.
Just as important in Java and in modern programming in general is the basic concept of
asynchronous events. While programmers don’t actually deal with interrupts directly, they do
often find themselves writing event handlers, which, like interrupt handlers, are called asyn-
chronously when specific events occur. Such “event-driven programming” has a very different
feel from the more traditional straight-through, synchronous programming. We will begin with
the more traditional type of programming, which is still used for programming individual tasks,
but we will return to threads and events later in the text, starting in Chapter 6
∗ ∗ ∗
By the way, the software that does all the interrupt handling, handles communication with
the user and with hardware devices, and controls which thread is allowed to run is called the
operating system. The operating system is the basic, essential software without which a
computer would not be able to function. Other programs, such as word processors and Web
browsers, are dependent upon the operating system. Common operating systems include Linux,
various versions of Windows, and Mac OS.
One use of interpreters is to execute high-level language programs. For example, the pro-
gramming language Lisp is usually executed by an interpreter rather than a compiler. However,
interpreters have another purpose: they can let you use a machine-language program meant
for one type of computer on a completely different type of computer. For example, one of the
original home computers was the Commodore 64 or “C64”. While you might not find an actual
C64, you can find programs that run on other computers—or even in a web browser—that
“emulate” one. Such an emulator can run C64 programs by acting as an interpreter for the
C64 machine language.
∗ ∗ ∗
The designers of Java chose to use a combination of compilation and interpreting. Pro-
grams written in Java are compiled into machine language, but it is a machine language for
a computer that doesn’t really exist. This so-called “virtual” computer is known as the Java
Virtual Machine, or JVM. The machine language for the Java Virtual Machine is called Java
bytecode. There is no reason why Java bytecode couldn’t be used as the machine language of a
real computer, rather than a virtual computer. But in fact the use of a virtual machine makes
possible one of the main selling points of Java: the fact that it can actually be used on any
computer. All that the computer needs is an interpreter for Java bytecode. Such an interpreter
simulates the JVM in the same way that a C64 emulator simulates a Commodore 64 computer.
(The term JVM is also used for the Java bytecode interpreter program that does the simulation,
so we say that a computer needs a JVM in order to run Java programs. Technically, it would
be more correct to say that the interpreter implements the JVM than to say that it is a JVM.)
Of course, a different Java bytecode interpreter is needed for each type of computer, but
once a computer has a Java bytecode interpreter, it can run any Java bytecode program, and
the same program can be run on any computer that has such an interpreter. This is one of the
essential features of Java: the same compiled program can be run on many different types of
computers.
Java Interperter
for Mac OS
Java
Java Java Interperter
Compiler Bytecode
Program for Windows
Program
Java Interperter
for Linux
Why, you might wonder, use the intermediate Java bytecode at all? Why not just distribute
the original Java program and let each person compile it into the machine language of whatever
computer they want to run it on? There are several reasons. First of all, a compiler has to
understand Java, a complex high-level language. The compiler is itself a complex program.
A Java bytecode interpreter, on the other hand, is a relatively small, simple program. This
makes it easy to write a bytecode interpreter for a new type of computer; once that is done,
that computer can run any compiled Java program. It would be much harder to write a Java
compiler for the same computer.
Furthermore, some Java programs are meant to be downloaded over a network. This leads
to obvious security concerns: you don’t want to download and run a program that will damage
CHAPTER 1. THE MENTAL LANDSCAPE 8
your computer or your files. The bytecode interpreter acts as a buffer between you and the
program you download. You are really running the interpreter, which runs the downloaded
program indirectly. The interpreter can protect you from potentially dangerous actions on the
part of that program.
When Java was still a new language, it was criticized for being slow: Since Java bytecode was
executed by an interpreter, it seemed that Java bytecode programs could never run as quickly
as programs compiled into native machine language (that is, the actual machine language of the
computer on which the program is running). However, this problem has been largely overcome
by the use of just-in-time compilers for executing Java bytecode. A just-in-time compiler
translates Java bytecode into native machine language. It does this while it is executing the
program. Just as for a normal interpreter, the input to a just-in-time compiler is a Java bytecode
program, and its task is to execute that program. But as it is executing the program, it also
translates parts of it into machine language. The translated parts of the program can then be
executed much more quickly than they could be interpreted. Since a given part of a program is
often executed many times as the program runs, a just-in-time compiler can significantly speed
up the overall execution time.
I should note that there is no necessary connection between Java and Java bytecode. A
program written in Java could certainly be compiled into the machine language of a real com-
puter. And programs written in other languages can be compiled into Java bytecode. However,
the combination of Java and Java bytecode is platform-independent, secure, and network-
compatible while allowing you to program in a modern high-level object-oriented language.
(In the past few years, it has become fairly common to create new programming languages,
or versions of old languages, that compile into Java bytecode. The compiled bytecode programs
can then be executed by a standard JVM. New languages that have been developed specifically
for programming the JVM include Groovy, Clojure, and Processing. Jython and JRuby are
versions of older languages, Python and Ruby, that target the JVM. These languages make it
possible to enjoy many of the advantages of the JVM while avoiding some of the technicalities
of the Java language. In fact, the use of other languages with the JVM has become important
enough that several new features have been added to the JVM specifically to add better support
for some of those languages. And this improvement to the JVM has in turn made possible some
of the new features in Java 7 and Java 8.)
∗ ∗ ∗
I should also note that the really hard part of platform-independence is providing a “Graph-
ical User Interface”—with windows, buttons, etc.—that will work on all the platforms that
support Java. You’ll see more about this problem in Section 1.6.
a kind of “box” in memory that can hold data, even though you don’t have to know where in
memory that box is located.
In Java and in many other programming languages, a variable has a type that indicates
what sort of data it can hold. One type of variable might hold integers—whole numbers such as
3, -7, and 0—while another holds floating point numbers—numbers with decimal points such as
3.14, -2.7, or 17.0. (Yes, the computer does make a distinction between the integer 17 and the
floating-point number 17.0; they actually look quite different inside the computer.) There could
also be types for individual characters (’A’, ’;’, etc.), strings (“Hello”, “A string can include
many characters”, etc.), and less common types such as dates, colors, sounds, or any other kind
of data that a program might need to store.
Programming languages always have commands for getting data into and out of variables
and for doing computations with data. For example, the following “assignment statement,”
which might appear in a Java program, tells the computer to take the number stored in the
variable named “principal”, multiply that number by 0.07, and then store the result in the
variable named “interest”:
interest = principal * 0.07;
There are also “input commands” for getting data from the user or from files on the computer’s
disks, and there are “output commands” for sending data in the other direction.
These basic commands—for moving data from place to place and for performing
computations—are the building blocks for all programs. These building blocks are combined
into complex programs using control structures and subroutines.
∗ ∗ ∗
A program is a sequence of instructions. In the ordinary “flow of control,” the computer
executes the instructions in the sequence in which they occur in the program, one after the
other. However, this is obviously very limited: the computer would soon run out of instructions
to execute. Control structures are special instructions that can change the flow of control.
There are two basic types of control structure: loops, which allow a sequence of instructions
to be repeated over and over, and branches, which allow the computer to decide between two
or more different courses of action by testing conditions that occur as the program is running.
For example, it might be that if the value of the variable “principal” is greater than 10000,
then the “interest” should be computed by multiplying the principal by 0.05; if not, then the
interest should be computed by multiplying the principal by 0.04. A program needs some
way of expressing this type of decision. In Java, it could be expressed using the following “if
statement”:
if (principal > 10000)
interest = principal * 0.05;
else
interest = principal * 0.04;
(Don’t worry about the details for now. Just remember that the computer can test a condition
and decide what to do next on the basis of that test.)
Loops are used when the same task has to be performed more than once. For example,
if you want to print out a mailing label for each name on a mailing list, you might say, “Get
the first name and address and print the label; get the second name and address and print
the label; get the third name and address and print the label. . . ” But this quickly becomes
ridiculous—and might not work at all if you don’t know in advance how many names there are.
What you would like to say is something like “While there are more names to process, get the
CHAPTER 1. THE MENTAL LANDSCAPE 10
next name and address, and print the label.” A loop can be used in a program to express such
repetition.
∗ ∗ ∗
Large programs are so complex that it would be almost impossible to write them if there
were not some way to break them up into manageable “chunks.” Subroutines provide one way to
do this. A subroutine consists of the instructions for performing some task, grouped together
as a unit and given a name. That name can then be used as a substitute for the whole set of
instructions. For example, suppose that one of the tasks that your program needs to perform
is to draw a house on the screen. You can take the necessary instructions, make them into
a subroutine, and give that subroutine some appropriate name—say, “drawHouse()”. Then
anyplace in your program where you need to draw a house, you can do so with the single
command:
drawHouse();
This will have the same effect as repeating all the house-drawing instructions in each place.
The advantage here is not just that you save typing. Organizing your program into sub-
routines also helps you organize your thinking and your program design effort. While writing
the house-drawing subroutine, you can concentrate on the problem of drawing a house without
worrying for the moment about the rest of the program. And once the subroutine is written,
you can forget about the details of drawing houses—that problem is solved, since you have a
subroutine to do it for you. A subroutine becomes just like a built-in part of the language which
you can use without thinking about the details of what goes on “inside” the subroutine.
∗ ∗ ∗
Variables, types, loops, branches, and subroutines are the basis of what might be called
“traditional programming.” However, as programs become larger, additional structure is needed
to help deal with their complexity. One of the most effective tools that has been found is object-
oriented programming, which is discussed in the next section.
design of subroutines and control structures. Top-down programming doesn’t give adequate
consideration to the data that the program manipulates.
Another problem with strict top-down programming is that it makes it difficult to reuse
work done for other projects. By starting with a particular problem and subdividing it into
convenient pieces, top-down programming tends to produce a design that is unique to that
problem. It is unlikely that you will be able to take a large chunk of programming from another
program and fit it into your project, at least not without extensive modification. Producing
high-quality programs is difficult and expensive, so programmers and the people who employ
them are always eager to reuse past work.
∗ ∗ ∗
So, in practice, top-down design is often combined with bottom-up design. In bottom-up
design, the approach is to start “at the bottom,” with problems that you already know how to
solve (and for which you might already have a reusable software component at hand). From
there, you can work upwards towards a solution to the overall problem.
The reusable components should be as “modular” as possible. A module is a component of a
larger system that interacts with the rest of the system in a simple, well-defined, straightforward
manner. The idea is that a module can be “plugged into” a system. The details of what goes on
inside the module are not important to the system as a whole, as long as the module fulfills its
assigned role correctly. This is called information hiding , and it is one of the most important
principles of software engineering.
One common format for software modules is to contain some data, along with some sub-
routines for manipulating that data. For example, a mailing-list module might contain a list of
names and addresses along with a subroutine for adding a new name, a subroutine for printing
mailing labels, and so forth. In such modules, the data itself is often hidden inside the module;
a program that uses the module can then manipulate the data only indirectly, by calling the
subroutines provided by the module. This protects the data, since it can only be manipulated
in known, well-defined ways. And it makes it easier for programs to use the module, since they
don’t have to worry about the details of how the data is represented. Information about the
representation of the data is hidden.
Modules that could support this kind of information-hiding became common in program-
ming languages in the early 1980s. Since then, a more advanced form of the same idea has
more or less taken over software engineering. This latest approach is called object-oriented
programming , often abbreviated as OOP.
The central concept of object-oriented programming is the object, which is a kind of module
containing data and subroutines. The point-of-view in OOP is that an object is a kind of self-
sufficient entity that has an internal state (the data it contains) and that can respond to
messages (calls to its subroutines). A mailing list object, for example, has a state consisting
of a list of names and addresses. If you send it a message telling it to add a name, it will
respond by modifying its state to reflect the change. If you send it a message telling it to print
itself, it will respond by printing out its list of names and addresses.
The OOP approach to software engineering is to start by identifying the objects involved in
a problem and the messages that those objects should respond to. The program that results is
a collection of objects, each with its own data and its own set of responsibilities. The objects
interact by sending messages to each other. There is not much “top-down” in the large-scale
design of such a program, and people used to more traditional programs can have a hard time
getting used to OOP. However, people who use OOP would claim that object-oriented programs
tend to be better models of the way the world itself works, and that they are therefore easier
CHAPTER 1. THE MENTAL LANDSCAPE 12
DrawableObject
MultipointObject TwoPointObject
be reused directly if it fits exactly into a program you are trying to write, but if it just almost
fits, you can still reuse it by defining a subclass and making only the small changes necessary
to adapt it exactly to your needs.
So, OOP is meant to be both a superior program-development tool and a partial solution
to the software reuse problem. Objects, classes, and object-oriented programming will be
important themes throughout the rest of this text. You will start using objects that are built
into the Java language in the next chapter, and in Chapter 5 you will begin creating your own
classes and objects.
(If you would like to run this program, the source code, GUIDemo.java, as well as a compiled
program, GUIDemo.jar, are available on line. For more information on using this and other
examples from this textbook, see Section 2.6.)
Now, Java actually has two complete sets of GUI components. One of these, the AWT or
Abstract Windowing Toolkit, was available in the original version of Java. The other, which
is known as Swing , was introduced in Java version 1.2, and is used in preference to the AWT
in most modern Java programs. The program that is shown above uses components that are
part of Swing.
When a user interacts with GUI components, “events” are generated. For example, clicking
a push button generates an event, and pressing return while typing in a text field generates an
event. Each time an event is generated, a message is sent to the program telling it that the
event has occurred, and the program responds according to its program. In fact, a typical GUI
program consists largely of “event handlers” that tell the program how to respond to various
types of events. In this example, the program has been programmed to respond to each event
by displaying a message in the text area. In a more realistic example, the event handlers would
have more to do.
The use of the term “message” here is deliberate. Messages, as you saw in the previous sec-
tion, are sent to objects. In fact, Java GUI components are implemented as objects. Java
includes many predefined classes that represent various types of GUI components. Some of
these classes are subclasses of others. Here is a diagram showing just a few of Swing’s GUI
classes and their relationships:
JComponent
JCheckBox JRadioButton
Don’t worry about the details for now, but try to get some feel about how object-oriented
programming and inheritance are used here. Note that all the GUI classes are subclasses,
directly or indirectly, of a class called JComponent, which represents general properties that are
shared by all Swing components. In the diagram, two of the direct subclasses of JComponent
themselves have subclasses. The classes JTextArea and JTextField, which have certain behaviors
CHAPTER 1. THE MENTAL LANDSCAPE 15
sends a message to a domain name server to find out the corresponding IP address. Then, your
computer uses the IP address, rather than the domain name, to communicate with the other
computer.)
The Internet provides a number of services to the computers connected to it (and, of course,
to the users of those computers). These services use TCP/IP to send various types of data over
the net. Among the most popular services are instant messaging, file sharing, electronic mail,
and the World-Wide Web. Each service has its own protocols, which are used to control
transmission of data over the network. Each service also has some sort of user interface, which
allows the user to view, send, and receive data through the service.
For example, the email service uses a protocol known as SMTP (Simple Mail Transfer
Protocol) to transfer email messages from one computer to another. Other protocols, such as
POP and IMAP, are used to fetch messages from an email account so that the recipient can
read them. A person who uses email, however, doesn’t need to understand or even know about
these protocols. Instead, they are used behind the scenes by computer programs to send and
receive email messages. These programs provide the user with an easy-to-use user interface to
the underlying network protocols.
The World-Wide Web is perhaps the most exciting of network services. The World-Wide
Web allows you to request pages of information that are stored on computers all over the
Internet. A Web page can contain links to other pages on the same computer from which it
was obtained or to other computers anywhere in the world. A computer that stores such pages
of information is called a web server . The user interface to the Web is the type of program
known as a web browser . Common web browsers include Internet Explorer, Firefox, Chrome,
and Safari. You use a Web browser to request a page of information. The browser sends a
request for that page to the computer on which the page is stored, and when a response is
received from that computer, the web browser displays it to you in a neatly formatted form.
A web browser is just a user interface to the Web. Behind the scenes, the web browser uses a
protocol called HTTP (HyperText Transfer Protocol) to send each page request and to receive
the response from the web server.
∗ ∗ ∗
Now just what, you might be thinking, does all this have to do with Java? In fact, Java
is intimately associated with the Internet and the World-Wide Web. When Java was first
introduced, one of its big attractions was the ability to write applets. An applet is a small
program that is transmitted over the Internet and that runs on a web page. Applets make it
possible for a web page to perform complex tasks and have complex interactions with the user.
Alas, applets have suffered from a variety of security problems, and fixing those problems has
made them more difficult to use. Applets have become much less common on the Web, and in
any case, there are other options for running programs on Web pages.
But applets are only one aspect of Java’s relationship with the Internet. Java can be used to
write complex, stand-alone applications that do not depend on a Web browser. Many of these
programs are network-related. For example many of the largest and most complex web sites
use web server software that is written in Java. Java includes excellent support for network
protocols, and its platform independence makes it possible to write network programs that
work on many different types of computer. You will learn about Java’s network support in
Chapter 11.
Its support for networking is not Java’s only advantage. But many good programming
languages have been invented only to be soon forgotten. Java has had the good luck to ride on
the coattails of the Internet’s immense and increasing popularity.
CHAPTER 1. THE MENTAL LANDSCAPE 17
∗ ∗ ∗
As Java has matured, its applications have reached far beyond the Net. The standard version
of Java already comes with support for many technologies, such as cryptography and data
compression. Free extensions are available to support many other technologies such as advanced
sound processing and three-dimensional graphics. Complex, high-performance systems can be
developed in Java. For example, Hadoop, a system for large scale data processing, is written in
Java. Hadoop is used by Yahoo, Facebook, and other Web sites to process the huge amounts
of data generated by their users.
Furthermore, Java is not restricted to use on traditional computers. Java can be used to
write programs for many smartphones (though not for the iPhone). It is the primary develop-
ment language for Android-based devices. (Some mobile devices use a version of Java called
Java ME (“Mobile Edition”), but Android uses Google’s own version of Java and does not use
the same graphical user interface components as standard Java.) Java is also the programming
language for the Amazon Kindle eBook reader and for interactive features on Blu-Ray video
disks.
At this time, Java certainly ranks as one of the most widely used programming languages.
It is a good choice for almost any programming project that is meant to run on more than
one type of computing device, and is a reasonable choice even for many programs that will
run on only one device. It is probably still the most widely taught language at Colleges and
Universities. It is similar enough to other popular languages, such as C, C++, and Python,
that knowing it will give you a good start on learning those languages as well. Overall, learning
Java is a great starting point on the road to becoming an expert programmer. I hope you enjoy
the journey!
Quiz 18
Quiz on Chapter 1
(answers)
1. One of the components of a computer is its CPU. What is a CPU and what role does it
play in a computer?
5. If you have the source code for a Java program, and you want to run that program, you
will need both a compiler and an interpreter. What does the Java compiler do, and what
does the Java interpreter do?
6. What is a subroutine?
8. What is a variable? (There are four different ideas associated with variables in Java. Try
to mention all four aspects in your answer. Hint: One of the aspects is the variable’s
name.)
10. What is the “Internet”? Give some examples of how it is used. (What kind of services
does it provide?)
Chapter 2
On a basic level (the level of machine language), a computer can perform only very simple
operations. A computer performs complex tasks by stringing together large numbers of such
operations. Such tasks must be “scripted” in complete and perfect detail by programs. Creating
complex programs will never be really easy, but the difficulty can be handled to some extent by
giving the program a clear overall structure. The design of the overall structure of a program
is what I call “programming in the large.”
Programming in the small, which is sometimes called coding , would then refer to filling in
the details of that design. The details are the explicit, step-by-step instructions for performing
fairly small-scale tasks. When you do coding, you are working “close to the machine,” with some
of the same concepts that you might use in machine language: memory locations, arithmetic
operations, loops and branches. In a high-level language such as Java, you get to work with
these concepts on a level several steps above machine language. However, you still have to
worry about getting all the details exactly right.
This chapter and the next examine the facilities for programming in the small in the Java
programming language. Don’t be misled by the term “programming in the small” into thinking
that this material is easy or unimportant. This material is an essential foundation for all types
of programming. If you don’t understand it, you can’t write programs, no matter how good
you get at designing their large-scale structure.
The last section of this chapter discusses programming environments. That section
contains information about how to compile and run Java programs, and you should take a look
at it before trying to write and use your own programs or trying to use the sample programs
in this book.
19
CHAPTER 2. NAMES AND THINGS 20
using things like loops, branches, and subroutines. A syntactically correct program is one that
can be successfully compiled or interpreted; programs that have syntax errors will be rejected
(hopefully with a useful error message that will help you fix the problem).
So, to be a successful programmer, you have to develop a detailed knowledge of the syntax
of the programming language that you are using. However, syntax is only part of the story. It’s
not enough to write a program that will run—you want a program that will run and produce
the correct result! That is, the meaning of the program has to be right. The meaning of
a program is referred to as its semantics. More correctly, the semantics of a programming
language is the set of rules that determine the meaning of a program written in that language.
A semantically correct program is one that does what you want it to.
Furthermore, a program can be syntactically and semantically correct but still be a pretty
bad program. Using the language correctly is not the same as using it well. For example, a
good program has “style.” It is written in a way that will make it easy for people to read and
to understand. It follows conventions that will be familiar to other programmers. And it has
an overall design that will make sense to human readers. The computer is completely oblivious
to such things, but to a human reader, they are paramount. These aspects of programming are
sometimes referred to as pragmatics. (I will often use the more common term style.)
When I introduce a new language feature, I will explain the syntax, the semantics, and
some of the pragmatics of that feature. You should memorize the syntax; that’s the easy part.
Then you should get a feeling for the semantics by following the examples given, making sure
that you understand how they work, and, ideally, writing short programs of your own to test
your understanding. And you should try to appreciate and absorb the pragmatics—this means
learning how to use the language feature well, with style that will earn you the admiration of
other programmers.
Of course, even when you’ve become familiar with all the individual features of the language,
that doesn’t make you a programmer. You still have to learn how to construct complex programs
to solve particular problems. For that, you’ll need both experience and taste. You’ll find hints
about software development throughout this textbook.
∗ ∗ ∗
We begin our exploration of Java with the problem that has become traditional for such
beginnings: to write a program that displays the message “Hello World!”. This might seem like
a trivial problem, but getting a computer to do this is really a big first step in learning a new
programming language (especially if it’s your first programming language). It means that you
understand the basic process of:
1. getting the program text into the computer,
2. compiling the program, and
3. running the compiled program.
The first time through, each of these steps will probably take you a few tries to get right. I
won’t go into the details here of how you do each of these steps; it depends on the particular
computer and Java programming environment that you are using. See Section 2.6 for informa-
tion about creating and running Java programs in specific programming environments. But in
general, you will type the program using some sort of text editor and save the program in a file.
Then, you will use some command to try to compile the file. You’ll either get a message that the
program contains syntax errors, or you’ll get a compiled version of the program. In the case of
Java, the program is compiled into Java bytecode, not into machine language. Finally, you can
run the compiled program by giving some appropriate command. For Java, you will actually use
CHAPTER 2. NAMES AND THINGS 21
an interpreter to execute the Java bytecode. Your programming environment might automate
some of the steps for you—for example, the compilation step is often done automatically—but
you can be sure that the same three steps are being done in the background.
Here is a Java program to display the message “Hello World!”. Don’t expect to understand
what’s going on here just yet; some of it you won’t really understand until a few chapters from
now:
/** A program to display the message
* "Hello World!" on standard output.
*/
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
} // end of class HelloWorld
The command that actually displays the message is:
System.out.println("Hello World!");
This command is an example of a subroutine call statement. It uses a “built-in subroutine”
named System.out.println to do the actual work. Recall that a subroutine consists of the
instructions for performing some task, chunked together and given a name. That name can be
used to “call” the subroutine whenever that task needs to be performed. A built-in subroutine
is one that is already defined as part of the language and therefore automatically available for
use in any program.
When you run this program, the message “Hello World!” (without the quotes) will be
displayed on standard output. Unfortunately, I can’t say exactly what that means! Java is
meant to run on many different platforms, and standard output will mean different things on
different platforms. However, you can expect the message to show up in some convenient or
inconvenient place. (If you use a command-line interface, like that in Oracle’s Java Development
Kit, you type in a command to tell the computer to run the program. The computer will type
the output from the program, Hello World!, on the next line. In an integrated development
environment such as Eclipse, the output might appear somewhere in one of the environment’s
windows.)
You must be curious about all the other stuff in the above program. Part of it consists of
comments. Comments in a program are entirely ignored by the computer; they are there for
human readers only. This doesn’t mean that they are unimportant. Programs are meant to be
read by people as well as by computers, and without comments, a program can be very difficult
to understand. Java has two types of comments. The first type begins with // and extends to
the end of a line. There is a comment of this form on the last line of the above program. The
computer ignores the // and everything that follows it on the same line. The second type of
comment starts with /* and ends with */, and it can extend over more than one line. The first
three lines of the program are an example of this second type of comment. (A comment that
actually begins with /**, like this one does, has special meaning; it is a “Javadoc” comment
that can be used to produce documentation for the program.)
Everything else in the program is required by the rules of Java syntax. All programming in
Java is done inside “classes.” The first line in the above program (not counting the comment)
says that this is a class named HelloWorld. “HelloWorld,” the name of the class, also serves as
CHAPTER 2. NAMES AND THINGS 22
the name of the program. Not every class is a program. In order to define a program, a class
must include a subroutine named main, with a definition that takes the form:
public static void main(String[] args) {
hstatements i
}
When you tell the Java interpreter to run the program, the interpreter calls this main()
subroutine, and the statements that it contains are executed. These statements make up the
script that tells the computer exactly what to do when the program is executed. The main()
routine can call other subroutines that are defined in the same class or even in other classes,
but it is the main() routine that determines how and in what order the other subroutines are
used.
The word “public” in the first line of main() means that this routine can be called from out-
side the program. This is essential because the main() routine is called by the Java interpreter,
which is something external to the program itself. The remainder of the first line of the routine
is harder to explain at the moment; for now, just think of it as part of the required syntax.
The definition of the subroutine—that is, the instructions that say what it does—consists of
the sequence of “statements” enclosed between braces, { and }. Here, I’ve used hstatementsi as
a placeholder for the actual statements that make up the program. Throughout this textbook,
I will always use a similar format: anything that you see in hthis style of texti (italic in angle
brackets) is a placeholder that describes something you need to type when you write an actual
program.
As noted above, a subroutine can’t exist by itself. It has to be part of a “class”. A program
is defined by a public class that takes the form:
public class hprogram-name i {
hoptional-variable-declarations-and-subroutines i
public static void main(String[] args) {
hstatements i
}
hoptional-variable-declarations-and-subroutines i
}
The name on the first line is the name of the program, as well as the name of the class.
(Remember, again, that hprogram-namei is a placeholder for the actual name!)
If the name of the class is HelloWorld, then the class must be saved in a file called
HelloWorld.java. When this file is compiled, another file named HelloWorld.class will
be produced. This class file, HelloWorld.class, contains the translation of the program into
Java bytecode, which can be executed by a Java interpreter. HelloWorld.java is called the
source code for the program. To execute the program, you only need the compiled class file,
not the source code.
The layout of the program on the page, such as the use of blank lines and indentation, is not
part of the syntax or semantics of the language. The computer doesn’t care about layout—you
could run the entire program together on one line as far as it is concerned. However, layout is
important to human readers, and there are certain style guidelines for layout that are followed
by most programmers.
CHAPTER 2. NAMES AND THINGS 23
Also note that according to the above syntax specification, a program can contain other
subroutines besides main(), as well as things called “variable declarations.” You’ll learn more
about these later, but not until Chapter 4.
2.2.1 Variables
Programs manipulate data that are stored in memory. In machine language, data can only be
referred to by giving the numerical address of the location in memory where the data is stored.
CHAPTER 2. NAMES AND THINGS 24
In a high-level language such as Java, names are used instead of numbers to refer to data. It
is the job of the computer to keep track of where in memory the data is actually stored; the
programmer only has to remember the name. A name used in this way—to refer to data stored
in memory—is called a variable.
Variables are actually rather subtle. Properly speaking, a variable is not a name for the
data itself but for a location in memory that can hold data. You should think of a variable as
a container or box where you can store data that you will need to use later. The variable refers
directly to the box and only indirectly to the data in the box. Since the data in the box can
change, a variable can refer to different data values at different times during the execution of
the program, but it always refers to the same box. Confusion can arise, especially for beginning
programmers, because when a variable is used in a program in certain ways, it refers to the
container, but when it is used in other ways, it refers to the data in the container. You’ll see
examples of both cases below.
(In this way, a variable is something like the title, “The President of the United States.”
This title can refer to different people at different times, but it always refers to the same office.
If I say “the President is playing basketball,” I mean that Barack Obama is playing basketball.
But if I say “Hillary Clinton wants to be President” I mean that she wants to fill the office, not
that she wants to be Barack Obama.)
In Java, the only way to get data into a variable—that is, into the box that the variable
names—is with an assignment statement. An assignment statement takes the form:
hvariable i = hexpression i;
where hexpressioni represents anything that refers to or computes a data value. When the
computer comes to an assignment statement in the course of executing a program, it evaluates
the expression and puts the resulting data value into the variable. For example, consider the
simple assignment statement
rate = 0.07;
The hvariablei in this assignment statement is rate, and the hexpressioni is the number 0.07.
The computer executes this assignment statement by putting the number 0.07 in the variable
rate, replacing whatever was there before. Now, consider the following more complicated
assignment statement, which might come later in the same program:
interest = rate * principal;
Here, the value of the expression “rate * principal” is being assigned to the variable
interest. In the expression, the * is a “multiplication operator” that tells the computer
to multiply rate times principal. The names rate and principal are themselves variables,
and it is really the values stored in those variables that are to be multiplied. We see that when
a variable is used in an expression, it is the value stored in the variable that matters; in this
case, the variable seems to refer to the data in the box, rather than to the box itself. When
the computer executes this assignment statement, it takes the value of rate, multiplies it by
the value of principal, and stores the answer in the box referred to by interest. When a
variable is used on the left-hand side of an assignment statement, it refers to the box that is
named by the variable.
(Note, by the way, that an assignment statement is a command that is executed by the
computer at a certain time. It is not a statement of fact. For example, suppose a program
includes the statement “rate = 0.07;”. If the statement “interest = rate * principal;”
is executed later in the program, can we say that the principal is multiplied by 0.07? No!
CHAPTER 2. NAMES AND THINGS 25
The value of rate might have been changed in the meantime by another statement. The
meaning of an assignment statement is completely different from the meaning of an equation
in mathematics, even though both use the symbol “=”.)
2.2.2 Types
A variable in Java is designed to hold only one particular type of data; it can legally hold that
type of data and no other. The compiler will consider it to be a syntax error if you try to
violate this rule by assigning a variable of the wrong type to a variable. We say that Java is a
strongly typed language because it enforces this rule.
There are eight so-called primitive types built into Java. The primitive types are named
byte, short, int, long, float, double, char, and boolean. The first four types hold integers
(whole numbers such as 17, -38477, and 0). The four integer types are distinguished by the
ranges of integers they can hold. The float and double types hold real numbers (such as 3.6 and
-145.99). Again, the two real types are distinguished by their range and accuracy. A variable
of type char holds a single character from the Unicode character set. And a variable of type
boolean holds one of the two logical values true or false.
Any data value stored in the computer’s memory must be represented as a binary number,
that is as a string of zeros and ones. A single zero or one is called a bit. A string of eight
bits is called a byte. Memory is usually measured in terms of bytes. Not surprisingly, the byte
data type refers to a single byte of memory. A variable of type byte holds a string of eight
bits, which can represent any of the integers between -128 and 127, inclusive. (There are 256
integers in that range; eight bits can represent 256—two raised to the power eight—different
values.) As for the other integer types,
• short corresponds to two bytes (16 bits). Variables of type short have values in the range
-32768 to 32767.
• int corresponds to four bytes (32 bits). Variables of type int have values in the range
-2147483648 to 2147483647.
• long corresponds to eight bytes (64 bits). Variables of type long have values in the range
-9223372036854775808 to 9223372036854775807.
You don’t have to remember these numbers, but they do give you some idea of the size of
integers that you can work with. Usually, for representing integer data you should just stick to
the int data type, which is good enough for most purposes.
The float data type is represented in four bytes of memory, using a standard method for
encoding real numbers. The maximum value for a float is about 10 raised to the power 38.
A float can have about 7 significant digits. (So that 32.3989231134 and 32.3989234399 would
both have to be rounded off to about 32.398923 in order to be stored in a variable of type
float.) A double takes up 8 bytes, can range up to about 10 to the power 308, and has about
15 significant digits. Ordinarily, you should stick to the double type for real values.
A variable of type char occupies two bytes in memory. The value of a char variable is a
single character such as A, *, x, or a space character. The value can also be a special character
such a tab or a carriage return or one of the many Unicode characters that come from different
languages. Values of type char are closely related to integer values, since a character is actually
stored as a 16-bit integer code number. In fact, we will see that chars in Java can actually be
used like integers in certain situations.
It is important to remember that a primitive type value is represented using ony a certain,
finite number of bits. So, an int can’t be an arbitrary integer; it can only be an integer
CHAPTER 2. NAMES AND THINGS 26
in a certain finite range of values. Similarly, float and double variables can only take on
certain values. They are not true real numbers in the mathematical sense. For example, the
mathematical constant π can only be approximated by a value of type float or double, since
it would require an infinite number of decimal places to represent it exactly. For that matter,
simple numbers like 1/3 can only be approximated by floats and doubles.
2.2.3 Literals
A data value is stored in the computer as a sequence of bits. In the computer’s memory, it
doesn’t look anything like a value written on this page. You need a way to include constant
values in the programs that you write. In a program, you represent constant values as literals.
A literal is something that you can type in a program to represent a value. It is a kind of name
for a constant value.
For example, to type a value of type char in a program, you must surround it with a pair
of single quote marks, such as ’A’, ’*’, or ’x’. The character and the quote marks make up a
literal of type char. Without the quotes, A would be an identifier and * would be a multiplication
operator. The quotes are not part of the value and are not stored in the variable; they are just
a convention for naming a particular character constant in a program. If you want to store the
character A in a variable ch of type char, you could do so with the assignment statement
ch = ’A’;
Certain special characters have special literals that use a backslash, \, as an “escape character”.
In particular, a tab is represented as ’\t’, a carriage return as ’\r’, a linefeed as ’\n’, the
single quote character as ’\’’, and the backslash itself as ’\\’. Note that even though you
type two characters between the quotes in ’\t’, the value represented by this literal is a single
tab character.
Numeric literals are a little more complicated than you might expect. Of course, there
are the obvious literals such as 317 and 17.42. But there are other possibilities for expressing
numbers in a Java program. First of all, real numbers can be represented in an exponential
form such as 1.3e12 or 12.3737e-108. The “e12” and “e-108” represent powers of 10, so that
1.3e12 means 1.3 times 1012 and 12.3737e-108 means 12.3737 times 10−108 . This format can be
used to express very large and very small numbers. Any numeric literal that contains a decimal
point or exponential is a literal of type double. To make a literal of type float, you have to
append an “F” or “f” to the end of the number. For example, “1.2F” stands for 1.2 considered
as a value of type float. (Occasionally, you need to know this because the rules of Java say that
you can’t assign a value of type double to a variable of type float, so you might be confronted
with a ridiculous-seeming error message if you try to do something like “x = 1.2;” if x is a
variable of type float. You have to say “x = 1.2F;". This is one reason why I advise sticking
to type double for real numbers.)
Even for integer literals, there are some complications. Ordinary integers such as 177777
and -32 are literals of type byte, short, or int, depending on their size. You can make a literal
of type long by adding “L” as a suffix. For example: 17L or 728476874368L. As another
complication, Java allows binary, octal (base-8), and hexadecimal (base-16) literals. I don’t
want to cover number bases in detail, but in case you run into them in other people’s programs,
it’s worth knowing a few things: Octal numbers use only the digits 0 through 7. In Java, a
numeric literal that begins with a 0 is interpreted as an octal number; for example, the octal
literal 045 represents the number 37, not the number 45. Octal numbers are rarely used, but
you need to be aware of what happens when you start a number with a zero. Hexadecimal
CHAPTER 2. NAMES AND THINGS 27
numbers use 16 digits, the usual digits 0 through 9 and the letters A, B, C, D, E, and F. Upper
case and lower case letters can be used interchangeably in this context. The letters represent
the numbers 10 through 15. In Java, a hexadecimal literal begins with 0x or 0X, as in 0x45
or 0xFF7A. Finally, binary literals start with 0b or 0B and contain only the digits 0 and 1; for
example: 0b10110.
As a final complication, numeric literals in Java 7 can include the underscore character (“ ”),
which can be used to separate groups of digits. For example, the integer constant for seven
billion could be written 7 000 000 000, which is a good deal easier to decipher than 7000000000.
There is no rule about how many digits have to be in each group. Underscores can be especially
useful in long binary numbers; for example, 0b1010 1100 1011.
I will note that hexadecimal numbers can also be used in character literals to represent
arbitrary Unicode characters. A Unicode literal consists of \u followed by four hexadecimal
digits. For example, the character literal ’\u00E9’ represents the Unicode character that is an
“e” with an acute accent.
For the type boolean, there are precisely two literals: true and false. These literals are
typed just as I’ve written them here, without quotes, but they represent values, not variables.
Boolean values occur most often as the values of conditional expressions. For example,
rate > 0.05
is a boolean-valued expression that evaluates to true if the value of the variable rate is greater
than 0.05, and to false if the value of rate is not greater than 0.05. As you’ll see in Chapter 3,
boolean-valued expressions are used extensively in control structures. Of course, boolean values
can also be assigned to variables of type boolean. For example, if test is a variable of type
boolean, then both of the following assignment statements are legal:
test = true;
test = rate > 0.05;
What, after all, would the computer do with the value computed by the function in this case?
You have to tell the computer to do something with the value. You might tell the computer to
display it:
System.out.print( Math.sqrt(x) ); // Display the square root of x.
or you might use an assignment statement to tell the computer to store that value in a variable:
lengthOfSide = Math.sqrt(x);
The function call Math.sqrt(x) represents a value of type double, and it can be used anyplace
where a numeric literal of type double could be used.
The Math class contains many static member functions. Here is a list of some of the more
important of them:
• Math.abs(x), which computes the absolute value of x.
• The usual trigonometric functions, Math.sin(x), Math.cos(x), and Math.tan(x). (For
all the trigonometric functions, angles are measured in radians, not degrees.)
• The inverse trigonometric functions arcsin, arccos, and arctan, which are written as:
Math.asin(x), Math.acos(x), and Math.atan(x). The return value is expressed in radi-
ans, not degrees.
• The exponential function Math.exp(x) for computing the number e raised to the power
x, and the natural logarithm function Math.log(x) for computing the logarithm of x in
the base e.
• Math.pow(x,y) for computing x raised to the power y.
• Math.floor(x), which rounds x down to the nearest integer value that is less than or
equal to x. Even though the return value is mathematically an integer, it is returned
as a value of type double, rather than of type int as you might expect. For example,
Math.floor(3.76) is 3.0. The function Math.round(x) returns the integer that is closest
to x, and Math.ceil(x) rounds x up to an integer. (“Ceil” is short for “ceiling”, the
opposite of “floor.”)
• Math.random(), which returns a randomly chosen double in the range 0.0 <=
Math.random() < 1.0. (The computer actually calculates so-called “pseudorandom”
numbers, which are not truly random but are effectively random enough for most pur-
poses.) We will find a lot of uses for Math.random in future examles.
For these functions, the type of the parameter—the x or y inside the parentheses—can be
any value of any numeric type. For most of the functions, the value returned by the function
is of type double no matter what the type of the parameter. However, for Math.abs(x), the
value returned will be the same type as x; if x is of type int, then so is Math.abs(x). So, for
example, while Math.sqrt(9) is the double value 3.0, Math.abs(9) is the int value 9.
Note that Math.random() does not have any parameter. You still need the parentheses,
even though there’s nothing between them. The parentheses let the computer know that this is
a subroutine rather than a variable. Another example of a subroutine that has no parameters
is the function System.currentTimeMillis(), from the System class. When this function is
executed, it retrieves the current time, expressed as the number of milliseconds that have passed
since a standardized base time (the start of the year 1970, if you care). One millisecond is one-
thousandth of a second. The return value of System.currentTimeMillis() is of type long (a
64-bit integer). This function can be used to measure the time that it takes the computer to
CHAPTER 2. NAMES AND THINGS 32
perform a task. Just record the time at which the task is begun and the time at which it is
finished and take the difference.
Here is a sample program that performs a few mathematical tasks and reports the time
that it takes for the program to run. On some computers, the time reported might be zero,
because it is too small to measure in milliseconds. Even if it’s not zero, you can be sure that
most of the time reported by the computer was spent doing output or working on tasks other
than the program, since the calculations performed in this program occupy only a tiny fraction
of a millisecond of a computer’s time.
/**
* This program performs some mathematical computations and displays the
* results. It also displays the value of the constant Math.PI. It then
* reports the number of seconds that the computer spent on this task.
*/
public class TimedComputation {
public static void main(String[] args) {
long startTime; // Starting time of program, in milliseconds.
long endTime; // Time when computations are done, in milliseconds.
double time; // Time difference, in seconds.
startTime = System.currentTimeMillis();
double width, height, hypotenuse; // sides of a triangle
width = 42.0;
height = 17.0;
hypotenuse = Math.sqrt( width*width + height*height );
System.out.print("A triangle with sides 42 and 17 has hypotenuse ");
System.out.println(hypotenuse);
System.out.println("\nMathematically, sin(x)*sin(x) + "
+ "cos(x)*cos(x) - 1 should be 0.");
System.out.println("Let’s check this for x = 1:");
System.out.print(" sin(1)*sin(1) + cos(1)*cos(1) - 1 is ");
System.out.println( Math.sin(1)*Math.sin(1)
+ Math.cos(1)*Math.cos(1) - 1 );
System.out.println("(There can be round-off errors when"
+ " computing with real numbers!)");
System.out.print("\nHere is a random number: ");
System.out.println( Math.random() );
System.out.print("The value of Math.PI is ");
System.out.println( Math.PI );
endTime = System.currentTimeMillis();
time = (endTime - startTime) / 1000.0;
System.out.print("\nRun time in seconds was: ");
System.out.println(time);
} // end main()
} // end class TimedComputation
CHAPTER 2. NAMES AND THINGS 33
PERCIVAL.
It was Epsom week. London was all astir with the influx of company
returning from the races.
A pale girl sat alone in one of the apartments of an hotel in Brook
Street, listening long and anxiously to the coming sounds of the
carriage-wheels, as they whirled along in that direction.
At length a carriage stopped before the door, and in a few moments
a lady entered the room, whose showy costume and flushed excited
countenance, (forming so strong a contrast to the appearance of the
other, whom she warmly greeted,) plainly evinced her to have but
just returned from that gay resort, the Stand at Epsom.
"You are come then, dear Mary. I hope you have not been very long
waiting."
"No, not so very long," and the eyes of the speaker wandered
anxiously towards the door, as if she seemed to expect the
appearance of a second person.
Mrs. de Burgh understood that glance too well—she shook her head
compassionately.
"Alas!—no, dear Mary; you must not expect to see him just now; he
has been unfortunately prevented—that was the reason which made
me so late; but I will tell you all about it presently, only let me have
a glass of wine first, for I am nearly exhausted."
And during the interval of suspense, whilst Mrs. de Burgh refreshed
herself after the fatiguing pleasures of the day, let us remind our
readers, that the momentous year had some little time ago drawn to
a close. Its expiration had not, however, brought with it, any
immediate results.
Nothing had been seen or heard of Eugene Trevor by any of the
family for the first month or two. He had been in London only at
intervals, and he had not opened any communication with his
fiancée, till she—on coming to London at the urgent solicitation of
her sister Lady Morgan, who was not well—had a few days after her
arrival, been surprised by a note from Mrs. de Burgh, whom she was
not aware was even in town, begging her to come to her—naming a
particular day—at the hotel where she was staying—as Eugene
Trevor wished particularly to see her. She added that he would be
obliged by her not mentioning the object of this visit to her relations,
lest by any chance they might interfere with the interview, and it
was very necessary that it should occur, before any more general
communication took place.
"Still mystery and concealment!" was poor Mary's disappointed
soliloquy. "Why not come here openly and see and speak to me? But
I will go this once, as Eugene wishes it, and I cannot refuse perhaps
without occasioning trouble and confusion."
And so she went; for still alas! the attractive chain too powerfully
bound her, and her heart could not but spring forward with yearning
hope to this meeting once again, with her intended. It may be
imagined, therefore, how her heart had sunk within her, at Mrs. de
Burgh's disappointing communication.
"Prevented coming," after having had her hopes and expectations
strained to such a pitch—and she awaited with painful solicitude the
promised explanation.
She had not seen her cousin since her last unhappy time in London,
and though, even then, to a certain degree, a kind of estrangement
had risen up between them; and all that she had since heard by
report of the gay wife's conduct and proceedings, had not greatly
raised the beautiful Olivia in her esteem, yet Mary could not but
retain a grateful remembrance of the warm-hearted kindness she
had received whilst under her roof—and a still more pleasing and
vivid impression of the too tenderly cherished associations, with
which she was so intimately connected.
But at this moment, the dearest friend on earth would have only
been appreciated by Mary, as the being on whose lips she hung for
information on the subject, and which she alone at this moment had
the power to communicate; and "why had not Eugene come?" was
all that spoke in her anxious countenance, or in the faltering tone in
which she attempted, with some show of cousinly interest, to make
a few inquiries after Louis and the children.
Mrs. de Burgh came at last to her relief—if relief it could be called—
for the first thing she heard was, that Eugene instead of coming to
see her, intended setting off for Montrevor that very evening.
"And why?" Mary with quivering lips interrupted.
"Having lost a large sum of money on the Derby, he was obliged to
have immediate recourse to his father for the necessary cash to
cover this unfortunate transaction. He has therefore commissioned
me to break to you this intelligence. I cannot tell you, my dear Mary,
the state of mind poor Eugene was in when we parted—not only on
account of the immediate disappointment this occasioned him; but
because this enormous loss must again retard the possibility of his
marriage taking place at present. My dear Mary, you are doomed to
the trial of hope deferred—the strength and constancy of your
attachment has indeed been sorely taxed."
Mary did not immediately reply. She sat very pale, her eyes fixed
upon the ground, something more than common disappointment
expressed in her thoughtful countenance.
At length she looked up, and said in a grave and anxious tone:
"Does Eugene always lose like this at races?"
"Oh no, dear! fortunately," laughed Mrs. de Burgh, "not often; he is
very lucky in general," but checking herself, as she saw Mary's
shocked countenance, "I mean," and she hesitated, "that after all he
has not so very decided a taste for this sort of thing," and Mrs. de
Burgh laughed again, saying: "but, my dear girl, do not look so very
serious upon the subject, what is there so very shocking in it after
all."
Mary thought it was a subject, to her at least, of most serious
importance and concern. A new and uncomfortable misgiving began
to arise in her mind.
Was it in any way relating to this propensity in Eugene Trevor,
against which Louis de Burgh originally warned her—and did it in
reality—more than the reason which Eugene had brought forth to
her brother, tend to interfere in any way with her happiness? So
strongly did this idea suddenly possess her, that she could not
refrain from asking Mrs. de Burgh whether she thought this was the
case. Her cousin's evasive answer did not tend much to the removal
of her suspicions.
Eugene certainly did play—did bet a little on the turf. She thought
Mary had always been aware of that—men must have some pursuit,
some excitement. If it were not one thing it was another—equally—
perhaps one might call it—"not quite right;" however, all the best
men in London were on the turf. Eugene was only like the rest, but
with married men, it was quite different.
"Indeed, Mary," the fair lady continued, "Eugene always assures me,
he means to give up everything of the sort when he marries, and I
am quite sure he will do so. I only wish you were married, dear."
Mary only sighed.
"You are not getting weary of your engagement, Mary?" Mrs. de
Burgh inquired.
"Weary!—oh, no, Olivia. I was sighing for Eugene's sake."
"You may well do so, for he is, I assure you, very unhappy at all this
delay."
Mary shook her head, and her lip curled a little disdainfully. The
gesture seemed to say, "Whose fault is it now?"
Mrs. de Burgh seemed to understand it as such, for she said—
"It is all that miserly old father's fault. He could set everything right
at once, if he chose."
"But," said Mary, in a low tone, "I see no end of all this."
"No," hesitated Mrs. de Burgh, "not I suppose till the brother turns
up; unless, indeed—" she murmured.
"What?" inquired Mary, anxiously.
"You had better come and stay with me at Silverton," was Mrs. de
Burgh's indirect reply.
Mary smiled dejectedly.
"That would never do," she replied, "they would not consent to my
doing so, under present circumstances."
"They—who are they? I am sure, Mary, I should not allow any
brother or sister to interfere with my proceedings. You are of age,
and quite at liberty, I should imagine, to act as you please on any
subject."
Mary shook her head. She did not feel quite so independent-spirited
as all that—and besides, she did not herself see that such a step
would be quite expedient at present.
She did not, however, say this aloud, and Mrs. de Burgh attributed
her silence to yielding consent.
"Eugene wishes it very much I can assure you."
Mary looked up as if the tempter himself had murmured the
insinuating observation in her ear, for there was something
significant in the way Mrs. de Burgh had spoken, which she could
not but understand, and still more in the words which followed.
"If you were only married to Eugene, Mary, you might rely on his
giving up all objectionable and hurtful things."
"But as that cannot be," sighed Mary, despondingly.
"It could," hesitated Mrs. de Burgh; "it is only your friends'
opposition which would stand in the way, until Eugene is able to
settle something satisfactory as to his future prospects. Were I you,
Mary, if it were only for Eugene's sake, I should not be so scrupulous
about securing each other's happiness and his welfare, as he tells
me you are."
But Mary turned away almost indignantly. If the proposal had even
revolted her spirit when coming from Eugene's own lips, much more
so, did it grate upon her feelings, when thus insinuated by those of
another.
But whatever might here have ensued, was interrupted by the
entrance of Mr. de Burgh. It seemed that he had only arrived in
London that day, unexpectedly to Mrs. de Burgh, who otherwise
would not have planned the meeting of Mary and Eugene.
He came evidently in one of his London humours, as his wife called
it; and though he greeted Mary kindly, she fancied there was a
certain alteration in his manner towards her, which she instinctively
felt to originate in his disapprovement of the present circumstances
of her engagement; she remembered that he never was friendly to
the affair, though the direct subject was now avoided by each of the
party.
He sat and made captious and cutting allusions to the races, and
every one concerned therein, which, whether really intended at
Eugene, Mary interpreted as such—and they touched the poor girl to
the quick.
Probably she was not far wrong in her supposition as to the
pointedness of his remarks, for suddenly glancing on his listener's
downcast anxious countenance he exclaimed, addressing his wife:
"Bye the bye, Olivia, I mean to be off abroad in a day or two."
"Good Heavens, Louis! what new fancy is this?"
"Why, I have heard something to-day which has really put me quite
into a fever."
"Well, what is it? Some nonsense, I dare say."
"I at least do not think it so. Dawson, who I saw to-day, declares
that Trevor, Eustace Trevor I mean, was seen by some one not long
ago in Switzerland. Yes," he continued, encouraged by Mary's glance
of intense and startled interest, "he was seen with another person—
the keeper I suppose they talk about—somewhere on the Alps."
"The Alps!—poor fellow! gone there to cool his brain, I suppose,"
said Mrs. de Burgh, whose countenance nevertheless had bespoke
her not a little moved by this communication.
"Cool his brain!—nonsense! cool enough by this time, depend upon
it."
"But does Eugene know of this?" faltered Mary.
"I suppose so," replied Mr. de Burgh, coldly.
"Impossible, Louis!" Mary exclaimed with eagerness.
"Well, perhaps so. I don't know at all," Mr. de Burgh continued. "I
shouldn't be so much surprised if he did; there are a great many
things which surprise me more than that, Mary; for instance you
yourself—yes, you, Mary," as she lifted up her eyes to her cousin's
handsome face, with quiet surprise, "that you should see things in a
light so different to what I should have expected from you."
"Ridiculous!" interposed Mrs. de Burgh—"that is to say that you
should have expected her to have seen everything with your own
jaundiced, prejudiced perception; but about Eustace Trevor."
"Yes, about Eustace Trevor; he is a subject certainly worth a little of
your interest and inquiry. Mary, you should have known him,"
exclaimed Mr. de Burgh, with rising enthusiasm.
"You were very much attached to him then?" demanded Mary, with
deep interest.
"Attached to him!—yes, indeed I was; that was a man whom one
might well glory in calling friend; or," he murmured to himself, "a
woman might be proud to worship as a lover."
"Yes," interposed Mrs. de Burgh, "I suppose he was a very superior,
delightful person; but I own he always appeared to me, even as a
boy, a little tête monté, so that it did not surprise me so very much
when I heard of the calamity which had befallen him. He was just
the sort of person upon whose mind any strong excitement, or
sudden shock would have had the like effect."
"Olivia, you are talking nonsense," Mr. de Burgh petulantly
exclaimed.
"It was his mother's death, I think, I heard which brought on this
dreadful crisis?" Mary inquired.
"Exactly so," answered Mrs. de Burgh.
"How do you know?" exclaimed her husband. "What does any one
know about the matter?"
"We can only judge from what one has heard from the best
authority," again persisted his wife.
"Best authority! well, I can only say that far from being of your
opinion, I should have said that Eustace Trevor had been as far from
madness as earth from heaven."
"Really, Louis!" exclaimed Mrs. de Burgh, perceiving Mary's look of
anxious interest and surprise, "one would fancy from the way you
talk that you suspected him never really to have been mad."
bearing in her secret soul restless doubts and blind misgivings, she
shrank even from confiding to her most beloved Arthur.
CHAPTER IV.
I knew that in thy bosom dwelt
A silent grief, a hidden fear,
A sting which could be only felt
By spirits to their God most dear,
Which yet thou felt'st from year to year,
Unsoftened, nay, embitter'd still;
And many a secret sigh and tear
Heaved thy sad heart, thine eyes did fill,
And anxious thoughts thou hadst
presaging direst ill.
MOULTRIE.
The sequel only brought forth for our heroine further disturbance
and discomfort.
The newly-risen impediment to the marriage was of necessity the
subject of correspondence. He again threw the blame upon his
father, urging his increasing infirmities of mind and body as the
excuse.
But the plea appeared to Mary's friends evasive and ambiguous, and
greatly indeed was the strength and stability of her affection tried by
the urgent solicitations of those so dear to her, that she would
consent to break off entirely this ill-starred—and as they the more
and more considered it—objectionable engagement.
But no, there was yet one still more dear to her; and to him, through
good and evil report, her spirit yet must cling—
"And stand as stands a lonely tree,
That still unbroke, though gently bent,
Still waves with fond fidelity
Its boughs above a monument."
By letter too—for there was one crisis of affairs during which the
lovers corresponded on the anxious subject, Eugene failed not to
urge the maintenance of an engagement which on his part he
declared he would never consent to be the first to relinquish.
Then, how could Mary cast aside an attachment, a hope which had
become so linked with the happiness of her existence, that to
contemplate its extinction, was to see before her extended
WILLIS.
An early morning in Italy! Who that from experience has not enjoyed
—can realise the conception, much less describe, the luxurious
delight of the first hours of a summer morning in that radiant
climate.
"It was the morn of such a day, as must have risen on Eden first,"
that Mary Seaham went forth from the little inn near Tivoli, to join
her brother who had preceded her some little time to make
arrangements respecting their intended excursion of the day.
She waited—but when he did not come, could no longer resist the
tempting aspect of the scenery without, to stroll onwards from the
house towards the merry waters which danced on their musical way
not far distant from the spot; and as she proceeded through the
fragrant air—beneath the transparent sky, the sigh she heaved could
have been caused but by the burden of enjoyment now weighing
upon her senses; for all human care—all sadness, all unrest, all
passionate yearnings or pensive remembrances—in short, all
unconnected with "the mere and breathing charm of life," seemed in
that thrilling hour, annihilated and forgotten.
But something glittering on the ground, near a flower she had
stooped to pick, suddenly attracted her attention. She took it up and
examined it more closely. It was a massive signet ring. What was
Mary's astonishment to see engraved upon the seal, the initials "E.
T." with the Trevor coat of arms.
Her first thought was of Eugene—could it be that he by some
strange coincidence was near? or that he had purposely followed her
to Italy? and her heart beat fast, and her cheek glowed at the
suggestion. Yet she had never remembered observing such a ring on
Eugene's finger, and then—another indefinite recollection of having
somewhere before seen that same impression on some letter,
certainly not from her lover, occurred to her.
Yes—and suddenly the breakfast-table at Silverton, and that letter—
the letter to Eugene which she had ever since suspected must have
been the turning-point of her previous perfect felicity, but which she
had always supposed must have been from Eugene's father. That
large red seal the little Louisa had displayed before her eyes. All was
now before her. But how then came it lying here upon this foreign
soil?
Was it forbidden her to lose, even for a moment, the thrilling
consciousness of the fate which bound her, that there should be now
thrown across her very path, this startling reminder?
Standing fixed to the spot—turning the signet over and over in her
hand, an uncertain, half-bewildered expression on her sweet face—a
sudden idea which crimsoned it to the very temples, then leaving it
paler than before—suddenly lit up her countenance.
How, indeed, came it lying there? "E. T." Surely from the old man's
finger it had not dropped; and if not from Eugene's, might it, could it
have been from that of the lost, unhappy, wandering brother,
Eustace's?
With what object, what intent, she scarcely knew herself—but
impulse moved her, with beating heart and trembling step, to pursue
the path which she had taken, only remembering the while, that last
night, after she was in bed, there had been an arrival at the inn. Two
gentlemen from Rome, the cameriera who called her in the morning
told her, had roused the house up at a very late hour; and that one
of these belated travellers had nevertheless already pressed the
dewy turf before her—that it might be him who was the loser, was
perhaps, the paramount idea which now possessed her as she
hurried on over this fair Italian ground as light in limb—alas! less
light at heart as when bounding over the breezy wilds of her native
land.
She had not been wrong in her conjecture. A sudden turn in the
lovely vale she had entered presented to her view, at no great
distance from the spot she had attained, a broken fountain, the
silvery sound of whose ringing waters faintly reached her ear; and
near this, half concealed by the branches of a leaning tree, she
discerned the figure of a man, standing watching its light and
sparkling play.
A few half irresolute steps brought her nearer and nearer still—a few
more, and she stood attracted as if by an irresistible spell almost
close behind the object of her search. His face had been turned
away, but the light rustling of her garments when she drew so near,
attracted his attention.
He looked round, and there stood Mary with parted lips and
crimsoned brow—that look of strange, deep, and eager scrutiny
directed towards him.
Never did the face of mortal man undergo such immediate change,
as did the calm, noble countenance which at the same time revealed
itself to the intruder; never were two simple words uttered with such
thrilling fervency of tone, as was the ejaculation which broke from
the stranger's lips.
"Miss Seaham," he exclaimed; and in accents scarce less earnest in
its emotion, Mary's trembling lips faltered Mr. Temple's name.
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.
ebookbell.com