0% found this document useful (0 votes)
2 views80 pages

A Java Reference Ucb Cs61b Textbook Itebooks download

The document is a reference for Java programming, authored by Paul N. Hilfinger from UC Berkeley, and includes various topics such as basic program structure, compilation, execution, and object-oriented programming concepts. It also features links to additional Java-related ebooks available for download. The content is structured into sections covering fundamental programming concepts, syntax, and advanced topics in Java.

Uploaded by

nehrigsornum
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views80 pages

A Java Reference Ucb Cs61b Textbook Itebooks download

The document is a reference for Java programming, authored by Paul N. Hilfinger from UC Berkeley, and includes various topics such as basic program structure, compilation, execution, and object-oriented programming concepts. It also features links to additional Java-related ebooks available for download. The content is structured into sections covering fundamental programming concepts, syntax, and advanced topics in Java.

Uploaded by

nehrigsornum
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 80

A Java Reference Ucb Cs61b Textbook Itebooks

download

https://ebookbell.com/product/a-java-reference-ucb-
cs61b-textbook-itebooks-23835948

Explore and download more ebooks at ebookbell.com


Here are some recommended products that we believe you will be
interested in. You can click the link to download.

Learning Java An Introduction To Programming With Java The Complete


Reference Java Programming For Beginners A Practical Guide To Learn
Java In 10 Days Or Less With Handson Projects Neos Thanh

https://ebookbell.com/product/learning-java-an-introduction-to-
programming-with-java-the-complete-reference-java-programming-for-
beginners-a-practical-guide-to-learn-java-in-10-days-or-less-with-
handson-projects-neos-thanh-12081296

Java In A Nutshell A Desktop Quick Reference 8th Benjamin J Evans

https://ebookbell.com/product/java-in-a-nutshell-a-desktop-quick-
reference-8th-benjamin-j-evans-50587402

Java In A Nutshell A Desktop Quick Reference 7th Edition Benjamin J


Evans

https://ebookbell.com/product/java-in-a-nutshell-a-desktop-quick-
reference-7th-edition-benjamin-j-evans-7435650

Java In A Nutshell A Desktop Quick Reference 4th Ed David Flanagan

https://ebookbell.com/product/java-in-a-nutshell-a-desktop-quick-
reference-4th-ed-david-flanagan-1355390
Java In A Nutshell A Desktop Quick Reference 7th Edition Benjamin J
Evans

https://ebookbell.com/product/java-in-a-nutshell-a-desktop-quick-
reference-7th-edition-benjamin-j-evans-10010652

Java 17 Quick Syntax Reference A Pocket Guide To The Java Se Language


Apis And Library 3rd Ed Mikael Olsson

https://ebookbell.com/product/java-17-quick-syntax-reference-a-pocket-
guide-to-the-java-se-language-apis-and-library-3rd-ed-mikael-
olsson-35358400

Pure Jsp Java Server Pages A Codeintensive Premium Reference James


Goodwill

https://ebookbell.com/product/pure-jsp-java-server-pages-a-
codeintensive-premium-reference-james-goodwill-230417306

Android Software Internals Quick Reference A Field Manual And Security


Reference Guide To Javabased Android Components 1st Edition James
Stevenson

https://ebookbell.com/product/android-software-internals-quick-
reference-a-field-manual-and-security-reference-guide-to-javabased-
android-components-1st-edition-james-stevenson-24057900

Java Allinone Desk Reference For Dummies 2nd Edition Lowe Doug

https://ebookbell.com/product/java-allinone-desk-reference-for-
dummies-2nd-edition-lowe-doug-35774716
A Java Reference:
Assorted Java Reference Material

Paul N. Hilfinger
University of California, Berkeley
Copyright c 2001, 2002, 2004, 2006, 2008, 2011, 2012, 2013, 2014 by Paul N.
Hilfinger. All rights reserved.

Acknowledgments. Many thanks to Soheil Golshan, Ashwin Iyengar, Kegan


Kawamura, Benson Limketkai, Vadim Perelman, Barath Raghavan, Chen Tang,
Michael Yang, and Asa Daniel Zernik for finding many errors in previous editions
of this document. Remaining errors are, of course, my own.
Contents

1 Java Overview 9
1.1 Basic Program Structure . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.2 Compilation and Execution . . . . . . . . . . . . . . . . . . . . . . . 11
1.3 Simple Values and Expressions . . . . . . . . . . . . . . . . . . . . . 12
1.3.1 Writing Numbers . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3.2 Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.3.3 Comparisons and Logical Operations . . . . . . . . . . . . . . 14
1.3.4 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.3.5 Static Methods: Abstracting Computation . . . . . . . . . . . 17
1.4 Conditional Execution . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.4.1 If statements . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.4.2 Conditional Expressions . . . . . . . . . . . . . . . . . . . . . 19
1.4.3 Case analysis and the Switch Statement . . . . . . . . . . . . 19
1.5 Arrays I: The Command Line . . . . . . . . . . . . . . . . . . . . . . 21
1.6 Example: Finding Primes . . . . . . . . . . . . . . . . . . . . . . . . 22
1.6.1 Starting from the top . . . . . . . . . . . . . . . . . . . . . . 23
1.6.2 Starting from the bottom . . . . . . . . . . . . . . . . . . . . 23
1.6.3 Meeting in the middle . . . . . . . . . . . . . . . . . . . . . . 26
1.7 Example: Pig Latin . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.7.1 Vowels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.7.2 Translation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
1.7.3 Counting Consonants . . . . . . . . . . . . . . . . . . . . . . 29
1.7.4 To the top . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1.8 Variables and Assignment . . . . . . . . . . . . . . . . . . . . . . . . 32
1.9 Repetition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
1.9.1 Indefinite iteration . . . . . . . . . . . . . . . . . . . . . . . . 35
1.9.2 Definite Iteration . . . . . . . . . . . . . . . . . . . . . . . . . 37
1.9.3 Example: Iterative Prime-Finding . . . . . . . . . . . . . . . 40
1.9.4 Example: Counting . . . . . . . . . . . . . . . . . . . . . . . 41
1.10 Arrays II: Creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
1.10.1 Example: Linear Interpolation . . . . . . . . . . . . . . . . . 43
1.10.2 Example: The Sieve of Eratosthenes . . . . . . . . . . . . . . 44
1.10.3 Multi-dimensional Arrays . . . . . . . . . . . . . . . . . . . . 46
1.11 Introduction to Objects . . . . . . . . . . . . . . . . . . . . . . . . . 48

3
4 CONTENTS

1.11.1 Simple Object Type Definition and Creation . . . . . . . . . 48


1.11.2 Instance Methods . . . . . . . . . . . . . . . . . . . . . . . . . 50
1.11.3 Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
1.11.4 Example: A Prime-Number Class . . . . . . . . . . . . . . . . 52
1.12 Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
1.13 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
1.14 Packages and Access Control . . . . . . . . . . . . . . . . . . . . . . 60
1.15 Handling Exceptional Cases . . . . . . . . . . . . . . . . . . . . . . . 62
1.15.1 Built-in Exceptions . . . . . . . . . . . . . . . . . . . . . . . . 62
1.15.2 What Exactly is an Exception? . . . . . . . . . . . . . . . . . 62
1.15.3 Throwing Exceptions Explicitly . . . . . . . . . . . . . . . . . 63
1.15.4 Catching Exceptions . . . . . . . . . . . . . . . . . . . . . . . 63

2 Describing a Programming Language 65


2.1 Dynamic and Static Properties . . . . . . . . . . . . . . . . . . . . . 65
2.2 Describing Lexical Structure and Syntax . . . . . . . . . . . . . . . . 67

3 Lexical Basics 69
3.1 Layout: Whitespace and Comments . . . . . . . . . . . . . . . . . . 69

4 Values, Types, and Containers 71


4.1 Values and Containers . . . . . . . . . . . . . . . . . . . . . . . . . . 72
4.1.1 Containers and Names . . . . . . . . . . . . . . . . . . . . . . 72
4.1.2 Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
4.2 Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
4.2.1 Static vs. dynamic types . . . . . . . . . . . . . . . . . . . . . 75
4.2.2 Type denotations in Java . . . . . . . . . . . . . . . . . . . . 76
4.3 Environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
4.4 Applying the model to Java . . . . . . . . . . . . . . . . . . . . . . . 77

5 Declarations 79
5.1 Scope and the Meaning of Names . . . . . . . . . . . . . . . . . . . . 80
5.1.1 Block structure . . . . . . . . . . . . . . . . . . . . . . . . . . 80
5.1.2 Selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
5.1.3 Packages and Imports . . . . . . . . . . . . . . . . . . . . . . 82
5.2 Local Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
5.3 Type Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
5.4 Class Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
5.4.1 Kinds of class members . . . . . . . . . . . . . . . . . . . . . 88
5.4.2 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
5.4.3 Class Modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . 89
5.4.4 Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
5.5 Interface Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . 91
5.6 Enumerated Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
5.7 Nested Classes and Interfaces . . . . . . . . . . . . . . . . . . . . . . 94
5.7.1 Member types . . . . . . . . . . . . . . . . . . . . . . . . . . 94
CONTENTS 5

5.7.2 Local classes . . . . . . . . . . . . . . . . . . . . . . . . . . . 95


5.7.3 Anonymous classes . . . . . . . . . . . . . . . . . . . . . . . . 97
5.7.4 What on earth is this all for? . . . . . . . . . . . . . . . . . . 98
5.8 Method (Function) Declarations . . . . . . . . . . . . . . . . . . . . 99
5.8.1 Variable-Length Parameter Lists . . . . . . . . . . . . . . . . 100
5.8.2 Method signatures . . . . . . . . . . . . . . . . . . . . . . . . 101
5.8.3 Overloading and hiding methods . . . . . . . . . . . . . . . . 103
5.8.4 Overriding . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
5.9 Constructor Declarations . . . . . . . . . . . . . . . . . . . . . . . . 107
5.9.1 Rationale. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
5.9.2 Instance and field initializers . . . . . . . . . . . . . . . . . . 109
5.9.3 Some Useful Constructor Idioms . . . . . . . . . . . . . . . . 110
5.10 Initialization of Classes . . . . . . . . . . . . . . . . . . . . . . . . . . 112
5.11 Access control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
5.12 The Java Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
5.12.1 Executing a Program . . . . . . . . . . . . . . . . . . . . . . 114
5.13 Annotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
5.13.1 Deprecated . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
5.13.2 Override . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
5.13.3 SuppressWarnings . . . . . . . . . . . . . . . . . . . . . . . . 118

6 The Expression Language 119


6.1 Syntactic overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
6.1.1 Prefix, Postfix, and Infix Operators . . . . . . . . . . . . . . . 121
6.1.2 Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
6.2 Conversions and Casts . . . . . . . . . . . . . . . . . . . . . . . . . . 123
6.2.1 Explicit conversions . . . . . . . . . . . . . . . . . . . . . . . 123
6.2.2 Implicit conversions . . . . . . . . . . . . . . . . . . . . . . . 124
6.2.3 Promotions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
6.3 Integers and Characters . . . . . . . . . . . . . . . . . . . . . . . . . 125
6.3.1 Integral values and their literals . . . . . . . . . . . . . . . . . 126
6.3.2 Modular integer arithmetic . . . . . . . . . . . . . . . . . . . 129
6.3.3 Manipulating bits . . . . . . . . . . . . . . . . . . . . . . . . 132
6.4 Floating-Point Numbers . . . . . . . . . . . . . . . . . . . . . . . . . 135
6.4.1 Floating-Point Literals . . . . . . . . . . . . . . . . . . . . . . 136
6.4.2 Floating-point arithmetic . . . . . . . . . . . . . . . . . . . . 137
6.5 Booleans and Conditionals . . . . . . . . . . . . . . . . . . . . . . . . 141
6.5.1 Boolean literals . . . . . . . . . . . . . . . . . . . . . . . . . . 142
6.5.2 Boolean operations . . . . . . . . . . . . . . . . . . . . . . . . 142
6.5.3 Comparisons and Equality . . . . . . . . . . . . . . . . . . . . 142
6.5.4 Conditional expressions . . . . . . . . . . . . . . . . . . . . . 143
6.6 Reference Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
6.6.1 Allocating class instances . . . . . . . . . . . . . . . . . . . . 144
6.6.2 Field Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
6.6.3 Testing types . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
6 CONTENTS

6.6.4 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148


6.6.5 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
6.7 Assignment, Increment, and Decrement Operators . . . . . . . . . . 154
6.8 Method Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
6.8.1 Static method calls . . . . . . . . . . . . . . . . . . . . . . . . 157
6.8.2 Instance Method Calls . . . . . . . . . . . . . . . . . . . . . . 158
6.9 Constant Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . 160
6.10 Reflection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
6.10.1 Type java.lang.Class . . . . . . . . . . . . . . . . . . . . . . . 161
6.11 Definite Assignment and Related Obscure Details . . . . . . . . . . . 163
6.11.1 Assignments to fields . . . . . . . . . . . . . . . . . . . . . . . 164
6.11.2 Blank final variables . . . . . . . . . . . . . . . . . . . . . . . 165

7 Statements 167
7.1 Sequencing, Blocks, and Empty Statements . . . . . . . . . . . . . . 168
7.2 Conditional Control . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
7.2.1 If Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
7.2.2 Switch Statements . . . . . . . . . . . . . . . . . . . . . . . . 170
7.3 About Statement Format . . . . . . . . . . . . . . . . . . . . . . . . 173
7.4 Iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
7.4.1 While Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
7.4.2 Traditional For Loops . . . . . . . . . . . . . . . . . . . . . . 175
7.4.3 For Loops for Collections and Arrays . . . . . . . . . . . . . . 178
7.5 Jump Statements and Labels . . . . . . . . . . . . . . . . . . . . . . 179
7.5.1 The ‘break’ Statement . . . . . . . . . . . . . . . . . . . . . . 180
7.5.2 The ‘continue’ Statement . . . . . . . . . . . . . . . . . . . . 182
7.5.3 The ‘return’ Statement . . . . . . . . . . . . . . . . . . . . . 183

8 Exception Handling 185


8.1 Throw Statements and Exception Types . . . . . . . . . . . . . . . . 186
8.2 Catching Exceptions: Try Statements . . . . . . . . . . . . . . . . . 186
8.2.1 Simple example: single handler . . . . . . . . . . . . . . . . . 188
8.2.2 Multiple handlers. . . . . . . . . . . . . . . . . . . . . . . . . 189
8.2.3 Using the Caught Exception. . . . . . . . . . . . . . . . . . . 189
8.2.4 The Finally Clause . . . . . . . . . . . . . . . . . . . . . . . . 190
8.3 Declaring Thrown Exceptions . . . . . . . . . . . . . . . . . . . . . . 191
8.4 Exceptions in the java.lang Package . . . . . . . . . . . . . . . . . . 194

9 Strings, Streams, and Patterns 197


