Contents

Preface

Acknowledgments

Chapter 1: An Introduction to Java

1.1 Java as a Programming Platform

1.2 The Java “White Paper” Buzzwords

1.2.1 Simple

1.2.2 Object-Oriented

1.2.3 Distributed

1.2.4 Robust

1.2.5 Secure

1.2.6 Architecture-Neutral

1.2.7 Portable

1.2.8 Interpreted

1.2.9 High-Performance

1.2.10 Multithreaded

1.2.11 Dynamic

1.3 Java Applets and the Internet

1.4 A Short History of Java

1.5 Common Misconceptions about Java

Chapter 2: The Java Programming Environment

2.1 Installing the Java Development Kit

2.1.1 Downloading the JDK

2.1.2 Setting up the JDK

2.1.3 Installing Source Files and Documentation

2.2 Using the Command-Line Tools

2.3 Using an Integrated Development Environment

2.4 Running a Graphical Application

2.5 Building and Running Applets

Chapter 3: Fundamental Programming Structures in Java

3.1 A Simple Java Program

3.2 Comments

3.3 Data Types

3.3.1 Integer Types

3.3.2 Floating-Point Types

3.3.3 The char Type

3.3.4 Unicode and the char Type

3.3.5 The boolean Type

3.4 Variables

3.4.1 Initializing Variables

3.4.2 Constants

3.5 Operators

3.5.1 Mathematical Functions and Constants

3.5.2 Conversions between Numeric Types

3.5.3 Casts

3.5.4 Combining Assignment with Operators

3.5.5 Increment and Decrement Operators

3.5.6 Relational and boolean Operators

3.5.7 Bitwise Operators

3.5.8 Parentheses and Operator Hierarchy

3.5.9 Enumerated Types

3.6 Strings

3.6.1 Substrings

3.6.2 Concatenation

3.6.3 Strings Are Immutable

3.6.4 Testing Strings for Equality

3.6.5 Empty and Null Strings

3.6.6 Code Points and Code Units

3.6.7 The String API

3.6.8 Reading the Online API Documentation

3.6.9 Building Strings

3.7 Input and Output

3.7.1 Reading Input

3.7.2 Formatting Output

3.7.3 File Input and Output

3.8 Control Flow

3.8.1 Block Scope

3.8.2 Conditional Statements

3.8.3 Loops

3.8.4 Determinate Loops

3.8.5 Multiple Selections—The switch Statement

3.8.6 Statements That Break Control Flow

3.9 Big Numbers

3.10 Arrays

3.10.1 The “for each” Loop

3.10.2 Array Initializers and Anonymous Arrays

3.10.3 Array Copying

3.10.4 Command-Line Parameters

3.10.5 Array Sorting

3.10.6 Multidimensional Arrays

3.10.7 Ragged Arrays

Chapter 4: Objects and Classes

4.1 Introduction to Object-Oriented Programming

4.1.1 Classes

4.1.2 Objects

4.1.3 Identifying Classes

4.1.4 Relationships between Classes

4.2 Using Predefined Classes

4.2.1 Objects and Object Variables

4.2.2 The LocalDate Class of the Java Library

4.2.3 Mutator and Accessor Methods

4.3 Defining Your Own Classes

4.3.1 An Employee Class

4.3.2 Use of Multiple Source Files

4.3.3 Dissecting the Employee Class

4.3.4 First Steps with Constructors

4.3.5 Implicit and Explicit Parameters

4.3.6 Benefits of Encapsulation

4.3.7 Class-Based Access Privileges

4.3.8 Private Methods

4.3.9 Final Instance Fields

4.4 Static Fields and Methods

4.4.1 Static Fields

4.4.2 Static Constants

4.4.3 Static Methods

4.4.4 Factory Methods

4.4.5 The main Method

4.5 Method Parameters

4.6 Object Construction

4.6.1 Overloading

4.6.2 Default Field Initialization

4.6.3 The Constructor with No Arguments

4.6.4 Explicit Field Initialization

4.6.5 Parameter Names

4.6.6 Calling Another Constructor

4.6.7 Initialization Blocks

4.6.8 Object Destruction and the finalize Method

4.7 Packages

4.7.1 Class Importation

4.7.2 Static Imports

4.7.3 Addition of a Class into a Package

4.7.4 Package Scope

4.8 The Class Path

4.8.1 Setting the Class Path

4.9 Documentation Comments

4.9.1 Comment Insertion

4.9.2 Class Comments

4.9.3 Method Comments

4.9.4 Field Comments

4.9.5 General Comments

4.9.6 Package and Overview Comments

4.9.7 Comment Extraction

4.10 Class Design Hints

Chapter 5: Inheritance

5.1 Classes, Superclasses, and Subclasses

5.1.1 Defining Subclasses

5.1.2 Overriding Methods

5.1.3 Subclass Constructors

5.1.4 Inheritance Hierarchies

5.1.5 Polymorphism

5.1.6 Understanding Method Calls

5.1.7 Preventing Inheritance: Final Classes and Methods

5.1.8 Casting

5.1.9 Abstract Classes

5.1.10 Protected Access

5.2 Object: The Cosmic Superclass

5.2.1 The equals Method

5.2.2 Equality Testing and Inheritance

5.2.3 The hashCode Method

5.2.4 The toString Method

5.3 Generic Array Lists

5.3.1 Accessing Array List Elements

5.3.2 Compatibility between Typed and Raw Array Lists

5.4 Object Wrappers and Autoboxing

5.5 Methods with a Variable Number of Parameters

5.6 Enumeration Classes

5.7 Reflection

5.7.1 The Class Class

5.7.2 A Primer on Catching Exceptions

5.7.3 Using Reflection to Analyze the Capabilities of Classes

5.7.4 Using Reflection to Analyze Objects at Runtime

5.7.5 Using Reflection to Write Generic Array Code

5.7.6 Invoking Arbitrary Methods

5.8 Design Hints for Inheritance

Chapter 6: Interfaces, Lambda Expressions, and Inner Classes

6.1 Interfaces

6.1.1 The Interface Concept

6.1.2 Properties of Interfaces

6.1.3 Interfaces and Abstract Classes

6.1.4 Static Methods

6.1.5 Default Methods

6.1.6 Resolving Default Method Conflicts

6.2 Examples of Interfaces

6.2.1 Interfaces and Callbacks

6.2.2 The Comparator Interface

6.2.3 Object Cloning

6.3 Lambda Expressions

6.3.1 Why Lambdas?

6.3.2 The Syntax of Lambda Expressions

6.3.3 Functional Interfaces

6.3.4 Method References

6.3.5 Constructor References

6.3.6 Variable Scope

6.3.7 Processing Lambda Expressions

6.3.8 More about Comparators

6.4 Inner Classes

6.4.1 Use of an Inner Class to Access Object State

6.4.2 Special Syntax Rules for Inner Classes

6.4.3 Are Inner Classes Useful? Actually Necessary? Secure?

6.4.4 Local Inner Classes

6.4.5 Accessing Variables from Outer Methods

6.4.6 Anonymous Inner Classes

6.4.7 Static Inner Classes

6.5 Proxies

6.5.1 When to Use Proxies

6.5.2 Creating Proxy Objects

6.5.3 Properties of Proxy Classes

Chapter 7: Exceptions, Assertions, and Logging

7.1 Dealing with Errors

7.1.1 The Classification of Exceptions

7.1.2 Declaring Checked Exceptions

7.1.3 How to Throw an Exception

7.1.4 Creating Exception Classes

7.2 Catching Exceptions

7.2.1 Catching an Exception

7.2.2 Catching Multiple Exceptions

7.2.3 Rethrowing and Chaining Exceptions

7.2.4 The finally Clause

7.2.5 The Try-with-Resources Statement

7.2.6 Analyzing Stack Trace Elements

7.3 Tips for Using Exceptions

7.4 Using Assertions

7.4.1 The Assertion Concept

7.4.2 Assertion Enabling and Disabling

7.4.3 Using Assertions for Parameter Checking

7.4.4 Using Assertions for Documenting Assumptions

7.5 Logging

7.5.1 Basic Logging

7.5.2 Advanced Logging

7.5.3 Changing the Log Manager Configuration

7.5.4 Localization

7.5.5 Handlers

7.5.6 Filters

7.5.7 Formatters

7.5.8 A Logging Recipe

7.6 Debugging Tips

Chapter 8: Generic Programming

8.1 Why Generic Programming?

8.1.1 The Advantage of Type Parameters

8.1.2 Who Wants to Be a Generic Programmer?

8.2 Defining a Simple Generic Class