9.1 Bytes and Characters . . . . . . . . . . . . . . . . . . . . . . . . . . 198
9.1.1 ASCII and Unicode . . . . . . . . . . . . . . . . . . . . . . . 198
9.1.2 The class Character . . . . . . . . . . . . . . . . . . . . . . . 201
9.2 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
9.2.1 Constructing Strings . . . . . . . . . . . . . . . . . . . . . . . 202
9.2.2 String Accessors . . . . . . . . . . . . . . . . . . . . . . . . . 207
CONTENTS 7

9.2.3 String Comparisons, Tests, and Searches . . . . . . . . . . . . 209


9.2.4 String Hashing . . . . . . . . . . . . . . . . . . . . . . . . . . 210
9.3 StringBuilders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
9.4 Readers, Writers, Streams, and Files . . . . . . . . . . . . . . . . . . 211
9.4.1 Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
9.4.2 Readers and InputStreams . . . . . . . . . . . . . . . . . . . 217
9.4.3 Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
9.4.4 PrintStreams and PrintWriters . . . . . . . . . . . . . . . . . 218
9.5 Regular Expressions and the Pattern Class . . . . . . . . . . . . . . 219
9.6 Scanner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223

10 Generic Programming 227


10.1 Simple Type Parameters . . . . . . . . . . . . . . . . . . . . . . . . . 228
10.2 Type Parameters on Methods . . . . . . . . . . . . . . . . . . . . . . 230
10.3 Restricting Type Parameters . . . . . . . . . . . . . . . . . . . . . . 231
10.4 Wildcards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
10.5 Generic Programming and Primitive Types . . . . . . . . . . . . . . 232
10.6 Formalities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
10.7 Caveats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236

11 Multiple Threads of Control 239


11.1 Creating and Starting Threads . . . . . . . . . . . . . . . . . . . . . 242
11.2 A question of terminology . . . . . . . . . . . . . . . . . . . . . . . . 243
11.3 Synchronization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
11.3.1 Mutual exclusion . . . . . . . . . . . . . . . . . . . . . . . . . 246
11.3.2 Wait and notify . . . . . . . . . . . . . . . . . . . . . . . . . . 248
11.3.3 Volatile storage . . . . . . . . . . . . . . . . . . . . . . . . . . 250
11.4 Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251

Index 255
8 CONTENTS
Chapter 1

Java Overview

Different people have different ways of learning programming languages. Your au-
thor likes to read reference manuals (believe it or not)—at least if they are rea-
sonably complete—on the grounds that this is the most efficient way to absorb a
language quickly. Unfortunately, it is an approach that only works when one knows
what to expect from a programming language, and has the necessary mental cub-
byholes already constructed and ready for filing away specific details. Less grizzled
programmers usually benefit from some kind of tutorial introduction, in which we
look at examples of programs and program fragments. That’s the purpose of this
chapter. After reading it, the succeeding chapters of this book ought to be somewhat
more digestible.

1.1 Basic Program Structure


Let’s start with the traditional simplest program:

/* Sample Program #1 */
public class Hello {
public static void main (String[] arguments) {
System.out.println ("Hello, world!"); // Message + newline
}
}

This example illustrates a number of things about Java:

Java programs are collections of definitions. In this case, we have definitions


of a class named Hello, and a function (or method) named main.

Definitions are grouped into classes. Java programs may contain definitions of
functions, variables, and a few other things. Every such definition is contained
in (is a member of ) some class.

Dots indicate some kind of containment. In the example above, System is a


class and out is a variable defined in that class. We can think of that variable,

9
10 CHAPTER 1. JAVA OVERVIEW

in turn, as referring to an object that has parts (members), one of which is the
println method. So in general, you can read X.Y as “the Y that is (or whose
definition is) contained in X.” We sometimes call ‘.’ the selection operator.

The syntax “method-name(expressions)” denotes a function call. (Also called


method call or method (or function) invocation.) The program first evaluates
the expressions, which are called actual parameters. In our example, there
is only one (more would be separated by commas), and its value is a string
of characters. Next, the value(s) of any actual parameters are handed off to
(passed) to the indicated method, which then does whatever it does (unsur-
prisingly, System.out.println prints the string that you pass it, followed by
an end-of-line.)

Executing a complete program means calling a method named main. (Not


just any method called main, but we’ll get to that detail later). Appropriately
enough, the method called is often referred to as the main program. You won’t
always have to write a main method:

• Sometimes, your task is to write a component or a package of components


for use in one or more other programs. These will consist of a set of
classes, not necessarily containing a main method.
• Sometimes, you are writing something that is intended to be dropped into
an existing framework of supporting components. For example, when you
write a Java applet (a program intended to be run by a Web browser when
one clicks on the appropriate thing) the browser will supply a standard
main, and your applet provides one of the methods it calls.

But for standalone programs (also called application programs), main is where
things start.

Comments are surrounded by /* */ or by // and the end of the line. Only


humans read comments; they have no effect on the program.

A note on printing. It isn’t theoretically central to the topic of programming,


but the printing or other display of results is obviously rather important. Many in-
troductory Java texts get rather hung up on the use of various GUI (Graphical User
Interface) tools for displaying and inputting text, commands, or other communica-
tions. I’d rather keep it simple, so we’ll start with straightforward interaction with
a textual display and keyboard. For output purposes, we use System.out.println
as you’ve seen, which comes with a couple of useful variants. Here is an equivalent
to the main method above:

public static void main (String[] args) {


System.out.print ("Hello,");
System.out.print (" world!");
System.out.println ();
}
1.2. COMPILATION AND EXECUTION 11

javac java
Hello.java Hello.class Hello world!
(compiler) (interpreter)

standard
class
library

Figure 1.1: From program to execution. We first process our sample program
with the javac compiler to create a class file, which we can then execute with an
interpreter (java) to finally print a message. In this tiny program, pre-supplied
programs from the standard class library actually do most of the work.

By comparing the two versions, you can probably deduce that the difference be-
tween print and println is that println ends the line immediately after printing,
whereas print does not. You’ll use print to break the printing of a complex line
of output into pieces.

1.2 Compilation and Execution


Precise details on how to prepare and run this program differ from one implemen-
tation of Java to another. Here is a typical sequence.
• Put the program in one or more files. It generally makes things easier for
the Java system if you put each class in a file named after the class—for our
example, Hello.java. One can put several classes into a file or name the file
arbitrarily, but the Java system will then sometimes be unable to find what
it needs.

• Compile the file with a Java compiler. A compiler is a translation program


that converts a source program (our little sample program is a source program)
into some form that is more easily executed. Java compilers typically translate
each class into a class file. For example, if we use Sun Microsystems’s software,
the command line

javac Hello.java

will translate class Hello into the file Hello.class.

• Execute the program by invoking a Java interpreter. An interpreter is a


program that executes programs. In the case of Sun’s software, the command

java Hello

runs our program, producing the output line

Hello, world!
12 CHAPTER 1. JAVA OVERVIEW

The argument to the java program is the name of the class containing the
desired main method. The interpreter finds out what it is supposed to do
by reading the file Hello.class, together with a library of other class files
that implement standard, pre-defined parts of Java (like the System class
mentioned above).

There are numerous variations on this process. There are systems in which the
compiler, rather than producing a .class file for input to an interpreter, produce a
machine-language or executable file that the hardware of your machine can execute
directly. This arrangement is typical for languages such as C and C++.
As another variation, the interpreter in many Java implementations produces
machine code from .class files “just in time” for it to be executed when needed—
hence the common term JIT compiler.
Typical interactive development environments (IDEs), such as Eclipse, tend to
hide what’s really happening from you. You just write your program and push some
button labeled “Run”, and the IDE compiles whatever is needed and executes it.

1.3 Simple Values and Expressions


You can think of a program as a set of instructions for creating values and moving
them around, eventually sending them to something that does something visible
with them, like displaying them, or moving some physical control. Values may either
be primitive—in Java, these are various kinds of numbers, characters (as from an
alphabet), and booleans (true/false)—or they may structured into compound values.
A programming language construct that produces a value is called an expression.

1.3.1 Writing Numbers


Something that denotes a number is known as a numeral, or, especially in pro-
gramming languages, as a numeric literal. Java has both integral and floating-point
literals (the difference being that the latter can have fractional parts). Here are
some examples, which are mostly self-explanatory:

class Numerals {
public static void main (String[] args) {
// A. All print 42
System.out.println (42); // Base 10
System.out.println (052); // Base 8 (starts with 0)
System.out.println (0x2a); // Base 16 (a=10, b=11, ..., f=15)
// B. All print 31.45
System.out.println (31.45);
System.out.println (3.145e1); // en or En means ×10n
System.out.println (3145e-2);
// C. Prints 12345678901
System.out.println (12345678901L);
}
1.3. SIMPLE VALUES AND EXPRESSIONS 13

Technically, what we think of as negative numbers, such as -3, are actually positive
literals operated on by the negation operator (-).
Example C indirectly illustrates a common feature of “production” programming
languages such as C, C++, Java, Fortran, Pascal, Basic, and so on. For reasons
having to do with fast and efficient execution, the “integers” in these programming
languages comprise a tiny, finite portion of the mathematical integers. Ordinary
integers in Java, for example, are all in the range −231 to 231 −1, or about ±2 billion.
To get somewhat larger integers, you must use a distinct type of value, known as a
long, whose literals have a trailing ‘L’ on them. These give you a range of −263 to
263 − 1. To go even further requires one of the built-in library classes (appropriately
called java.math.BigInteger), for which there aren’t any built-in literals.

1.3.2 Arithmetic
Java expressions include the familiar algebraic notation, which you can play with
easily enough by putting examples into a main function:

class Arith {
public static void main (String[] args) {
// A. Prints 3
System.out.println ((3 + 7 + 10) * (1000 - 8)
/ 992 - 17);
// B. Prints 2.7166666666666663
System.out.println (2.0 + 1.0/2 + 1.0/6 + 1.0/24 + 1.0/120);
// C. Prints 2
System.out.println (2 + 1/2 + 1/6 + 1/24 + 1/120);
// D. Prints -3
System.out.println (1 - 2 - 2);
// E. Prints 17
System.out.println (117 % 20);
// F. Prints Infinity
System.out.println (1.0 / 0.0);
// G. Prints -2147483648
System.out.println (2147483647 + 1);
// H. Prints NaN
System.out.println (0.0 / 0.0);
// I. Halts the program with an exception
System.out.println (1/0);
}
}
As you can see, these examples look pretty much like what you might write by hand,
and illustrate a few more points:

• ‘*’ denotes multiplication and ’%’ denotes remainder.


14 CHAPTER 1. JAVA OVERVIEW

• Operators have precedences. Example B illustrates grouping: the subex-


pression 2.0 + 1.0/2 is interpreted as 2.0+(1.0/2), not (2.0+1.0)/2, because
the division operator groups more tightly (or has higher precedence than) the
addition operator. Example A uses parentheses to control grouping.

• Operators associate. Example D illustrates grouping when the operators


have the same precedence. It is interpreted as (1 − 2) − 2, not 1 − (2 − 2),
because subtraction (like most operators) associates left (or groups left) with
operators of the same precedence.

• Integer quantities and floating-point quantities are distinct. In math-


ematics, the quantity written ‘1’ can be interpreted as either an integer or a
real number, and the expression 1/2 always means the same as 0.5. In Java (as
in most programming languages), a number written without a decimal point
(an integral quantity) is of a different type from one written with a decimal
point (a floating-point quantity), and the rules of arithmetic differ markedly.
Division of two integers throws away the fractional part of the answer to yield
an integer, whereas division of floating-point numbers behaves more like regu-
lar mathematics. Thus 1/2 yields 0, while 1.0/2.0 yields 0.5. When the two
types are mixed, Java first converts the integer quantities to floating point.

• Floating-point arithmetic approximates real arithmetic. If you work


out the mathematical value you’d normally expect from example B, you’ll
see it differs slightly from the one printed, which appears to be off by about
3.7×10−16 . Floating-point arithmetic is a compromise between computational
speed and mathematical truth. The results of each operation are computed,
correctly rounded, to a certain number of binary digits (in this case, 52).

• Arithmetic has limited range. Example G illustrates that when an integer


value becomes too large, the result “wraps around” to the smallest number.
There are special values (which print as Infinity and -Infinity to represent
numbers that are too large in floating point, which are also used when non-zero
floating-point numbers are divided by 0 (Example F).

• Arithmetic nonsense has predictable effects. Example H shows that a


floating-point operation with an undefined value (there’s no sensible definition
one can give to 0.0/0.0) yields a strange special value called NaN (for “Not A
Number”). The analogous integer operation causes an error (what Java calls
an exception), since for various reasons, there is no available integer to use as
NaN.

1.3.3 Comparisons and Logical Operations


Comparison operators and logical operators produce the two boolean values true
and false:
class Compare {
public static void main (String[] args) {
1.3. SIMPLE VALUES AND EXPRESSIONS 15

// A. All print true


System.out.println (true);
System.out.println (3 < 4);
System.out.println (3 <= 4); System.out.println (3 <= 3);
System.out.println (4 > 3);
System.out.println (4 >= 3); System.out.println (3 >= 3);
System.out.println (4 != 3); System.out.println (3 == 3);
// B. All print false
System.out.println (false);
System.out.println (3 < 3); System.out.println (3 != 3);
// C. All print true
System.out.println (3 < 4 && 4 < 5);
System.out.println (3 > 4 || 4 < 5);
System.out.println (! (3 < 4 && 4 < 3));
// D. All print true
System.out.println (3 < 4 || 1/0 == 0);
System.out.println (! (3 > 4 && 1/0 == 0));
}
}

Again, this is all pretty easy to figure out, once you see the transliterations Java
uses for common notations:

≤ =⇒ <= ≥ =⇒ >=
= =⇒ == 6= =⇒ !=
and =⇒ && or =⇒ ||
not =⇒ !

All of the operators demonstrated have precedences below those of arithmetic


operators, with the logical operators having the lowest precedences, except that
logical not (!) has a precedence equal to that of the negation operator (-3). If
that strikes you as potentially confusing, welcome to the club. Java has a large
collection of operators at 15 different levels of precedence, which quickly become
difficult to remember. As a stylistic matter, therefore, feel free to use parentheses
even when operator-precedence rules make them redundant, if that makes your
program clearer.
Example D illustrates that && and || are “short-circuit” operators. Even though
the second operand in both these cases would cause an exception, no such thing
happens because the || only evaluates its right operand if needed. Upon evaluating
its left operand, and finding it true, it skips evaluation of the right operand, while
the && doesn’t bother to evaluate its right operand if the left evaluates to false. This
is an important property of these two operators; the first operand acts as a kind of
guard on the second. All the other arithmetic and comparison operators, as well as
method calls, always evaluate all their operands.
16 CHAPTER 1. JAVA OVERVIEW

1.3.4 Strings
In programming-language jargon, a string is a sequence of characters. We write
strings in double quotes, using a backslash where needed to indicate special char-
acters, including double quotes and backslashes:

System.out.println ("Simple string.");


System.out.println (""); // An empty string
System.out.println ("Say \"Hello.\""); // \" is double quote
System.out.println ("Name:\tJohn"); // \t is tab
System.out.println ("\\FOO\\BAR");
System.out.println ("One thing\nThe other thing");

These statements print (on Unix systems):

Simple string.

Say "Hello."
Name: John
\FOO\BAR
One thing
The other thing

The newline character (notated \n) denotes the end-of-line on Unix systems. This
is not, unfortunately, universal, which is why I’ve used println rather than \n to
put things on separate lines (println “does the right thing” at the end of a line for
whatever system you use).
Characters, the components of strings, have their own literals, which are enclosed
in single quotes, with the same back-slashing notation:

’A’ ’\t’ ’\’’ ’"’ ’\n’

The + operator works on strings, but in that case means “concatenate”, as in

System.out.println ("The value of" +


" 17+25 is " + (17+25) + ".");

which prints

The value of 17+25 is 42.

You might well protest at this point that (17+25) yields an integer, not a string.
This is correct; conveniently, though, the + operator is smart enough that when one
of its operands is a string, and the other isn’t, it converts the other operand to a
string. In fact, underneath the hood, the println method ultimately prints strings,
and the variations that work on other types first perform this same conversion.
There are quite a few other operations on strings, of which some of the more
important are these:
1.3. SIMPLE VALUES AND EXPRESSIONS 17

("19-character string").length () =⇒ 19 length of string


("abcd").charAt (3) =⇒ ’d’ get a character (num-
ber from 0)
("abcd").equals ("abcd") =⇒ true compare contents
("Hello, world!").substring (7, 12) =⇒ "world" substring between
start and end posi-
tions
("Hello, world!").substring (7) =⇒ "world!" substring starting at
given position
The .equals method here is interesting. You might think that == would work, but
for reasons we’ll see later, that is not a reliable way to compare strings.

1.3.5 Static Methods: Abstracting Computation


Method (function) definition is the most basic abstraction mechanism in a typical
programming language. It enables you to “define a new verb” for later use in your
program, making it unnecessary to write, remember, or even know the details of
how to perform some action.
In Java, there are static methods (also called class methods) and non-static (or
instance) methods. We’ll look at instance methods later. Static methods correspond
to plain, ordinary functions, subprograms, or procedures in other programming
languages (such as C, Pascal, Fortran, Scheme, or Basic). We’ve already seen
examples of static method definition (of the main method).
The basic syntax is relatively easy:

A static Tr N (T1 N1 , T2 N2 , ...) {


B
}

where

• Tr , T1 , etc., denote types of values. Tr is the type of value returned (produced,


yielded) by the method, and the other Ti are the formal-parameter types, the
types of values that may be passed to the method. In Java, unlike dynamically
typed languages such as Scheme or the scripting languages Python and Perl,
one must be specific about the types of most quantities. You can indicate that
a method does stuff (printing, for example), but does not return a value, by
using the special “type” void for Tr .

• A is one of the keywords public, private, protected, or it is simply missing


(the default). It indicates the access of the method—what other parts of the
program may call it. The public modifier, as you might guess, means that the
method may be called from anywhere. The private modifier restricts access
to the same class. (See §1.14)

• N is the name by which the method is known. A method definition always


occurs inside a class definition. The full name of a static method N defined in
18 CHAPTER 1. JAVA OVERVIEW

a class C is C.N (dot means “that is defined in”). However, the simple name
N works within the same class.

• N1 , etc., are the formal parameters. These are names by which the body of
the method (B) can refer to the values passed to it.

• { B } is the body of the method. B is a sequence of statements that perform


whatever computation the method is supposed to perform (B may be empty
if the method does nothing).

• The header of the method definition—everything except the body—defines


its signature, which consists of its name, return type, and formal-parameter
types.

So far, the only statements we’ve seen are method calls (to println). We’ll
see more later, but there’s one particularly important ones for methods that return
values: the statement

return E;

means “end this call to the method, causing it to yield the value E (an expression).”
Here are two examples:

/** The square of X. */


public static double square (double x) {
return x*x;
}

/** The distance between points (X0, Y0) and (X1, Y1). */
public static double dist (double x0, double y0, double x1, double y1) {
return Math.sqrt (square (x1 - x0) + square (y1 - y0));
// NOTE: Math.sqrt is a standard square-root function */
}

These two examples also illustrate some documentation conventions that I’ll be
using throughout. Comments beginning with ‘/**’ are, by convention, called docu-
mentation comments. They are to be used before definitions of things to describe
what those things do or are for. In the case of methods, I refer to the parameter
names by writing them in upper case (the idea being that this is a way to set them
off from the rest of the text of the comment in a way that does not depend on
fancy fonts, colors, or the like). At least one tool (called javadoc) recognizes these
comments and can process them into on-line documentation.

1.4 Conditional Execution


To do anything very interesting, programs eventually have to make decisions—to
perform different calculations depending on the data. There are several constructs
to represent this in Java. Here, we’ll consider the simplest.
1.4. CONDITIONAL EXECUTION 19

1.4.1 If statements
An if-statement has one of the forms
if (condition) then-part
// or
if (condition) then-part else else-part
(Normally, though, we lay these statements out on separate lines, as you’ll see).
The condition is a boolean expression. If it evaluates to true, the program executes
the then-part (a statement), and otherwise the else-part, which simply defaults to
the empty statement if absent.
We’ll often need to have then-part or else-part contain more than one statement.
The trick used for this purpose (and for other constructs that have a “statement”
part that needs to be several statements) is to use a kind of statement called a block.
A block consists of any number of statements (including zero) enclosed in curly
braces ({ }). Unlike other statements you’ve seen, it does not end in a semicolon.
For example:
if (3 > 4) {
System.out.println ("3 > 4.");
System.out.println ("Looks like we’re in trouble.");
} else
System.out.println ("OK");

1.4.2 Conditional Expressions


The expression C ? Et : Ef yields either the value of Et or Ef , depending on
whether C evaluates to true or false. That is, ‘?’ means roughly “then” and ‘:’
means “otherwise”, with an invisible “if” in front. This peculiar-looking ternary
operator is not commonly used in C, C++, or Java, perhaps because it, well, looks
peculiar. It is only your author’s desire for balance that prompts its inclusion here.
Here are some examples:
System.out.println (3 < 4 ? "Less" : "More"); // Prints Less
System.out.println (4 < 3 ? "Less" : "More"); // Prints More
// The next two mean the same, and print 3.1
System.out.println (1 < 0 ? 1.1 : 1 > 2 ? 2.1 : 3.1);
System.out.println (1 < 0 ? 1.1 : (1 > 2 ? 2.1 : 3.1));
The expressions after ‘?’ and ‘:’ must be the same type of thing; 3<4 ? 1 : "Hello"
is erroneous.

1.4.3 Case analysis and the Switch Statement


From time to time, you’ll find yourself in a situation where you need to break some
subproblem down into several cases. This is something to avoid if possible, but not
all problems lend themselves to simple, unconditional formulae. You can always get
by with multiple uses of the if statement, like this mathy example:
20 CHAPTER 1. JAVA OVERVIEW

if (x < -10.0)
y = 0.0;
else if (x < 0.0)
y = 1.0 / f(-x);
else if (x < 10.0)
y = f(x);
else
y = Double.POSITIVE_INFINITY;
This compound if statement is so common that we customarily format as you see
above, instead of indenting the entire else part of the first if, etc., like this:
// Example of how NOT to format your program
if (x < -10.0)
y = 0.0;
else
if (x < 0.0)
y = 1.0 / f(-x);
else
if (x < 10.0)
y = f(x);
else
y = Double.POSITIVE_INFINITY;
Sometimes, you’ll encounter programs where first, there are lots of cases, and
second, each test is of the form
if (E = some integral constant)
where E is the same each time. For this purpose, there is a special construct,
introduced with the keyword switch. For example, consider this fragment:
if (action == PICK_UP)
acquireObject ();
else if (action == DROP)
releaseObject ();
else if (action == ENTER || action == EXIT)
changeRooms (action);
else if (action == QUIT) {
cleanUp ();
return;
} else if (action == CLIMB)
...
else
ERROR ();
Here, action is some integral variable (this might include character constants as
well, but not strings), and the upper-case names are all defined in a class somewhere
as symbolic constants standing for integers. The old-fashioned way to do this is
1.5. ARRAYS I: THE COMMAND LINE 21

static final int // ’final’ means ’constant’


QUIT = 0,
PICK_UP = 1,
DROP = 2,
ENTER = 3,
EXIT = 4,
CLIMB = 5,
etc.
As a matter of style, whenever you represent some set of possible values with ar-
bitrary integers like this, always introduce meaningful symbols like these—avoid
sprinkling your program with “mystery constants.” Recent versions of Java, how-
ever, have introduced enumerated types for this purpose. We’ll get to them in §5.6.
An arguably clearer way to write the if statement above is with switch, as
follows:
switch (action) {
case PICK_UP:
acquireObject ();
break;
case DROP:
releaseObject ();
break;
case ENTER: case EXIT:
changeRooms (action);
break;
case QUIT:
cleanUp ();
return;
case CLIMB:
...
default:
ERROR ();
}
Here, the break statements mean “leave this switch statement.”

1.5 Arrays I: The Command Line


Before finally turning to an example, we’ll need one other little piece of syntax to
allow simple communication from the outside world to our program. I said earlier
that the main program looks like this:
public static void main (String[] args) ...
This notation means that the formal parameter, args, is an array of strings1 .
For our immediate purposes, this means that it references a sequence of string
1
The name args is arbitrary, and you are free to choose another.
22 CHAPTER 1. JAVA OVERVIEW

values, called args[0], args[1], etc., up to args[args.length - 1]. That is,


args.length is the number of strings in args. When you start your program with
java MainClassName foo bar baz
the method main is called with "foo" as args[0], "bar" as args[1], and "baz" as
args[2].
You have to be careful to remember that the arguments to main are strings.
The following main program won’t work:
class Remainder {
public static void main (String[] operands) {
System.out.println (operands[0] % operands[1]);
}
}
You might think that you could run this with
java Remainder 1003 12
and have it print 7. However, until told otherwise, the Java system will not assume
that a string is to be treated as a number just because all its characters happen to
be digits. The operation of converting a string of characters into a number requires
specific action in Java:
class Remainder {
public static void main (String[] operands) {
System.out.println (Integer.parseInt (operands[0])
% Integer.parseInt (operands[1]));
}
}
That is, the Integer.parseInt method converts a string of decimal digits to an in-
teger. (There’s a similar method Double.parseDouble for floating-point numbers).

1.6 Example: Finding Primes


You’ve now seen a great deal of the expression language of Java, enough in fact to
write quite elaborate programs in the functional style. Let’s start with a simple
program to find prime numbers. A prime number is an integer larger than 1 whose
only positive divisors are itself and 12 . Suppose that we want a program that, when
given a number, will print all primes less than or equal to that number, perhaps in
groups of 10 like this:
You type: java primes 101
It types: 2 3 5 7 11 13 17 19 23 29
31 37 41 43 47 53 59 61 67 71
73 79 83 89 97 101
2
Depending on whom you read, there can be negative primes as well, but for us, this would be
an unnecessary complication, so we stick to positive primes.
1.6. EXAMPLE: FINDING PRIMES 23

1.6.1 Starting from the top


There are many ways to attack a simple problem like this. We may proceed top-
down, starting with a sort of overall outline or skeleton, which we subsequently fill
in, or bottom-up, building pieces we know we’ll need and assembling them into a
whole. Finally, we might use a little of both, as we’ll do here. For example, the
description above suggests the following program, with comments in place of stuff
we haven’t written yet:

class primes {
/** Print all primes up to ARGS[0] (interpreted as an
* integer), 10 to a line. */
public static void main (String[] args) {
printPrimes (Integer.parseInt (args[0]));
}

/** Print all primes up to and including LIMIT, 10 to


* a line. */
private static void printPrimes (int limit) {
// do the work
}
}

This is a simple example of the classic “put off until tomorrow,” top-down school of
programming, in which we simplify our task in stages by assuming the existence of
methods that do well-defined pieces of it (writing down their definitions, not includ-
ing their bodies, but including comments that will remind us what they’re supposed
to do). Then we handle each incomplete piece (sometimes called an obligation) by
the same process until there are no more incomplete pieces

1.6.2 Starting from the bottom


Our problem involves prime numbers, so it might well occur to you that it would
be useful to have a method that tests to see if a number is prime. Let’s proceed,
bottom-up now, to define one, hoping to tie it in later to program we’ve started
building from the top.

/** True iff X is a prime number. */


private static boolean isPrime (int x) {
return /*( X is prime )*/;
}

I’ve introduced a piece of pseudo-Java here to help in developing our program: the
notation

/*( description of a value )*/


24 CHAPTER 1. JAVA OVERVIEW

is intended to denote an obligation to produce some expression (as yet undeter-


mined) that yields a value fitting the given description. The description “X is prime”
is a true/false sentence, so in this example, isPrime yields true iff X is prime3 :
One general technique is to work backward from possible answers to the condi-
tions under which those answers work. For example, we know immediately that a
number is not prime—that we should return false—if it is ≤ 1, so we can replace
the dummy comment as follows:

if (x <= 1)
return false;
else
return /*( True iff X is prime, given that X>1 )*/;

I’ll call this the method of guarded commands: the “guards” here are the conditions
in the if statements, and the “commands” are the statements that get executed
when a condition is true.
For larger numbers, the obvious brute-force approach is to try dividing x by all
positive numbers ≥ 2 and < x. If there are none, then x must be prime, and if any
of them divides x, then x must be composite (non-prime). Let’s put this task off
until tomorrow, giving us our finished isPrime method:

private static boolean isPrime (int x) {


if (x <= 1)
return false;
else
return ! isDivisible (x, 2);
}
/** True iff X is divisible by any positive number >=K and < X,
* given K > 1. */
private static boolean isDivisible (int x, int k) {
/*{ return true iff x is divisible by some integer j, k ≤ j <
x; }*/
}
Here, I am using another piece of pseudo-Java: the comment

/*{ description of an action }*/

is intended to denote an obligation to produce one or more statements that perform


the described action.
By the way, we saw conditional expressions in §1.4. They allow an alternative
implementation of isPrime:

private static boolean isPrime (int x) {


return (x <= 1) ? false : ! isDivisible (x, 2);
}
3
The notation iff used here and elsewhere is mathematician’s shorthand for “if and only if.”
1.6. EXAMPLE: FINDING PRIMES 25

To tackle this new obligation, we can again use guarded commands. For one
thing, we know that isDivisble should return false, according to its comment, if
k ≥ x, since in that case, there aren’t any numbers ≥ k and < x:

if (k >= x)
return false;
else
/*{ return true iff x is divisible by some integer j,
where k ≤ j < x, assuming that k<x; }*/

Now, if we assume that k < x, then (always following the documentation comment)
we know that one case where we should return true is where k divides x:

if (k >= x)
return false;
else if (x % k == 0)
return true;
else
/*{ return true iff x is divisible by some integer j, k ≤ j <
x,
assuming k<x, and x is not divisible by k; }*/

Here, I’ve used the remainder operator to test for divisibility.


Well, if k itself does not divide x, then for x to be divisible by some number ≥ k
and < x, x must be divisible by a number ≥ k + 1 and < x. How do we test for
that? By a curious coincidence, we just happen to have a method, isDivisible,
whose comment says that if given two parameters, x and k, it returns “True iff x is
divisible by any positive number ≥ k and < x, given k > 1.” So our final answer is

/** True iff X is divisible by any positive number >=K and < X,
* given K > 1. */
private static boolean isDivisible (int x, int k) {
if (k >= x)
return false;
else if (x % k == 0)
return true;
else
return isDivisible (x, k+1);
}

Now you might object that there’s something circular about this development:
to finish the definition of isDivisible, we used isDivisible. But in fact, the
reasoning used is impeccable: assuming that isDivisible does what its comment
says, the body we’ve developed can only return a correct result. The only hole
through which an error could crawl is the question of whether isDivisble ever gets
around to returning a result at all, or instead keeps calling itself, forever putting off
until tomorrow the production of a result.
26 CHAPTER 1. JAVA OVERVIEW

However, you can easily convince yourself there is no problem here. Each time
isDivisible gets called, it is called on a problem that is “smaller” in some sense.
Specifically, the difference x − k gets strictly smaller with each call, and (because
of the guard k >= x) must stop getting smaller once x − k ≤ 0. (Formally, we use
the term variant for a quantity like x − k, which shrinks (or grows) with every call
but cannot pass some fixed, finite limit.) We have established that isDivisible is
not circular, but is a proper recursive definition.

1.6.3 Meeting in the middle


We are left with one final obligation, the printPrimes procedure:

/** Print all primes up to and including LIMIT, 10 to a line. */


private static void printPrimes (int limit) {
/*{ do the work }*/
}

Let’s make the reasonable assumption that we’ll be printing prime numbers one at a
time by looking at each number up to the limit, and figuring out whether to print it.
What do we need to know at any given time in order to figure out what to do next?
First, clearly, we need to know how far we’ve gotten so far—what the next number
to be considered is. Second, we need to know what the limit is, so as to know when
to stop. Finally, we need to know how many primes we’ve already printed, so that
we can tell whether to start a new line. This all suggests the following refinement:

private static void printPrimes (int limit) {


printPrimes (2, limit, 0);
System.out.println ();
}

/** Print all primes from L to U, inclusive, 10 to a line, given


* that there are initially M primes printed on the current
* line. */
private static void printPrimes (int L, int U, int M) {
...
}
This illustrates a small point I hadn’t previously mentioned: it’s perfectly legal to
have several methods with the same name, as long as the number and types of the
arguments distinguish which you intend to call. We say that the name printPrimes
here is overloaded.
To implement this new method, we once again employ guarded commands. We
can easily distinguish four situations:

A. L > U , in which case there’s nothing to do;

B. L ≤ U and L is not prime, in which case we consider the next possible prime;
1.6. EXAMPLE: FINDING PRIMES 27

C. L ≤ U and L is prime and M is less than 10, in which case we print L and go
on to the next prime); and

D. L ≤ U and L is prime and M is divisible by 10, which is like the previous


case, but first we go to the next line of output and adjust M ).

A completely straightforward transliteration of all this is:

if (L > U) // (A)
;
if (L <= U && ! isPrime (L)) // (B)
printPrimes (L+1, U, M);
if (L <= U && isPrime (L) && M != 10) { // (C)
System.out.print (L + " ");
printPrimes (L+1, U, M+1);
}
if (L <= U && isPrime (L) && M == 10) { // (D)
System.out.println ();
System.out.print (L + " ");
printPrimes (L+1, U, 1);
}

Well, this is a little wordy, isn’t it? First of all, the conditions in the if statements
are mutually exclusive, so we can write this sequence more economically as:

if (L > U) // (A)
;
else if (! isPrime (L)) // (B)
printPrimes (L+1, U, M);
else if (M != 10) { // (C)
System.out.print (L + " ");
printPrimes (L+1, U, M+1);
} else { // (D)
System.out.println ();
System.out.print (L + " ");
printPrimes (L+1, U, 1);
}

Step (A) looks kind of odd. We often write things like this as

if (L > U)
return;

to make it clearer that we’re done at this point, or we can factor the condition like
this:

if (L <= U) {
28 CHAPTER 1. JAVA OVERVIEW

if (! isPrime (L)) // (B)


printPrimes (L+1, U, M);
else if (M != 10) { // (C)
System.out.print (L + " ");
printPrimes (L+1, U, M+1);
} else { // (D)
System.out.println ();
System.out.print (L + " ");
printPrimes (L+1, U, 1);
}
}

I use the term “factor” here in a sort of arithmetical sense. Just as we can rewrite
ab + ac + ad as a(b + c + d), so also we can “factor out” the implicit !(L <= U) from
all the other conditions and just drop the L > U case.
Finally, recognizing the M keeps track of the number of primes already printed
on the current line and doing a little more factoring, we get this:

if (L <= U) {
if (! isPrime (L)) // (B)
printPrimes (L+1, U, M);
else {
if (M == 10) {
System.out.println ();
M = 0;
}
System.out.print (L + " ");
printPrimes (L+1, U, M+1);
}
}

1.7 Example: Pig Latin


We’d like to write a program (never mind why) that translates into “Pig Latin.”
There are numerous dialects of Pig Latin; we’ll use the simple rule that one trans-
lates into Pig Latin by moving any initial consonants to the end of the word, in
their original order, and then appending “ay.” So,
You type: java pig all gaul is divided into three parts
It types: allay aulgay isay ividedday intoay eethray artspay
We’ll simplify our life further by agreeing that ‘y’ is a consonant.

1.7.1 Vowels
This time, let’s start from the bottom. Presumably, we’ll need to know whether a
letter is a consonant. Here’s a brute-force way:
1.7. EXAMPLE: PIG LATIN 29

static boolean isVowel (char x) {


return x == ’a’ || x == ’e’ || x == ’i’ || x == ’o’ || x == ’u’;
}

(This method has default access; I haven’t labeled it specifically private or public.
Most of the time, in fact, this is fine, although it is often good discipline (that is,
leads to cleaner programs) to keep things as private as possible.)

Aside: Tedious programs. When you find yourself writing a particularly te-
dious expression, it’s often a hint to look around for some shortcut (you will prob-
ably spend longer looking for the shortcut than you would grinding through the
tedium, but you are likely to learn something that you can use to relieve later
tedium). For example, if you browse through the detailed documentation for the
String type (see, for example, §9.2), you’ll find the useful function indexOf, which
returns the first point in a string where a given character appears, or −1 if it doesn’t
appear at all. Then the return statement above is simply

return ("aeiou").indexOf (x) >= 0;

1.7.2 Translation
Now let’s turn to the problem of actually re-arranging a string. We’ve already seen
all the parts: substring will extract a piece of a string, and ‘+’ will concatenate
strings. So, if we just knew how many consonants there were at the beginning of a
word, w, the translation would just be

w.substring (k) + w.substring (0, k) + "ay"

where k is the number of consonants at the beginning of w. This expression works


for any value of k between 0 and the length of w, inclusive. But which value to
choose? Again, we put that off until tomorrow:

/** Translation of W (a single word) into Pig Latin. */


static String toPig (String w) {
return w.substring (consonants (w)) + w.substring (0, consonants (w)) + "ay";
}

/** The number of consonants at the beginning of W (a single word). */


static int consonants (String w) {
/*{ return the number of consonants at start of W }*/;
}

1.7.3 Counting Consonants


Assume now that tomorrow has arrived, let’s consider how to implement consonants,
again using a guarded command approach. Look for easy (or “base”) cases. Clearly,
we return 0 if w is empty:
30 CHAPTER 1. JAVA OVERVIEW

if (w.length () == 0)
return 0;
else
/*{ return the number of consonants at start of W,
assuming W is not empty }*/;
Likewise, in the remaining case, we should return 0 if w starts with a vowel:
if (w.length () == 0)
return 0;
else if (isVowel (w.charAt (0)))
return 0;
else
/*{ return the number of consonants at start of W,
assuming W starts with a consonant }*/;

Finally, a word that starts with a consonant clearly has one more consonant at the
beginning than the “tail” of that word (the word with its first letter removed):
if (w.length () == 0)
return 0;
else if (isVowel (w.charAt (0)))
return 0;
else
return 1 + consonants (w.substring (1));
and there’s nothing left to do. Optionally, we can condense things a bit, if desired:
if (w.length () == 0 || isVowel (w.charAt (0)))
return 0;
else
return 1 + consonants (w.substring (1));
Again, this program exemplifies a typical feature of the functional programming
style: we’ve assembled a method from a collection of facts about the problem:
• An empty string has no consonants at the beginning.

• A string that starts with a vowel has no consonants at the beginning.

• A string that isn’t empty and doesn’t start with a vowel has one more conso-
nant at the beginning than its tail does.
We could actually have written these independently and in any order and with
redundant guards; for example:
if (w.length () > 0 && !isVowel (w.charAt (0)))
return 1 + consonants (w.substring (1));
else if (w.length () > 0 && isVowel (w.charAt (0)))
return 0;
1.7. EXAMPLE: PIG LATIN 31

else if (w.length () == 0)
return 0;
// Should never get here.
(Java compilers, being none too bright, will complain that we might not execute a
return, but we know the cases are exhaustive.) However, we usually take advantage
of the cases we’ve already eliminated at each step to shorten the tests.

Cutting expenses. As it happens, the substring method in Java is considerably


more expensive than charAt. So we might consider ways to use the latter exclusively.
For example,
/** The number of consonants at the beginning of W (a single word). */
static int consonants (String w) {
return consonants (w, 0);
}

/** The number of consonants at the beginning of the substring of W


* that starts at position K. */
static int consonants (String w, int k) {
/*{ return the number of consonants immediately at and
after position k start of w }*/;
}
For the body of this second consonants method, we can use the the same facts as
before, expressed slightly differently:
if (w.length () <= k || isVowel (w.charAt (k)))
return 0;
else
return 1 + consonants (w, k+1);
This new consonants method is a generalization of the original; it can count conso-
nants anywhere in a word, not just at the front. As a result, the resulting function
is arguably smaller and cleaner than our first version. Generalization often has
this effect (and just as often makes things more complex than they have to be—
programming will always require judgment).

1.7.4 To the top