8.3 Generic Methods

8.4 Bounds for Type Variables

8.5 Generic Code and the Virtual Machine

8.5.1 Type Erasure

8.5.2 Translating Generic Expressions

8.5.3 Translating Generic Methods

8.5.4 Calling Legacy Code

8.6 Restrictions and Limitations

8.6.1 Type Parameters Cannot Be Instantiated with Primitive Types

8.6.2 Runtime Type Inquiry Only Works with Raw Types

8.6.3 You Cannot Create Arrays of Parameterized Types

8.6.4 Varargs Warnings

8.6.5 You Cannot Instantiate Type Variables

8.6.6 You Cannot Construct a Generic Array

8.6.7 Type Variables Are Not Valid in Static Contexts of Generic Classes

8.6.8 You Cannot Throw or Catch Instances of a Generic Class

8.6.9 You Can Defeat Checked Exception Checking

8.6.10 Beware of Clashes after Erasure

8.7 Inheritance Rules for Generic Types

8.8 Wildcard Types

8.8.1 The Wildcard Concept

8.8.2 Supertype Bounds for Wildcards

8.8.3 Unbounded Wildcards

8.8.4 Wildcard Capture

8.9 Reflection and Generics

8.9.1 The Generic Class Class

8.9.2 Using Class<T> Parameters for Type Matching

8.9.3 Generic Type Information in the Virtual Machine

Chapter 9: Collections

9.1 The Java Collections Framework

9.1.1 Separating Collection Interfaces and Implementation

9.1.2 The Collection Interface

9.1.3 Iterators

9.1.4 Generic Utility Methods

9.1.5 Interfaces in the Collections Framework

9.2 Concrete Collections

9.2.1 Linked Lists

9.2.2 Array Lists

9.2.3 Hash Sets

9.2.4 Tree Sets

9.2.5 Queues and Deques

9.2.6 Priority Queues

9.3 Maps

9.3.1 Basic Map Operations

9.3.2 Updating Map Entries

9.3.3 Map Views

9.3.4 Weak Hash Maps

9.3.5 Linked Hash Sets and Maps

9.3.6 Enumeration Sets and Maps

9.3.7 Identity Hash Maps

9.4 Views and Wrappers

9.4.1 Lightweight Collection Wrappers

9.4.2 Subranges

9.4.3 Unmodifiable Views

9.4.4 Synchronized Views

9.4.5 Checked Views

9.4.6 A Note on Optional Operations

9.5 Algorithms

9.5.1 Sorting and Shuffling

9.5.2 Binary Search

9.5.3 Simple Algorithms

9.5.4 Bulk Operations

9.5.5 Converting between Collections and Arrays

9.5.6 Writing Your Own Algorithms

9.6 Legacy Collections

9.6.1 The Hashtable Class

9.6.2 Enumerations

9.6.3 Property Maps

9.6.4 Stacks

9.6.5 Bit Sets

Chapter 10: Graphics Programming

10.1 Introducing Swing

10.2 Creating a Frame

10.3 Positioning a Frame

10.3.1 Frame Properties

10.3.2 Determining a Good Frame Size

10.4 Displaying Information in a Component

10.5 Working with 2D Shapes

10.6 Using Color

10.7 Using Special Fonts for Text

10.8 Displaying Images

Chapter 11: Event Handling

11.1 Basics of Event Handling

11.1.1 Example: Handling a Button Click

11.1.2 Specifying Listeners Concisely

11.1.3 Example: Changing the Look-and-Feel

11.1.4 Adapter Classes

11.2 Actions

11.3 Mouse Events

11.4 The AWT Event Hierarchy

11.4.1 Semantic and Low-Level Events

Chapter 12: User Interface Components with Swing

12.1 Swing and the Model-View-Controller Design Pattern

12.1.1 Design Patterns

12.1.2 The Model-View-Controller Pattern

12.1.3 A Model-View-Controller Analysis of Swing Buttons

12.2 Introduction to Layout Management

12.2.1 Border Layout

12.2.2 Grid Layout

12.3 Text Input

12.3.1 Text Fields

12.3.2 Labels and Labeling Components

12.3.3 Password Fields

12.3.4 Text Areas

12.3.5 Scroll Panes

12.4 Choice Components

12.4.1 Checkboxes

12.4.2 Radio Buttons

12.4.3 Borders

12.4.4 Combo Boxes

12.4.5 Sliders

12.5 Menus

12.5.1 Menu Building

12.5.2 Icons in Menu Items

12.5.3 Checkbox and Radio Button Menu Items

12.5.4 Pop-Up Menus

12.5.5 Keyboard Mnemonics and Accelerators

12.5.6 Enabling and Disabling Menu Items

12.5.7 Toolbars

12.5.8 Tooltips

12.6 Sophisticated Layout Management

12.6.1 The Grid Bag Layout

12.6.1.1 The gridx, gridy, gridwidth, and gridheight Parameters

12.6.1.2 Weight Fields

12.6.1.3 The fill and anchor Parameters

12.6.1.4 Padding

12.6.1.5 Alternative Method to Specify the gridx, gridy, gridwidth, and gridheight Parameters

12.6.1.6 A Helper Class to Tame the Grid Bag Constraints

12.6.2 Group Layout

12.6.3 Using No Layout Manager

12.6.4 Custom Layout Managers

12.6.5 Traversal Order

12.7 Dialog Boxes

12.7.1 Option Dialogs

12.7.2 Creating Dialogs

12.7.3 Data Exchange

12.7.4 File Dialogs

12.7.5 Color Choosers

12.8 Troubleshooting GUI Programs

12.8.1 Debugging Tips

12.8.2 Letting the AWT Robot Do the Work

Chapter 13: Deploying Java Applications

13.1 JAR Files

13.1.1 Creating JAR files

13.1.2 The Manifest

13.1.3 Executable JAR Files

13.1.4 Resources

13.1.5 Sealing

13.2 Storage of Application Preferences

13.2.1 Property Maps

13.2.2 The Preferences API

13.3 Service Loaders

13.4 Applets

13.4.1 A Simple Applet

13.4.2 The applet HTML Tag and Its Attributes

13.4.3 Use of Parameters to Pass Information to Applets

13.4.4 Accessing Image and Audio Files

13.4.5 The Applet Context

13.4.6 Inter-Applet Communication

13.4.7 Displaying Items in the Browser

13.4.8 The Sandbox

13.4.9 Signed Code

13.5 Java Web Start

13.5.1 Delivering a Java Web Start Application

13.5.2 The JNLP API

Chapter 14: Concurrency

14.1 What Are Threads?

14.1.1 Using Threads to Give Other Tasks a Chance

14.2 Interrupting Threads

14.3 Thread States

14.3.1 New Threads

14.3.2 Runnable Threads

14.3.3 Blocked and Waiting Threads

14.3.4 Terminated Threads

14.4 Thread Properties

14.4.1 Thread Priorities

14.4.2 Daemon Threads

14.4.3 Handlers for Uncaught Exceptions

14.5 Synchronization

14.5.1 An Example of a Race Condition

14.5.2 The Race Condition Explained

14.5.3 Lock Objects

14.5.4 Condition Objects

14.5.5 The synchronized Keyword

14.5.6 Synchronized Blocks

14.5.7 The Monitor Concept

14.5.8 Volatile Fields

14.5.9 Final Variables

14.5.10 Atomics

14.5.11 Deadlocks

14.5.12 Thread-Local Variables

14.5.13 Lock Testing and Timeouts

14.5.14 Read/Write Locks

14.5.15 Why the stop and suspend Methods Are Deprecated

14.6 Blocking Queues

14.7 Thread-Safe Collections

14.7.1 Efficient Maps, Sets, and Queues

14.7.2 Atomic Update of Map Entries

14.7.3 Bulk Operations on Concurrent Hash Maps

14.7.4 Concurrent Set Views

14.7.5 Copy on Write Arrays

14.7.6 Parallel Array Algorithms

14.7.7 Older Thread-Safe Collections

14.8 Callables and Futures

14.9 Executors

14.9.1 Thread Pools

14.9.2 Scheduled Execution

14.9.3 Controlling Groups of Tasks

14.9.4 The Fork-Join Framework

14.9.5 Completable Futures

14.10 Synchronizers

14.10.1 Semaphores

14.10.2 Countdown Latches

14.10.3 Barriers

14.10.4 Exchangers

14.10.5 Synchronous Queues

14.11 Threads and Swing

14.11.1 Running Time-Consuming Tasks

14.11.2 Using the Swing Worker

14.11.3 The Single-Thread Rule

Appendix

Index