Finally, we want to apply toPig to each of the command-line arguments and print
the results. With what you’ve seen so far, an approach rather like the last version
of consonants seems reasonable:
class pig {
public static void main (String[] words) {
translate (words, 0);
System.out.println ();
32 CHAPTER 1. JAVA OVERVIEW

/** Print the translations of SENT[K], SENT[K+1], ..., all on one line */
static void translate (String[] sent, int k) {
...
}
In this case, translate doesn’t have to do anything if k is already off the end of
the array sent (for “sentence”). Otherwise, it has to print the translation of word
#k, followed by the translations of the following words. So,
if (k < sent.length) {
System.out.print (toPig (sent[k]) + " ");
translate (sent, k+1);
}
which completes the program.

1.8 Variables and Assignment


Method signatures and documentation comments are abstractions of actions. When
you write translate in the main program of §1.7, you should be thinking of “trans-
lation into Pig Latin,” and not the details of this procedure, because any method
that correctly translates a word into Pig Latin would serve the main program, not
just the one you’ve happened to write. Likewise, the formal parameters of methods
are abstractions of values. For example, k in the translate method of the last sec-
tion refers to “the index of the first word to translate,” rather than any particular
value.
Formal parameters are a particular kind of variable. Although in some ways
similar to mathematical variables, they aren’t quite the same thing: whereas in
mathematics, a variable denotes values, in computer languages they denote con-
tainers of values. The difference is that computer languages provide an assignment
operation, which in Java is written = (a choice inherited from Fortran, and requiring
the use of == for equality). The expression
x = 43
has 43 as its value, but also has the side effect of placing the value 43 in the
container x. Until this value is replaced by another assignment, any use of x yields
the value 43. An expression such as
x = x + 2;
first finds the value (contents) of x, adds 2, and then places the result back in x.
This particular sort of statement is so common that there is a shorthand4 :
4
You’ll find that most C, C++, and Java programmers also use another shorthand, x++ or ++x,
to increment x by one. You won’t see me use it, since I consider it a superfluous and ugly language
misfeature.
1.8. VARIABLES AND ASSIGNMENT 33

x += 2
as well as -=, *=, etc.
This last example demonstrates something confusing about variables: depending
on where it is used, x can either mean “the container named x” or “the value
contained in the container named x”. It has the first meaning in what are called
left-hand side contexts (like the left-hand side of an assignment operator) and the
second in right-hand side or value contexts.
You can introduce new variables as temporary quantities in a method by using
a local-variable declaration, with one of the following forms:
Type variable-name;
Type variable-name = initial-value;
For example,
int x;
String[] y;
double pi = 3.1415926535897932383;
double pi2 = pi * pi;
A declaration with initialization is just like a declaration of a variable followed by
an assignment. With either of these forms, you can save some typing by re-using
the Type part:
int x, y;
int a = 1, b = 2, c;
Be careful with this power to abbreviate; compactness does not necessarily lead to
readability.
If you’re used to typical scripting languages (like Perl or Python), or to Lisp
dialects (such as Scheme), you may find it odd to have to say what type of value
a variable contains. However, this requirement is common to most “production”
languages these days. The original purpose of such static typing was to make it
easier for compilers to produce fast programs. Although some authors praise the
“radical” and “liberating” alternative of having no restrictive variable types (dy-
namic typing), experience suggests that static typing provides both useful internal
consistency checking and documentation that is of increasing value as programs
start to become large.
With the program features we’ve seen so far, local variables and the assignment
statement are theoretically unnecessary. When we look at iterative statements in
the next section, you’ll see places where local variables and assignment become
necessary. Still, they can provide shorthand to avoid repeating expressions, such as
in this rewrite of a previous example
static String toPig (String w) {
int numCon = consonants (w);
return w.substring (numCon) + w.substring (0, numCon) + "ay";
}
34 CHAPTER 1. JAVA OVERVIEW

or this example, involving an if statement:


if (x % k == 0)
System.out.println (x + " is divisible by " + k);
Version 1:
else
System.out.println (x + " is not divisible by " + k);

String sense;
if (x % k == 0)
sense = " ";
Version 2:
else
sense = " not ";
System.out.println (x + " is" + sense + "divisible by " + k);
They may also be used for breaking up huge, unreadable expressions into bite-sized
pieces:
Version 1: tanh = u / (1.0 + u*u / (3.0 + u*u / (5.0 + u*u / 7.0)));

double u2 = u*u, tanh;


tanh = 7.0;
tanh = 5.0 + u2/tanh;
Version 2:
tanh = 3.0 + u2/tanh;
tanh = 1.0 + u2/tanh;
tanh = u / tanh;
This example also shows another use of a variable (u2) to represent a repeated
expression.

1.9 Repetition
In the Scheme language, a tail recursive method (one in which the recursive call is
the last operation in the method, like printPrimes in §1.6.3) is always implemented
in such a way that the recursive calls can go on indefinitely (to any depth)—in
Scheme, printPrimes would consume the same amount of computer memory for
all values of its arguments. The typical imperative “production” languages in use
today (including Java) do not put this requirement on their compilers, so that it
is possible for the original Java version of printPrimes to fail for large values of
limit. To a large extent, this difference is historical. Defining a function in the early
algebraic languages (from which Java, C, and C++ descend) was a much less casual
occurrence than in current practice and functions tended to be larger. Programmers
relied on other methods to get repetitive execution. That tendency has survived,
although the culture has changed so that programmers are more willing to introduce
function definitions.
As a result, most commonly used languages include constructs for expressing
repetition (or iteration). These come in two flavors: those where the (maximum)
1.9. REPETITION 35

number of repetitions is explicit (definite iteration) and those in which repetition


terminates when some general condition is met and the number of repetitions is not
directly expressed (indefinite iteration).

1.9.1 Indefinite iteration


Consider the problem of computing the gcd (greatest common divisor) of two non-
negative integers—the largest integer that divides both. Recursively, this is easy
using the method of guarded commands. First, we notice that if one of the numbers
is 0, then (since every positive integer divides 0), the other number must be the
gcd:

/** The greatest common divisor of A, and B, where A,B >= 0 */


static int gcd (int a, int b)
{
if (b == 0)
return a;
else
return /*( the gcd of a and b, given that b != 0 )*/;
}

Next, we use the fact that if a = r mod b for the remainder 0 ≤ r < b, then the gcd
of b and r is the same as the gcd of a and b:

/** The greatest common divisor of A, and B, where A,B >= 0 */


static int gcd (int a, int b)
{
if (b == 0)
return a;
else
return gcd (b, a % b);
}

[Why does this terminate? What is the variant here?]


Were you to do this on a small slate (with limited space), you might end up
re-using the same space for each new set of values for a and b. You would then be
treating a and b as local variables and you would think of the process as something
like “keep repeating this calculation, changing a and b until b = 0.” In Java, we
might write this:

static int gcd (int a, int b) {


while (b != 0) {
int b1 = a % b;
a = b; b = b1;
} // Now b == 0
return a;
}
36 CHAPTER 1. JAVA OVERVIEW

This last program’s relationship to the preceding recursive version might be a little
clearer if we re-write the former like this:
static int gcd (int a, int b)
{
if (b != 0)
return gcd (b, a % b);

return a;
}
A statement of the form
while (condition) statement
means “if condition evaluates to false, do nothing (“exit the loop”); otherwise exe-
cute statement (called the loop body) and then repeat the entire process.” Another
way to say the same thing is that the while loop is equivalent to
if (condition) {
statement
while (condition) statement
}
This is a recursive definition, with the inner while loop functioning as the recursive
“call.”
The while loop tests whether to terminate before each iteration. It is sometimes
desirable to test after each iteration, so that the loop body is always executed at
least once. For example, in a program that communicates with its users using a
simple text-based interface, you’ll often want to prompt for a response, read the
response, and repeat the process until the response is legal. For this purpose, there
is a do-while loop:
String response;
do {
System.out.print ("Proceed? [y/n] ");
response = readWord ();
} while (! (response.equals ("y") || response.equals ("n")));
(Assume that readWord reads the next whitespace-delimited word typed as input.)
This loop corresponds to the following recursive function:
static String getResponse () {
System.out.print ("Proceed? [y/n] ");
String response = readWord ();
if (response.equals ("y") || response.equals ("n"))
return response;
else
return getResponse ();
}
1.9. REPETITION 37

Many loops fall into neither of these categories. Instead, one discovers whether
to stop only in the middle of a computation. For this purpose, Java has a general-
purpose exiting construct, break, which in its simplest form ends execution of
the enclosing loop. For example, suppose that we want to prompt for and read a
sequence of words from some input source and print their Pig Latin translations,
one per line, until we get to a single period. We could write

String word;
System.out.print ("> ");
word = readWord ();
while (! word.equals (".")) {
System.out.println (word + " => " + toPig (word));
System.out.print ("> ");
word = readWord ();
}

but the repetition of the statements for prompting and reading is a little annoying.
With break, we can use a “loop and a half,” like this:

while (true) {
System.out.print ("> ");
word = readWord ();
if (word.equals ("."))
break;
System.out.println (word + " => " + toPig (word));
}

The “while (true)” statement loops indefinitely, since its condition is, of course,
never false. It is only stopped by the break statement in the middle of the loop
body.

Question: What do these two loops do?

while (false) { do {
System.out.println ("Hello!"); System.out.println ("Hello!")
} } while (false);

1.9.2 Definite Iteration


Consider the computation of N !, the factorial function, which for non-negative
integers is defined by the recurrence

0! = 1
(N + 1)! = (N + 1) · N !
38 CHAPTER 1. JAVA OVERVIEW

or to write it out explicitly5 ,


Y
N! = 1 · 2 · · · N = k.
1≤k≤N

The recurrence suggests a recursive definition6 :


/** N!, for N >= 0. */
static long factorial (long N) {
if (N <= 0)
return 1;
else
return N * factorial (N-1);
}
I’ve chosen to use type long because the factorial function grows quickly, and long
is an integer type that accommodates values up to 263 − 1 (slightly less than 1019 ).
Now this last function is not tail-recursive; it multiplies by N after the recursive
call. A simple trick makes it tail recursive—we compute a running product as an
extra parameter:
static long factorial (long N) {
return factorial (N, 1);
}

/** N! * P, assuming N >= 0. */


static long factorial (long N, long p) {
if (N <= 0)
return p;
else return factorial (N-1, p*N);
}
This function is now amenable to being converted to a loop directly:
static long factorial (long N0) {
long p, N;
N = N0; p = 1;
while (N > 0) {
p *= N; // Means p = p*N
N -= 1; // Means N = N-1
}
return p;
}
5
Q P
The symbol means “product of” just as means “sum of.” When N is 0, so that you have
an empty product, mathematical convention makes the value of that product 1, the multiplicative
identity. By the same token, an empty sum is 0 by convention, the additive identity.
6
This function yields 1 if given a negative argument. Since negative arguments are illegal (says
the comment), the function may yield any result—or even fail to terminate—and still conform to
the “letter of the specification.” Therefore, substituting ≤ for = in the test is perfectly correct.
1.9. REPETITION 39

The call factorial(N,1) corresponds to initializing p to 1. This is a typical example


of a reduction loop used to perform a certain binary operation on a sequence of
values. The variable p serves as the accumulator.
This loop fits a very common pattern: one variable (here, N) is first initialized,
and then incremented or decremented each time through a loop until it reaches
some limit. The loop therefore has a predictable maximum number of iterations
each time it is started. Numerous programming languages (FORTRAN, Algol,
Pascal, and Ada, to name just a few) have special definite iteration constructs for
just such combinations of actions. The Ada version, for example is
p := 1;
for N in reverse 1 .. N0 loop
p := p*N;
end loop;
Here, N is a loop control variable, which is modified only by the loop statement and
may not be assigned to.
Instead of having a restricted definite iteration like other languages, Java (as in
C and C++) has a more general form, in which we explicitly write the initialization,
bounds test, and increment in one statement:
long p, N;
p = 1;
for (N = N0; N > 0; N -= 1)
p *= N;
return p;
This for statement is little more than a compact shorthand for a while loop with
some initial stuff at the beginning. In general,
{ S0 ;
while (C) {
for (S0 ; C; S1 )
⇐⇒ B
B
S1
} }
If you take this equivalence literally, you’ll see that it’s also legal to write
long p;
p = 1;
for (long N = N0; N > 0; N -= 1)
p *= N;
declaring the loop-control variable in the loop itself.
In this case, since multiplication is commutative, we can also write
long p;
p = 1;
for (long N = 1; N <= N0; N += 1)
p *= N;
40 CHAPTER 1. JAVA OVERVIEW

and get the same effect. For whatever reason, incrementing loops like this tend to
be more common than decrementing loops.
The three parts of a for statement all have defaults: the test is true if omitted,
and the other two parts default to the null statement, which does nothing. Thus,
you will find that many programmers write an infinite loop (while (true). . . ) as
for (;;) ...

1.9.3 Example: Iterative Prime-Finding


Let’s look at what happens when we replace the recursive methods in §1.6 with
iterative constructs. First, let’s start with the original prime-testing methods from
that section, re-arranged slightly to make the conversion clear:
private static boolean isPrime (int x) {
if (x <= 1)
return false;
else
return ! isDivisible (x, 2);
}
private static boolean isDivisible (int x, int k) {
if (k < x) {
if (x % k == 0)
return true;
else
return isDivisible (x, k+1);
}
return false;
}
Using essentially the same techniques we used for factorial, we get the following
iterative version for isDivisible:
private static boolean isDivisible (int x, int k) {
while (k < x) {
if (x % k == 0)
return true;
k += 1;
}
return false;
}
which we may also code as a for loop with a null initialization clause:
for (; k < x; k += 1)
if (x % k == 0)
return true;
return false;
1.9. REPETITION 41

Now we can actually get rid of the isDivisible method altogether by integrating
it into isPrime:

private static boolean isPrime (int x) {


if (x <= 1)
return false;
for (int k = 2; k < x; k += 1)
if (x % k == 0)
return false;
return true;
}
Since isPrime evaluates ! isDivisible(x, 2), we had to be careful also to reverse
the sense of some of the return values.
Similar manipulations allow us also to convert printPrimes:

/** Print all primes up to and including LIMIT, 10 to a line. */


private static void printPrimes (int limit) {
int n;
n = 0;
for (int L = 2; L <= U; L += 1) {
if (isPrime (L)) {
if (n != 0 && n % 10 == 0)
System.out.println ();
System.out.print (L + " ");
n += 1;
}
}
System.out.println ();
}

(The full syntax of for actually allows us to make this even shorter by replacing the
first three lines of the body with

for (int L = 2, n = 0; L <= U; L += 1) {

but I am not sure that this is any clearer.)

1.9.4 Example: Counting


The consonant-counting method in the Pig Latin translator (§1.7.3) looked like this:

/** The number of consonants at the beginning of W (a single word). */


static int consonants (String w) {
return consonants (w, 0);
}

static int consonants (String w, int k) {


42 CHAPTER 1. JAVA OVERVIEW

if (w.length () <= k || isVowel (w.charAt (k)))


return 0;
else
return 1 + consonants (w, k+1);
}

This looks like a reduction loop, as introduced in §1.9.2, except that we stop pre-
maturely at the first vowel. Indeed, we can use the same structure:

static int consonants (String w) {


int n;
n = 0;
for (int k = 0; k < w.length () && ! isVowel (w.charAt (k)); k += 1)
n += 1;
return n;
}

1.10 Arrays II: Creation


You saw arrays in §1.5, where they were used as the argument to the main program.
Array types are the most basic type used to hold sequences of items. If T is any
type (so far, we’ve seen int, long, char, double, boolean, and String), then
‘T []’ denotes the type “array of T .” This definition is completely recursive, so that
‘T [][]’ is “array of array of T .”
The array types are examples of what are called reference types in Java. This
means that a declaration such as

int[] A; // (1)

tells us that at any given time, A contains either a reference (or pointer ) to an array
of ints, or it contains something called the null pointer, which points at nothing
(not even at an array containing 0 ints). For example, A declared above initially
contains a null pointer, and after

A = new int[] { 3, 2, 1 }; // (2)

it contains a pointer to an array containing 3 ints: A[0]==3, A[1]==2, A[2]==1.


You should keep pictures like this in your mind:

After (1): A:
After (2): A: 3 2 1
As illustrated in statement (2) above, one creates a new array for A to point
to with the new operator. More commonly, you’ll simply want to create an array
of a given size first, and fill in its contents later. So you’ll often see statements or
declarations like these:
1.10. ARRAYS II: CREATION 43

A = new int[100];
int[] B = new int[A.length];

which make A and B point at 100-element arrays, initially containing all 0’s.
The syntax in (2) is convenient when using arrays to contain constant tables
of values. For this purpose, Java (following C) allows a slightly condensed syntax
when (and only when) you combine array declaration with creation. The following
declaration, for example, is equivalent to (2):

int[] A = { 3, 2, 1 };

1.10.1 Example: Linear Interpolation


Interpolation is a procedure for approximating the value of a function at some point
where its value is unknown from its (known) values at surrounding, known points. If
the function is reasonably well-behaved (that is, continuous, and with a sufficiently
small second derivative), one can linearly interpolate y = f (x), given yi = f (xi ) and
yi+1 = f (xi+1 ), with xi ≤ x ≤ xi+1 and xi 6= xi+1 as

x − xi
y ≈ yi + (yi+1 − yi ) · (1.1)
xi+1 − xi

We’d typically have an ascending sequence of xi and would choose the two that
bracketed our desired x.
Suppose we’d like to write a program to carry out linear interpolation. Actu-
ally, with such a common, useful, and well-defined procedure as interpolation, we’d
probably be best advised to cast it as a general-purpose method, rather than a main
program. This method would take as its arguments an ordered array of xi values,
an array of corresponding yi (that is f (xi )) values, and a value x. The output would
be our approximation to f (x):

public class Interpolate {

/** Given XI in strictly ascending order, YI with


* 0 < XI.length = YI.length, and X with
* XI[0] <= X <= XI[XI.length-1], a linear approximation
* to a function whose value at each XI[i] is YI[i]. */

public static double eval (double x, double[] xi, double[] yi)


{
For some i such that x >= xi[i] and x <= xi[i+1],
return
yi[i] + (yi[i+1] - yi[i]) * ((x - xi[i]) / (xi[i+1] - xi[i]));
}
}
44 CHAPTER 1. JAVA OVERVIEW

You should be able to see that the return expression is just a transcription of
formula (1.1).
To find i, an obvious approach is to work our way along xi until we find an
adjacent pair of values that bracket x. We can use a for loop, like this:

for (int i = 0; ; i += 1)
if (xi[i] <= x && x <= xi[i+1])
return · · ·;

The return statement has the effect of exiting the loop as well as returning a value.
Since the documentation on this method requires that there be some i satisfying
the if statement, we know that the function must eventually execute the return, if
it is called properly.
This raises a more general, and very important, engineering issue: what to do
when a caller violates the “contract” established by a documentation comment. In
this case, Java will catch such violations indirectly. If there is no value of i that
works properly, or if the length of yi is shorter than that of xi, a call to this method
will eventually cause an exception when the program tries to perform an array
indexing operation with an index that’s “off the end” of the array. We’ll talk about
these more in §1.15. For now it suffices to say that causing (in Java terminology,
throwing) an exception halts the program with a somewhat informative message.

1.10.2 Example: The Sieve of Eratosthenes


We’ve considered one way to find all primes by using a function that determines
whether any particular integer is prime. There are ways to do compute primes “by
the batch,” one of the simplest of which is the sieve of Eratosthenes. The idea
behind this algorithm is to find primes one at time, and for each prime found, to
immediately eliminate all multiples of the prime from any further consideration.
Conceptually, we start with a sequence of integers, like this:

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

Starting at the left, we find the next empty box. Since it is marked ‘2’, we cross off
every second box, starting from 22 = 4, giving

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

The process now repeats. The next empty box is marked ‘3’, so we cross off each
third box, starting from 32 = 9, giving

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
1.10. ARRAYS II: CREATION 45

Now cross off every fifth box starting from 52 = 25, giving

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

No further work is needed (since 72 is off the end of our sequence), and the boxes
that remain empty correspond to primes.
Why does this work? Basically, it is set up in such a way that we cross off every
number that is divisible by some smaller prime. Since the primes are not divisible
by smaller primes, they are never crossed off. We can start crossing starting off at
the square because we know that if a prime p divides a composite number q < p2 ,
then q will already have been crossed off. This is because q/p is a factor of q and
q/p < p if q < p2 . So we crossed off q either when we processed q/p (if it is prime)
or when we processed one of its (smaller) prime factors.
Java has no direct notion of “boxes that can be crossed off,” so we must find a
way to represent these with the constructs we do have. A convenient possibility is
to use an array of boolean values, with, say false meaning “not crossed off yet”
(possibly prime) and true meaning “crossed off” (definitely composite). Here is
one possible implementation:

/** Returns an array, p, of size N+1 such that p[k] is true iff
* k is a prime. */
public static boolean[] primes (int n)
{
boolean[] sieve = new boolean[n+1];
// All entries are initially false.
sieve[0] = sieve[1] = false;

for (int k = 2; k*k <= n; k += 1) {


/* If k is prime (has not been crossed off), then */
if (! sieve[k]) {
/* Cross of every k’th number, starting from k*k */
for (int j = k*k; j <= n; j += k)
sieve[j] = true;
}
}

return sieve;
}

To use this function in printPrimes (page 41):

private static void printPrimes (int limit) {


boolean[] isPrime = primes (limit);
int n;
n = 0;
46 CHAPTER 1. JAVA OVERVIEW

for (int L = 2; L <= U; L += 1) {


if (isPrime[L]) {
if (n != 0 && n % 10 == 0)
System.out.println ();
System.out.print (L + " ");
n += 1;
}
}
}

1.10.3 Multi-dimensional Arrays


As the illustrations suggest, an array is naturally thought of as a one-dimensional
sequence of things. Suppose, though, that we want to represent some sort of two-
dimensional table of values—something like a matrix in linear algebra. One pos-
sibility is to make creative use of a one-dimensional array. For example, represent
the matrix
 
1 3 5 7
 
A =  2 5 8 11 
3 7 11 15

with the array

int[] A = { 1, 3, 5, 7, 2, 5, 8, 11, 3, 7, 11, 15 };

The problem is one of inconvenience for the programmer. Instead of typical math-
ematical notation such as Ai,j for the element at row i and column j, one is forced
to write A[i * 4 + j] instead (assuming rows and columns numbered from 0).
Therefore, programming languages devoted to scientific computation (where you do
this sort of thing a lot) usually have some notation specifically for multi-dimensional
arrays as well.
In Java, though, we can simply rely on the fact that arrays can be arrays of any
type of value, including arrays. So, our 3 × 4 matrix, above, may be represented as
an array of 3 4-element integer arrays:

int[][] A;
A = new int[][] { new int [] { 1, 3, 5, 7 },
new int [] { 2, 5, 8, 11 },
new int [] { 3, 7, 11, 15 } };

or, since this is very tedious to write, we can put everything into the declaration of
A, in which case we are allowed a little abbreviation:

int[][] A = { { 1, 3, 5, 7 }, { 2, 5, 8, 11 }, { 3, 7, 11, 15 } };
1.10. ARRAYS II: CREATION 47

Diagrammatically,

A:

1 3 5 7
2 5 8 11
3 7 11 15
th
Now A[i] gives us the entire i row and A[i][j] gives us Aij .
As for one-dimensional arrays, we also have the option of creating a “blank”
array, and later filling it in, as in this program to create a Hilbert matrix, which is
 
1 1/2 1/3 1/4 · · ·

 1/2 1/3 1/4 1/5 · · · 

 
 1/3 1/4 1/5 1/6 · · · 
 

 1/4 1/5 1/6 1/7 · · · 

.. .. .. ..
. . . .
public static double[][] Hilbert (int N) {
double[][] result = new double[N][N];
for (int i = 0; i < N; i += 1)
for (int j = 0; j < N; j += 1)
result[i][j] = 1.0 / (i + j + 1);
return result;
}
Although nice rectangular arrays such as these are the most common, the rows
are all quite independent of each other, and nothing keeps us from creating more
irregular structures, such as this version of Pascal’s triangle (in which each square
contains either 1 or the sum of the two squares above it):

1
P :
1 1
1 2 1
1 3 3 1
1 4 6 4 1
Here’s a possible program for this purpose:

public static int[][] Pascal (int N) {


// Create array of N initially null rows.
int[][] result = new int[N][];
for (int i = 0; i < N; i += 1) {
// Set row #i to a row of i+1 0’s.
48 CHAPTER 1. JAVA OVERVIEW

result[i] = new int[i+1];


// The ends of the row are 1.
result[i][0] = result[i][i] = 1;
for (int j = 1; j < i; j += 1)
result[i][j] = result[i-1][j-1] + result[i-1][j];
}
return result;
}

1.11 Introduction to Objects


In §1.10, I mentioned that array types are examples of reference types, types in which
the values are pointers to things (objects) that themselves can contain variables. The
type String is another example. A simple variable of a reference type conceptually
looks like one of the pictures below:

Var1:
42
Var2:
Var3:
The variable Var1 doesn’t point at anything; it contains a null pointer, appropriately
denoted null in Java. The variables Var2 and Var3 both contain pointers to the
same object.
This particular object contains two variables, one an integer, and one a (null)
pointer. You’ve already seen how to get at these variables (instance variables) in
the case of an array: for an array pointed to by A, they are referred to A.length
and A[i] for non-negative i < A.length (the latter are usually called the elements
of A). Arrays, however, are a special case. Let’s look at some more typical objects.

1.11.1 Simple Object Type Definition and Creation


So far, we’ve used class declarations simply to contain static methods. They actually
have another use: each class definition introduces a new type of object. For example,
let’s start with this simple declaration:

/** A point in 2-dimensional Euclidean space */


class Point {
double x, y;
other definitions
}

This tells us that Point is a type of object that contains two instance variables. A
variable declaration such as
1.11. INTRODUCTION TO OBJECTS 49

Point A, B;
tells us that A and B can contain pointers to Point objects. Initially, however, A
and B contain null pointers. The expression new Point() has as its value a new
(i.e., never-before-seen) pointer to a Point object, so that after
A = new Point ();
B = new Point ();
A and B do point to Point objects. The instance variables are now available as A.x
and A.y, so that after
A.x = 16.0; A.y = 1.2;
B.x = A.x / 2.0; B.y = A.y / 2.0;
we have

A:
x: 16.0
B:
y: 1.2

x: 8.0
y: 0.6
It’s probably not too early to emphasize that A and B contain pointers, not
Point objects. To see why this distinction matters, consider the result of
B = A;
B.x = 42.0; B.y = 19.0;
System.out.println ("A.x = " + A.x + ", A.y = " + A.y);
Here’s what gets printed:
A.x = 42.0, A.y = 19.0
despite the fact that we never explicitly assigned to A.x or A.y. Here’s the final
situation pictorially:

A:
x: 42.0
B:
y: 19.0

x: 8.0
y: 0.6
As you can see, the object originally pointed to by B has not been changed
(despite the assignment B = A), only B (the pointer variable) has changed so that
it now contains the same contents (arrow) as does A. The values of A and B are
pointers, not objects.
50 CHAPTER 1. JAVA OVERVIEW

1.11.2 Instance Methods


The centrality of classes in the syntax of Java reflects an underlying philosophy of
program construction, object-based programming, characterized by having programs
organized by types of object. That is, the actual executable code is collected into
methods that are themselves grouped by class (object type). From the programmer’s
point of view, a type of object is characterized by the operations that may be
performed on it. We’ve seen one kind of operation: selection of fields (like x and y
above) using ‘.’ syntax. More generally, we’d like to be able to introduce arbitrarily
complex operations; for this purpose we use methods.
So far, we’ve looked only at static methods, which correspond to ordinary sub-
programs such as are found in all programming languages. Like other object-based
languages, Java provides an additional kind of method—an instance method—that
is intended to be used on objects of a class. For example, suppose that we’d like to
know how far a particular Point is from the origin. We might first try expanding
the class as follows:

class Point {
double x, y;

/** Distance from P to the origin. */


static double dist (Point p) {
return Math.sqrt (p.x * p.x + p.y * p.y);
}
}

And now, given a point Q, we write Point.dist(Q) to get its length. However,
most Java programmers would write dist differently:

/** Distance of THIS from the origin. */


double dist () {
return Math.sqrt (this.x * this.x + this.y * this.y);
}
Since we don’t say static, this version of dist is an instance method. To use it on
Q, we write Q.dist().
The change is largely “syntactic sugar.” In effect, an instance method, f , that
is defined in a class named C

• Has an implicit first parameter that is not listed in the parameter list. The
formal type of the parameter is C and its name is this;

• Is called using the syntax E.f (· · ·), where E evaluates to a (non-null) C. E


becomes the value of this, the implicit first parameter.

That is, the instance-method version of dist corresponds roughly to a static method
declared:

static double dist (Point this) { ... }


Other documents randomly have
different content
CHAPTER XXXIV
SPIDERS AND SCORPIONS

Most people think that spiders are insects. But this is a very great
mistake, for they are just about as unlike insects as they can
possibly be.
Insects, for example, always have distinct heads. But spiders
never do, for their heads are so sunk and lost in their chests that
you cannot possibly tell where the one leaves off and the other
begins. So that spiders have their bodies divided into two parts only
instead of into three, as is always the case in the insects.
Then insects always have six legs; spiders always have eight.
Insects have wings; spiders have none. Insects have feelers; spiders
have none. Insects nearly always have a great many eyes, which are
six-sided; spiders never have more than eight eyes, which are round.
And while insects may have biting jaws, or sucking jaws, or a trunk,
or a beak, spiders always have poison-fangs, which no insect ever
possesses.
So you see that as far as the outside of their bodies is concerned,
spiders are very different indeed from insects. And the differences
inside the body are just as great. Insects have no hearts, the only
blood-vessel in their bodies being one long tube which runs along
the back; but spiders have quite a big heart, and a good many
arteries as well. Insects have no lungs, but breathe by means of
slender tubes which run to every part of the body; but spiders have
quite big lungs, in which the blood is purified just as it is in our own.
Insects have no brains, but only bunches of nerves in different parts
of their bodies; but spiders have quite big brains. And besides this,
while all insects which spin silk produce it through their mouths,
spiders always do so by means of organs at the very end of the
body. So that inside, as well as outside, there is hardly any respect
in which spiders and insects really resemble one another.
The silk-organs of a spider are very wonderful indeed.
Remember, in the first place, that the silk, as long as it remains in
the body of the spider, is a liquid—a kind of thick gum, which is
produced and stored up in six long narrow bags, or glands. Then if
you look at the end of a spider's body through a good strong
magnifying-glass—or, better still, through a microscope—you will see
several little projections, which we call spinnerets. Now each of
these spinnerets is covered with hundreds of tinier projections still,
every one of which has an extremely small hole in the middle. And
all these holes communicate, by means of very slender tubes, with
one of the silk-glands.
So what a spider does when it wants to spin its line is to squeeze
a little drop of silk into one of the spinnerets. It then just touches
the object to which the line is to be fastened, and draws its body
away. And as it does so a delicate thread comes out from every one
of the projections on the spinneret; and all these threads unite
together into one stout cord. That is why a spider's thread is so
strong. It really consists of several hundred separate threads all
firmly fastened together. And if the spider wants to spin a stronger
line still, it can unite all the threads coming from several spinnerets
into one, so as to make a very stout cord indeed.
Spiders use this silk for all sorts of different purposes. In the first
place, they use it for snaring insects.

The Garden-Spider
Let us take for an example, the web of the common garden-
spider. It is to be seen in every garden, resting in the middle of its
web; and you may always recognize it by the white cross upon its
back. But I don't suppose that you have ever seen it spinning its net.
For it always does so very early in the morning, generally beginning
before sunrise, so that it may be quite ready for use as soon as the
insects begin to fly.
First of all, the spider makes a kind of outer framework of very
strong silken cords, and fastens it firmly in position by stout guy-
ropes of the same material. Next, she carries a thread right across
the middle and fixes it down on either side. Then, starting from the
center, she carries thread after thread to the margin, carefully
testing the strength of each by giving it two or three smart pulls,
and fastening it firmly down. When she has finished this part of her
task, the web looks like a badly shaped wheel.
The next thing that the spider does is to spin a little silken
platform in the middle of her web to sit upon. And as soon as she
has done this she begins to spin the spiral thread. Beginning from
the center, she goes round and round and round, fastening the
thread down every time that it crosses one of the straight cords—the
spokes, as it were, of the wheel—until at last the web is finished.
Then she goes to the little platform in the middle, and there
remains, upside down, waiting for an insect to blunder into her net.
By and by, perhaps, a bluebottle fly does so. Then she shakes the
web violently for a few moments, so as to entangle it more
thoroughly, rushes down upon it, seizes it, and plunges her fangs
into its body. But if she catches a wasp or a bee she nearly always
cuts it carefully out, drops it to the ground, and then patches up the
hole in her web. For she knows perfectly well that wasps and bees
can sting!
Would you like to know why it is that flies stick to the web as
soon as they touch it? The microscope shows us. All the way along,
the spiral thread is set with very tiny drops of liquid gum. So tiny are
these drops indeed, that there are between eighty and ninety
thousand of them in a large web! And would you like to know why it
is that the spider does not stick to the web as the flies do? Well, the
fact is that only the spiral thread is set with these little gummy
drops, and that as the spider runs about over her web she is most
careful to place her feet only on the straight threads, and never on
the spiral line. Other spiders, however, snare their prey in quite a
different way.

The Marmignatto
This small spider, found on our western plains, is remarkable for
feeding on large insects, such as grasshoppers and field-crickets,
which it catches in an ingenious manner. It stretches a few silken
threads across a narrow path way, quite close to the ground, along
which these insects are likely to pass, and lies in wait just opposite
until a grasshopper or a cricket approaches. When it comes to the
threads the insect is sure to get at least one of its feet entangled.
Then it stops, and tries to shake itself free. The only result of its
struggles, of course, is that its other feet become entangled too; and
while it is struggling the marmignatto springs upon its back, fastens
a silken thread to it, springs down again, and fastens the other end
to a grass-stem close by. Over and over again it does this, and
before very long the unfortunate insect is firmly fastened down by
hundreds of threads, and is quite unable to break free, or even to
move one of its legs. Then the spider leaps upon its back once more,
plunges its fangs into its body, and proceeds to suck its blood.

Hunting-Spiders
Perhaps you may have seen little hairy black spiders, with white
markings upon the upper part of their bodies, running about in an
odd jerky way on sunny fences and walls. These are called hunting-
spiders, because they hunt their prey instead of snaring it. You may
see them gradually creeping up to a fly, so slowly that they hardly
seem to move, and then suddenly leaping upon it when they are
about two inches away. Then spider and fly, locked in one another's
embrace, go falling toward the ground together. But they never
reach it, for wherever a hunting-spider goes it always trails a rope of
silk behind it, and fastens it down at intervals. So when it springs
from the fence it is brought up at once by its own thread, and
swings in the air till its victim is dead. Then it just climbs up its
thread, and so gets back to the fence.

Bird-Spiders
These great spiders of the tropics hunt for prey in much the
same way. Only instead of catching flies on walls they prowl about
the branches of trees in search of small birds, springing upon them
when they are roosting at night, and killing them almost immediately
by a smart bite from their venomous fangs. These spiders, of course,
are very large. Indeed, the body of a full-grown bird-spider is as big
as a man's fist, while its great hairy legs cover nearly a square foot
of ground when they are fully spread out.

Trap-door Spiders
These famous spiders are found more or less commonly in all
warm countries. They all live in tunnels in the ground, which they
dig by means of their fangs; and as they do not want the situation of
their nest to be discovered, they carry the earth away to a little
distance as fast as they dig it up, and carefully hide it. Very often the
hole which they dig in this way is eighteen inches or two feet deep.
And at the bottom it always turns sideways for an inch or two, so
that the general shape of the burrow is very much like that of a
stocking.
This hole is always dug in the side of a bank, so that when there
is a heavy fall of rain the water may run away without flooding it.
When the burrow is finished, the spider lines it throughout with
two sheets of silk. The outer sheet, which comes next to the earth,
is rather coarse in texture, and is quite waterproof, in order to keep
the tunnel dry. The inner one is very much finer and softer, so that
the little home may be as comfortable as possible.
As soon as the lining process is completed, the spider sets to
work on the trap-door. This she makes in the cleverest manner
possible. First she measures the doorway most carefully by the aid
of her feelers. Then she spins a thin silken pad of exactly the same
size and shape. This is sticky on the top, like the spiral thread of the
web of the garden-spider: and she sprinkles it all over with very
small scraps of earth. Upon this she fastens another silken pad,
which she sprinkles with earth in the same way. And then comes
another and then another, and so on till the door is sufficiently thick.
Finally, she fastens it in position by means of a hinge, which is also
made of silk; and she always places this hinge on the upper side of
the doorway, so that the door may fall down behind her by its own
weight whenever she leaves the burrow. She is rather a lazy
creature, you see, and does not want to have the trouble of shutting
the door for herself! And if she left it open, every passer-by would
find out where she had made her home.
The door always fits most wonderfully into its place, and the
spider carefully covers the top with little bits of moss and small
scraps of earth and stone, so as to make it exactly like the surface of
the ground all round it. Indeed, unless one happens to see the
spider push it open, it is almost impossible to find it.
When one of these spiders is in her burrow, she always fastens
about half a dozen silken threads to the inner side of the door,
carries them down to the bottom, and sits with one of her feet
resting upon each. No one can then try to force her door open
without her knowledge, and as soon as she feels the least pull upon
the threads she rushes up the burrow, clings to the walls with her
hind feet, seizes the door with her front ones, and pulls it downward
with all her might. And if the door is forced open in spite of her
efforts, she slips into a sort of side tunnel which she always makes
near the top of her burrow, and stays there until the danger is past.

The Raft-Spider
There are several spiders which live on or in the water. One of
these is the raft-spider, which is found in the fen districts of England.
If you should happen to meet with it you can recognize it at once,
for all round the upper part of its body is a narrow band of yellow,
and inside this is a row of small white spots.
This spider is about an inch long, and owes its name to the fact
that it actually makes a little raft on which to go out searching for
water-insects. Collecting together a quantity of little bits of leaf and
cut grass and reeds, it fastens them firmly together with silken
threads, just as shipwrecked sailors might lash planks together with
ropes in order to escape from a sinking vessel. In this way it makes
a small floating platform, perhaps a couple of inches in diameter.
When the raft is finished, the spider gets upon it, pushes off from
the shore, and allows the current to carry it along. By and by,
perhaps, it catches sight of some water-insect floating at the
surface, or of a drowning fly which has fallen into the stream. Then
it leaves its raft, runs along over the surface of the water, seizes its
victim, and carries it back to the raft to be devoured. And if it should
be alarmed, or think itself in danger, it gets under the raft and clings
to the lower surface, so that it cannot be seen from above.

The Water-Spider
More curious still is the water-spider, which actually makes its
nest under water. This spider, which is almost black in color, and has
a very hairy body and legs, is common in ponds and canals, and
spends almost the whole of its life beneath the water. Its little silken
nest is shaped like a thimble, with the mouth downward, and is
placed among weeds, to which it is firmly fastened down by guy-
ropes, also of silk. And when it is finished the spider fills it with air.
She does this in a most curious manner. Rising to the surface, she
turns upside down, pokes her long hind legs out of the water, and
crosses the tips. Then she dives again, carrying down a big bubble
of air between these hairy legs and her equally hairy body as she
does so. She next gets exactly underneath the entrance to her nest
and separates her legs. The result is, of course, that the air-bubble
floats up and occupies the upper part. Another bubble is now
brought down in the same way, and so the spider goes on, fetching
bubble after bubble, until at last her little nest is completely filled
with air. Then she gets inside it, and watches for the grubs of water-
insects to swim by.
In this wonderful nest the spider lays her eggs and brings up her
family. When the little ones have been hatched, of course, the air in
the nest very soon becomes too impure to breathe. Then the little
spiders cling tightly to the walls, while the mother gets outside and
tilts the whole nest sideways, so that all the exhausted air floats up
in one big bubble to the surface. Then she pulls the nest back into
position, hurries up to the top of the water and brings down a
bubble of air, and then another, and so on until the nest is filled with
air all over again.
If you ever catch one of these spiders, and keep it for awhile in a
jar of water with a little piece of water-weed, you may see it
spinning its wonderful nest, and filling it with air, perhaps half a
dozen times a day.

Gossamers
Before we leave the spiders altogether, we must tell you
something about the wonderful little creatures called gossamers.
These are really the young of a good many different kinds of spiders.
It often happens, of course, that several families, with perhaps five
or six hundred little ones in each, are all living quite close to one
another. The result is that there is not sufficient food for them all. So
they make up their minds to go out into the world and seek their
fortunes; and this is how they do it.
Choosing a warm, sunny morning in the early part of the
autumn, all the little spiders climb the nearest bush, and each one
makes its way to the very tip of a leaf. Then, clinging firmly to its
hold, it begins to pour out a very slender thread of silk from one of
its spinnerets. You know that on warm, sunny days the air near the
ground soon becomes heated and rises, as hot air always does; and
in rising it carries up these delicate gossamer-threads, as they are
called, with it. Still the little spiders hold on, and pour out their lines,
till at last each has several feet of thread rising straight up into the
air above it. Then suddenly they all let go, and are carried up into
the air at the ends of their own threads. So they go on, up and up
and up, till at last they meet a gentle breeze, which carries them
along with it. So, perhaps, they travel for thirty, forty, or fifty miles,
or even farther still. And when at last they make up their minds to
descend, all that they have to do is to roll up the threads which have
been supporting them, and down they come floating gently back to
earth. One good name for them is ballooning spiders.
Haven't you sometimes found on a warm autumn morning that
all the trees and bushes, and even the grass and low plants, are
quite covered with threads of silk? The next time you see such a
sight look carefully, and you will find that on every thread a little
baby spider is sitting. Then you may be quite sure that all these little
spiders set out early in the morning to seek their fortunes, and that,
borne up by their slender threads, they have traveled for many long
miles through the air.

Scorpions
These formidable creatures are closely related to the spiders.
They are found in all warm countries, with the exception of New
Zealand, and may easily be known by two facts. In the first place, in
front of the legs they have a pair of great, strong claws, which look
very much like those of a crab. And in the second place, the last five
joints of the body are narrowed into a long, slender tail, at the end
of which is a claw-like sting. When they attack an enemy, or seize a
victim, they grasp it with the claws, turn the tail over the back, and
force the sting into its body. And the poison which is introduced into
the wound is so powerful that the sting of a large scorpion is almost
as severe as the bite of an adder.
During the daytime scorpions hide away under stones and logs,
or in crevices in the ground, or perhaps under the loose bark of dead
trees. But very soon after sunset they come out from their retreats
and prowl about all night long in search of insects; and it is at such
times that they invade camps and houses, get into shoes, etc., and
persons get stung unless they are very careful.
Centipedes and Millepedes
One can easily recognize centipedes by the great number of their
feet. The name centipede, indeed, means hundred-footed. None of
these creatures, however, have exactly a hundred limbs. Some only
have fifteen pairs of legs; some have as many as one hundred and
twenty-one pairs. But whether they be many or few, the number of
pairs is always odd.
Another very curious fact about centipedes is that they have no
less than four pairs of jaws. But the fourth pair take the form of
fangs, which are very stout and strong, and very much curved, while
at their base, just inside the head, is a little bag of poison. In the
northern centipedes, which are quite small, the fangs are not large
enough, nor the poison sufficiently strong, to cause a serious
wound. But some of the tropical species, which grow to the length of
nearly a foot, are quite as venomous as the largest scorpions.
The food of these creatures consists chiefly of worms and
insects. But the larger ones will kill lizards, and even mice, and have
been known to prey upon victims actually larger than themselves.
The eggs of centipedes are laid in little clusters on the ground in
some dark, damp nook, and when they have all been deposited the
mother centipede coils herself round them, and there remains
guarding them until they hatch.
Millepedes, in some ways, are very much like centipedes; but
they only have two pairs of jaws instead of four, and they are nearly
all vegetable-feeders. The long, smooth, and slender Julus
millepedes are plentiful in every garden. And in tropical countries
they sometimes grow to a length of six inches. Even the largest,
however, are perfectly harmless, for they have no poison-fangs as
the centipedes have, and the only way in which they ever attempt to
defend themselves is by pouring out a small drop or two of a fluid
which smells rather nasty, and no doubt protects them from the
attacks of birds.
CHAPTER XXXV
CRUSTACEANS

We now come to a very important class of animals, which


includes the crabs, the lobsters, the shrimps, and the prawns. These
creatures, together with the mollusks, are often called shell-fish,
although the "shell" of a crab is not in the least like the shell of an
oyster, for example, or like that of a whelk, or a snail. It is only a
sort of crust upon the skin, made chiefly of carbonate of lime. That
is why these animals are called crustaceans; and instead of growing,
like true shells, this coat never increases in size at all.
But crabs and lobsters grow? Yes: but not as other animals do, a
little every day. They only grow, as a rule, once a year; and they get
a whole twelvemonth's growth into about two days!
When, in warm weather, the proper time approaches, they hide
away in some crevice among the rocks, where none of their enemies
are likely to find them. This is because they are going to throw off
their so-called shells; and they know that when these are gone they
will be deprived of their natural armor, and of their weapons too, and
so will be quite at the mercy even of foes much smaller than
themselves. Then a very strange thing happens. Part of their flesh
actually turns to water! Sometimes, if you happen to take up a crab
in a fish-market, and shake it, you will hear water swishing about
inside it. This is a "watery" crab, and is not good to eat; for it was
just about to change its "shell" when it was caught. A good deal of
its flesh has actually turned to water.
Now this always happens a few days before the "shell" is thrown
off; and the animal wriggles and twists about inside it, in order to
loosen the attachments which bind it to its body. It also rubs its
feelers against its legs, and its legs against one another, in order to
loosen their hard coverings in the same way. This goes on, perhaps,
for three or four days. Then, suddenly, the "shell" splits across, and
the animal, with a tremendous effort, springs right out of it, while
the "shell" closes up again, and looks just as it did before. One might
really think that there were two crabs instead of only one.
For some little time the animal now lies perfectly still. It is
exhausted by its efforts, and its muscles are so cramped that they
feel quite hard to the touch. This cramp soon passes off, however;
and then at once the animal begins to grow. It grows very fast.
Indeed, you can almost see it grow, for a whole year's increase in
size has to take place in about forty-eight hours. Then a fresh crust
is gradually formed upon the skin, and two or three days later the
animal is once more clad in a coat of mail, and is ready to leave its
retreat and face its enemies. For a whole twelvemonth after this it
grows no bigger. But at the end of that time the process is repeated,
and so on, year after year, until at last the animal reaches its full
size.

Forms of Crustaceans
The bodies of the crustacean animals are made up of a number
of rings, or segments, like those of the insects. But there are always
twenty of these rings, instead of thirteen; six forming the head,
while there are eight in the thorax and six in the hind body.
Then—again like the insects—crustaceans have feelers, or
antennæ, upon their heads. You can see these very well indeed in a
lobster or a shrimp. But instead of having one pair of these organs,
as insects have, they always possess two pairs. And it is rather
curious to find that at the base of the front pair there are two little
organs which seem to be ears, specially formed for hearing in the
water, while at the base of the second pair are two other little
organs which seem to serve as a nose, specially made for smelling in
the water.
And—once more like the insects—crustaceans have to pass
through several different forms before they reach the perfect state.
They are hatched in the first place from eggs, which the mother
animal carries about with her for some little time firmly fastened to
the hairs of the swimmerets, which we find under the hind part of
her body. You will often find a shrimp with quite a large bunch of
these eggs; and if you look at them carefully with a good strong
magnifying-glass, you will see that they are all glued down to hairs.
Inside each of these eggs an odd little creature is formed, which
is called the nauplius. Sometimes it is hatched while still in that
state, and swims about through the water. But in almost all the
higher crustaceans a change takes place before it leaves the egg,
and it appears at last in the form of a zoëa.
This is a kind of crustacean caterpillar, and a very odd little
creature it is. A great naturalist once described it as an animal "with
goggle eyes, a hawk's beak, a scorpion's tail, a rhinoceros' horn, and
a body fringed with legs, yet hardly bigger than a grain of sand!"
Certainly it does not look in the least like the crab, or lobster, or
shrimp into which it is going, by and by, to turn. And it swims in the
oddest way possible, by turning endless somersaults in the water!
These zoëas are sometimes found in immense shoals, the surface
of the sea being quite thick with them for miles. And they are useful
little creatures, for they feed on the tiny scraps of decaying matter
which are always floating about in the sea, just as tadpoles and
gnat-grubs do in ponds, thus helping to keep the water pure. But a
very great number of them are devoured by whales. For when
whalebone-whales are hungry, they swim with open mouths through
a shoal of these little creatures, and then strain them out of the
water by means of the whalebone fringe which hangs down from the
upper jaw.
After a time the zoëa throws off its skin and appears in quite a
different form. It is now called a megalopa, or big-eyed creature,
because it has very large eyes, which are usually set on foot-stalks,
and project to quite a long distance from the sides of the head. And
as the zoëa is a kind of crustacean caterpillar, so the megalopa is a
kind of crustacean chrysalis. It generally has a long, slender body,
made up of several joints. And it swims by flapping this to and fro in
the water.

Crabs
First among the crustaceans come the crabs, of which there are a
great many different kinds. They are distinguished by having the tail
tucked under the body, and firmly soldered, so to speak, to the
"shell" on either side.
You can find several kinds of these creatures by hunting among
the rocks on the sea-shore when the tide is out. There is the
common shore-crab, for example, which is green in color. It is
generally to be found hiding under masses of growing seaweed. But
sometimes you may see it prowling about in search of prey. It is
wonderfully active, and will even pounce upon the sandhoppers as
they go skipping about, just as a hunting-spider will pounce upon
flies, seldom or never missing its aim. It will catch flies, too, leaping
upon them when they settle, and shutting them up, as it were, in a
kind of cage formed by its legs. Then it pokes one claw carefully into
this cage, seizes the prisoners, pulls them to pieces, and pokes the
fragments into its mouth.
Swimming about in the pools, too, you may often find a fiddler-
crab, which is so called because its movements in the water rather
remind one of a man who is playing the violin. You will find that its
hind legs are very much flattened, and are fringed with stiff hairs, so
that they may be used as oars. In fact, the animal rows itself
through the water. Both these crabs, sad to say, are cannibals, and
are always ready to attack and devour their own kind.
Then there is the edible crab, or blue crab, which is common on
many parts of our coasts. The edible crab of Europe is somewhat
different. You are not likely to meet with the larger examples, which
live in deeper water. But even the smaller ones can give a very sharp
nip with their great claws, and you will find it as well to be very
careful in handling them. The best plan is to seize them with the
thumb and finger just behind these claws, then they are perfectly
harmless. The larger crabs, which sometimes weigh as much as
twelve pounds, are extremely powerful, and in more than one case a
man has been killed by them, having been seized by the wrist as he
was groping among the rocks, and held in a grip from which he
could not break away until he was drowned by the rising tide.
These crabs are captured by means of crab-pots, made of
basketwork, which have the entrance so formed that while the crabs
can easily enter, they cannot possibly get out again. These pots are
baited with pieces of fresh fish, and are then weighted with stones,
and lowered to the bottom of the sea among the rocks, at a depth of
from three to about twenty fathoms. They are also caught on lines
baited with meat. No hook is needed, for the crab clings to the meat
till it reaches the surface of the water, when it must be flung into the
boat or somehow captured quickly, before it has time to let go and
sink.
Some crabs live on dry land, sometimes at a distance of two or
three miles from the sea, which they only visit at intervals. Among
these are the famous calling-crabs, found in many of the warmer
parts of the world. These crabs obtain their name from the fact that
one of the great claws of the male is very much larger than the
other. So big is it, indeed, that it has to be held aloft over the body
when the animal is running, in order to prevent it from losing its
balance and toppling over. And as soon as the crab begins to move
this huge claw is jerked up and down, just as if the creature were
"calling," or beckoning, to its companions. The calling-crabs live in
burrows in the sand, which are often placed as close to one another
as those in a rabbit-warren.

Hermit-Crabs
Next we come to those small, curious creatures known as hermit-
crabs, which form a kind of connecting link between the crabs and
the lobsters, for their tails, instead of being firmly soldered down
underneath their bodies, are quite free.
But the odd thing about these animals is that their tails have no
shelly covering. The front part of the body is protected by a coat of
mail, just as it is in all the other crabs; but the hind part is quite bare
and soft. The consequence is that a hermit-crab is always very
nervous indeed about his tail. He is dreadfully afraid that one of his
many enemies may creep up behind, and bite it when he is not
looking. So he always tucks it away in an empty shell like that of a
whelk or a sea-snail, which he drags about with him wherever he
goes!
You may often find these curious crabs by hunting for them in
the pools among the rocks at low water. The crab always sits just
inside the entrance of the shell, which he closes and guards with one
of his great claws. And if you try to pull him out, you will find that
you are quite unable to do so, for he has a pair of strong pincers at
the end of his body, by which he holds the shell so firmly that you
can tear him in two without forcing him to loose his grip.
Sometimes you will find that a sea-anemone has fastened itself
to the edge of a shell in which a hermit-crab is living. This is a great
advantage to the crab; for while there are many fishes which would
be quite ready to crunch him up, shell and all, no fish will ever
meddle with a sea-anemone. So as long as the anemone remains on
his shell he is perfectly safe.
And this plan is also a great advantage to the anemone, which is
sure to get plenty of food without any trouble. For when the crab
finds the dead body of some small creature, and begins to pull it to
pieces, a quantity of small fragments is sure to float upward in the
water. And the anemone catches them with its spreading tentacles
and feeds upon them.

The Robber-Crab
One of the most extraordinary crustaceans is this, which is found
in many of the islands in the Indian Ocean. It is like the hermit-crabs
in some ways, but the tail is covered with shelly plates, just like the
rest of the body; and instead of living in shells in the sea, it lives in
deep burrows on dry land.
But the oddest thing of all with regard to this crab is its food.
What do you think it feeds upon? Cocoanuts! That seems impossible,
doesn't it? One would imagine that the crab could never get the nuts
open. But it manages in this way: First of all, it pulls away the fibers
from that end of the nut at which the three eyeholes are situated.
With one of its stout claws it then hammers away at one of these till
it breaks its way through. And finally, after allowing the milk to run
away, it pokes its hind claws, which are very slender indeed, through
the opening and picks out the white fleshy part of the nut a little
piece at a time.
It is said, too, that this crab sometimes opens a nut by poking
the smaller joint of one of its claws into the hole, and then striking it
over and over again upon a big stone.
The burrow of the robber-crab is rather a deep one, and is nearly
always situated beneath the roots of a tree. And at the end of the
burrow is a large chamber, in which the crab piles up a quantity of
cocoanut fiber to serve as a bed.

Lobsters
Of course you know the lobster very well by sight; and perhaps
you know that until it is boiled it is black, not red. But do you know
how it swims? If so, you know that it has two different ways of
swimming. When it is not in a hurry it swims slowly forward by
means of its swimmerets, of which it has five pairs under the hinder
part of its body. But if it is startled or alarmed it swims swiftly
backward by means of its tail.
If you look at a lobster's tail, you will see that it is very broad and
flat, and that on either side of it are two plates, which are quite as
flat, and, if anything, are rather broader. So, when these are spread,
the tail looks like a fan. And the animal swims by first stretching out
its body almost straight, and then doubling it suddenly with all its
force. As it does so, the tail and the tail-plates spread out, and act
very much like a broad oar. And the result is that the lobster darts
swiftly backward through the water. Shrimps and prawns swim in
exactly the same way.
Lobsters are very quarrelsome creatures, and are constantly
fighting; and it very often happens that in these battles they pull off
one another's limbs. They seem to feel very little pain, however,
from such an injury, and before very long new legs begin to grow in
place of the old ones, so that in course of time the wounded
creatures are as perfect as ever.
Sometimes lobsters will throw off their limbs when they are not
attacked at all. They do so, for example, if they are suddenly
frightened; and it is said that if a heavy gun is fired near the surface
of the water, every lobster for a long way round will shed its great
claws in alarm.
You will notice, on looking at a lobster, that one of the great
claws is a good deal smaller than the other; and sometimes people
think that this is a new claw which is growing in place of one that
has been lost, and that it has not yet reached its full size. This,
however, is a mistake, for one of the claws is always much bigger
than the other; and the reason is that they are used for different
purposes. The larger claw is intended as a weapon, and with this the
lobster fights. But the smaller one is chiefly employed as a kind of
anchor, by means of which the animal can cling to the weeds or
rocks at the bottom of the sea.
Lobsters are caught in pots made of basketwork, just as crabs
are. But they are not nearly so dainty as crabs, and do not mind
whether the bait is fresh or putrid. They are always very much
attracted, too, by any object that glitters, and many a lobster has
been lured to its death merely by one or two oyster-shells hung up
inside the pot in such a manner as to show the shining pearly
interior.

Crayfish
The crayfish is a kind of fresh-water lobster, which is found
commonly in many parts of the world, and numerously in the central
and southern parts of the United States. Most species hide all day
long under the projecting edges of big stones, or in holes in the
bank, only coming out after nightfall to search for food. The British
crayfish is said to be particularly fond of the deserted burrow of a
water-vole, and as it sits inside it always guards the entrance with its
great claws, striking fiercely at any enemy which may be bold
enough to come within reach.
One, at least, of the American kinds sinks its own burrows, in the
form of round holes in the soil of damp meadows. These holes go
down to water, which the animal cannot live long away from; and a
part of the soil dug out is piled about the mouth of the hole in a little
tower or chimney, sometimes several inches high.
In Europe crayfish are eaten and regarded as a delicacy when
properly cooked; and there is no reason why the American ones
should not be equally good, but they are rarely if ever used as food
by us. The flesh tastes like that of the lobster, but is more tender.

Shrimps and Prawns


These are really only tiny lobsters, and if you examine them
carefully you will find that their bodies are made in exactly the same
way. They swim, too, by means of their tails, and dart about so
swiftly that it is almost impossible to follow their movements. You
may often find them in numbers in the pools which are left among
the rocks by the retreating tide. But as they are almost colorless
until they are boiled, it is very difficult to see them, and they look
just like shadows darting to and fro in the water.
You can easily tell a prawn from a shrimp, for the beak which
projects in front of its head is covered with sharp points, which are
almost exactly like the teeth of a saw. It feeds upon the bodies of
the various small creatures which die by millions every day. In this
way it helps to keep the water of the sea pure. It feeds in a curious
way, tearing off tiny scraps of flesh with the little pincers at the tips
of the second pair of legs, and poking them into its mouth one after
another. The sides of these limbs are covered with hairs, so that
they form little brushes; and with these the prawn carefully cleans
its body and limbs, rubbing off every little speck of dirt which may
happen to cling to them.

Sandhoppers
You can hardly walk along a sand shore when the tide is rising
without seeing sandhoppers leaping and twisting about in
thousands. If you turn over a bunch of seaweed which has been
flung up by the waves just above high-water mark, you are almost
sure to find forty or fifty of these odd little creatures hiding under it.
In some ways they are rather like shrimps. But they differ from them
in having their eyes set on the head itself, instead of on little foot-
stalks projecting from it. And they have no carapace, or shelly shield,
covering the middle part of the body.
How do these creatures hop? By first doubling up their bodies,
and then straightening them out again with a kind of jerk. It is
exactly opposite, in fact, to the way in which shrimps and lobsters
swim.
Sandhoppers do not follow the retreating tide, but bury
themselves in the sand very soon after the waves have ceased to
break over them. Even when the surface of the sand is quite dry you
can find their burrows by stamping with your foot, when a number
of little round holes will suddenly open all round you.
These creatures have wonderfully sharp little teeth, and if you
allowed a swarm of them to rest for a little while on your
handkerchief you would most likely find that it was full of tiny holes
when you took it up. They will eat almost anything, either animal or
vegetable, and are quite as useful as the shrimps and prawns in
helping to keep the sea-water pure. But they have a great many
enemies, for sea-birds, land-birds, crabs, and all sorts of other
creatures, destroy them literally in millions.
The Fresh-water Shrimp
This shrimp is very much like the sandhopper in some ways. You
may find it in numbers in almost any small stream or rivulet. It hides
under stones, or in little crevices in the bank, darting out now and
then to seize one of the tiny creatures upon which it feeds, and then
hurrying back with it to its retreat. When it is in the water it travels
along by a series of jerks; sometimes swimming with its back
uppermost, and sometimes on one side. But if it is placed on dry
ground it is perfectly helpless, for its legs are not nearly strong
enough to carry it, and the only result of its struggles is to turn it
round and round in a screw-like manner without forcing it forward at
all.

Woodlice
These odd little creatures are really crustaceans, although they
belong to quite a different group from that about which you have
just been reading. They simply swarm in all damp places. Under
logs, in heaps of decaying leaves, and under the bark of dead trees,
they are always extremely plentiful, and you may also find them in
hundreds in cellars and outhouses. There are several different kinds,
one of which rolls itself up into a ball when it is touched or alarmed.
This is called the pill-woodlouse, or pill-armadillo. Another one is
remarkable for the fact that the mother carries her little ones about
with her in a pouch underneath her body for some little time after
they are born.

Barnacles
You would hardly think that barnacles were crustaceans, would
you? Yet they are; though certainly they are very unlike any of those
about which we have been telling. You can find them in countless
thousands upon the rocks which are left bare by the tide at low
water, and very often the hulls of ships are so covered with them
that the vessels have to be taken into dry dock and thoroughly
cleaned before they are fit to start upon a voyage.
These animals fasten themselves down to their hold by a kind of
foot-stalk, which is firmly attached by a very strong cement. The
upper part of the body becomes covered with a shell, consisting of
several pieces, or valves; and between these, six odd little limbs can
be poked out at will. These limbs are very hairy, and are always
waving about, so as to sweep into the mouth any tiny scraps of food
which may be floating in the water.
There are a great many kinds of barnacles, some of which look
very much like acorns, and grow to a considerable size. These are
known as acorn-barnacles. And there is another, shaped rather like a
piece of round tube, which burrows into the skin of whales, in which
it spends all the remainder of its life! Sometimes it bores its way
down so far that it actually reaches the blubber.
The young of these strange creatures pass through several
transformations, just like those of the lobster and the crab. First,
there is a nauplius, then a zoëa, and then a megalopa, all of which
swim freely about in the water, never fastening themselves down
until they are ready to pass into the perfect form.
LIFE ON THE SEA-BOTTOM.
1. Sticklebacks. 2. Carp. 3, 5, 6, 13, 17. Sea-
Anemones. 4. Shrimps. 7. Prawn. 8. Fiddler
Crab. 9. Starfish. 10. Sea-horses. 11.
Edible Mussels. 12. Serpula Worm. 14.
Hermit-Crab in Whelk's Shell. 15. Sea-urchins.
16. Rock Crab. 18. Polyzoan (Flustra). 19.
Corallines (Gorgonia).
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.

More than just a book-buying platform, we strive to be a bridge


connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.

Join us on a journey of knowledge exploration, passion nurturing, and


personal growth every day!

ebookbell.com

You might also like