Murachs Beginning Java With Eclipse Compress
Murachs Beginning Java With Eclipse Compress
murach’s
beginning
Java with
Eclipse
Joel Murach
Michael Urban
10 9 8 7 6 5 4 3 2
ISBN: 978-1-890774-89-9
Content
Introduction xv
Appendixes
Appendix A How to set up Windows for this book 607
Appendix B How to set up Mac OS X for this book 619
Expanded contents v
Expanded contents
Section 1 Get started right
Chapter 1 An introduction to Java programming
An overview of Java.............................................................................4
Java timeline.....................................................................................................................4
Java editions.....................................................................................................................4
How Java compares to C++ and C#.................................................................................6
Types of Java applications.................................................................8
Two types of desktop applications...................................................................................8
Two types of web applications.......................................................................................10
Mobile apps....................................................................................................................12
An introduction to Java development............................................. 14
The code for a console application.................................................................................14
How Java compiles and interprets code.........................................................................16
Introduction to IDEs for Java development....................................................................18
An introduction to Eclipse................................................................20
How to select a workspace.............................................................................................20
How to import a project into a workspace.....................................................................22
How to open a file in the code editor.............................................................................24
How to compile and run a project..................................................................................26
How to enter input for a console application.................................................................26
How to work with two or more projects........................................................................28
How to remove a project from a workspace...................................................................28
An introduction to MySQL..............................................................490
What MySQL provides................................................................................................490
Ways to interact with MySQL......................................................................................492
How to open a database connection.............................................................................494
How to enter and execute a SQL statement.................................................................494
A SQL script that creates a database............................................496
How to drop, create, and select a database...................................................................496
How to create a table and insert data............................................................................496
How to create a user and grant privileges....................................................................496
The SQL statements for data manipulation..................................498
How to select data from a table....................................................................................498
How to insert, update, and delete rows........................................................................500
Introduction
Murach’s Beginning Java is especially designed for beginning programmers
and programmers with limited experience who want to learn Java at a
professional level. Because Java is a language that’s especially difficult for
beginners, we knew we needed to do something different to make this the
best beginning book on the market. That’s why this book isn’t like any of the
competing books.
Even better, this isn’t just a beginning book. By the time you finish this
book, you’ll have all the skills that you need for moving on to Java web
programming or Android programming. You’ll also know the basics for building
desktop applications that get their data from MySQL databases.
Companion books
When you finish this book, you’ll have all of the Java skills that you need
for web or mobile programming with Java. Then, if you want to move on to web
programming, Murach’s Java Servlets and JSP will show you how to use Java
servlets and JavaServer Pages to develop professional web applications. Or, if
you want to move on to Android programming, Murach’s Android Programming
will get you started with that.
Another Murach book that you should be aware of is Murach’s Java
Programming. This book has been one of the best-selling Java books since its
first edition in 2001, but it isn’t a beginning book. As a result, it is organized
differently, moves faster, goes into greater depth, and presents some additional
subjects, particularly on GUI programming and handling data. In general,
though, you shouldn’t need this book if you have Murach’s Beginning Java.
xviii Introduction
An overview of Java................................................................4
Java timeline.....................................................................................................4
Java editions......................................................................................................4
How Java compares to C++ and C#.................................................................6
Types of Java applications.....................................................8
Two types of desktop applications....................................................................8
Two types of web applications........................................................................10
Mobile apps.....................................................................................................12
An introduction to Java development.................................14
The code for a console application.................................................................14
How Java compiles and interprets code.........................................................16
Introduction to IDEs for Java development....................................................18
An introduction to Eclipse....................................................20
How to select a workspace..............................................................................20
How to import a project into a workspace......................................................22
How to open a file in the code editor............................................................. 24
How to compile and run a project..................................................................26
How to enter input for a console application..................................................26
How to work with two or more projects.........................................................28
How to remove a project from a workspace...................................................28
Perspective............................................................................30
4 Section 1 Get started right
An overview of Java
In 1996, Sun Microsystems released a new programming language called
Java. Today, Java is owned by Oracle and is one of the most widely used
programming languages in the world.
Java timeline
Figure 1-1 starts by describing all major releases of Java starting with
version 1.0 and ending with version 1.8. Throughout Java’s history, the terms
Java Development Kit (JDK) and Software Development Kit (SDK) have been
used to describe the Java toolkit. In this book, we’ll use the term JDK since it’s
the most current and commonly used term.
In addition, different numbering schemes have been used to indicate the
version of Java. For example, Java SE 8 or Java 1.8 both refer to the eighth
major version of Java. Similarly, Java SE 7 and Java 1.7 both refer to the seventh
major version of Java. The documentation for the Java API uses the 1.x style
of numbering. As a result, you should be familiar with it. However, it’s also
common to only use a single number such as Java 6.
This book shows how to use Java 8. However, Java is backwards compatible,
so it should also work for future versions of Java. In addition, most of the skills
described in this book have been a part of Java since its earliest versions. As a
result, those skills should work with earlier versions of Java.
Java editions
This figure also describes the three most common editions of Java. To start,
there is the Standard Edition, which is known as Java SE. It’s designed for
general purpose use on desktop computers and servers, and it’s the edition that
you’ll learn how to work with in this book. For example, you can use Java SE to
create a desktop application like the one presented at the end of chapter 22.
The Enterprise Edition is known as Java EE. It’s designed to develop distrib-
uted applications that run on an intranet or the Internet. You can use Java EE to
create web applications.
The Micro Edition is known as Java ME. It’s designed to run on devices that
have limited resources such as mobile devices, TV set-top boxes, printers, smart
cards, hotel room key cards, and so on.
With some older versions of Java, Java SE was known as J2SE (Java 2
Platform, Standard Edition). Similarly, Java EE was known as J2EE (Java 2
Platform, Enterprise Edition). If you are searching for information about Java on
the Internet, you may come across these terms. However, they aren’t commonly
used anymore.
Chapter 1 An introduction to Java programming 5
Java timeline
Year Month Event
1996 January JDK 1.0 released.
1997 February JDK 1.1 released.
1998 December SDK 1.2 released.
1999 August Java 2 Platform, Standard Edition (J2SE) released.
December Java 2 Platform, Enterprise Edition (J2EE) released.
2000 May J2SE with SDK 1.3.
2002 February J2SE with SDK 1.4.
2004 September J2SE 5.0 with JDK 1.5.
2006 December Java SE 6 with JDK 1.6.
2010 April Oracle buys Sun.
2011 July Java SE 7 with JDK 1.7.
2014 March Java SE 8 with JDK 1.8.
Java editions
Platform Description
Java SE (Standard Edition) For general purpose use on desktop compu-
ters and servers. Some early versions were
called J2SE (Java 2 Platform, Standard
Edition).
Java EE (Enterprise Edition) For developing distributed applications that
run on an intranet or the Internet. Some early
versions were called J2EE (Java 2 Platform,
Enterprise Edition).
Java ME (Micro Edition) For devices with limited resources such as
mobile devices, TV set-top boxes, printers,
and smart cards.
Description
•• The Java Development Kit (JDK) includes a compiler, a runtime environment, and
other tools that you can use to develop Java applications. Some early versions were
called the Software Development Kit (SDK).
Java compared to C#
Feature Description
Syntax Java syntax is similar to C# syntax.
Platforms Like Java, compiled C# code can run on any platform that has
a runtime environment for it.
Speed Java runs faster than C# in most contexts.
Memory Like Java, C# handles most memory operations automatically.
A console application
A GUI application
Description
•• A console application uses the console to interact with the user.
•• A GUI application uses a graphical user interface to interact with the user.
An applet
A servlet
Description
•• An applet is a type of Java application that runs within a web browser.
•• In the past, it was possible to run applets in most web browsers. Today, fewer and
fewer web browsers support applets. As a result, they are effectively obsolete.
•• A servlet is a type of Java application that runs on a web server.
•• A servlet accepts requests from clients and returns responses to them. Typically, the
clients are web browsers.
Mobile apps
You can also use Java to develop mobile apps, which are applications that
run on a mobile device such as a smartphone or tablet. In particular, Java is
commonly used to write the code for apps that run on Android devices. For
example, figure 1-5 shows a mobile app that was developed with Java. This app
performs the same task as the applications presented in the previous figures.
An app works much like a traditional application. However, the user inter-
face has to be modified so that it’s appropriate for a mobile device. In this figure,
for example, the user interface has been modified to work with a touch-screen
device that has a small screen and no keyboard. As a result, the user can use the
keypad that’s displayed onscreen to enter numbers and can press the Done button
on this keypad to perform the calculation.
The Android operating system includes its own virtual machine that supports
a subset of Java, including most features of Java 6 and 7. As a result, if you use
Java to develop Android apps, you can’t use all of the features of Java, especially
the newest ones. That’s because the Android virtual machine is not a Java virtual
machine. In other words, the Android virtual machine can’t run compiled Java
code, and a Java virtual machine can’t run compiled Android code. Still, you can
use most features of Java to write code for Android apps, and it’s easy enough to
compile that code so the Android virtual machine can run it.
Chapter 1 An introduction to Java programming 13
A mobile app
Description
•• A mobile app uses a mobile device such as a smartphone or tablet to interface with
the user.
•• The Android operating system supports a subset of Java, including most features of
Java 6 and 7.
import java.text.NumberFormat;
import java.util.Scanner;
Description
•• When you develop a Java application, you typically use a code editor to work with
the source code for the application. Files that contain source code have the .java
extension.
•• The Java compiler translates Java source code into a platform-independent
format known as Java bytecodes. Files that contain Java bytecodes have the .class
extension.
•• A Java virtual machine (JVM) includes a Java interpreter that executes Java
bytecodes. Most modern implementations of the JVM have replaced the Java
interpreter with a just-in-time compiler (JIT compiler). A JIT compiler is similar to
an interpreter in some ways, but it improves performance significantly.
•• A Java runtime environment (JRE) has all of the components necessary to run
bytecodes including a JVM. Since JREs are available for most operating systems,
Java bytecodes can be run on most operating systems.
Description
•• To develop Java applications, you typically use an Integrated Development
Environment (IDE) like those listed above. All of these IDEs are either free or have
free editions.
An introduction to Eclipse
In Eclipse, a project is a folder that contains all the folders and files for an
application. The easiest way to get started with Eclipse is to import an existing
project. For example, you can import the projects for any of the applications
presented in this book after you download them from our website as described in
the appendixes.
Description
•• In Eclipse, a project contains the folders and files for a Java application.
•• When you start Eclipse, you typically select the workspace you want to use. A
workspace stores information about how to configure Eclipse including which
projects to display.
•• When Eclipse is running, you can switch to a different workspace by selecting
the FileSwitch Workspace command. This restarts Eclipse and selects the new
workspace.
•• Once you have selected a workspace, it appears in the Workspace menu. This
makes it easy to switch between workspaces.
•• After you select a workspace, Eclipse may display a Welcome page. If so, you can
click the Workbench icon to go to the workbench, which is where you work on
code.
A project that uses the Console window for input and output
Description
•• Eclipse lets you import and work with two or more projects at the same time.
Mac OS X notes
•• To enable right-clicking, you can edit the system preferences for the mouse.
•• To use the Windows keys shown in this book, you may need to hold down the
Command or Function (Fn) keys to modify those keys.
Perspective
In this chapter, you learned some background information about Java. In
addition, you learned how to use Eclipse to import, compile, and run existing
projects. With that as background, you’re ready to start learning how to write
Java code and create new projects.
Summary
•• You can use the Java Development Kit (JDK) to develop Java applications.
•• The Standard Edition (SE) of Java is called Java SE.
•• You can use Java SE to create desktop applications that run on your
computer.
•• A desktop application can use a graphical user interface (GUI) or a console
to display output and get user input. Applications that use a console to
interact with the user are known as console applications.
•• You can use the Enterprise Edition of Java, which is known as Java EE, to
create server-side applications using servlets and JavaServer Pages (JSPs).
•• The Java compiler translates source code into a platform-independent format
known as Java bytecodes.
•• A Java runtime environment (JRE) includes all of the software needed to run
bytecodes.
•• A JRE includes an implementation of a Java virtual machine (JVM).
•• A JVM includes a Java interpreter to translate the Java bytecodes into native
code that can be understood by the underlying operating system.
•• Most modern JVMs have replaced the Java interpreter with a just-in-time
compiler (JIT compiler). A JIT compiler is similar to an interpreter in some
ways, but it improves performance significantly.
•• An Integrated Development Environment (IDE) can make working with Java
easier by providing code completion, error detection, automatic compilation,
and a debugger.
•• In Eclipse, a project is a folder that contains all of the folders and files that
make up an application.
•• In Eclipse, a workspace can hold one or more projects.
•• If an application prints text to the console, Eclipse displays the text in the
Console window. Eclipse also allows you to enter input into the Console
window.
Chapter 1 An introduction to Java programming 31
Open and run the console version of the Future Value application
1. Start Eclipse. When you are prompted for a workspace, navigate to the
murach/java_eclipse folder on your hard disk and select it.
2. Import the project named ch01_FutureValueConsole into the workspace.
3. Expand the murach.fv package.
4. Open the Main.java file in the code editor and review its code to get an idea of
how this console application works.
5. Press Ctrl+F11 to run the application.
6. Click in the Console window to make it active and enter values for monthly
investment, yearly interest rate, and years when you’re prompted for them.
Then, when you’re asked if you want to continue, enter “n” to exit the appli-
cation.
Open and run the GUI version of the Future Value application
7. Import the project named ch01_FutureValueGUI into the workspace.
8. Expand the murach.fv package.
9. Open the .java files in the code editor and review their code. This should give
you an idea of what it takes to develop a simple GUI application. For now,
don’t worry if you don’t understand this code! You’ll learn how to write code
like this at the end of this book.
10. Click the Run button in the toolbar to run the application.
11. Enter values in the first three text boxes, click the Calculate button, and view
the result of the calculation. Then, click the Exit button to exit the application.
Set the main project and run the applications again
12. Select the ch01_FutureValueConsole project in the Projects window. Then,
press Ctrl+F11 to run this application.
13. Select the ch01_FutureValueGUI project in the Projects window. Then, click
the Run button to run this application.
14. Exit Eclipse.
2
How to start writing Java
code
The quickest and best way to learn Java programming is to do Java program-
ming. That’s why this chapter shows you how to start writing Java code. When
you finish this chapter, you should be able to write a simple application that
performs a calculation and prints the result of the calculation to the console.
} end of class
Description
•• A class stores Java code. Each class starts with a class declaration.
•• A package is a folder that contains one or more classes. They are useful for
organizing multiple classes. Most classes start with a package statement that identi-
fies the folder that contains the class.
•• A method is a block of code that performs a task. A class can contain one or more
methods.
•• A class can contain one main method. This method is often the starting point for an
application. You can execute this method by running the class.
•• Opening and closing braces identify the start and end of classes and methods. The
code within the braces can be referred to as a block of code.
•• The public keyword is an access modifier that allows a class or method to be used
by other code.
•• The file name for a class is the same as the class name with .java as the extension.
Description
•• A statement performs a task and ends with a semicolon.
•• You can start a statement at any point in a line and continue the statement from one
line to the next. To make your code easier to read, you should use indentation and
extra spaces to align statements and parts of statements.
•• A comment typically documents what the code does. Well-written comments can be
helpful to the programmer who writes the code and to other programmers who need
to review or maintain the code later.
•• To code a single-line comment, type // followed by the comment. You can code a
single-line comment on a line by itself or after a statement. A comment that’s coded
after a statement is sometimes called an end-of-line comment.
•• To code a block comment, type /* at the start of the block and */ at the end. You can
also code asterisks to identify the lines in the block, but that isn’t necessary.
Bye
Description
•• Although the appearance of a console may differ from one system to another, you
can always use the println and print methods of the System.out object to print data
to the console.
The code editor with the starting source code for a project
Description
•• To open a .java file in the code editor, double-click on it in the Package Explorer
window. Then, you can use normal editing techniques to work with the source
code.
•• To collapse the code for a method or comment, click the minus sign (-) to its left.
Then, a plus sign (+) appears to the left of the method or comment, and you can
click the plus sign to display the code again.
•• To save the source code for a file, use the FileSave command (Ctrl+S) or click
the Save All Files button in the toolbar.
•• To rename a file, right-click on it, select the RefactorRename command, and
enter the new name in the resulting dialog box.
•• To delete a file, you can right-click on it, select the Delete command, and confirm
the deletion in the resulting dialog box.
Figure 2-5 How to work with Java source code and files
44 Section 1 Get started right
Description
•• You can use the code completion feature to help you enter the names of classes
and objects and select from the methods and fields that are available for a class or
object.
•• The first time you use code completion, Eclipse will prompt you to enable it in the
popup.
•• To activate the code completion feature for entering a class or object name, press
Ctrl+Spacebar after entering one or more letters of the class or object name. Then,
a list of all the classes and objects that start with those letters is displayed. Or, you
can simply wait a short period of time and the code completion window will open
automatically.
•• To activate the code completion feature for a method or field of a class or object,
enter a period after a class or object name. Then, a list of all the methods and fields
for that class or object is displayed.
•• To insert an item from a code completion list, use the arrow keys to select the item
and press the Enter key. If the item requires parentheses, they’re added automati-
cally. If the item requires one or more arguments, default values are added for those
arguments and the first argument is highlighted so you can enter its value. Then,
you can press the Tab key and enter the values for any remaining arguments.
•• If you enter the opening quote for a string of text, the code completion feature
automatically adds the closing quote and places the cursor between the two quotes
so you can enter the text.
Description
•• Eclipse often detects syntax errors as you enter code into the code editor.
•• When Eclipse detects a syntax error, it displays a red error icon to the left of the
statement in error and it places a red wavy line under the statement.
•• To get more information about a syntax error, you can position the mouse pointer
over the error icon or the wavy line under the statement.
Example
double productPrice; // declaration statement
productPrice = 14.95; // assignment statement
Java keywords
boolean if interface class true
char else package volatile false
byte final switch while throws
float private case return native
void protected break throw implements
short public default try import
double static for catch synchronized
int new continue finally const
long this do transient goto
abstract super extends instanceof null
Description
•• Java provides for eight primitive data types that you can use for storing values in
memory. The two most common are the int and double data types.
•• A variable stores a value that can change as an application executes.
•• To create a variable, you can start by declaring its data type and name. Then, you
can assign a value to the variable to initialize it. It’s common to initialize integer
variables to 0 and double variables to 0.0.
•• A keyword is a word that’s reserved by the Java language such as int and double. As
a result, you can’t use a keyword as the name for a variable.
For some common variable names, programmers typically use just one or
two lowercase letters. For instance, they often use i as the name of an int variable
that’s used as a counter variable. This is acceptable in short blocks of code where
it’s easy to understand what the variable does.
When naming a variable, you can’t use a Java keyword as the name of the
variable. There are 50 keywords reserved by the Java language that are shown
in figure 2-8. To help you identify keywords in your code, most Java IDEs
display these keywords in a different color than the rest of the Java code. As you
progress through this book, you’ll learn how to use most of these keywords.
Description
•• An assignment statement assigns a value to a variable that’s already declared. This
value can be a literal value, another variable, or an expression like the arithmetic
expressions shown in the next figure.
•• If you attempt to declare a variable a second time, it causes an error.
•• Java is a case-sensitive language. As a result, make sure to use the correct case
when referring to the names of variables.
Description
•• An arithmetic expression consists of one or more operands and arithmetic
operators.
•• When an expression mixes the use of int and double variables, Java automatically
casts the int types to double types. To retain the decimal places, the variable that
receives the result must be a double.
•• If you use multiple operators in one expression, you can use parentheses to specify
the sequence of operations. Then, Java performs the operations in the innermost set
of parentheses first, followed by the operations in the next set, and so on.
Examples
String message1 = "Invalid data entry.";
String message2 = ""; // an empty string
String message3 = null; // a null string
Description
•• A string can consist of one or more characters including letters, numbers, and
special characters like *, &, and #.
•• In Java, a string is actually a String object that’s created from the String class that’s
part of the Java API (Application Programming Interface). This API provides all
the classes that are included as part of the JDK.
•• Since a string is an object created from the String class, you start the declaration
for a string by coding String with a capital S. By contrast, you don’t use any capital
letters when declaring primitive types such as the int and double types.
•• To specify the value of a string, you can enclose text in double quotation marks.
This is known as a string literal.
•• To assign a null to a string, you can use the null keyword. This means that the
String variable doesn’t point to a String object that’s allocated in memory.
•• To assign an empty string to a String object, you can code a set of quotation marks
with nothing between them. This means that the value of the string is known but
that the string doesn’t contain any characters.
•• To join (or concatenate) a string with another string or a data type, use a plus sign
(+). Whenever possible, Java automatically converts the data type and joins it with
the string.
Quotation marks
"Type \"x\" to exit"
Backslashes
"C:\\java\\files"
Description
•• Within a string, you can use escape sequences to include certain types of special
characters such as new lines and tabs. You can also use escape sequences to include
characters that are part of the Java syntax such as quotation marks and backslashes.
The console
Welcome to the Code Tester
Code: java
Price: 49.5
Quantity: 2
Total: 99.0
Bye!
// perform a calculation
double total = price * quantity;
Perspective
The goal of this chapter is to get you started with Java programming. Now,
if you understand how the Code Tester application works, you can get some
hands-on experience coding variables and arithmetic expressions of your own.
However, this application doesn’t get input from the user or format the output
that’s displayed to the user. To do that, you can use some of the classes that are
available from the Java API as described in the next chapter.
Also, keep in mind that this chapter is just an introduction to Java program-
ming. In chapter 7, you’ll learn more about working with primitive data types,
including how to work with the other six primitive data types. And in chapter 9,
you’ll learn more about working with strings.
Summary
•• A class stores Java code. A package is a folder that can store one or more
Java classes. Packages are used to organize classes.
•• A class can contain one or more methods. A method is a block of code that
performs a task.
•• A main method is a special type of method that’s executed when you run the
class that contains it.
•• A statement performs a task and ends with a semicolon.
•• Comments typically document what code does.
•• You can use the Eclipse code editor to enter and edit code. As you enter
code, you can use the code completion feature to help you enter the names of
classes and objects and select from fields and methods.
•• Java provides for eight primitive data types. Two of the most common are
the int and double types.
•• Variables store data that changes as an application runs. An assignment
statement can assign a value to a variable.
•• A string can consist of one or more characters including letters, numbers,
and special characters. You can use the plus sign to join a string with another
string or primitive type.
•• You can use escape sequences to include special characters in strings.
Chapter 2 How to start writing Java code 61
Sum: 301.75
Count: 6
Average: 50.291666666666664
Code: android
Description: Murach's Android Programming
Price: 57.5
Quantity: 2
Total: 115.0
Tax Percent: 7.5
Tax Amount: 8.625
Grand Total: 123.625
14. Declare and initialize a String variable for the product description.
15. Declare and initialize a double variable for the tax percent. For now, you can
assign a value of .075, which is 7.5%.
16. Declare and initialize a double variable for the tax amount. Then, calculate the
amount by multiplying the total by the tax percent and assign the result to this
variable.
17. Declare and initialize a double variable for the grand total. Then, calculate the
grand total by adding the total and tax amounts and assign the result to this
variable.
18. Modify the string that displays the data so the application prints it to the
console as shown above. To get the tax percent to display correctly, you can
multiply it by 100.
19. Run the application to make sure it works correctly.
Continue to test and experiment!
20. Add code to test any Java features described in this chapter.
21. Experiment with any Eclipse features described in this chapter.
3
How to use classes
and methods
This chapter shows you how to write a complete Java application that gets input
from a user, makes a calculation, formats the output, and displays it to the user.
This teaches you how to use some of the classes and methods that are available
from the Java API. When you finish this chapter, you should be able to write
comparable applications of your own.
Common packages
Package name Description
java.lang Classes that are fundamental to the Java language, including classes
that work with primitive data types and strings.
java.util Utility classes, including those for getting input from the console.
java.text Classes that handle text, including those that format numbers and dates.
Common classes
java.lang.String
java.lang.Integer
java.lang.Double
java.util.Scanner
java.text.NumberFormat
Description
•• The API for the Java SE provides a large library of classes that are organized into
packages.
•• All classes stored in the java.lang package are automatically available to all Java
code.
•• To use classes that aren’t in the java.lang package, you can code an import state-
ment. To import one class, specify the package name followed by the class name.
To import all classes in a package, specify the package name followed by an
asterisk (*).
Example
Scanner sc = new Scanner(System.in); // creates a Scanner object named sc
Example
String line = sc.nextLine(); // get a String object from the console
Example
double price = Double.parseDouble(line); // convert a String to a double
Description
•• When you create an object from a Java class, you are creating an instance of the
class. Then, you can use the methods of the class by calling them from the object.
•• Some Java classes contain static methods. You can call these methods directly from
the class without creating an object.
•• When you create an object from a class, the constructor may require one or more
arguments. These arguments must have the required data types. If there are multiple
arguments, you must code them in the correct sequence, and you must separate each
argument with a comma.
•• When you call a method from an object or a class, the method may require one or
more arguments. Here again, these arguments must have the required data types. If
there are multiple arguments, you must code them in the correct sequence, and you
must separate each argument with a comma.
•• When you call a method from an object or a class, the method may return a primitive
value or an object. If you want to use this data, you can assign the primitive value or
object to a variable.
Here, the argument is the String variable named line created in the second
example. This method returns a double value, and this example assigns it to the
double variable named price.
As you read this book, you’ll learn how to use dozens of classes and
methods. For now, though, you just need to focus on the syntax for creating an
object from a class, for calling a method from an object, and for calling a static
method from a class.
Description
•• The Java SE API contains thousands of classes and methods that can help you do
most of the tasks that your applications require.
•• You can use a browser to view the Java SE API on the Internet by going to this
address:
http://docs.oracle.com/javase/8/docs/api
•• You can select the name of the package in the top left frame to display information
about the package and the classes it contains. Then, you can select a class in the
lower left frame to display the documentation for that class in the right frame.
•• Once you display the documentation for a class, you can scroll through it or click a
link to get more information.
Figure 3-3 How to use the API documentation to research Java classes
70 Section 1 Get started right
Description
•• To create a Scanner object that gets input from the console, specify System.in in the
parentheses.
•• When the nextLine method of the Scanner class runs, the application waits for the
user to enter text with the keyboard. To complete the entry, the user presses the
Enter key.
•• Since the Scanner class is not in the java.lang package, you typically include an
import statement whenever you use this class.
Description
•• The Integer and Double classes provide static methods that you can use for
converting values from a String object to an int or double value.
•• If the parseInt and parseDouble methods can’t successfully parse the string, they
will cause an error to occur. In Java terminology, this is known as throwing an
exception. Later in this book, you’ll learn how to handle exceptions by catching
them.
How to get a double value from the user with two statements
String priceLine = sc.nextLine();
double price = Double.parseDouble(priceLine);
How to get a double value from the user with one statement
double price = Double.parseDouble(sc.nextLine());
Description
•• When you use the format method, the result is automatically rounded by using
a rounding technique called half-even. This means that the number is rounded
up if the preceding digit is odd, but the extra decimal places are truncated if the
preceding digit is even.
•• Since the NumberFormat class is in the java.text package, you typically include an
import statement when you use this class.
The examples in figure 3-7 use the default currency, percent, and number
formats for the United States. If you want to use the default format for the
current locale, you can modify the method that gets the NumberFormat object by
passing it this argument:
Locale.getDefault()
For example, you can call the getCurrencyInstance method like this:
NumberFormat.getCurrencyInstance(Locale.getDefault());
Then, the NumberFormat object that’s created uses the currency format for the
current locale. For example, if you’re in Europe, it uses the symbol for the Euro
instead of the symbol for the U.S. dollar.
import java.text.NumberFormat;
// perform a calculation
double total = price * quantity;
The console
Welcome to the Line Item Calculator
Code: java
Price: $49.50
Quantity: 2
Total: $99.00
Bye!
Description
•• Although the appearance of a console may differ from one system to another, you
can always use the print and println methods to print data to the console.
Relational operators
Operator Name Description
== Equality Returns a true value if both operands are equal.
!= Inequality Returns a true value if left and right operands are not equal.
> Greater Than Returns a true value if left operand is greater than right
operand.
< Less Than Returns a true value if left operand is less than the right
operand.
>= Greater Than Or Equal Returns a true value if left operand is greater than or equal
to right operand.
<= Less Than Or Equal Returns a true value if left operand is less than or equal to
right operand.
Description
•• A Boolean expression is an expression that evaluates to either true or false.
•• You can use the relational operators to compare two numeric operands and return a
Boolean value that is either true or false.
•• To test two strings for equality, you must call one of the methods of the String
class. The equality operator (==) does not test two strings for equality.
// get input from the user, process it, and display output here
The console
Loop 1
Loop 2
Loop 3
Loop 4
Description
•• A while loop executes the block of statements within its braces as long as the
Boolean expression is true. When the expression becomes false, the while loop
skips its block of statements so execution continues with the next statement in
sequence.
•• Any variables that are declared in the block of statements for a while loop have
block scope. As a result, you can only access them within that block.
•• If the Boolean expression in a while loop never becomes false, the loop never
ends. Then, the application goes into an infinite loop. In Eclipse, you can cancel an
infinite loop by clicking on the Terminate button in the Console window.
Description
•• An if/else statement, or just if statement, always contains an if clause. In addition, it
can contain one or more else if clauses, and a final else clause.
•• Any variables that are declared within a block for an if/else clause have block
scope. As a result, they can only be accessed within that block.
•• If a clause requires just one statement, you don’t have to enclose the statement in
braces. However, it’s generally considered a good practice to always include braces.
That way, if you decide to add more statements to a clause later, you won’t acciden-
tally introduce a bug.
LINE ITEM
Code: java
Price: $57.50
Quantity: 2
Total: $115.00
Continue? (y/n): y
LINE ITEM
Code: jsp
Price: $57.50
Quantity: 1
Total: $57.50
Continue? (y/n): n
Bye!
Description
•• When the application starts, the user can enter a product code that identifies a
product and the quantity for that product. The application determines the product
price based on the product code. Then, it calculates the total amount for the line
item and displays the line item.
•• After calculating the total for the invoice, the user can enter “y” or “Y” at the
prompt to continue. Or, the user can enter “n” or any other character to end the
application.
The code
Figure 3-13 shows the code for the Line Item application. Although this
application is simple, it gets input from the user, performs a calculation that uses
this input, and displays the result of the calculation.
This code begins with a package statement that declares that it is stored in
the murach.lineitem package. As a result, this code is stored in the
murach/lineitem subfolder of the application folder.
The two import statements import the NumberFormat and Scanner classes.
As a result, the rest of this code can use these classes without having to prefix
the class name with the package name.
The class declaration specifies a name of LineItemApp. As a result, this code
is stored in a file named LineItemApp.java.
The main method is coded within the braces of the LineItemApp class. This
method is executed when you run the LineItemApp class.
The main method begins by printing a welcome message to the console.
Then, it creates a Scanner object named sc. Although this object could be created
within the while loop, that would mean that the object would be recreated each
time through the loop, which would be inefficient.
Before the while loop, the code declares a String variable named choice and
initializes it to “y”. Then, the loop checks whether the choice variable is equal
to “y”. If so, it starts by getting the product code from the user and storing it
in a String variable named productCode. Then, it gets a quantity from the user,
converts it from a String object to an int value, and stores it in a variable named
quantity.
After getting this data, an if/else statement sets the double variable named
price based on the value of product code. If, for example, the productCode is
equal to “java”, the price is set to 57.50.
When the if/else statement is finished, this code calculates the line item total
by multiplying the price and quantity. Then, it stores the result of that calculation
in a double variable named total.
After this calculation, this code uses the NumberFormat class to apply
currency formatting to the price and total variables. In addition, it creates a
String variable named message that contains string literals, variables, and escape
sequences for new line characters. Then, it prints that string to the console.
After printing this data to the console, this code displays a message that asks
the user if he or she wants to continue. If the user enters “y” or “Y”, the loop is
repeated. Otherwise, the application ends.
If you’re new to programming, you can learn a lot by writing simple
applications like the Line Item application. This gives you a chance to become
comfortable with getting input, performing calculations, and displaying output.
In addition, it gives you a chance to get comfortable with control statements such
as while loops and if/else statements.
Chapter 3 How to use classes and methods 89
import java.text.NumberFormat;
import java.util.Scanner;
// calculate total
double total = price * quantity;
Continue? (y/n): y
Continue? (y/n): n
Bye!
Description
•• When the application starts, the user can enter a monthly investment, yearly interest
rate, and number of years. Then, it calculates the future value of the investment at
the end of the specified number of years and displays that value to the user.
•• After calculating the future value, the user can enter “y” or “Y” at the prompt to
continue. Or, the user can enter “n” or any other character to end the application.
Figure 3-14 The user interface for the Future Value application
92 Section 1 Get started right
The code
Figure 3-15 shows the code for this application. This code uses a while loop
to determine when the application ends. Within this loop, the code gets the three
entries from the user. Then, it converts these entries to the same time unit, which
is months. To do that, it multiplies the number of years by 12 and divides the
yearly interest rate by 12. In addition, it divides the yearly interest rate by 100 so
it calculates the interest correctly.
Once those variables are prepared, a second while loop calculates the future
value. This loop executes one time for each month. Within this loop, the first
statement adds the monthly investment to the future value. The second statement
calculates the amount of monthly interest. The third statement adds the monthly
interest to the future value. And the fourth statement increments the counter
variable.
When this loop finishes, the code displays the result. To do that, it uses the
NumberFormat class to apply currency formatting to the future value. Then, it
asks whether the user wants to continue.
Chapter 3 How to use classes and methods 93
import java.text.NumberFormat;
import java.util.Scanner;
Perspective
The goal of this chapter has been to show you how to create a console
application that uses classes and methods from the Java API to get input from
the user and display output to the user. Now, if you understand how the Line
Item and Future Value applications work, you’ve come a long way. However,
these applications don’t use objects in a professional way. That’s why the next
two chapters show you how to convert the Line Item application into an
object-oriented application that uses objects in a professional way.
Also, keep in mind that this chapter is just an introduction to Java program-
ming. As a result, you’ll learn more details about writing Java code as you
progress through this book. For example, you’ll learn more about coding
control statements in chapter 8.
Summary
•• You call a method from an object and you call a static method from a class.
A method may require one or more arguments.
•• Before you use a class from the Java SE API that isn’t in the java.lang
package, you typically code an import statement for the class.
•• When you use a constructor to create an object from a Java class, you are
creating an instance of the class.
•• You can use the static methods of the Integer and Double classes to convert
strings to int and double values.
•• You can use the NumberFormat class to apply standard currency, percent,
and number formats to any of the primitive numeric types.
•• You can code a while loop that executes a block of statements repeatedly
when its Boolean expression returns a true value and skips that block of
statements when its Boolean expression returns a false value.
•• You can code an if statement to control the logic of an application based on
the true or false values of Boolean expressions.
Chapter 3 How to use classes and methods 95
LINE ITEM
Code: java
Description: Murach's Java Programming
Price: $57.50
Quantity: 2
Total: $115.00
Continue? (y/n):
Continue? (y/n): y
Continue? (y/n): n
Bye!
An introduction to classes...................................................98
How encapsulation works...............................................................................98
The relationship between a class and its objects..........................................100
How to work with a class that defines an object..............102
The Product class..........................................................................................102
How to code instance variables....................................................................104
How to code constructors.............................................................................106
How to code methods...................................................................................108
How to create an object from a class............................................................ 110
How to call the methods of an object...........................................................112
How to work with static fields and methods.................... 114
The ProductDB class.................................................................................... 114
How to code and call static fields and methods........................................... 116
When to use static fields and methods......................................................... 116
The Product Viewer application......................................... 118
The user interface......................................................................................... 118
The ProductApp class................................................................................... 118
More skills for working with classes and methods.........120
Reference types compared to primitive types..............................................120
How to overload methods.............................................................................122
How to use the this keyword........................................................................124
The Product class with overloading..............................................................126
Perspective..........................................................................128
98 Section 1 Get started right
An introduction to classes
The first two figures in this chapter introduce you to some concepts that
apply to classes. That includes how encapsulation works and how a class relates
to its objects.
Description
•• The fields of a class store the data of a class.
•• The methods of a class define the tasks that a class can perform. Often, these
methods provide a way to work with the fields of a class.
•• Encapsulation is one of the fundamental concepts of object-oriented programming.
This means that the class controls which of its fields and methods can be accessed
by other classes. As a result, the fields in the class can be hidden from other classes,
and the methods in a class can be modified or improved without changing the way
that other classes use them.
Description
•• A class can be thought of as a template from which objects are made.
•• Once an instance of a class is created, it has an identity (a unique address) and a
state (the data that it stores). As an application runs, an object’s state may change.
import java.text.NumberFormat;
// the constructor
public Product() {
code = "";
description = "";
price = 0;
}
other classes because they’re declared with the private keyword. In addition, all
of the code contained within the constructor and methods is hidden.
Because of that, you can change any of the code within the constructors and
methods of this class without having to change the way other classes call these
constructors and methods. For example, if you want to modify the
getPriceFormatted method so it uses the current locale when it formats the price,
you can modify the code within this method so it does that. However, when you
change the data that’s returned by a method like this, it’s possible that the code
that calls this method won’t work correctly after this change. As a result, you
should take care when modifying a method that’s used by other classes.
Examples
private double price;
private int quantity;
private String code;
private Product product;
Description
•• A field of a class defines the data that’s available to the entire class. A field can be
an instance variable or a constant. To learn how to work with constants, see
chapter 7.
•• An instance variable stores data that’s available to the entire object. In other words,
an instance variable stores data that’s available to an instance of a class.
•• An instance variable may be a primitive data type, an object created from a Java
class such as the String class, or an object created from a user-defined class such as
the Product class.
•• Typically, instance variables are declared with the private keyword. This helps to
prevent other classes from directly accessing instance variables.
•• You can declare the instance variables for a class anywhere outside the constructors
and methods of the class.
Description
•• A constructor can be used to create, or construct, an object from a class.
•• The constructor must use the same name and capitalization as the name of the class.
•• To code a constructor that has parameters, code a data type and name for each
parameter within the parentheses that follow the class name.
•• The name of a constructor combined with the parameter list forms the signature
of the constructor. Although you can code multiple constructors for a class, each
constructor must have a unique signature. This is known as overloading a constructor.
•• You can use the keyword named this to refer to an instance variable of the current
object. This is required if an instance variable has the same name as a parameter of
the constructor. Otherwise, it’s optional.
•• If you don’t explicitly initialize an instance variable, Java automatically initial-
izes it for you by setting numeric variables to zero, boolean variables to false, and
variables for objects to null.
A set method
public void setCode(String code) {
this.code = code;
}
Description
•• To allow other classes to access a method, use the public keyword. To prevent other
classes from accessing a method, use the private keyword.
•• When you name a method, you should start each name with a verb. It’s a Java
standard to use the verb set for methods that set the values of instance variables and
to use the verb get for methods that return the values of instance variables. These
methods are typically referred to as set and get accessors.
•• To code a method that doesn’t return data, use the void keyword for the return type.
•• To code a method that returns data, code a return type in the method declaration.
Then, code a return statement in the body of the method to return the data.
•• To code a method that has a parameter, code the data type and name of the param-
eter between the parentheses of the method.
No arguments
Product product;
product = new Product();
No arguments
Product product = new Product();
Three arguments
Product product = new Product("java", "Murach's Java Programming", 57.50);
Description
•• To create an object, you use the new keyword to create a new instance of a class.
Each time the new keyword creates an object, Java calls the constructor for the
object, which initializes the instance variables for the object and stores the object in
memory.
•• After you create an object, you assign it to a variable. When you do, a reference
to the object is stored in the variable. Then, you can use the variable to refer to the
object. As a result, objects are known as reference types.
•• The variable for a reference type stores a reference to an object.
•• To send arguments to the constructor, code the arguments between the paren-
theses that follow the class name. To send more than one argument, separate the
arguments with commas.
•• When you send arguments to the constructor, the arguments must be in the
sequence called for by the constructor and they must have data types that are
compatible with the data types of the parameters for the constructor.
Description
To call a method that doesn’t accept arguments, type an empty set of parentheses
after the method name.
To call a method that accepts arguments, enter the arguments between the
parentheses that follow the method name. Here, the data type of each argument
must be compatible with the data type that’s specified by the method’s parameters.
To code more than one argument, separate the arguments with commas.
If a method returns data, you can code an assignment statement to assign the data
that’s returned to a variable. Here, the data type of the variable must be compatible
with the return type of the method.
Description
•• You can use the static keyword to identify a method as a static method.
•• A more realistic ProductDB class would get the data for the Product object from a
database.
import java.util.Scanner;
Description
•• You can use the static keyword to code static methods and static fields. Since static
methods and static fields belong to the class, not to an object created from the class,
they are sometimes called class methods and class fields.
•• There are two types of fields: variables and constants. To learn how to code
constants, see chapter 7.
•• When you code a static method, you can only use static fields and fields that are
defined in the method. In other words, you can’t use instance variables in a static
method.
•• To call a static method, type the name of the class, followed by the dot operator,
followed by the name of the static method, followed by a set of parentheses. If the
method requires arguments, code the arguments within the parentheses, separating
multiple arguments with commas.
•• To call a static field, type the name of the class, followed by the dot operator,
followed by the name of the static field.
Figure 4-10 How to code and call static methods and fields
118 Section 1 Get started right
The console
Welcome to the Product Viewer
PRODUCT
Code: java
Description: Murach's Beginning Java
Price: $49.50
Continue? (y/n): n
Bye!
import java.util.Scanner;
Description
•• A variable for a primitive type always stores its own copy of the primitive value. As
a result, changing the value for one primitive type variable doesn’t change the value
of any other primitive type variables.
•• A variable for a reference type stores a reference to the object. This allows multiple
reference type variables to refer to the same object. As a result, changing the data
for one object also changes the data for any other variables that refer to that object.
•• When you code a method that has a primitive type parameter, the parameter gets its
own copy of the value that’s passed to the method. As a result, if the method changes
the value of the parameter, that change doesn’t affect any variables outside the method.
•• When you code a method that has a reference type parameter, the parameter
refers to the object that’s passed to the method. As a result, if the method uses the
parameter to change the data in the object, these changes are reflected by any other
variables outside the method that refer to the same object.
The console
java|Murach's Java Programming|57.5
java/Murach's Java Programming/57.5
Product: java|Murach's Java Programming|57.5
Description
•• When you create two or more methods with the same name but with different
parameter lists, the methods are overloaded. It’s common to use overloaded
methods to provide two or more versions of a method that work with different data
types or that supply default values for omitted parameters.
•• The name of the method combined with the parameter list forms the signature
of the method. Although you can use the same name for multiple methods, each
method must have a unique signature.
•• Within a class, you can call one regular method from another regular method by
coding the method name and its arguments. In other words, you don’t need to prefix
the method name with the object name.
Description
•• Java implicitly uses the this keyword for instance variables and methods. As a result,
you don’t need to explicitly code it unless a method parameter or a variable that’s
declared within a method has the same name as an instance variable. Then, you need
to use the this keyword to identify the instance variable.
•• If you use the this keyword to call one constructor from another constructor in the
same class, the statement that uses the this keyword must be the first statement in the
constructor.
import java.text.NumberFormat;
public Product() {
this("", "", 0);
}
// all get and set methods are the same as the Product class
// shown earlier in this chapter
Perspective
At this point, you may be wondering why you should take the time to
create an object-oriented application like the one shown in this chapter. After
all, you could accomplish the same task with less code by coding a procedural
application like the one shown in chapter 3.
Although there are many advantages to the object-oriented approach, I’ll
just mention two for now. First, dividing the code into classes makes it easier
to reuse code. For example, any application that needs to work with products
can use the Product and ProductDB classes. Second, using classes helps you
separate the different layers of an application. That can simplify the devel-
opment of the application and make the application easier to maintain and
enhance later on. In the next chapter, you’ll learn how to use classes to struc-
ture an application so it has three layers.
Summary
•• The Unified Modeling Language (UML) is the standard modeling language
for working with object-oriented languages. You can use UML class
diagrams to identify the fields and methods of a class.
•• Encapsulation lets you control the fields and methods within a class that are
exposed to other classes. When fields are encapsulated within a class, it’s
called data hiding.
•• Multiple objects can be created from a single class. Each object can be
referred to as an instance of the class.
•• The data that makes up an object can be referred to as its state. Each object
is a separate entity with its own state.
•• A field is a variable or constant that’s defined at the class level. An instance
variable stores data that’s available to an object (instance) of a class.
•• You can use a constructor to create, or construct, an object from a class.
•• When you code the methods of a class, you often code public get and set
methods, called accessors, that provide access to its instance variables.
•• If you want to code a method or constructor that accepts arguments, you
code a list of parameters between the parentheses for the constructor or
method. For each parameter, you must include a data type and a name.
•• You can use the static keyword to define static fields and static methods.
Then, you can call those fields and methods directly from the class, not from
an object created from the class.
•• The name of a method combined with the list of parameter types is known as
the signature of the method. You can overload a method by coding different
parameter lists for methods that have the same name.
•• When coding a class, you can use the this keyword to refer to the current
object.
Chapter 4 How to code your own classes and methods 129
Description
•• To simplify development and maintenance, many applications use a three-tier
architecture to separate the application’s user interface, business rules, and database
processing. Each tier of the architecture may consist of one or more classes.
•• The classes in the presentation tier control the application’s user interface. For
a console application, the presentation tier typically consists of a class with a
main method and any other classes related to console input and output. For a GUI
application, the user interface typically consists of one class for each window of the
GUI.
•• The classes in the database tier handle all of the application’s data processing.
•• The classes in the business tier define the business objects and rules for the applica-
tion. These classes act as an interface between the classes in the presentation and
database tiers.
import java.text.NumberFormat;
import java.text.NumberFormat;
import murach.business.Product;
import java.util.Scanner;
import murach.db.ProductDB;
import murach.business.LineItem;
import murach.business.Product;
Description
A package can store one or more classes.
Each package name corresponds with a folder that has the same name. The names
you use should be unique to prevent conflicts with other packages.
When you store a class in a package, the first statement of the class must be a
package statement that specifies the name of the package.
After the package statement, you can code the import statements for the class.
These statements work the same for the packages and classes that you create as
they do for the packages and classes of the Java API.
Description
•• To navigate through existing packages, use the Package Explorer to expand or
collapse the packages within a project.
•• To add a new package to a project, right-click on the project name or the src folder
in the Package Explorer, select the NewPackage command, and enter the name of
the package in the resulting dialog box.
•• To rename a package, select the RefactorRename command and use the resulting
dialog box to specify the new name.
•• To move a class from one package to another, drag it in the Package Explorer.
Then, click the OK button in the resulting dialog box.
•• To delete a package from a project, right-click on the package and select the Delete
command from the resulting menu. If the package contains classes, this also deletes
those classes.
•• When you use Eclipse to work with packages, it automatically updates the corre-
sponding folders. In addition, it automatically updates any package or import
statements in the project that need it.
The console
Welcome to the Line Item Calculator
LINE ITEM
Code: java
Description: Murach's Beginning Java
Price: $49.50
Quantity: 2
Total: $99.00
Continue? (y/n):
Description
•• The Line Item application accepts a product code and quantity from the user,
creates a line item using that information, and displays the result to the user.
•• The two instance variables of the LineItem class store a Product object and an
int value for the quantity. The first four methods of the LineItem class access the
values of these variables. The getTotal method calculates the line item total. And
the getTotalFormatted method formats the total as a currency value.
Figure 5-4 The user interface and the class diagram for the Line Item application
140 Section 1 Get started right
import java.text.NumberFormat;
public LineItem() {
this.product = null;
this.quantity = 0;
}
import java.util.Scanner;
import murach.db.ProductDB;
import murach.business.LineItem;
import murach.business.Product;
Perspective
If you understand the Line Item application presented in this chapter, you
understand a lot about Java programming, including how to use packages and
classes to create a three-tier structure. With that as background, you’re ready to
learn more details about using Java. And that’s what you’ll learn in the rest of
this book.
But first, the next chapter shows how to test and debug the Line Item
application presented in this chapter. That way, whenever your code doesn’t
work correctly, you’ll have some skills that you can use to fix it.
Summary
•• A three-tier architecture separates an application into three layers, or tiers.
•• The presentation tier consists of the user interface.
•• The database tier consists of the database and the database classes that work
with it.
•• The business tier consists of the business classes that define the business
objects and rules of the application.
LINE ITEM
Code: java
Description: Murach's Java Programming
Price: $57.50
Quantity: 2
Total: $59.50
Continue? (y/n):
Description
•• To test a Java application, you run it to make sure that it works properly no matter
what combinations of valid or invalid data you enter.
•• When you debug an application, you find the cause of all the errors (bugs) that
you find when you test the application. Then, you fix those errors. This process is
known as debugging.
Description
•• An identifier is a name that refers to a piece of Java code such as a variable,
method, class, or package.
A compile-time error
A runtime error
A logic error
Description
•• The first step in fixing an error is to determine the cause of the error. Once you
know the cause of the error, it’s often easy to fix the error.
•• For a compile-time error, go to the line in the source code that won’t compile. In
Eclipse, you can do that by clicking on the link to the line of source code. That
should give you a strong indication of what caused the error.
•• For a runtime error, go to the line in the source code that was running when the
application crashed. In Eclipse, you can do that by clicking on the link to the line of
source code. That should give you a strong indication of what caused the error.
•• For a logic error, review the output, review the source code, and try to figure out
how the source code produced that output. It’s often difficult to determine what
caused the error, but some of the techniques presented later in this chapter can help.
Description
•• A simple way to trace the execution of an application is to insert println statements
at key points in the code that print messages to the console.
•• The messages that are printed to the console can indicate what code is being
executed, or they can display the values of variables.
•• When you see an incorrect value displayed, there is a good chance that the applica-
tion contains a logic error between the current println statement and the previous
one.
Description
•• When debugging, you need to stop application execution before the line of code
that caused the error. Then, you can examine variables and step through code as
described in the next few figures.
•• To stop application execution, you can set a breakpoint. Then, when you run the
application, execution stops when it reaches the breakpoint.
•• To set a breakpoint for a line, open the code editor for the class and double-click on
the line number. The breakpoint is identified by a small blue circle that’s placed to
the left of the line number.
•• To remove a breakpoint, double-click on the line number again.
•• You can set and remove breakpoints either before you start debugging or while
you’re debugging. In most cases, you’ll set at least one breakpoint before you start
debugging.
•• To start debugging for the current project, click the Debug button on the toolbar.
•• You can also start debugging by right-clicking on a project or a class that contains a
main method and selecting the Debug AsJava Application command.
A debugging session
Description
•• When a breakpoint is reached, execution is stopped before the line is executed.
•• The arrow in the bar at the left side of the code editor shows the line that will be
executed next. This arrow may overlap with the breakpoint symbol.
•• The Variables window shows the values of the variables that are in scope for the
current method. This window is displayed by default when you start a debug-
ging session. If you close it, you can open it again using the WindowShow
ViewVariables command.
•• If a variable in the Variables window refers to an object, you can view the values
for that object by clicking the arrow to the left of the object name to expand it.
•• You can use the buttons on the Debug toolbar to control the execution of an application.
When the Variables window displays variables for numbers and strings, it
shows the value. In this figure, for example, the variable named total has a value
of 287.5.
However, when the Variables window displays a variable that refers to an
object, it doesn’t display the values of its variables automatically. Instead, it
displays an arrow icon to the left of the object’s name. Then, you can view the
values for the object by clicking on that arrow icon to expand it. In figure 6‑6,
for example, the variable named currency refers to an object that’s created from
the NumberFormat class.
Similarly, when you are examining the code from within an object that’s
executing, the Variables window begins by displaying a variable named this that
refers to the current object. As a result, you can expand this variable to view the
values of the instance variables that are defined by the current object. In figure
6‑6, for example, you can expand the variable named this to view the values of
the instance variables for the current LineItem object.
Description
•• A stack trace is a list of the methods that have been called in the reverse order in
which they were called.
•• By default, Eclipse displays a stack trace in the Debug window that’s located in
the upper left corner of the IDE. If you close it, you can open it again using the
WindowShow ViewDebug command.
•• To jump to a line of code in the code editor that’s displayed in the stack trace, click
on that line in the stack trace.
•• When you are finished with the debugger, you can return to the Java perspective by
clicking the Java button that’s displayed on the right side of the toolbar next to the
Debug button.
Perspective
Before you put an application into production, you should test it and debug
it thoroughly. Now that you’ve completed this chapter, you should have the
skills you need to test an application to identify any bugs it may contain. In
addition, you should be able to use the Eclipse debugger to locate the cause of
those bugs.
The skills presented in this chapter should give you a solid foundation
for testing and debugging any application that you develop. However, Eclipse
provides some additional features that you can use to test and debug your appli-
cations. After reading this chapter, you should have the background you need to
learn more about other debugging features that are available from Eclipse.
As you begin to develop more complex applications, you may also want
to learn about unit testing. Unit testing is a way of creating tests for individual
units of source code such as methods to make sure they work correctly. Unit
tests can automate much of the application testing you would normally have
to do manually. By automating the testing, it’s more likely that the testing will
actually be done each time an application is updated. This makes it easier to
find and fix a bug since it’s easier to determine what new code introduced the
bug.
Summary
•• To test an application, you run it to make sure that it works properly no
matter what combinations of valid or invalid data you enter.
•• When you debug an application, you find and fix all of the errors (bugs) that
you find when you test the application. This process is known as debugging.
•• Compile-time errors violate the rules for how Java statements must be
written. These errors are detected by the Java compiler before you can run
the application.
•• Runtime errors occur while you are running an application. These types of
errors throw exceptions that stop the execution of the application.
•• Logic errors don’t cause the application to crash, but they prevent it from
working correctly.
•• A simple way to trace the execution of an application is to insert println
statements at key points in the code.
•• Eclipse includes a powerful tool known as a debugger that can help you find
and fix errors.
•• When debugging, Eclipse switches from the Java perspective to the Debug
perspective. You can click on the Java and Debug buttons in the toolbar to
switch between these perspectives.
•• You can set a breakpoint on a line of code to stop code execution just before
that line of code. Then, you can step through the code and view the values of
the variables as the code executes.
•• A stack trace is a list of methods in the reverse order in which they were called.
Chapter 6 How to test and debug an application 163
12. Click in the Console window again. Then, enter “n” to exit the application and
end the debugging session.
Set a breakpoint and step through the application
13. Click on the Java button in the toolbar to switch back to the Java perspective.
14. Open the LineItemApp class and set a breakpoint on the first line of code in
the main method.
15. Click on the Debug button in the toolbar. If necessary, confirm that you want
to switch to the Debug perspective.
16. Use the Step Over and Step Into buttons to step through each line of the appli-
cation. To do that, use the Step Over button for most statements and the Step
Into button for any statements that call constructors and methods from the
LineItem, Product, and ProductDB classes. As you do this, use the Console
window to enter data and the Variables window to inspect the variables. This
should give you a good idea of how this code works.
Stop the debugger and remove the breakpoints
17. Once you have the hang of stepping through this application, click the Termi-
nate button to end the application and the debugging session.
18. Click the Java button to switch back to the Java perspective.
19. Remove the breakpoints that you set earlier in this exercise. To do that, you
can double-click on the line number for each breakpoint.
Section 2
Essential skills
as you need them
This section consists of four chapters that show you how to use more of the
core Java features. Chapter 7 presents the most important skills for working
with data types and operators. Chapter 8 presents the most important skills
for working with control statements. Chapter 9 presents the most important
skills for working with strings. And chapter 10 presents the concepts and
techniques you need to know to work with arrays.
We have designed each chapter in this section as an independent unit.
As a result, you can read these chapters in any sequence you like. If, for
example, you want to learn more about control structures, you can read
chapter 8 next. Or, if you want to learn about arrays, you can read chapter 9
next.
7
How to work with primitive
types and operators
In chapter 2, you learned how to use two of the eight primitive data types. In
addition, you learned how to use operators to perform some simple arithmetic
calculations. Now, you’ll learn about the other six primitive data types. In
addition, you’ll learn the details for using operators to work with these data
types at a professional level.
Description
•• Integers are whole numbers.
•• Floating-point numbers provide for very large and very small numbers that require
decimal positions, but with a limited number of significant digits. A single-precision
number provides for numbers with up to 7 significant digits. A double-precision
number provides for numbers with up to 16 significant digits.
•• The Unicode character set provides for over 65,000 characters with two bytes used
for each character. The ASCII character set provides characters for the English
language. These characters are the first 256 characters of the Unicode character set.
•• A Boolean value can be true or false. In Java, the boolean data type provides for
Boolean values. Like the other primitive types, it uses all lowercase letters.
Technical notes
•• To express the value of a floating-point number, you can use scientific notation.
For example, 2.382E+5 means 2.382 times 105, which is a value of 238,200.
Conversely, 3.25E-8 means 3.25 times 10-8, which is a value of .0000000325. Java
sometimes uses this notation to display the value of a floating-point number.
•• Because of the way floating-point numbers are stored internally, they can’t repre-
sent the exact value of the decimal places in some numbers. This can cause a
rounding problem. Later in this chapter, you’ll learn how to use the BigDecimal
class to solve these rounding problems.
•• By default, Java uses Intel 80-bit extended precision floating-point when it is avail-
able from the CPU. As a result, code that uses floating-point numbers may produce
slightly different results on different systems.
Example
int counter; // declaration statement
counter = 1; // assignment statement
Examples
int counter = 1; // initialize an int variable
double price = 14.95; // initialize a double variable
float interestRate = 8.125F; // F indicates a floating-point value
long numberOfBytes = 20000L; // L indicates a long integer
int population1 = 1734323; // initialize an int variable
int population2 = 1_734_323; // improve readability – Java 7 and later
double distance = 3.65e+9; // scientific notation
char letter1 = 'A'; // stored as a two-digit Unicode character
char letter2 = 65; // integer value for a Unicode character
boolean valid = false; // where false is a keyword
int x = 0, y = 0; // initialize 2 variables with 1 statement
Description
•• A variable stores a value that changes as an application executes. In other words, a
variable varies as an application executes.
•• Before you can use a variable, you must declare its data type and its name.
•• After you declare a variable, you can assign a value to the variable. To do that, you
use the assignment operator (=).
•• You can initialize a variable by declaring it and assigning a value to it. To do that,
you can use two statements, but it’s common to use one statement.
•• To declare and initialize more than one variable for a single data type in a single
statement, use commas to separate the assignments.
•• To identify float values, you must type an f or F after the number.
•• To identify long values, you can type an l or L after the number.
Naming conventions
•• Start variable names with a lowercase letter and capitalize the first letter in all
words after the first word. This naming convention is known as camel case.
•• Try to use meaningful names that are easy to remember as you code.
Examples
final int DAYS_IN_NOVEMBER = 30;
final float SALES_TAX = .075F;
final double LIGHT_YEAR_MILES = 5.879e+12;
Description
A constant stores a value that does not change as an application executes. In other
words, a constant remains constant as an application executes.
To declare a constant, you begin the declaration statement with the final keyword.
After that, the skills for initializing variables also apply to constants.
To make it easy to distinguish between variables and constants, most Java
developers use camel case for variables and all caps for constants.
Naming conventions
Capitalize all of the letters in constants and separate words with underscores.
Try to use meaningful names that are easy to remember.
Description
•• An arithmetic expression consists of arithmetic operators that operate on one or
more numbers known as operands.
•• Binary operators operate on two operands.
•• An assignment statement can assign the value of an expression to a variable. Then,
when Java executes the assignment statement, it determines the value of the expres-
sion and stores the result in the variable.
Description
•• Unary operators operate on just one operand.
•• When you use an increment or decrement operator as a postfix to a variable, Java
performs the increment or decrement operation after other operations.
•• When you use an increment or decrement operator as a prefix to a variable, Java
performs the increment or decrement operation before other operations.
•• If you code an increment or decrement operation as a single statement, not as part
of an expression, it doesn’t matter whether the operator is prefixed or postfixed.
Statements that use the same variable on both sides of the equals sign
count = count + 1; // count is increased by 1
count = count – 1; // count is decreased by 1
total = total + 100.0; // total is increased by 100.0
total = total – 100.0; // total is decreased by 100.0
price = price * .8; // price is multiplied by .8
sum = sum + nextNumber; // sum is increased by the value of nextNumber
Description
•• Besides the assignment operator (=), Java provides for five compound assignment
operators. These operators provide a shorthand way to code common assignment
operations.
•• The compound assignment operators are also referred to as the augmented assign-
ment operators.
If you have trouble creating an expression like this for a difficult calculation,
you can often break the expression down into a series of statements as shown
in the last four lines of code. Here, the first statement adds the monthly invest-
ment amount to the current value. The second statement calculates the monthly
interest rate. The third statement calculates the monthly interest amount. And the
fourth statement adds the interest to the current value. This takes away the need
for parentheses. In addition, it makes the code easier to read and debug.
Chapter 7 How to work with primitive types and operators 181
Description
•• Unless parentheses are used, the operations in an expression takes place from left to
right in the order of precedence.
•• To specify the sequence of operations, you can use parentheses. Then, the opera-
tions in the innermost set of parentheses are done first, followed by the operations
in the next set, and so on.
double d = 95.0;
int i = 86, j = 91;
double average = (d+i+j)/3; // convert i and j to double values
// average = 90.666666...
Examples
int grade = (int) 93.75; // convert double to int (grade = 93)
double d = 95.0;
int i = 86, j = 91;
int average = ((int)d+i+j)/3; // convert d to int value (average = 90)
int remainder = ((int)d+i+j)%3; // convert d to int value (remainer = 2)
Description
•• If you assign a less precise data type to a more precise data type, or you assign a
smaller data type to a larger data type, Java automatically performs the cast and makes
the conversion. This can be referred to as an implicit cast or a widening conversion.
•• When you code an arithmetic expression, Java implicitly casts the less precise data
types to the most precise data type.
•• To code an assignment statement that assigns a more precise data type to a less
precise data type, you must use parentheses to specify the less precise data type.
This can be referred to as an explicit cast or a narrowing conversion.
•• When you code an explicit cast in an arithmetic expression, Java performs the cast
before any arithmetic operations.
•• Since each char value has a corresponding int value, you can implicitly or explicitly
cast between these types.
Description
•• You can use the static methods of the Math class to perform common arithmetic
operations. This figure summarizes the methods that are the most useful for
business applications.
•• When a method requires one or more arguments, you code them between the
parentheses, separating multiple arguments with commas.
•• In some cases, you need to cast the result to the data type that you want.
Description
•• The BigDecimal class provides a way to perform accurate decimal calculations in
Java. It also provides a way to store numbers with more than 16 significant digits.
Description
•• With this code, all of the numbers are stored in BigDecimal objects, and all of the
results have two decimal places that have been rounded correctly when needed.
•• Once the results have been calculated, you can use the NumberFormat methods to
format the values in the BigDecimal objects without any fear of rounding problems.
The code
Much of the code for the Invoice application works like the code for the Line
Item application presented in chapter 3. As a result, the following description
focuses on the new skills that were presented in this chapter.
To start, this code imports the BigDecimal class and the RoundingMode
enumeration. This allows you to use the BigDecimal class to round numbers that
have decimal places as described earlier in this chapter.
Within the while loop, the first statement prompts the user to enter a
subtotal. Then, the second statement gets a String object for the text that the
user entered. Next, the third statement creates a new BigDecimal object from
this String object, calls the setScale method directly from this object, and
calls the doubleValue method directly from the setScale method. This returns
a double value that’s rounded to 2 decimal places and stores it in the variable
named subtotal. This is necessary because it’s possible that the user might enter
a subtotal that had more than 2 decimal places. In that case, this code would
prevent a rounding error by rounding the number to 2 decimal places.
After getting a double value for the subtotal, the loop uses an if/else state-
ment to calculate the discount amount based on the value of the subtotal. If, for
example, the subtotal is greater than or equal to 200, the discount amount is .2
times the subtotal (a 20% discount). If that condition isn’t true and the subtotal
is greater than or equal to 100, the discount is .1 times subtotal (a 10% discount).
Otherwise, the discount amount is 0.
Chapter 7 How to work with primitive types and operators 191
The console
Welcome to the Invoice Total Calculator
INVOICE
Subtotal: $100.05
Discount percent: 10%
Discount amount: $10.01
Total before tax: $90.04
Sales tax: $4.50
Invoice total: $94.54
Continue? (y/n): n
Bye!
The code
package murach.invoice;
import java.util.Scanner;
import java.text.NumberFormat;
import java.math.BigDecimal;
import java.math.RoundingMode;
After the if/else statement, this code calculates the discount amount by
multiplying the subtotal by the discount percent. Since this can result in more
than 2 decimal places, this code uses the BigDecimal class to round the result
to 2 decimal places, and it returns the number as a double value. To do that, this
code creates a new BigDecimal object from the double value for the discount
amount, uses the setScale method to round the number, and uses the doubleValue
method to return the double value. Then, this code calculates the total before tax
by subtracting discountAmount from subtotal.
This code continues by declaring a constant named SALES_TAX_PCT
that stores the sales tax percent. Here, this constant is set to a value of .05 (5%).
Then, this code multiplies this constant by the total before tax to get the sales tax
amount. Since this amount might contain more than 2 decimal places, this code
uses the BigDecimal class to round this number to 2 decimal places using the
same technique that was used earlier in this class.
After this code finishes making all of its calculations, it uses the
NumberFormat class to apply currency and percent formatting to the monetary
and percent values. Then, it prints a message to the console that includes these
values. Since all of the monetary values have been rounded to 2 decimal places
before this formatting was applied, the values that are displayed should add up.
In other words, this application shouldn’t contain any rounding errors.
Unfortunately, this application still doesn’t handle the exception that’s
thrown if the user doesn’t enter a valid value for the subtotal. However, you’ll
learn how to handle this exception in the next chapter.
Chapter 7 How to work with primitive types and operators 193
// calculate total
double total = totalBeforeTax + salesTax;
System.out.println(message);
Perspective
If this chapter has succeeded, you should now be able to work with any of
the primitive data types you need in your applications. In addition, you should
be able to use the Math class whenever you need it. And you should be able
to use the BigDecimal class to solve the problems that are associated with
floating-point numbers such as rounding errors.
Summary
•• Java provides eight primitive data types to store integer, floating-point,
character, and boolean values.
•• Variables store data that changes as an application runs. Constants store data
that doesn’t change as an application runs. You use assignment statements to
assign values to variables.
•• You can use arithmetic operators to form arithmetic expressions, and you
can use some assignment operators as a shorthand for some types of arith-
metic expressions.
•• Java can implicitly cast a less precise data type to a more precise data type.
Java also lets you explicitly cast a more precise data type to a less precise
data type.
•• You can use the static methods of the Math class to perform mathematical
operations such as calculating the square root of a number.
•• You can use the BigDecimal class to create BigDecimal objects that store
decimal values that aren’t limited to 16 significant digits. In addition, you
can use the methods of these objects to perform operations such as addition,
subtraction, multiplication, division, and rounding.
Chapter 7 How to work with primitive types and operators 195
7. Before the while loop, declare a total variable of the float type. After the code
that displays the line item, use the compound addition operator to add the
total for the line item to the total variable. After the while loop, display the
total like this:
Invoice total: 287.5
8. Before the while loop, declare one variable of the float type that stores the
largest line item and another variable of the float type that stores the smallest
line item. After displaying the line item, use the max and min methods of the
Math class to update the values for the largest and smallest line items. After
the loop, display the total like this:
Largest line item: 172.5
Smallest line item: 100.0
To get this to work correctly, you need to initialize the minimum value to a
very large value.
196 Section 2 Essential skills as you need them
Relational operators
Operator Name Description
== Equality Returns a true value if both operands are equal.
!= Inequality Returns a true value if the left and right operands
are not equal.
> Greater Than Returns a true value if the left operand is
greater than the right operand.
< Less Than Returns a true value if the left operand is less
than the right operand.
>= Greater Than Or Equal Returns a true value if the left operand is
greater than or equal to the right operand.
<= Less Than Or Equal Returns a true value if the left operand is less
than or equal to the right operand.
Boolean expressions
discountPercent == 2.3 // equal to a numeric literal
letter == 'y' // equal to a char literal
isValid == true // equal to a true value
Description
•• You can use the relational operators to create a Boolean expression that compares
two operands and returns a Boolean value that is either true or false.
•• If you compare two numeric operands that are not of the same type, Java converts
the less precise operand to the type of the more precise operand before comparing
the operands.
•• A variable of the boolean type stores a Boolean value of true or false.
•• The floating-point types (double and float) don’t always represent the exact value of
a number. As a result, you shouldn’t use the equals operator (==) to compare them
for equality.
•• String objects are reference types, not primitive types. As a result, you shouldn’t
use the equals operator (==) to compare them for equality. Instead, you should use
the equals or equalsIgnoreCase methods of the String class as described in
chapter 3.
Logical operators
Operator Name Description
&& And Returns a true value if both expressions are true. This operator
only evaluates the second expression if necessary.
|| Or Returns a true value if either expression is true. This operator
only evaluates the second expression if necessary.
! Not Reverses the value of the expression.
(subtotal > 250 && subtotal < 500) || isValid // 2 logical operators
Description
•• You can use the logical operators to create a Boolean expression that combines two
or more Boolean expressions.
•• Since the && and || operators only evaluate the second expression if necessary,
they’re sometimes referred to as short-circuit operators and are slightly more
efficient than the & and | operators.
•• By default, Not operations are performed first, followed by And operations, and
then Or operations. These operations are performed after arithmetic operations and
relational operations.
•• You can use parentheses to change the sequence of operations. In addition, you can
use parentheses to clarify the sequence of operations.
Description
•• An if/else statement, or just if statement, always contains an if clause. In addition, it
can contain one or more else if clauses, and one else clause.
•• A pair of braces defines a block of code. Any variables declared within a block have
block scope. As a result, they can only be used within that block.
•• Java evaluates if/else statements from the top down. Once a clause evaluates to true,
Java skips the rest of the if/else statement. As a result, it’s most efficient to code the
most likely conditions first and the least likely conditions last.
If efficiency isn’t your primary concern, you should code the conditions
in a logical sequence. For example, you could start by coding a condition that
checks for the highest subtotal and work your way down to the lowest subtotal.
This would simplify the condition for each clause by removing the need for the
logical operators. As always, the easier your code is to read and understand, the
easier it is to test, debug, and maintain.
The fourth example of this figure shows an if/else statement that contains
multiple statements within each clause. Here, the first statement sets the variable
named discountPercent, and the second statement sets the variable named
shippingMethod. Since these clauses contain multiple statements, the braces are
required.
If a clause only contains a single statement, the braces are optional. In that
case, you can just end the clause with a semicolon as shown in the fifth and sixth
examples. Here, the fifth example shows an if/else statement that uses two lines
per clause. Then, the sixth example shows an if statement that uses one line.
Some programmers prefer the second approach since it clearly shows that the
clause should only contain a single statement.
However, it’s generally considered a good coding style to use braces for all
if/else statements. That’s why the first three examples in part 1 of this figure use
them. That way, you won’t introduce bugs later if you add more statements and
forget to add the braces.
When coding if statements, it’s a common practice to code one if state-
ment within another if statement. This is known as nesting if statements, and
it’s shown by the third example in this figure. When you nest if statements,
it’s a good practice to indent the nested statements and their clauses since this
allows the programmer to easily identify where each nested statement begins
and ends. In this figure, for example, Java only executes the nested statement if
the customer type is “r”. Otherwise, it executes the statements in the outer else
clause.
Chapter 8 How to code control statements 205
Nested if statements
double discountPercent;
if (customerType.equals("r")) {
if (subtotal >= 100) { // begin nested if
discountPercent = .2;
} else {
discountPercent =.1;
} // end nested if
}
else {
discountPercent = .4;
}
Description
•• If a clause in an if/else statement contains just one statement, you don’t have to
enclose the statement in braces. You can just end the clause with a semicolon.
•• It’s generally considered a good coding style to use braces for all if/else statements.
That way, you won’t introduce bugs later if you add more statements and forget to
add the braces.
•• Whenever necessary, you can nest one if statement within another.
Description
•• Prior to Java 7, the switch statement could only be used with an expression that
evaluated to one of these integer types: char, byte, short, or int.
•• Starting with Java 7, the switch statement can also be used with string expressions.
Then, the switch statement uses the equals method of the String object to compare
the strings. As a result, the strings in switch statements are case-sensitive.
•• The switch statement transfers control to the appropriate case label. If control isn’t
transferred to one of the case labels, the optional default label is executed.
•• For primitive types, switch statements are generally more efficient than if/else
statements.
The third example shows how to code a switch statement that sets a day
variable to “weekday” or “weekend” depending on the value of the integer in the
variable named dayOfWeek. Here, the case labels for 1, 2, 3, and 4 don’t contain
any statements, so execution falls through to the case label for 5. As a result, day
is set to “weekday” for any of those values. Similarly, whenever dayOfWeek
equals 6 or 7, day is set to “weekend”.
Although a break statement is coded at the end of the last case label in this
example, you should know that it isn’t required. If you omit this break statement,
program execution automatically falls through to the statement that follows
the switch statement. However, it’s generally considered a good programming
practice to code a break statement at the end of the last case label. That way,
if you add a new case label after the last case label, your switch statement still
works correctly. Similarly, if you move the last case label so it occurs earlier in
the switch statement, it still works correctly.
When you code switch statements, you can nest one statement within
another. You can also nest if/else statements within switch statements and switch
statements within if/else statements. Here again, you should try to code the state-
ments with a logical structure that is relatively easy to understand. If necessary,
you can also add comments that clarify the logic of your code.
Chapter 8 How to code control statements 209
Description
•• If a case label doesn’t contain a break statement, code execution falls through to the
next label. Otherwise, the break statement ends the switch statement.
•• The case labels can be coded in any sequence.
The console
Welcome to the Invoice Calculator
INVOICE
Subtotal: $100.00
Discount percent: 10%
Discount amount: $10.00
Total before tax: $90.00
Sales tax: $4.50
Invoice total: $94.50
Continue? (y/n): n
Bye!
Description
•• In a while loop, the condition is tested before the loop is executed.
•• A while loop executes the block of statements within the loop as long as its
Boolean expression is true.
•• If a loop requires more than one statement, you must enclose the statements in
braces. This identifies the block of statements that are executed by the loop, and
any variables or constants that are declared in that block have block scope.
•• If a loop requires just one statement, you don’t have to enclose the statement in
braces. However, it’s generally considered a good practice to use braces to identify
the statements that are executed by the loop.
•• If the condition for a loop never becomes false, the loop never ends. This is known
as an infinite loop. Although infinite loops can be useful at times, beginning
programmers often code them accidentally. In Eclipse, you can cancel an infinite
loop by clicking on the Terminate button in the Console window.
Description
•• A do-while loop works like a while loop, except that the condition is tested after the
loop is executed.
•• In general, while loops are preferred over do-while loops. In practice, while loops
are commonly used and do-while loops are rarely used.
•• One problem with a do-while loop is that it’s possible for the while statement to
get separated from the loop if a programmer inserts code between the loop and the
while statement. This can introduce a bug that’s difficult to find and fix.
Description
•• A for loop is useful when you need to increment or decrement a counter that
determines how many times the loop is executed.
•• Within the parentheses of a for loop, you code an initialization expression that gives
the starting value for the counter, a Boolean expression that determines when the
loop ends, and an increment expression that increments or decrements the counter.
•• The loop ends when the Boolean expression is false.
•• If necessary, you can declare the counter variable before the for loop. Then, this
variable is in scope after the loop finishes executing.
•• Within the parentheses of a for loop, all three expressions are optional. As a result,
you can code an infinite for loop by coding the semicolons that separate these
expressions but by not coding any of these expressions.
The console
2
5
7
value found - exit loop!
The console
invalid value – continue loop!
0
1
2
invalid value – continue loop!
Description
•• To jump to the end of the current loop, you can use the break statement.
•• To skip the rest of the statements in the current loop and jump to the top of the
current loop, you can use the continue statement.
Description
An exception is an object that contains information about an error that has occurred.
When an error occurs in a method, the method throws an exception.
If an exception is thrown when you’re testing a console application, some
information about the exception, including its name and stack trace, is displayed at
the console.
A stack trace is a list of the methods that were called before the exception occurred.
The list appears in reverse order, from the last method called to the first method
called.
All exceptions are subclasses of the Exception class. The Exception class
represents the most general type of exception. Each successive layer of subclasses
represents more specific exceptions.
The RuntimeException class represents exceptions that occur at runtime. All of the
exceptions described in this chapter are runtime exceptions.
Console output
Enter monthly investment: $100
Error! Invalid number. Try again.
Description
•• In a try statement (or try/catch statement), you code any statements that may throw
an exception in a try block. Then, you can code a catch block that handles any
exceptions that may occur in the try block.
•• When an exception occurs, any remaining statements in the try block are skipped
and the statements in the catch block are executed.
•• Any variables or objects that are used in both the try and catch blocks must be
declared before the try and catch blocks so both the try and catch blocks can access
them.
•• If you use a catch block to catch a specific type of exception, you should also
import the package that contains that exception class.
The code
Part 1 of this figure shows the Financial class that’s stored in the package
named murach.calculators. This class contains a single static method named
calculateFutureValue. This method accepts three arguments: (1) the monthly
investment, (2) the yearly interest rate, and (3) the number of years. From these
arguments, this method calculates the future value and returns it.
Within this method, the first two statements convert the yearly values to
monthly values. To do that, the first statement divides the yearly interest rate by
12 to convert it to a monthly interest rate, and divides that rate by 100 to convert
it to a percent value. Then, the second statement multiples the number of years
by 12 to get the number of months.
After this method creates the monthly variables, it uses a for loop to calcu-
late the future value. To do that, it executes the loop once for each month.
Within the loop, the first statement adds the monthly investment to the future
value. The second statement calculates the amount of interest for the month. And
the third statement adds the interest to the future value. After the loop, the return
statement method returns the future value to the calling method.
Chapter 8 How to code control statements 225
The console
Welcome to the Future Value Calculator
Continue? (y/n): y
Continue? (y/n): n
Bye!
return futureValue;
}
}
Part 2 of this figure shows the Console class that’s stored in the package
named murach.ui. This class contains static methods that display data on the
console and get input from the console.
To start, this class begins with the import statement for the Scanner class.
Then, within the class, the first statement declares a static instance variable for
a Scanner object named sc and creates this object. As a result, all of the static
methods in this class can use that Scanner object.
The two displayLine methods use the println method of the System.out
object to display data to the console. Here, the first displayLine method displays
a blank line, and the second displayLine method displays the specified string on
its own line.
The getString method begins by displaying the specified string to prompt the
user to enter data. For example, you could specify a string of “Enter your name:”
to prompt the user to enter a string. Then, this method uses the nextLine method
of the Scanner object to get a String object for the data that the user enters, and it
returns that String object.
The getInt method begins by declaring an int variable named i. This variable
stores the int value that’s returned by this method. Then, this method uses an
infinite while loop to continue prompting the user until he or she enters a valid
integer. Within the infinite while loop, the first statement displays the prompt.
For example, you specify a string of “Enter years:” to prompt the user to enter an
integer for the number of years.
After the prompt, this method uses a try/catch statement. Within the try
block, the first statement attempts to convert the data that the user enters to an
integer. If this conversion throws a NumberFormatException, the catch block
prints an error message that indicates that the user didn’t enter a valid integer
and the while loop continues. As a result, it prompts the user for the integer
again.
However, if this conversion succeeds, the code in the try block stores the
integer in the variable named i. Then, the try block calls the break statement.
This exits the while loop, which returns the integer stored in the variable
named i.
The getDouble method works like the getInt method. However, it works with
the double type instead of the int type.
Chapter 8 How to code control statements 227
import java.util.Scanner;
Part 3 of this figure shows the Main class that’s stored in the package named
murach.ui. This class contains the main method for the application. Much of the
code for this method works like the main method for the Line Item application
presented in chapter 3. As a result, the following description focuses on the new
skills that were presented in this chapter.
To start, this application begins with import statements that import the
NumberFormat class and the Financial class shown in part 1 of this figure. As a
result, this application can use the Financial class to calculate the future value,
and it can use the NumberFormat class to format the future value.
Within the main method, the first two statements use the Console class to
display a welcome message. Then, within the while loop, the first three state-
ments use the getDouble and getInt methods of Console class. These statements
get the double and int values that correspond with the monthly investment, the
yearly interest rate, and number of years. Here, the Console class converts the
string that’s entered by the user to the correct numeric type and handles the
exception that’s thrown if the user enters an invalid number. As a result, it makes
it easy to get numeric data from the user.
After getting the numeric data from the user, this code uses the Financial
class shown earlier to calculate the future value. Then, this code uses the
Console class and the NumberFormat class to display the future value with
currency formatting.
After displaying the future value, this code uses the Console class to ask
the user if he or she wants to continue. To do that, this code uses the getString
method to get the data that’s entered by the user.
Chapter 8 How to code control statements 229
import java.text.NumberFormat;
import murach.calculators.Financial;
Perspective
If this chapter has succeeded, you should now be able to use if, switch,
while, do-while, and for statements. These are the Java statements that imple-
ment the selection, case, and iteration structures, and they provide the logic of
an application. You should also be able to code try/catch statements that handle
some runtime exceptions that occur when the user enters invalid numbers.
Summary
•• You can use the relational operators to create Boolean expressions that
compare primitive data types and return true or false values, and you can use
the logical operators to connect two or more Boolean expressions.
•• To determine whether two strings are equal, you can call the equals or
equalsIgnoreCase method from a String object.
•• You can use if/else statements and switch statements to control the logic of
an application, and you can nest these statements whenever necessary.
•• You can use while, do-while, and for loops to repeatedly execute one or more
statements until a Boolean expression evaluates to false, and you can nest
these statements whenever necessary.
•• You can use break statements to jump to the end of the current loop, and you
can use continue statements to jump to the start of the current loop.
•• An exception is an object that’s created from the Exception class or one
of its subclasses. This object contains information about an error that has
occurred.
•• The stack trace is a list of methods that were called before an exception
occurred.
•• You can code a try statement to create an exception handler that catches and
handles any exceptions that are thrown. This is known as exception handling.
Chapter 8 How to code control statements 231
Description
•• You can initialize a String variable by assigning a String literal or another variable
that refers to a String object.
•• To join (or concatenate) one string with another string or another data type, you can
use the + operator.
•• To append a string or another data type to a string, you can use the += operator.
•• When you join or append other data types to a String object, Java automatically
converts the other data types to String objects so they can be used as part of the
string.
Description
•• The String class provides methods that you can use to compare strings.
•• The equality operator (==) checks whether two strings refer to the same String
object. It’s possible for two strings to contain the same characters, but to refer
to different String objects. As a result, you should not use this operator to check
whether two strings contain the same characters.
Code that gets the index values for the two spaces
String name = "Martin Van Buren";
int index1 = name.indexOf(" "); // index1 is 6
int index2 = name.indexOf(" ", index1+1); // index2 is 10
Another way to get the index values for the two spaces
String name = "Martin Van Buren";
int index1 = name.lastIndexOf(" "); // index1 is 10
int index2 = name.lastIndexOf(" ", index1-1); // index2 is 6
Description
•• You can use an index to refer to each character within a string where 0 is the first
character, 1 is the second character, and so on.
Code that removes spaces from the start and end of a string
String choice = " y ";
choice = choice.trim(); // choice is "y"
Code that parses a first name and last name from a string
String name = "Mike Murach";
int index = name.indexOf(" "); // index is 4
String firstName = name.substring(0, index); // firstName is "Mike"
String lastName = name.substring(index + 1); // lastName is "Murach"
Description
•• String objects are immutable. As a result, they can’t grow or shrink.
•• StringBuilder objects are mutable, which means you can modify the characters
in the string. The capacity of a StringBuilder object is automatically increased if
necessary.
•• The StringBuilder class was introduced with Java 5. It’s designed to replace the
older StringBuffer class.
•• The StringBuffer class has identical constructors and methods as the StringBuilder
class. As a result, you can use it to accomplish the same tasks.
•• The StringBuffer class isn’t as efficient as the StringBuilder class, but it is
thread-safe. As a result, you can use it instead of the StringBuilder class whenever
you need to make sure your code is thread-safe.
As you learned earlier in this chapter, you can accomplish the same task
by using the String class and the += operator. However, if you do that, Java
must create a new String object for each statement. In contrast, when you
use the append method of the StringBuilder class, Java doesn’t create a new
StringBuilder object. Instead, it increases the length of the StringBuilder object.
If necessary, it also increases the capacity of the StringBuilder object. As a
result, the StringBuilder object usually works more efficiently than the String
object.
The second example in figure 9-5 shows how a StringBuilder object
automatically increases its capacity as the length of the string increases. Here,
the first statement creates an empty StringBuilder object with a capacity of 8
characters. The second statement uses the capacity method to verify that the
capacity is 8. The third statement appends a string of 17 characters to the empty
string. Since this exceeds the capacity of the StringBuilder object, Java automati-
cally increases the capacity by doubling the current capacity and adding 2. As a
result, this code increases the capacity from 8 to 18 characters. Then, the last two
statements verify the new length and capacity.
Description
•• The StringBuilder class provides many of the same methods as the String class. In
addition, it contains some methods that make it easier to modify strings.
The console
Welcome to the Product Lister
import murach.db.ProductDB;
import murach.business.Product;
list.append(
StringUtil.pad("=========", CODE_WIDTH));
list.append(
StringUtil.pad("=================================", DESC_WIDTH));
list.append(
StringUtil.pad("=========", PRICE_WIDTH));
list.append("\n");
list.append(
StringUtil.pad(product.getCode(), CODE_WIDTH));
list.append(
StringUtil.pad(product.getDescription(), DESC_WIDTH));
list.append(
StringUtil.pad(product.getPriceFormatted(), PRICE_WIDTH));
list.append("\n");
Perspective
Now that you’ve finished this chapter, you should be able to use the String
and StringBuilder classes to work with strings. These skills are fundamental to
developing Java applications. Keep in mind that this chapter has only covered
some of the most useful methods of these classes. As a result, if you want to
learn about the other methods of these classes, you can look them up in the
documentation for the Java API.
Summary
•• You can use methods of the String class to compare all or part of a string,
locate a string within another string, and return parts of a string.
•• When working with strings, you often need to use an index to refer to the
characters that make up the string. In a string, the first character has an index
of 0, the second character has an index of 1, and so on.
•• String objects are immutable. As a result, you can’t add, delete, or modify
individual characters in a string.
•• StringBuilder objects are mutable. As a result, you can use the methods of
the StringBuilder class to append, insert, delete, or replace characters in a
StringBuilder object.
•• StringBuilder objects are more efficient than String objects, especially if you
need to modify the string that you’re working with.
Chapter 9 How to work with strings 251
Or this:
Other examples
An array of String objects
String[] titles = new String[3];
Description
•• An array can store multiple primitive types such as int values or multiple reference
types such as String objects. An element is one of the items in an array.
•• To create an array, you must declare a variable of the correct type and instantiate an array
object that the variable refers to. You can declare and instantiate the array in separate
statements, or you can combine the declaration and instantiation into a single statement.
•• To declare an array variable, you code a set of empty brackets after the type or the
variable name.
•• To instantiate an array, you use the new keyword and specify the length, or size, of
the array in brackets following the array type.
•• When you instantiate an array of primitive types, numeric types are set to zeros and
boolean types to false. When you create an array of reference types, they are set to nulls.
The syntax for creating an array and assigning values in one statement
type[] arrayName = {value1, value2, value3, ...};
Description
•• To refer to the elements in an array, you use an index that ranges from zero (the first
element in the array) to one less than the number of elements in the array.
•• If you specify an index that’s less than zero or greater than the upper bound of the
array, Java throws an ArrayIndexOutOfBoundsException.
•• You can instantiate an array and provide initial values in a single statement by
listing the values in braces. The number of values you provide determines the size
of the array.
14.95
12.95
11.95
9.95
Description
•• You can use for loops to process each element in an array.
•• You can use the length field of an array to determine the number of elements in the
array.
14.95
12.95
11.95
9.95
Description
•• Java 5 introduced the enhanced for loop. This loop simplifies the code required
to loop through arrays. The enhanced for loop is sometimes called a foreach loop
because it lets you process each element of an array.
•• Within the parentheses of an enhanced for loop, you declare a variable with the
same type as the array followed by a colon and the name of the array.
•• With each iteration of the loop, the variable that’s declared by the for loop is
assigned the value of the next element in the array.
•• You can also use enhanced for loops to work with collections as described in
chapter 14.
Description
Two-dimensional arrays use two indexes and allow data to be stored in a table that
consists of rows and columns. This can also be thought of as an array of arrays
where each row is a separate array of columns.
Most two-dimensional arrays are rectangular arrays where each row has the same
number of columns. However, it’s also possible to create jagged arrays where each
row may have a different number of columns.
If necessary, you can extend this two-dimensional syntax to work with arrays that
have more than two dimensions.
Figure 10-5 How to work with rectangular arrays
264 Section 2 Essential skills as you need them
0 1 2 3 4 5 6 7 8 9
Description
•• All of these methods accept arrays of primitive data types and arrays of objects for
the array argument, and they all accept primitive types and objects for the value
argument.
•• For the sort method to work correctly with an array of objects created from a
user-defined class, such as the Product class, the class must implement the
Comparable interface. For more information about implementing interfaces, see
chapter 12.
The first example in figure 10-7 shows how this works. Here, the code
creates two variables that refer to the same array. More specifically, the grades
variable and the percentages variable both refer to the same array. As a result,
any change to the grades variable is reflected by the percentages variable and
vice versa. In this example, for instance, the third statement sets percentages[1]
to 70.2. As a result, this change is reflected by grades[1]. This is shown by the
statement that prints grades[1]. Since the percentages and grades variables both
refer to the same array, this statement prints the value 70.2.
Description
•• Like a string, an array is a reference type.
•• To create a reference to an existing array, you can use the assignment operator (=)
to assign a variable that points to an existing array to another variable. Then, both
variables point to the same array.
•• To check if two array variables refer to the same array, you can use the equality
operator (==).
•• The copyOf method was introduced with Java 6. As a result, it only works with
Java 6 and later. Prior to Java 6, you can use the arraycopy method of the System
class.
•• When you copy an array, the new array must be the same type as the source array.
The console
Welcome to the Month Selector
Continue? (y/n): y
Continue? (y/n): n
// validate input
if (monthNumber < 1 || monthNumber > monthName.length) {
Console.displayLine("Invalid month number. Try again.");
continue;
}
// display output
int monthIndex = monthNumber - 1;
Console.displayLine("You selected: "
+ monthName[monthIndex] + "\n");
Perspective
Now that you’ve finished this chapter, you should know how to work with
one-dimensional and two-dimensional arrays. Although arrays are a core part
of Java, they may not always provide the functionality you need. In many
cases, it’s preferable to use a more advanced data structure called a collection.
For example, instead of using an array as shown in this chapter, you may want
to use an ArrayList object as shown in chapter 14.
Summary
•• An array is a special type of object that can store multiple elements of the
same type.
•• When working with arrays, you can use an index to identify any element
in the array. An index of 0 refers to the first element, 1 refers to the second
element, and so on.
•• The length (or size) of an array is the number of elements that are in the
array.
•• For loops are often used to process arrays. Java 5 introduced a new type of
for loop, called an enhanced for loop or a foreach loop, that lets you process
each element of an array without using indexes.
•• A one-dimensional array provides for a single column of elements. In
contrast, a two-dimensional array, or an array of arrays, provides for a table
of elements that has rows and columns.
•• A two-dimensional array can be rectangular, where each row has the same
number of columns, or jagged, where each row may have a different number
of columns.
•• You can use the Arrays class to fill, sort, search, copy, and compare arrays.
•• Like a string, an array is a reference type. As a result, you should use the
copy method of the Arrays class if you want to copy the data of an array, and
you should use the equals method of the Arrays object if you want to check
whether two arrays store the same data.
Chapter 10 How to work with arrays 271
Average: 50.9526671843517
4. Use the sort method of the Arrays class to sort the values in the array, and
print the median value (the 50th value) to the console like this:
Median: 52.18369291650803
5. Print the 9th value of the array to the console and every 9th value after that like
this:
Position: 9 8.927702403161032
Position: 18 14.053128749806076
...
Position: 99 22.471670293184822
272 Section 2 Essential skills as you need them
Object-oriented
programming skills
In the first section of this book, you learned how to create your own classes
and use them to create a well-structured, object-oriented application. That’s
a great start to object-oriented programming. Now, the chapters in this
section teach the rest of the skills for object-oriented programming that you
should know. Chapter 11 shows you how to use inheritance, an important
object-oriented skill. Chapter 12 shows you how to use interfaces, another
important object-oriented skill. And chapter 13 shows several more skills
including how to work with inner classes, how to work with enumerations,
and how to add API documentation to the classes that you create.
Because each of the chapters in this section builds on the previous
chapters, we recommend reading these chapters in sequence. In addition,
we recommend reading all of the chapters in this section before going on
to section 4 or 5. That’s because most of the chapters in sections 4 and 5
expect you to understand how inheritance, interfaces, inner classes, and
enumerations work.
11
How to work
with inheritance
Inheritance is one of the key concepts of object-oriented programming. It
lets you create a class that’s based on another class. When used correctly,
inheritance can reduce code duplication and simplify the overall design of an
application.
An introduction to inheritance...........................................276
How inheritance works.................................................................................276
How the Object class works..........................................................................278
Basic skills for working with inheritance..........................280
How to create a superclass........................................................................... 280
How to create a subclass...............................................................................282
How polymorphism works.......................................................................... 284
The Product application.....................................................286
The console...................................................................................................286
The Product, Book, and Software classes....................................................288
The ProductDB class....................................................................................288
The ProductApp class...................................................................................292
More skills for working with inheritance...........................294
How to cast objects.......................................................................................294
How to compare objects...............................................................................296
How to work with the abstract and final keywords..........298
How to work with the abstract keyword.......................................................298
How to work with the final keyword........................................................... 300
Perspective..........................................................................302
276 Section 3 Object-oriented programming skills
An introduction to inheritance
Inheritance allows you to create a class that’s based on another class. The
next two figures introduce some of the basic concepts of inheritance.
Description
•• Inheritance lets you create a new class based on an existing class. Then, the new
class inherits the fields and methods of the existing class.
•• A class that inherits from an existing class is called a derived class, child class, or
subclass. A class that another class inherits is called a base class, parent class, or
superclass.
•• A subclass can extend the superclass by adding new fields and methods to the
superclass. It can also override a method from the superclass with its own version
of the method.
Description
•• The Object class in the java.lang package is the superclass for all classes. In other
words, every class inherits the Object class or some other class that ultimately
inherits the Object class. As a result, the methods defined by the Object class are
available to all classes.
•• When coding classes, it’s recommended to override the toString method so that it
returns a string that’s concise, informative, and easy for a person to read.
Access modifiers
Keyword Description
private Available within the current class.
public Available to classes in all packages.
protected Available to classes in the same package and to subclasses.
no keyword coded Available to classes in the same package.
import java.text.NumberFormat;
public Product() {
}
// get and set accessors for the code, description, and price
// instance variables
@Override
public String toString() {
return description;
}
Description
•• Access modifiers specify the accessibility of the members declared by a class.
•• Protected members are accessible to the current class, to other classes in the same
package, and to subclasses.
•• An annotation is a standard way to provide information about your code. When you
override a method, you can add the @Override annotation to the method.
public Book() {
super(); // call constructor of Product superclass
author = "";
count++;
}
@Override
public String toString() { // override the toString method
return super.toString() + // call method of Product superclass
" by " + author;
}
}
Description
•• You can directly access fields that have public or protected access in the superclass
from the subclass.
•• You can extend the superclass by adding new fields and methods to the subclass.
•• You can override the public and protected methods in the superclass by coding
methods in the subclass that have the same signatures as methods in the superclass.
However, you can’t override private methods in the superclass because they aren’t
available to the subclass.
•• You use the super keyword to call a constructor or method of the superclass. If you
call a constructor of the superclass, it must be the first statement in the constructor
of the subclass.
Product p;
p = b;
System.out.println(p.toString()); // calls toString from the Book class
p = s;
System.out.println(p.toString()); // calls toString from the Software class
Description
•• Polymorphism is a feature of inheritance that lets you treat objects of different
subclasses that are derived from the same superclass as if they had the type of the
superclass. If, for example, Book is a subclass of Product, you can treat a Book
object as if it were a Product object.
•• If you access a method of a superclass object and the method is overridden in the
subclasses of that class, polymorphism determines which method is executed based
on the object’s type. For example, if you call the toString method of a Product
object, the toString method of the Book class is executed if the object is a Book
object.
The console
Figure 11-6 shows the console for the Product application. This application
works much like the Product application presented in chapter 4. However, there
are three main differences. First, this application displays an additional piece of
information about each product, which varies depending on whether the product
is a book or software. In particular, it displays an author for a book and a version
number for software. Second, this application displays a count of the total
number of objects it has created. Third, if the user enters an invalid product code,
the application displays an appropriate error message.
Chapter 11 How to work with inheritance 287
Product count: 1
Continue? (y/n): y
Product count: 2
Continue? (y/n): y
Continue? (y/n):
Description
•• This version of the Product application handles two types of products: books and
software.
•• If you enter the product code for a book, the information about the product includes
an author.
•• If you enter the product code for software, the information about the product
includes a version number.
import java.text.NumberFormat;
public Product() {}
@Override
public String toString() {
return description;
}
public Book() {
super();
author = "";
count++;
}
@Override
public String toString() {
return super.toString() + " by " + author;
}
}
public Software() {
super();
version = "";
count++;
}
@Override
public String toString() {
return super.toString() + " " + version;
}
}
Figure 11-8 The code for the Book and Software classes
Chapter 11 How to work with inheritance 291
import murach.business.Book;
import murach.business.Product;
import murach.business.Software;
Product p = null;
if (productCode.equalsIgnoreCase("java")
|| productCode.equalsIgnoreCase("jsp")
|| productCode.equalsIgnoreCase("mysql")) {
Book b = new Book();
if (productCode.equalsIgnoreCase("java")) {
b.setCode(productCode);
b.setDescription("Murach's Java Programming");
b.setPrice(57.50);
b.setAuthor("Joel Murach");
} else if (productCode.equalsIgnoreCase("jsp")) {
b.setCode(productCode);
b.setDescription("Murach's Java Servlets and JSP");
b.setPrice(57.50);
b.setAuthor("Mike Urban");
} else if (productCode.equalsIgnoreCase("mysql")) {
b.setCode(productCode);
b.setDescription("Murach's MySQL");
b.setPrice(54.50);
b.setAuthor("Joel Murach");
}
p = b; // set Product object equal to the Book object
} else if (productCode.equalsIgnoreCase("eclipse")) {
Software s = new Software();
s.setCode("eclipse");
s.setDescription("Eclipse");
s.setPrice(0.00);
s.setVersion("4.4.2");
p = s; // set Product object equal to the Software object
}
return p;
}
}
import java.util.Scanner;
import murach.db.ProductDB;
import murach.business.Product;
System.out.println();
System.out.println("Product count: " + Product.getCount() + "\n");
The console
This is a Book object
Description
•• Java can implicitly cast a subclass to a superclass. As a result, you can use a
subclass whenever a reference to its superclass is called for. For example, you can
specify a Book object whenever a Product object is expected because Book is a
subclass of Product.
•• You must explicitly cast a superclass object when a reference to one of its
subclasses is required. For example, you must explicitly cast a Product object to
Book if a Book object is expected. This only works if the Product object is a valid
Book object. Otherwise, this throws a ClassCastException.
•• Casting affects the methods that are available from an object. For example, if you
store a Book object in a Product variable, you can’t call the setAuthor method
because it’s defined by the Book class, not the Product class.
•• You can use the instanceof operator to check if an object is an instance of a
particular class.
Both variables refer to different objects that store the same data
Product product1 = new Product();
Product product2 = new Product();
if (product1.equals(product2)) // expression returns false
Description
•• To test if two objects variables refer to the same object, you can use the equals
method of the Object class.
•• To test if two objects store the same data, you can override the equals method in the
subclass so it tests whether all instance variables in the two objects are equal.
•• Many classes from the Java API (such as the String class) already override the
equals method to test for equality.
@Override
public String toString() {
return description;
}
@Override
public String getDisplayText() { // implement the abstract method
return super.toString() + " by " + author;
}
}
Description
•• An abstract class is a class that can be inherited by other classes but that you can’t
use to create an object. To declare an abstract class, code the abstract keyword in
the class declaration.
•• An abstract class can contain fields, constructors, and methods just like other
superclasses. In addition, an abstract class can contain abstract methods.
•• To create an abstract method, you code the abstract keyword in the method declara-
tion and you omit the method body. Abstract methods cannot have private access.
However, they may have protected or default access (no access modifier).
•• When a subclass inherits an abstract class, all abstract methods in the abstract class
must be overridden in the subclass. Otherwise, the subclass must also be abstract.
•• An abstract class doesn’t have to contain abstract methods. However, any class that
contains an abstract method must be declared as abstract.
A final class
public final class Book extends Product {
// all methods in the class are automatically final
}
A final method
public final String getVersion() {
return version;
}
A final parameter
public void setVersion(final String version) {
Description
•• To prevent a class from being inherited, you can create a final class by coding the
final keyword in the class declaration.
•• To prevent subclasses from overriding a method of a superclass, you can create a
final method by coding the final keyword in the method declaration. In addition, all
methods in a final class are automatically final methods.
•• To prevent a method from assigning a new value to a parameter, you can code the
final keyword in the parameter declaration to create a final parameter. Then, if a
statement in the method tries to assign a new value to the parameter, the compiler
reports an error.
Perspective
Conceptually, this is one of the most difficult chapters in this book.
Although the basic idea of inheritance isn’t that difficult to understand, the
complications of polymorphism, overriding, and casting make inheritance
a difficult topic. So if you find yourself a bit confused right now, don’t be
disheartened. It will become clearer as you actually use the techniques you’ve
learned here and see them used in the Java API.
The good news is that you don’t have to understand every nuance of how
inheritance works to use it. In fact, since all classes automatically inherit the
Object class, you’ve already been using inheritance without even knowing
it. Now that you’ve completed this chapter, you should have a better under-
standing of how the Java API works. In addition, you should have a better idea
of how you can use inheritance to improve the design of your own classes.
Summary
•• Inheritance lets you create a new class based on an existing class. The
existing class is called the superclass, base class, or parent class, and the
new class is called the subclass, derived class, or child class.
•• A subclass inherits all of the fields and methods of its superclass that aren’t
private. The subclass can extend the superclass by adding its own fields and
methods, and it can override a method with a new version of the method.
•• All classes inherit the java.lang.Object class. This class provides methods,
such as the toString and equals methods, that are available to all classes.
•• You can use access modifiers to limit the accessibility of the fields and
methods declared by a class. Protected members can be accessed only by
classes in the same package or by subclasses.
•• An annotation is a standard way to provide information about your code
to other software tools and developers. When you override a method, it’s
generally considered a good practice to add the @Override annotation to the
method.
•• In a subclass, you can use the super keyword to access the fields, construc-
tors, and methods of the superclass.
•• Polymorphism is a feature of inheritance that lets you treat subclasses as
though they were their superclass.
•• Java can implicitly cast a subclass type to its superclass type, but you must
use explicit casting to cast a superclass type to a subclass type.
•• You can use the instanceof operator to check if an object is an instance of a
particular class.
•• Abstract classes can be inherited by other classes but can’t be used to create
an object. Abstract classes can include abstract methods.
Chapter 11 How to work with inheritance 303
•• If you extend an abstract class, you must implement all abstract methods.
Otherwise, you must also declare your class as abstract.
•• You can use the final keyword to declare final classes, final methods, and
final parameters. No class can inherit a final class, no method can override a
final method, and no statement can assign a new value to a final parameter.
Product count: 1
3. Open the Product class, and add an equals method as shown in this chapter.
Then, run the project again. This time, the output should indicate that the
products are being compared based on their data like this:
4. Repeat step 3 for the LineItem class. This time, the comparisons for both the
products and line items should be based on their data like this:
An introduction to interfaces.............................................308
A simple interface........................................................................................ 308
Interfaces compared to abstract classes....................................................... 310
Basic skills for working with interfaces............................312
How to code an interface..............................................................................312
How to implement an interface.................................................................... 314
How to inherit a class and implement an interface...................................... 316
How to use an interface as a parameter........................................................ 318
How to use inheritance with interfaces........................................................320
New features for working with interfaces.........................322
How to work with default methods...............................................................322
How to work with static methods.................................................................324
The Product Viewer application.........................................326
The console...................................................................................................326
The ProductReader interface........................................................................326
The ProductDB class....................................................................................326
The ProductApp class...................................................................................328
Perspective..........................................................................330
308 Section 3 Object-oriented programming skills
An introduction to interfaces
In some object-oriented programming languages, such as C++, a class can
inherit more than one class. This is known as multiple inheritance. Although
Java doesn’t support multiple inheritance, it does support a special type of
coding element known as an interface. An interface provides many of the advan-
tages of multiple inheritance without some of the problems that are associated
with it.
A simple interface
Figure 12-1 illustrates how you create and use an interface. Here, the first
example shows the code for a simple interface named Printable. This code is
similar to the code that defines a class and is stored in a file named Printable.
java. However, the code for an interface uses the interface keyword instead of the
class keyword. In addition, all of the methods in an interface are automatically
public and abstract. As a result, you don’t need to code the public or abstract
keywords for the methods in an interface.
The second example shows a Product class that implements the Printable
interface. To implement the Printable interface, the declaration for the Product
class uses the implements keyword followed by the name of the interface. Then,
the body of the Product class implements the print method that’s specified by the
Printable interface.
The third example shows that a Product object that implements the Printable
interface can be stored in a variable of the Printable type. In other words, an
object created from the Product class shown in this figure is both a Product
object and a Printable object. As a result, you can use this object anywhere a
Printable object is expected as shown later in this chapter.
Chapter 12 How to work with interfaces 309
import java.text.NumberFormat;
Resulting output
Description
•• An interface can define one or more methods. These methods are automatically
public and abstract. As a result, the interface only specifies the method signatures,
not any code that implements the methods.
•• A class that implements an interface can use any constants defined by the interface.
In addition, it must provide an implementation for each abstract method defined by
the interface. If it doesn’t, it must be declared as abstract.
A Printable interface
public interface Printable {
void print();
}
Advantages of an interface
•• A class can only directly inherit one other class, but a class can implement multiple
interfaces.
Description
•• A default method of an interface works much like a regular (non-static) method of
a class.
Description
•• Declaring an interface is similar to declaring a class except that you use the inter-
face keyword instead of the class keyword.
•• In an interface, all methods are automatically declared public and abstract.
•• In an interface, all fields are automatically declared public, static, and final.
•• When working with an interface, you can code the public, abstract, and final
keywords. However, they’re optional.
•• An interface that doesn’t contain any methods is known as a tagging interface. This
type of interface is typically used to identify that an object is safe for a certain type
of operation such as cloning or serializing.
@Override
public void print() {
String dept = "Unknown";
if (department == ADMIN) {
dept = "Administration";
} else if (department == EDITORIAL) {
dept = "Editorial";
} else if (department == MARKETING) {
dept = "Marketing";
}
Description
•• To declare a class that implements an interface, you use the implements keyword.
Then, you provide an implementation for each method defined by the interface.
•• If you forget to implement a method that’s defined by an interface that you’re
implementing, the compiler will issue an error message.
•• A class that implements an interface can use any constant defined by that interface.
@Override
public void print() { // implement the Printable interface
System.out.println(super.getDescription() + " by " + author);
}
}
Description
•• A class can inherit another class and also implement one or more interfaces.
•• If a class inherits another class that implements an interface, the subclass automati-
cally implements the interface. However, you can code the implements keyword in
the subclass for clarity.
•• If a class inherits another class that implements an interface, the subclass has access
to any methods of the interface that are implemented by the superclass and can
override those methods.
Resulting output
Resulting output
Description
•• You can declare a parameter that’s used by a method as an interface type. Then, you
can pass any object that implements the interface to the parameter.
•• You can also declare a variable as an interface type. Then, you can assign an instance
of any object that implements the interface to the variable, and you can pass the
variable as an argument to a method that accepts the interface type.
A ProductReader interface
public interface ProductReader {
Product getProduct(String code);
String getProducts();
}
A ProductWriter interface
public interface ProductWriter {
boolean add(Product p);
boolean update(Product p);
boolean delete(Product p);
}
A ProductConstants interface
public interface ProductConstants {
int CODE_SIZE = 10;
int DESCRIPTION_SIZE = 34;
int PRICE_SIZE = 10;
}
Description
•• An interface can inherit one or more other interfaces by specifying the inherited
interfaces in an extends clause.
•• An interface can’t inherit a class.
•• A class that implements an interface must implement all abstract methods declared
by the interface as well as all abstract methods declared by any inherited interfaces
unless the class is defined as abstract.
•• A class that implements an interface can use any of the constants declared in the
interface as well as any constants declared by any inherited interfaces.
Description
•• With Java 8 and later, you can add regular (non-abstract) methods to an interface.
These methods are known as default methods.
•• To add a regular method to an interface, you can begin the declaration for the
method with the default keyword.
•• When you code a class that implements an interface, you don’t need to implement
its default methods. Instead, you can use the default methods defined in the inter-
face in your class. However, if you want to change the functionality of a default
method, you can override it.
Description
•• With Java 8 and later, you can include static methods in interfaces.
•• To call a static method from an interface, prefix the static method with the name of
the interface.
The console
Figure 12-10 shows the console for the Product Viewer application. From
the user’s perspective, this application works the same as earlier versions of the
Product Viewer application. In short, it allows the user to enter a product code.
Then, it displays the details of the product with the specified code.
The console
Welcome to the Product Viewer
PRODUCT
Code: java
Description: Murach's Java Programming
Price: $57.50
Continue? (y/n): n
import murach.business.Product;
import murach.business.Product;
@Override
public Product getProduct(String productCode) {
Product product = new Product();
product.setCode(productCode);
if (productCode.equalsIgnoreCase("java")) {
product.setDescription("Murach's Java Programming");
product.setPrice(57.50);
} else if (productCode.equalsIgnoreCase("jsp")) {
product.setDescription("Murach's Java Servlets and JSP");
product.setPrice(57.50);
} else if (productCode.equalsIgnoreCase("mysql")) {
product.setDescription("Murach's MySQL");
product.setPrice(54.50);
} else {
product.setDescription("Unknown");
}
return product;
}
@Override
public String getProducts() {
return "This method hasn't been implemented yet.";
}
}
import java.util.Scanner;
import murach.business.Product;
import murach.db.ProductDB;
import murach.db.ProductReader;
Perspective
In this chapter, you’ve learned how to use interfaces and how they can
be used to improve the design of an application. That means that you should
now be able to implement all types of classes that are commonly used in
business applications. In the next chapter, though, you’ll learn some additional
object-oriented skills that will round out your knowledge of object-oriented
programming.
Summary
•• An interface is a special type of coding element that can contain static
constants and abstract methods.
•• With Java 8 and later, an interface can also contain regular methods, known
as default methods, and static methods.
•• A class can only inherit one other class, but it can implement more than one
interface.
•• To implement an interface, a class must implement all the abstract methods
defined by the interface.
•• An interface can inherit other interfaces. Then, the implementing class must
also implement all the abstract methods of the inherited interfaces.
•• An interface defines a Java type. As a result, you can use an object that’s
created from a class that implements an interface anywhere that interface is
expected.
•• A class does not have to implement default methods provided by the inter-
face, but it can override them.
Two AWT classes that you can use to handle a button click
Interface/Class Description
java.awt.event.ActionListener An interface that defines the method that contains the
code that’s executed when a user clicks a button.
java.awt.event.ActionEvent A class that defines an object that contains information
about an event such as the event that occurs when a
user clicks a button.
Description
•• Most modern applications use a GUI (graphical user interface) that displays
windows and components, such as buttons, to interact with the user.
•• Swing is the most common Java library for creating GUIs. Its classes are stored in
the javax.swing package.
•• With Swing, a window is also known as a frame.
•• When you write code for a GUI, you can handle events that occur on it. For
example, you can handle the event that occurs when a user clicks on a button. To
do that, you typically code an event listener that contains the code that’s executed
when an event occurs.
•• To handle events, Swing uses interfaces and classes from another Java library, the
AWT (Abstract Window Toolkit). This library is stored in the java.awt package.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public TestFrame() {
// code that sets up the frame
this.setTitle("Test Frame");
this.setSize(400, 100);
this.setLocationByPlatform(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Description
•• An inner class is a class that’s coded within another class.
public TestFrame() {
// code that starts setting up the frame
public TestFrame() {
// code that starts setting up the frame
Description
•• An anonymous class is a type of inner class that doesn’t have a name.
•• You can code the braces for an anonymous class immediately after the parentheses
that attempt to create an object from an interface.
•• Within the braces for an anonymous class, you can supply the code that implements
the interface.
•• If you want to use the object that’s created from the inner class more than once, you
can assign that object to a variable.
Description
•• An enumeration contains a set of related constants. The constants are defined
with the int type and are assigned values from 0 to the number of constants in the
enumeration minus 1.
•• An enumeration defines a type. Because of that, you can’t specify another type
where an enumeration type is expected. That means that enumerations are type-safe.
@Override
public String toString() {
String s = "";
if (ordinal() == 0) {
s = "UPS Next Day (1 business day)";
} else if (this.ordinal() == 1) {
s = "UPS Second Day (2 business days)";
} else if (this.ordinal() == 2) {
s = "UPS Ground (5 to 7 business days)";
}
return s;
}
}
Resulting output
Description
•• All enumerations inherit the java.lang.Object and java.lang.Enum classes and can
use or override the methods of those classes or add new methods.
•• By default, the toString method of an enumeration constant returns the same string
as the name method.
•• You can use a static import to import all of the constants of an enumeration or all of
the static fields and methods of a class.
Figure 13-5 How to enhance an enumeration and work with static imports
344 Section 3 Object-oriented programming skills
import java.text.NumberFormat;
/**
* The Product class represents a product and is used by
* the LineItem and ProductDB classes.
*/
public class Product {
/**
* Creates a new Product with default values.
*/
public Product() {
code = "";
description = "";
price = 0;
}
/**
* Sets the product code to the specified String.
*/
public void setCode(String code) {
this.code = code;
}
/**
* Returns a String that represents the product code.
*/
public String getCode() {
return code;
}
...
Description
•• A javadoc comment begins with /** and ends with */, and asterisks within the
comment are ignored. You can use javadoc comments to describe a class and its
public and protected fields, constructors, and methods.
•• A comment should be placed immediately above the class or member it describes.
For a class, that means that the comment must be placed after any import
statements.
•• If you enter a slash (/) followed by two or more asterisks on a blank line before the
code for a class, field, constructor, or method in Eclipse, Eclipse generates begin-
ning javadoc comments. That includes comments with some of the javadoc tags
you’ll learn about in the next figure.
The Product class with comments that use HTML and javadoc tags
package murach.business;
/**
* The <code>Product</code> class defines a product and is used
* by the <code>LineItem</code> and <code>ProductDB</code> classes.
* @author Joel Murach
* @version 1.0.0
*/
public class Product {
private String code;
private String description;
private double price;
/**
* Creates a <code>Product</code> with default values.
*/
public Product() {
code = "";
description = "";
price = 0;
}
/**
* Sets the product code.
* @param code A <code>String</code> for the product code.
*/
public void setCode(String code) {
this.code = code;
}
/**
* Gets the product code.
* @return A <code>String</code> for the product code.
*/
public String getCode() {
return code;
}
...
Figure 13-7 How to use HTML and javadoc tags in javadoc comments
348 Section 3 Object-oriented programming skills
Description
•• To generate the documentation for a project from Eclipse, select the project in
the Package Explorer. Then, select the ProjectGenerate Javadoc command. This
displays a Generate Javadoc dialog that allows you to configure the javadoc
command.
•• The first time you generate documentation, you must use the Generate Javadoc
dialog to specify the location of the javadoc command. To do that, you can click the
Configure button and specify the location of the javadoc command. After that, you
can click the Finish button to accept the default options.
•• By default, Eclipse stores the documentation for a project in a subfolder named doc
and displays this subfolder in the Package Explorer.
•• To view the documentation for the project, use the Package Explorer to navigate to
the doc folder and double-click on the index.html file. This opens the documenta-
tion in the main Eclipse window and displays it using a built-in browser.
•• If the project already contains documentation, the top of the Generate JavaDoc
dialog warns you that the new documentation may overwrite existing files.
Figure 13-8 How to generate and view the documentation for a package
350 Section 3 Object-oriented programming skills
Perspective
Now that you’ve finished this chapter, you should understand the concepts
for working with inner classes. You should be able to create and work with
enumerations. And you should be able to document your classes so other
programmers can use them. At this point, you have all of the object-oriented
programming skills you need to learn about more of the classes that are
available from the Java API such as the collection classes described in the
next chapter. In addition, you have a solid foundation for working with GUI
programming as described at the end of this book.
Summary
•• An inner class is a class that’s coded within another class. This is useful
when a class only makes sense within the context of another class.
•• An anonymous class is a type of inner class that doesn’t have a name. This
often results in more concise code than an inner class that has a name.
•• You can use an enumeration to define a set of related constants as a type.
Then, you can use the constants in the enumeration anywhere the enumera-
tion is allowed.
•• You can use static imports to import the constants of an enumeration or the
static fields and methods of a class. Then, you can refer to the constants,
fields, and methods without qualification.
•• You can use javadoc comments to document a class and its fields, construc-
tors, and methods. Then, you can generate HTML-based documentation for
your class.
Chapter 13 How to work with inner classes, enumerations, and documentation 351
Create an enumeration
1. Import the project named ch13_ex2_Enumeration that’s in the ex_starts
folder.
2. Create an enumeration named CustomerType. This enumeration should
contain constants that represent three types of customers: retail, trade, and
college.
Use an enumeration
3. Open the CustomerTypeApp class. Then, add a method to this class that
returns a discount percent (.10 for retail, .30 for trade, and .20 for college)
depending on the CustomerType variable that’s passed to it.
4. Add code to the main method that declares a CustomerType variable, assigns
one of the customer types to it, gets the discount percent for that customer
type, and displays the discount percent. It should display a message like this
to the console:
discountPercent: 0.3
toString: TRADE
toString: Trade
8. Run the application again to view the results of the toString method.
Chapter 13 How to work with inner classes, enumerations, and documentation 353
Description
•• A collection is an object that can hold other objects. Collections are similar to
arrays, but are more flexible to use.
•• With Java 5 and later, collections use a feature known as autoboxing to automati-
cally add and remove the wrapper classes for primitive types whenever necessary.
Collection interfaces
Interface Description
Collection Defines the basic methods available for all collections.
Set Defines a collection that does not allow duplicate elements.
List Defines a collection that maintains the sequence of elements in the list. It accesses
elements by their integer index and typically allows duplicate elements.
Map Defines a map. A map is similar to a collection. However, it holds one or more
key-value pairs instead of storing only values (elements). Each key-value pair
consists of a key that uniquely identifies the value, and a value that stores the data.
Description
•• The Java collection framework is interface based, which means that each class
in the collection framework implements one of the interfaces defined by the
framework.
•• The collection framework consists of two class hierarchies: Collection and Map. A
collection stores individual objects as elements. A map stores key-value pairs where
you can use a key to retrieve a value (element).
An introduction to generics
Prior to Java 5, the elements of a collection were defined as the Object type.
As a result, you could store any type of object as an element in a collection. At
first, this flexibility might seem like an advantage. But with it comes two disad-
vantages. First, there’s no way to guarantee that only objects of a certain type are
added to a collection. For example, you can’t limit an ArrayList so it can hold
only Product objects. Second, you must use casting whenever you retrieve an
object from a collection. That’s because an element can be any type of object.
For example, to retrieve a Product object from a collection, you must cast the
object to the Product type.
Java 5 introduced a new feature called generics that addresses these two
problems. The generics feature lets you specify the element type for a collection.
Then, Java can make sure that it only adds objects of the specified type to the
collection. Conversely, Java can automatically cast any objects you retrieve from
the collection to the correct type.
Figure 14-3 shows how the generics feature works. To specify a type when
you declare a collection, you code the type in angle brackets immediately
following the name of the collection class (such as ArrayList or LinkedList).
Prior to Java 7, you had to do this twice: once when you use the collection class
to declare the collection, and again when you use the constructor of the collec-
tion class to create an instance of the collection. However, Java 7 introduced
a feature that lets you simplify this code as shown by the last example in this
figure.
The first example shows a statement that declares and instantiates an
instance of an array list collection named codes that holds String objects. Here,
<String> is specified following the ArrayList class name to indicate that the
elements of the array list must be String objects.
The second and third examples are similar, but they create collections that
can hold integers and Product objects. Here, the second example uses a wrapper
class (the Integer class) instead of the primitive type (the int type). This allows
the collection to store an array of integer values. That’s necessary because it’s
illegal to declare a collection with a primitive type like this:
ArrayList<int> numbers = new ArrayList<int>(); // illegal!
If you’re using Java 7 or later, you can omit the type from the brackets
that follow the constructor as long as the compiler can infer the type from the
context. The fourth example shows how this works. Here, the code accomplishes
the same task as the first example but without duplicating the collection type.
Since this feature results in shorter and simpler code, it’s used throughout the
rest of this chapter.
Chapter 14 How to work with collections, generics, and lambdas 363
Description
•• Generics refers to a feature that lets you create typed collections. A typed collection
is a collection that can hold only objects of a certain type. This feature was intro-
duced with Java 5.
•• To declare a variable that refers to a typed collection, you list the type in angle
brackets (<>) following the name of the collection class.
•• When you use a constructor for a typed collection, you can specify the type
variable in angle brackets following the constructor name. The type variable can’t
be a primitive type such as int or double, but it can be a wrapper class such as
Integer or Double. It can also be a user-defined class such as Product.
•• Beginning with Java 7, you can omit the type from within the brackets that follow
the constructor if the compiler can infer the type from the context. This empty set
of brackets is known as the diamond operator.
•• If you do not specify a type for a collection, the collection can hold any type of
object. However, the Java compiler will issue warning messages whenever you
access the collection to warn you that type checking can’t be performed for the
collection.
Description
•• The ArrayList class uses an array internally to store the elements in the list.
•• The capacity of an array list automatically increases whenever necessary.
•• When you create an array list, you can use the default starting capacity of 10
elements, or you can specify the starting capacity.
•• If you know the number of elements that your list needs to be able to store, you can
improve the performance of the ArrayList class by specifying a starting capacity
that’s just over that number of elements.
Resulting output
java
jsp
mysql
Resulting output
Description
•• You can use the methods of the ArrayList class to add elements to an array list and
to get elements from an array list.
Figure 14-5 How to add and get the elements of an array list
368 Section 4 More essential skills as you need them
Resulting output
Resulting output
Resulting output
Description
•• You can use the methods of the ArrayList class to replace, remove, and search the
elements of an array list.
Figure 14-6 How to replace, remove, and search the elements of an array list
370 Section 4 More essential skills as you need them
Resulting output
[1, 2, 3]
Resulting output
1
2
3
Description
•• All primitive types have corresponding wrapper classes. For example, the Integer
class is the wrapper class for the int type, the Double class is the wrapper class for
the double type, and so on.
•• To store a primitive type in a collection, you can specify its wrapper class as the
type for the collection. Then, the compiler automatically converts the primitive
value to its wrapper type when adding values to the collection. This feature is
known as autoboxing.
•• To get a primitive type from a collection, you don’t need to do anything because the
compiler automatically gets the primitive value from the wrapper class for you.
The console
Welcome to the Invoice application
Description
•• This application allows you to enter one or more line items for the invoice. When
you’re done, it displays all of the line items that you entered. In addition, it displays
the total amount for the invoice.
•• To enter a line item, enter the product code and quantity for the line item. Then,
you can enter “y” to enter another line item, or you and enter “n” to complete the
invoice.
import java.text.NumberFormat;
import java.util.ArrayList;
// the constructor
public Invoice() {
lineItems = new ArrayList<>();
}
import murach.db.ProductDB;
import murach.business.Invoice;
import murach.business.LineItem;
import murach.business.Product;
An introduction to lambdas
In the previous chapter, you learned how to use an anonymous class to
implement a method that contains the code that’s executed when an event occurs.
Then, you learned how to pass this anonymous class to another method as a
parameter. Lambda expressions allow you to do something similar, but with a
much cleaner syntax. In particular, lambda expressions allow you to specify
the code that’s executed without having to create the anonymous class and its
method to store this code. In other words, lambda expressions allow you to store
functionality of a method and pass it to another method as a parameter.
This ability to treat functionality as if it were data can result in the benefits
listed in figure 14-11. It can allow you to write methods that are more flexible.
This can greatly reduce code duplication, which can make your code easier to
maintain.
However, lambda expressions do have some drawbacks as summarized in
this figure. As a result, you might not always want to use them. Most of these
drawbacks stem from the fact that the Java virtual machine doesn’t support
lambdas. Instead, the Java compiler rewrites lambdas into “normal” Java code.
This rewriting by the compiler results in three drawbacks. First, lambda
expressions can be difficult to debug because you can’t step through them with
the debugger like normal methods. Second, when a lambda throws an exception,
the stack trace can be difficult to understand. Third, methods that use lambdas
can sometimes be inefficient compared to methods that accomplish the same task
without using lambdas.
A fourth drawback is that lambda expressions can result in code that’s
confusing and difficult to maintain. This is especially true if you use lambda
expressions in situations where they aren’t necessary.
So, when should you avoid using a lambda expression? If you find yourself
needing to perform the same task more than once, you probably want to avoid
using a lambda expression. In that case, you probably want to store the code in a
normal method so that it is reusable.
Chapter 14 How to work with collections, generics, and lambdas 379
Lambdas expressions…
•• Are anonymous functions that can be passed as arguments to methods.
•• Allow you to treat functions like data.
Description
•• Like a method, a function has parameters and returns a value. An anonymous
function is a function that doesn’t have a name.
The output
Jane Doe
George Doe
Description
•• The filterContactsWithoutPhone method accepts a list of Contact objects, finds all
the contacts in the list that have a null phone number, adds these contacts to a new
list, and returns this list to the caller.
•• In the filterContactsWithoutPhone method, the code that filters the list is hard-coded.
As a result, this method is inflexible and fragile.
A functional interface
public interface TestContact {
boolean test(Contact c);
}
Jane Doe
George Doe
Jane Doe
Description
•• A functional interface can only contain one method.
•• A method can specify a functional interface as the type for a parameter. Then,
within the method, you can call the method of the functional interface from the
parameter.
•• You can pass a lambda expression to a method that accepts a functional interface
as a parameter. To code a lambda expression, you code the variable name, followed
by the lambda operator (->), followed by an anonymous function. The anonymous
function can use the variable name to call methods from the object type that’s used
by the method.
Description
•• The Predicate interface is a functional interface that’s available from the java.util.
function package.
•• The Predicate interface uses generics to specify the type of object that’s passed to
its test method.
Perspective
Now that you’ve finished this chapter, you should know how to work with
array lists, one of the most commonly used Java collections. This includes
knowing how to use generics to specify the type of object that’s stored by
a collection. This is a good foundation for learning how to work with other
collections.
You should also understand that many collections are available from the
Java API. Each of these collections provides functionality that’s useful in
certain situations. As a result, if the collections presented in this chapter don’t
provide the functionality that your application requires, there’s a good chance
that the Java API already includes a collection that does provide this function-
ality. To find that collection and to learn how it works, you can start by looking
in the documentation for the java.util package or by searching the Internet.
Finally, you should have a general idea of how lambda expressions work.
As you might expect, there’s plenty more to learn about lambda expressions. To
do that, you can search the Internet for a tutorial or get a more advanced book
about Java programming.
Summary
•• A collection is an object that’s designed to store other objects.
•• The most commonly used collection class is the ArrayList class. An array
list uses an array internally to store its data.
•• The generics feature, which became available with Java 5, lets you specify
the type of elements a collection can store. This feature also lets you create
generic classes that work with variable data types.
•• The diamond operator, which became available with Java 7, allows you to
code an empty set of brackets (<>) in the constructor of a typed collection
instead of having to code the type within those brackets.
•• A functional interface is an interface that only contains one method.
•• A lambda expression (also known as an anonymous function) can be passed
as an argument to a method that accepts a functional interface as a param-
eter. This allows you to treat functions like data.
Chapter 14 How to work with collections, generics, and lambdas 387
BOOKS BY TITLE:
[Java Programming, Java, Paperback]
[Java Programming, Java, Electronic]
BOOKS BY CATEGORY:
[Java Servlets and JSP, Java, Paperback]
[Java Servlets and JSP, Java, Electronic]
[Java Programming, Java, Paperback]
[Java Programming, Java, Electronic]
BOOKS BY FORMAT:
[MySQL, Database, Paperback]
[Java Servlets and JSP, Java, Paperback]
[Java Programming, Java, Paperback]
[Android Programming, Mobile, Paperback]
Pros
-- Works with older versions of Java.
Cons
-- Not thread-safe.
-- Not intuitive.
-- Not easy to localize for parts of the world that don’t use the Gregorian calendar.
Pros
-- Thread-safe.
-- Intuitive.
-- Easier to localize for parts of the world that don’t use the Gregorian calendar.
Cons
-- Doesn’t work with versions of Java prior to Java 8.
Description
•• Java 8 introduces a new date/time API that fixes some of the problems with the old
date/time API that was used prior to Java 8.
Description
• These classes represent the local date and time from the observer’s perspective.
• The LocalDateTime class is a combination of the LocalDate and LocalTime classes.
For a LocalDateTime object, you separate the strings for the date and time with a
T. This indicates the start of the time part of the string.
If any of the values are out of range, these methods typically throw a
DateTimeException. For example, if you specify a day of 32, these methods
throw this exception since no month has 32 days. Similarly, if you specify 25
hours or 61 seconds, these methods throw this exception.
All of these classes have several more static methods for creating dates and
times, but the ones presented in figure 15-2 are the most common. For more
information, you can look at the API documentation for these classes.
Description
•• The LocalDateTime class supports all of the get methods.
•• The LocalDate class only supports the get methods relevant to getting dates.
•• The LocalTime class only supports the get methods relevant to getting times.
•• LocalDate, LocalTime, and LocalDateTime objects are immutable. As a result,
these get methods do not have corresponding set methods.
Description
•• You can use these methods to compare LocalTime, LocalDate, and LocalDateTime
objects.
Description
To adjust a date/time object, you can use the with methods.
These methods create a new object from the existing date/time object. In other
words, they don’t alter the existing date/time object.
The LocalDateTime class supports all of the methods in the table.
The LocalDate class only supports the methods relevant to dates.
The LocalTime class only support the methods relevant to times.
These methods can throw a DateTimeException for arguments that are out of range.
The withMonth method may change the day if the current day stored in the object
is out of range for the new month.
Description
•• To adjust the date or time forward or backward, you can use the plus and minus methods
with the ChronoUnit enumeration to specify a period of time. However, it’s usually
easier to use the shortcut methods such as the plusWeeks or minusWeeks methods.
•• Shortcut methods exist for all of the ChronoUnit constants shown in this figure.
•• The LocalDateTime class supports all of the methods and ChronoUnit constants.
The LocalDate and LocalTime classes only support the methods and constants that
are relevant to them.
• All of the plus and minus methods return new objects of the same type. In other
words, they do not alter the existing objects.
• You can use method chaining to perform multiple calculations in a single statement.
The same is true with the time formatter. For example, suppose you have a
LocalTime object set to 14:30, and you use the SHORT format style to format it.
In the United States, the 12-hour AM/PM clock is the norm. As a result, in the
United States, this formats that time as:
2:30 PM
However, in countries where the 24-hour clock is the norm, this formats the time
as:
14:30
The FormatStyle enumeration provides for four format styles: SHORT,
MEDIUM, LONG, and FULL. Dates support all four of these format styles.
However, times only support the SHORT and MEDIUM styles. As a result, if
you want to use the same format style for both the date and time as shown in
the first example, you must use the SHORT or MEDIUM styles. Otherwise, the
compiler throws a DateTimeException. However, if you want, you can specify
one format style for the date and another style for the time as shown in the
second example.
There are several other formatters available, but they are beyond the scope of
this chapter. Also, if you can’t find a formatter that does what you need, you can
write your own. For more information on how to do this, see the API documenta-
tion for the DateTimeFormatter class.
Chapter 15 How to work with dates and times 403
Code that uses the same style to format both the date and time
DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDateTime(
FormatStyle.MEDIUM);
String currentDateTimeFormatted = dtf.format(currentDateTime);
Code that uses a separate style for the date and time
DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDateTime(
FormatStyle.LONG, FormatStyle.SHORT);
String currentDateTimeFormatted = dtf.format(currentDateTime);
Description
•• You can use the ofLocalized methods to format a date and time for the locale of the
system that the application is running on.
•• You can use the FormatStyle constants to specify the format style for the date and time.
•• If you attempt to use the LONG or FULL style to format a time, the compiler
throws a DateTimeException.
• If none of the formats included with the API meets your needs, you can write your
own custom formatters.
import java.text.NumberFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.ArrayList;
public Invoice() {
lineItems = new ArrayList<>();
invoiceDate = LocalDateTime.now();
}
Perspective
Now that you’ve finished this chapter, you should understand some of the
differences between the old date/time API that was available prior to Java 8 and
the new date/time API that’s available with Java 8 and later. In addition, you
should be able to use the classes provided by the new date/time API to work
with dates and times.
Summary
•• Prior to Java 8, it was common to use classes in the java.util and java.text
packages to work with and format dates and times.
•• With Java 8 or later, you can use the classes in the java.time package to work
with and format dates and times. This package has several advantages over
the older classes for working with dates and times.
An introduction to exceptions
All applications can encounter errors when they run. For example, a user
may enter data that’s not appropriate, or a file that your application needs may
get moved or deleted. These types of errors may cause a poorly-coded applica-
tion to crash and cause the user to lose data. In contrast, when an error occurs in
a well-coded application, the application notifies the user and attempts to recover
from the error. If it can’t recover, it saves as much data as possible, cleans up
resources, and exits the application as smoothly as possible.
In the old days of programming, this was rather difficult to do because
programming languages had no easy way to check for errors. Even worse, they
had no easy way to communicate those errors to other parts of the application
that might need to know about them. To address this problem, most modern
programming languages, including Java, support an error handling mechanism
known as exceptions. Exceptions allow you to write robust code that can handle
errors more easily and reliably. Before you learn how to handle errors, though,
you need to learn about the exception hierarchy and the exception handling
mechanism.
Description
•• An exception is an object of the Exception class or any of its subclasses. It repre-
sents a condition that prevents a method from successfully completing.
•• The Exception class is derived from a class named Throwable. Two types of excep-
tions are derived from the Exception class: checked exceptions and unchecked
exceptions.
•• Checked exceptions are checked by the compiler. As a result, you must write code
that handles all checked exceptions before you can compile your code.
•• Unchecked exceptions are not checked by the compiler, but they can occur at
runtime. It’s generally considered a good practice to write code that handles
unchecked exceptions. If an unchecked exception occurs and isn’t handled by your
code, your application terminates.
•• Like the Exception class, the Error class is also derived from the Throwable class.
However, the Error class identifies internal errors that are rare and can’t usually be
recovered from. As a result, you can usually ignore the Error class.
Description
•• When a method encounters a condition it can’t handle, that method should throw an
exception. This allows users of the method to handle the exception in a way that’s
appropriate for their applications. Many methods in the Java API throw exceptions.
•• When a method calls another method that throws a checked exception, the method
must either throw the exception to its caller or catch the exception and handle it
directly. Code that catches an exception is known as an exception handler.
•• When an exception occurs, the runtime system looks for the appropriate exception
handler. To do that, it looks through the stack trace, or call stack, which lists the
methods that have been called until it finds a method that catches the exception.
A method that catches two types of exceptions and uses a finally clause
public static String readFirstLine(String path) {
BufferedReader in = null;
try {
in = new BufferedReader(
new FileReader(path)); // may throw FileNotFoundException
String line = in.readLine(); // may throw IOException
return line;
} catch (FileNotFoundException e) {
System.out.println("File not found.");
return null;
} catch(IOException e) {
System.out.println("I/O error occurred.");
return null;
} finally {
try {
if (in != null) {
in.close(); // may throw IOException
}
} catch (Exception e) {
System.out.println("Unable to close file.");
}
}
}
Description
•• You can code a try block around any statements that may throw an exception.
•• You can code one catch block for each type of exception that may be thrown in the
try block. You should code the catch clauses in sequence from the most specific
class in the Throwable hierarchy to the least specific class.
•• You can code a finally block to free any system resources that are used by objects
created in the try block. The code in the finally block is always executed.
this code checks that this object is not null before it calls its close method. In
addition, the close method may throw an IOException, so you need to code a try
statement within the finally block that catches this exception.
When you code try statements, it’s often tempting to create empty catch
clauses for checked exceptions just to get your code to compile. However, this
can make debugging difficult because if an exception is thrown, you never find
out about it. Instead, your code doesn’t work correctly and gives no indication
of what went wrong. Furthermore, it’s all too easy to forget to code the excep-
tion handler later. In that case, the exception never gets handled. Instead, the
empty catch clause catches the exception and ignores it. This is sometimes called
swallowing an exception, or eating an exception, and it’s rarely an acceptable
coding practice.
Description
•• The try-with-resources statement is a special type of try statement that declares and
instantiates one or more objects that use system resources and automatically closes
those objects and releases the resources after the try statement finishes executing.
•• The try-with-resources statement was introduced with Java 7.
•• Any object that implements the java.lang.AutoCloseable interface can be created
using the try-with-resources statement.
•• As of Java 7, most of the classes in the Java API that use system resources have
been retrofitted to implement the AutoCloseable interface.
•• If an object doesn’t implement the AutoClosable interface, Eclipse warns you if
you attempt to use try-with-resources with it. It also causes a compile-time error.
java.io.FileNotFoundException:
c:\murach\java_eclipse\produx.txt (The system cannot find the
file specified)
java.io.FileNotFoundException:
c:\murach\java_eclipse\produx.txt (The system cannot find the
file specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:131)
at java.io.FileInputStream.<init>(FileInputStream.java:87)
at java.io.FileReader.<init>(FileReader.java:58)
at ProductApp.readFirstLine(ProductApp.java:70)
at ProductApp.main(ProductApp.java:10)
Description
•• The Throwable class provides methods that are available to all exceptions.
•• The System.err object works like the System.out object, but it prints data to the
standard error stream instead of the standard output stream.
•• It’s generally considered a good practice to remove the printStackTrace method
from production applications or replace it with a better way of logging exceptions.
Figure 16-5 How to use the methods of an exception
420 Section 4 More essential skills as you need them
Description
•• The multi-catch block allows you to use a single catch block for multiple excep-
tions that are at the same level in the inheritance hierarchy.
•• The multi-catch block was introduced with Java 7.
Description
•• Any method that calls a method that throws a checked exception must either catch
the exception or throw the exception. Otherwise, the application won’t compile.
•• To throw a checked exception, you code a throws clause in the method declara-
tion. The throws clause must name each checked exception that’s thrown up to the
calling method. If you list multiple exceptions, you can separate each exception
with a comma.
•• Although you can specify unchecked exceptions in the throws clause, the compiler
doesn’t force you to handle unchecked exceptions.
if (true) {
throw new IOException("I/O exception test");
}
return firstLine;
} catch (IOException e) {
// code to handle IOException goes here
}
Description
•• You use the throw statement to throw an exception. You can throw any object that’s
created from a subclass of the Throwable class.
•• You can use the constructors of the Throwable class to create a new exception.
Then, you can throw that exception. To throw an existing exception, you must first
catch it.
Figure 16-8 How to use the throw statement
426 Section 4 More essential skills as you need them
Description
•• To define a checked exception, inherit the Exception class or any of its subclasses.
•• To define an unchecked exception, inherit the RuntimeException class or any of its
subclasses.
•• By convention, each exception class should contain a default constructor that
doesn’t accept any arguments and another constructor that accepts a string
argument.
Resulting output
DBException: java.io.FileNotFoundException:
c:\murach\produx.txt (The system cannot find the file specified)
Description
•• Exception chaining lets you maintain exception information for exceptions that are
caught when new exceptions are thrown. Exception chaining uses the cause field,
which represents the original exception that caused the current exception to be
thrown.
Perspective
In this chapter, you learned the most important techniques for handling
exceptions in Java. Exceptions can help you write more robust, more error free
code by allowing an error to be propagated up the call stack where it can be
handled better than at the low level where the error occurred. For example, a
getProduct method that retrieves Product objects probably has no idea what
should be done if an error occurs. So this low-level method throws an exception
that’s handled by a higher-level method, which can write the exception to an
error log, display an error message, or even terminate the application. In short,
exception handling usually affects every level of an application’s design.
Summary
•• In Java, an exception is an object that’s created from a class that’s derived
from the Exception class or one of its subclasses. When an exception occurs,
a well-coded application notifies its users of the exception and minimizes
any disruptions or data loss that may result from the exception.
•• Exceptions derived from the RuntimeException class and its subclasses are
unchecked exceptions because they aren’t checked by the compiler. All other
exceptions are checked exceptions.
•• Any method that calls a method that throws a checked exception must either
throw the exception by coding a throws clause or catch it by coding
try/catch/finally blocks as an exception handler.
•• The try-with-resources statement is a special type of try statement that
declares and instantiates one or more objects that use system resources and
automatically closes the objects and releases the resources after the try state-
ment finishes executing.
•• The multi-catch block allows you to use a single catch block for multiple
exceptions that are at the same level in the inheritance hierarchy.
•• When coding your own methods, if you encounter a potential error that can’t
be handled within that method, you can code a throw statement that throws
the exception to another method. If you can’t find an appropriate exception
class in the Java API, you can code your own exception class.
•• You can create custom exception classes to represent exceptions your
methods might throw. This is often useful to hide the details of how a
method is implemented.
•• When you create custom exceptions, you can use exception chaining to save
information about the cause of an exception.
Chapter 16 How to handle exceptions 431
4. Run the application to make sure the finally clause works as expected. To test
what happens if the file is never opened, you can change the name of the file
to cause a FileNotFoundException. To test what happens if the close method
doesn’t work, you can throw an IOException just before the statement that
closes the resource.
Description
• To work with a directory or file, you use a Path object. A Path object can include a
root component as well as directory names and a file name.
Figure 17-1 How to work with directories and files (part 1 of 2)
436 Section 4 More essential skills as you need them
Resulting output
Description
•• Java 7 introduced the java.nio.file package (also known as NIO.2). This package
provides an improved way to access the default file system and is designed to
replace the functionality that was available from the java.io.File class.
•• The java.nio.file package provides support for many features that aren’t provided
by the java.io.File class.
•• When coding paths, you can use a front slash to separate directory names. This
works equally well for Windows and other operating systems.
•• To identify the name and location of a file, you can use an absolute path name to
specify the entire path for a file. You can also use a relative path name to specify
the path of the file relative to the current working directory (CWD). This is usually
but not always the directory that the application was started from.
•• Although the java.nio.file package was introduced with Java 7, the java.nio package
was introduced with Java 4.
Description
An input file is a file that is read by an application. An output file is a file that is
written by an application. Input and output operations are often referred to as I/O
operations or file I/O.
A stream is the flow of data from one location to another. To write data to a file
from internal storage, you use an output stream. To read from a file into internal
storage, you use an input stream.
To read and write text files, you use character streams. To read and write binary
files, you use binary streams.
Streams are not only used with disk devices, but also with input devices like
keyboards and network connections and output devices like PC monitors and
network connections.
Resulting output
Description
•• The java.io package contains dozens of classes that can be used to work with
different types of streams that have different functionality.
•• To get the functionality you need for a stream, you often need to combine, or layer,
two or more streams.
•• To make disk processing more efficient, you can use a buffered stream that adds a
block of internal memory called a buffer to the stream.
•• When working with buffers, you often need to flush the buffer. This sends all data
in the buffer to the I/O device. One way to do that is to use a try-with-resources
statement to automatically close the I/O stream after you use it.
only one write or read operation is required to flush or fill the buffer. In contrast,
if the data is written or read one field at a time, 4000 bytes might require
hundreds of I/O operations. For each I/O operation, the disk has to rotate to the
starting disk location. Since this rotation is extremely slow relative to internal
operations, buffering dramatically improves the performance of I/O operations.
Because this figure is only intended to give you an idea of how file I/O
works, you shouldn’t worry if you don’t understand it completely. As you
progress through this chapter, you’ll learn about all of the classes and methods
shown here in more detail.
Description
•• The Writer class is an abstract class that’s inherited by all of the classes in the Writer
hierarchy. To learn more about the Writer hierarchy, see the Java API documentation.
•• If the output file doesn’t exist when the FileWriter object is created, it’s created automat-
ically. If it does exist, it’s overwritten by default. If that’s not what you want, you can
specify true for the second argument of the constructor to append data to the file.
•• If you specify true for the second argument of the PrintWriter constructor, the
autoflush feature flushes the buffer each time the println method is called.
Description
•• To write a character representation of a data type to an output stream, you use the
print and println methods of the PrintWriter class. If you supply an object as an
argument, these methods call the toString method of the object.
•• To create a delimited text file, you delimit the records or rows in the file with one
delimiter, such as a new line character, and you delimit the fields or columns of
each record with another delimiter, such as a tab character.
•• To flush all data to the file, you can use a try-with-resources statement to automati-
cally close the stream when you’re done using it. You can also use the flush or close
methods of the stream to manually flush all data to the file.
Description
•• The Reader class is an abstract class that’s inherited by all of the classes in the
Reader hierarchy. To learn more about the Reader hierarchy, check the documenta-
tion for the Java API. All classes in the java.io package that end with Reader are
members of the Reader hierarchy.
•• Although you can read files with the FileReader class alone, the BufferedReader
class improves efficiency and provides better methods for reading character input
streams.
Sample output
Sample output
import java.util.*;
import java.io.*;
import java.nio.file.*;
import murach.business.Product;
line = in.readLine();
}
}
catch(IOException e) {
System.out.println(e);
return null;
}
}
return products;
}
The get method returns a Product object for a product that matches the
specified product code. To search for the product, this method loops through
each product in the products list until it finds one with the specified product
code. Finally, it returns that product. If no product has the specified code, this
method returns a null.
The saveAll method accesses the list of products and writes all of the
Product objects to the file. If this operation is successful, it returns a true value.
If an IOException is thrown, this method returns a false value. This indicates that
the save operation wasn’t successful.
The saveAll method starts by creating a buffered output stream that connects
to the products file. Then, this method uses a loop to write each product in the
list to the file. To do that, it uses the FIELD_SEP constant to separate each field
in a product record, and it uses the println method to insert a new line character
at the end of each product record.
The add method starts by calling the add method of the List interface to add
the product to the list of products. Then, it calls the saveAll method to save the
modified list to the products file so that the list and the file contain the same data.
Here, the add method returns the boolean value that’s returned by the saveAll
method. That way, if the saveAll method returns a true value, the add method
also returns a true value.
The delete method works similarly. It starts by calling the getAll method to
return a products list. Then, it calls the remove method of the List interface to
remove the product from the list. Finally, it calls the saveAll method to save the
list to the products file, and it returns the boolean value that’s returned by that
method.
The update method works a little differently. This method updates the data
for an existing product with the data in a new Product object. To start, this
method uses the get method to get the old Product object with the same product
code as the new Product object. Then, it gets the index for the old product and
removes that product from the list. Next, it inserts the new product into the list
where the old product used to be. Finally, it calls the saveAll method to save
the list to the products file, and it returns a value that indicates whether the save
operation was successful.
It’s important to note that this class won’t work correctly for multiple
users. For example, suppose user A and user B read the products file, and user
A modifies that file. Then, suppose user B also modifies the file. At this point,
user B’s changes overwrite user A’s changes. This is known as a concurrency
problem.
One way to reduce concurrency problems would be to read the data from the
file each time the getAll, get, add, update, and delete methods are called. That
way, the data is more likely to be current. However, this would be inefficient,
particularly if the file contained thousands of records, and it still wouldn’t be
thread-safe. The easiest and most professional way to solve this problem is to
use a database as described in chapters 19 and 20.
Chapter 17 How to work with file I/O 455
return true;
}
return saveAll();
}
}
The console
Figure 17-10 shows the console for the Product Manager application. When
it starts, this application displays a welcome message and a menu of commands.
Then, it prompts the user to enter one of those commands. In this figure, for
example, the user started by entering the list command. This displayed a list of
the products that are stored in the text file.
After displaying the products, the user used the add command to add a
new product to the text file. Then, the user used the del command to delete that
product. Finally, the user entered the exit command to end the application.
The console
Welcome to the Product Manager
COMMAND MENU
list - List all products
add - Add a product
del - Delete a product
help - Show this menu
exit - Exit this application
PRODUCT LIST
java Murach's Java Programming $57.50
jsp Murach's Java Servlets and JSP $57.50
mysql Murach's MySQL $54.50
android Murach's Android Programming $57.50
html5 Murach's HTML5 and CSS3 $54.50
oracle Murach's Oracle and PL/SQL $54.50
javascript Murach's JavaScript and jQuery $54.50
Bye.
Description
•• This application allows you to manage the products that are stored in a text file.
When it starts, it displays a list of commands that you can use. Then, it prompts
you to enter one of these commands.
•• To view the products, you can use the list command.
•• To add or delete a product, you can use the add or del commands.
•• To display the list of commands again, you can use the help command.
•• To exit the application, you can type the exit command.
import java.util.List;
import murach.business.Product;
import murach.io.ProductIO;
if (action.equalsIgnoreCase("list")) {
displayAllProducts();
} else if (action.equalsIgnoreCase("add")) {
addProduct();
} else if (action.equalsIgnoreCase("del") ||
action.equalsIgnoreCase("delete")) {
deleteProduct();
} else if (action.equalsIgnoreCase("help") ||
action.equalsIgnoreCase("menu")) {
displayMenu();
} else if (action.equalsIgnoreCase("exit")) {
System.out.println("Bye.\n");
} else {
System.out.println("Error! Not a valid command.\n");
}
}
}
if (products == null) {
System.out.println("\nError! Unable to get products.\n");
} else {
Product p;
StringBuilder sb = new StringBuilder();
for (Product product : products) {
p = product;
sb.append(StringUtil.padWithSpaces(
p.getCode(), 12));
sb.append(StringUtil.padWithSpaces(
p.getDescription(), 34));
sb.append(p.getPriceFormatted());
sb.append("\n");
}
System.out.println(sb.toString());
}
}
ProductIO.add(product);
System.out.println("\n" + description
+ " was added to the database.\n");
}
Perspective
In this chapter, you learned how to read and write text files. In addition,
you learned how you can use a class such as the ProductIO class to store the
data for business objects such as Product objects in a text file. This should help
you see how the presentation, business, and database layers of an application
can work together.
As you work with text files, remember that they are only one option for
storing data. Another option is to store data in a database. Because databases
provide sophisticated features for organizing and managing data, they’re used
for most serious applications. You’ll learn how to work with databases in
chapters 19 and 20.
If you need to read and write objects to a binary file, you may want to
consider using a Java feature known as object serialization. This feature
automates the process of reading and writing objects to a binary file. Most
programmers don’t need to write code that performs serialization unless they
are writing low-level code. For example, a programmer who is writing a Java
EE application server might use serialization to read and write objects to a
binary file. However, an application programmer who is using the application
server doesn’t need to write this code. Instead, the application programmer
only needs to provide objects that implement the Serializable interface.
Summary
•• A text file stores data as characters. A binary file stores data in a binary
format.
•• In a delimited text file, delimiters are used to separate the fields and records
of the file.
•• You use character streams to read and write text files. To get the function-
ality you need, you can layer two or more streams.
•• A buffer is a block of memory that is used to store the data in a stream
before it is written to or after it is read from an I/O device. When an output
buffer is full, its data is flushed to the I/O device.
•• When you work with I/O operations, you’ll need to catch or throw three
types of checked exceptions: IOException, FileNotFoundException, and
EOFException.
•• To identify a file when you create a File object, you can use an absolute path
name or a relative path name.
•• The java.nio.file package provides classes and interfaces that you can use to
check whether a file or directory exists, to get information about a path, to
create or delete directories and files, and to create a File object.
•• You can use the classes in the Writer and Reader hierarchies to work with a
text file.
Chapter 17 How to work with file I/O 461
Here, the first line is a user-friendly message, and the second line contains
details about the exception that was thrown.
9. Run the application to make sure it works correctly.
Test the new exception handling code
10. In the ProductIO class, add the following code to the beginning of the getAll
method:
if (true) {
throw new IOException("Test");
}
11. Run the application and test the exception handling. At this point, you should
be able to test the exception handling for the list, add, and delete commands.
12. In the ProductIO class, comment out the statement that throws the IOExcep-
tion. Then, run the application to make sure it still works correctly.
18
How to work with threads
When you run an application in Java, the application runs in one or more
threads. So far in this book, all of the applications have executed within a single
thread. In this chapter, you’ll learn how to develop applications that run in two
or more threads that perform separate tasks. For example, you can use one
thread to retrieve data from a database while another thread makes a compli-
cated calculation. Then, the application can alternate between the two tasks so
it runs more efficiently.
An introduction to threads.................................................464
How threads work........................................................................................ 464
Typical uses for threads............................................................................... 464
Classes and interfaces for working with threads......................................... 466
The life cycle of a thread............................................................................. 468
Two ways to create threads................................................470
Constructors and methods of the Thread class............................................470
How to extend the Thread class....................................................................472
How to implement the Runnable interface...................................................474
How to synchronize threads..............................................476
How to use synchronized methods...............................................................476
When to use synchronized methods.............................................................476
Perspective..........................................................................478
464 Section 4 More essential skills as you need them
An introduction to threads
Before you learn how to develop applications that use two or more threads,
you need to understand how threads work and when you would typically use
them. You also need to be familiar with the classes and interfaces you use when
you work with threads, and you need to understand the life cycle of a thread.
That’s what you’ll learn in the topics that follow.
Description
•• A thread is a single sequential flow of control within an application. A thread often
completes a specific task.
•• By default, a Java application uses a single thread, called the main thread.
However, some applications can benefit by using two or more threads to allow
different parts of the application to execute simultaneously.
•• On a computer that has just one CPU (central processing unit) core, the threads
don’t actually execute simultaneously. Instead, a part of the operating system
called the thread scheduler alternately lets each thread execute. This happens faster
than humans are able to realize, thus giving the appearance that all of the tasks
are running at the same time. As a result, this can make an application work more
efficiently.
•• Most modern CPUs have multiple cores and can run multiple threads at the same
time, even though there is only one CPU.
To give you some perspective on this, you should realize that the actual
amount of time that the CPU spends waiting for I/O to complete is much greater
than what’s indicated in figure 18-1. In fact, since each of the blocks that show
task 1 executing are about one half of an inch long, the blocks that show the
CPU waiting for I/O would probably need to be about the length of a football
field to show the wait time accurately. That’s about how much slower disk opera-
tions are than CPU operations.
The second reason for using threads is to improve the responsiveness of
applications that use graphical user interfaces. For example, when a user clicks
a button, he or she expects the application to respond immediately, even if the
application is busy doing something else. A GUI application that uses Swing as
described in chapters 21 and 22 automatically runs in a thread that handles the
events that occur when the user interacts with the GUI. Then, it updates the GUI
accordingly. However, if the application needs to perform a task that may take a
long time, this task should be performed in a second thread.
The final reason for using multithreading is to allow two or more users
to run server-based applications simultaneously. For example, Java servlets
automatically create one thread for each user. (To learn more about web
programming in Java, you can read, Murach’s Java Servlets and JSP. For now,
you should just realize that each person who uses a servlet runs it in a separate
thread. As a result, when you write servlet code, you must make sure that the
code is thread-safe.)
Description
•• After you create a Thread object, you can call its start method so the thread
scheduler can run the thread. Then, you can use the other methods shown above to
manage the thread.
•• The advantage of implementing the Runnable interface is that it allows the thread
to inherit a class other than the Thread class.
Thread states
State Description
New The thread has been created (its constructor has been called), but not yet started.
Runnable The thread’s start method has been called and the thread is available to be run by
the thread scheduler. A thread in Runnable state may actually be running, or it
may be waiting in the thread queue for an opportunity to run.
Blocked The thread has been temporarily removed from the Runnable state so it can’t be
executed. This can happen if the thread’s sleep method is called, if the thread
is waiting on I/O, or if the thread requests a lock on an object that’s already
locked. When the condition changes (for example, the I/O operation completes),
the thread is returned to the Runnable state.
Waiting The thread is waiting and allowing other threads to access the object. It remains
in the waiting state until another thread notifies it to stop waiting and re-enter
the Runnable state.
Terminated The thread’s run method has ended.
Description
•• All threads have a life cycle that can include five states: New, Runnable, Blocked,
Waiting, and Terminated.
Description
•• By default, the threads that you create explicitly are named numerically. If that’s
not what you want, you can specify the name on the constructor of the thread.
•• The sleep method throws an InterruptedException. Because this is a checked excep-
tion, you must throw or catch this exception when you use the sleep method.
Sample output
main started.
main starts Thread-0.
main finished.
Thread-0 started.
Thread-0 finished.
Sample output
main started.
main starts Thread-0.
main finished.
Thread-0 started.
Thread-0 finished.
Description
•• Asynchronous threads execute independently of each other. Synchronous threads
need to be coordinated if they could access the same field within a class or object at
the same time.
•• Concurrency refers to a state when multiple threads use the same class or object at
the same time. Whenever this happens, concurrency problems such as lost updates
may occur.
•• When you code a class that multiple threads may use, you need to make sure that
the class is thread-safe. This means that multiple threads can use it safely without
causing concurrency problems.
•• The synchronized keyword locks the class or object and guarantees that only one
thread at a time can execute any of its synchronized methods. Any other thread that
attempts to run any synchronized method for the class or object is blocked until the
first thread releases the lock by exiting the synchronized method.
•• A thread can run an unsynchronized method even if the class or object is locked by
a synchronized method. This can potentially cause problems if the unsynchronized
method accesses the same field that’s used by a synchronized method.
•• It’s a best practice to use synchronized methods whenever two or more threads
might execute the same method, and the method accesses instance variables of the
class or object. This is true even if the method only contains one line of code.
Perspective
In this chapter, you learned the basic skills for working with threads.
Threads are a complex topic, so this chapter could only provide a very brief
introduction. Frankly, threading is one of the most challenging topics in this
book. So don’t be too worried if you don’t understand every detail of how it
works. As you learn more about different types of Java programming, such as
web programming or Android programming, you’ll learn more about working
with threads in those environments.
On that note, there’s more to learn about working with threads when
programming applications that use graphical user interfaces (GUIs). One
important concept is described later in this book at the end of chapter 22.
Summary
•• A thread is a single sequential flow of control within an application that
often completes a specific task.
•• A multithreaded application consists of two or more threads whose execu-
tion can overlap.
•• A single core processor can only execute one thread at a time, and the thread
scheduler determines which thread to execute.
•• Most modern processors have multiple cores and can run more than one
thread at the same time. In this case, the thread scheduler determines which
threads to run, and which core to run them on.
•• Multithreading is typically used to improve the performance of applications
with I/O operations, to improve the responsiveness of GUI operations, and to
allow two or more users to run server-based applications simultaneously.
•• You can create a thread by extending the Thread class and then instantiating
the new class. Or, you can implement the Runnable interface and then pass a
reference to the Runnable object to the constructor of the Thread class.
•• You can use the methods of the Thread class to start a thread and to control
when a thread runs.
•• The synchronized keyword on a method ensures that two or more threads
cannot run the method at the same time.
•• Asynchronous threads execute independently of each other.
•• Synchronized methods can be used to ensure that two threads don’t run the
same method of an object simultaneously. When a thread calls a synchro-
nized method, the object that contains that method is locked so other threads
can’t access it.
•• It’s generally considered a best practice to synchronize any methods where
there’s potential for two threads to access the same field of a class or object
at the same time.
Chapter 18 How to work with threads 479
main started.
Thread-0 started.
Thread-1 started.
main finished.
1
3
5
2
4
7
9
Thread-0 finished.
6
8
10
Thread-1 finished.
8. Add a Thread.sleep call to CounterThread to make the thread sleep for one
second between each number. See if this changes the order of the output when
you run the application.
9. Run the application two or more times to make sure it works correctly. The
output may vary each time you run the application.
Real-world skills
For most Java applications in the real world, the critical data is stored in
a database. In most cases, this provides many advantages over storing
the data in a file as described in chapter 17. That’s why the first two
chapters in this section present the essential database skills that you need
for developing Java applications. In particular, they describe the essential
database skills that you need to develop the Product Manager application
that’s presented throughout this section.
In addition, most desktop Java applications use a graphical user
interface (GUI) to interact with the user. That’s why the third and fourth
chapters in this section show how to create a GUI. In particular, they
describe the essential skills you need to create the GUI for the Product
Manager application.
19
How to work
with a MySQL database
You can use Java to work with almost any type of database. For desktop or web
applications, it’s common to use an Oracle or MySQL database. For Android
apps, it’s common to use a SQLite database. The database you end up using
depends on many factors.
Of these databases, MySQL is one of the most popular for Java applica-
tions. In addition, there’s an open-source version that’s free, easy to install,
and easy to use. As a result, this chapter shows how to create a MySQL
database that can store the data for the Product Manager application that’s
described in the next few chapters. As you learn this, you will also learn some
basic concepts and SQL (Structured Query Language) skills that apply to all
databases.
Description
•• A relational database uses tables to store and manipulate data. Each table contains
one or more records, or rows, that contain the data for a single entry. Each row
contains one or more fields, or columns, with each column representing a single
item of data.
•• Most tables contain a primary key that uniquely identifies each row in the table.
•• The software that manages a relational database is called a database management
system (DBMS). Four popular database management systems today are Oracle,
Microsoft SQL Server, IBM’s DB2, and MySQL.
Foreign key
Description
•• The tables in a relational database are related to each other through their key
columns. For example, the ProductID column is used to relate the Product and
LineItem tables. The ProductID column in the LineItem table is called a foreign key
because it identifies a related row in the Product table.
•• Three types of relationships can exist between tables. The most common type is a
one-to-many relationship as illustrated above. However, two tables can also have a
one-to-one relationship or a many-to-many relationship.
Description
•• A database management system requires a name and data type for each column in a
table. Depending on the data type, the column definition can include other proper-
ties such as the column’s size.
•• Each column definition also specifies whether or not the column can contain a null.
A null indicates that the value of the column is not known.
•• A column definition can specify that the column is the primary key. A primary key
column can’t be null.
•• A column definition can specify that the column must contain a unique value. A
unique column can be null. However, if this column is not null, it must contain a
unique value.
An introduction to MySQL
MySQL is an open-source database management system (DBMS) that you
can download for free from the MySQL website (www.mysql.com) as described
in the appendixes. It is also available as part of a hosting package from many
Internet Service Providers (ISPs). MySQL Workbench is a free graphical tool
that makes it easy to work with MySQL. As of press time for this book, the
current version of MySQL Workbench is version 6.3, so that’s the version
presented in this chapter. However, with some minor variations, the skills
presented in this chapter should work for earlier and later versions as well.
MySQL is…
•• Inexpensive. MySQL is free for most uses and relatively inexpensive for other
uses.
•• Fast. By many accounts, MySQL is one of the fastest relational databases that’s
currently available.
•• Easy to use. Compared to other database management systems, MySQL is easy to
install and use.
•• Portable. MySQL runs on most modern operating systems including Windows, OS
X, and Linux.
MySQL provides…
•• Support for SQL. Like any modern database product, MySQL supports SQL,
which is the standard language for working with data that’s stored in relational
databases.
•• Support for multiple clients. MySQL supports access from multiple clients from a
variety of interfaces and programming languages including Java, PHP, Python, Perl,
and C.
•• Connectivity. MySQL can provide access to data via an intranet or the Internet.
•• Security. MySQL can protect access to your data so only authorized users can view
the data.
•• Referential integrity. With MySQL 5.5 and later, InnoDB tables are used by
default. These tables support referential integrity, which reduces the chance of data
corruption. Most commercial databases also provide this feature.
•• Transaction processing. With version 5.5, MySQL uses InnoDB tables by default.
These tables provide support for transaction processing, which reduces the chance
of data corruption. Most commercial databases also provide this feature.
MySQL Workbench
Description
•• When working with a desktop application, it’s common to use a GUI application
such as MySQL Workbench to work with a MySQL database.
Description
• To open a new SQL tab, press Ctrl+T or click the Create New SQL Tab button in
the SQL editor toolbar.
• To select the current database, double-click it in the Schemas section of the
Navigator window. This displays the selected database in bold.
• To enter a SQL statement, type it into the SQL tab.
• As you enter the text for a statement, the SQL tab applies color to various elements,
such as SQL keywords, to make them easy to identify.
• To execute a SQL statement, press Ctrl+Enter, or click the Execute Current
Statement button in the SQL editor toolbar. If the statement retrieves data, the data
is displayed in a Result grid below the SQL tab.
Description
•• You can use the CREATE DATABASE statement to create a database and the
DROP DATABASE statement to delete a database. These are SQL statements.
•• You can use the USE command to select the database that you want to work with.
•• You can use the CREATE TABLE statement to create a table. When you create a
table, you define each of its columns and you identify its primary key. To define a
column, you must supply the name and the data type, whether it’s automatically
generated for new rows, and so on.
•• When you use MySQL, the INSERT statement lets you insert one or more rows
into one table of a database. When you code it, you need to include data for all
columns that aren’t defined with default values or aren’t automatically generated.
•• You can use the GRANT statement to create a user, specify a password for that
user, and grant privileges to the user.
Figure 19-7 The script that creates the database named mma
498 Section 5 Real-world skills
Result set
Result set
Result set
Description
•• A SELECT statement is a SQL DML statement that returns a result set (or result
table) that consists of the specified rows and columns.
•• To specify the columns, you use the SELECT clause.
•• To specify the table that the data should be retrieved from, you use the FROM
clause.
•• To specify the rows, you use the WHERE clause.
•• To specify how the result set should be sorted, you use the ORDER BY clause.
An INSERT statement
That doesn’t use a column list
INSERT INTO Product
VALUES ('8', 'php', 'Murach''s PHP', '54.50')
An UPDATE statement
That updates the ListPrice column in one row
UPDATE Product
SET ListPrice = '57.50'
WHERE Code = 'javascript'
A DELETE statement
That deletes one row from the Product table
DELETE FROM Product
WHERE Code = 'php'
Description
•• The INSERT, UPDATE, and DELETE statements modify the data that’s stored in a
database. These statements don’t return a result set. Instead, they return the number
of rows that were affected by the query.
•• To identify a numeric or string literal in a SQL statement, you can enclose the
literal in single quotes ('). To include a single quote within a string literal that’s
enclosed in single quotes, you can enter two single quotes.
•• On Unix systems, the table and column names are case-sensitive.
Perspective
The primary goal of this chapter is to introduce you to the database
concepts and SQL statements that you’ll need to develop database applications
with Java. The secondary goal of this chapter is to present the basic skills that
you need to use MySQL. If this chapter has succeeded, you should now under-
stand the SQL statements presented in this chapter, and you should be able to
use MySQL Workbench to run them.
Keep in mind, though, that this chapter has presented just a small subset of
SQL skills. In particular, it has only presented the SQL statements you need to
understand the Java code presented in the next chapter. For a complete mastery
of SQL, you’ll probably want to get a book about SQL for the database that
you’re using. If, for example, you’re using MySQL, Murach’s MySQL presents
all of the SQL statements that you’ll need for your applications.
Summary
•• MySQL is a relational database management system (RDBMS) that can
manage one or more databases.
•• To retrieve and modify the data in one of its databases, MySQL provides
support for Structured Query Language (SQL), which is the standard
language for working with databases.
•• Whenever you use MySQL, its database server must be running. Usually,
this server starts automatically whenever you start your system.
•• To work with a MySQL database, you can use a graphical tool called
MySQL Workbench. It makes it easy to enter and run SQL statements.
•• A SQL script is a file that stores multiple SQL statements.
•• The SQL statements that you use for creating and deleting databases and
tables are part of the Data Definition Language (DDL).
•• The SQL statements that you use for retrieving and modifying the data in a
database make up the Data Manipulation Language (DML). These are the
SELECT, INSERT, UPDATE, and DELETE statements.
•• The SELECT statement can get data from one or more tables and put it in a
result set, or result table. This is commonly referred to as a query.
•• The INSERT, UPDATE, and DELETE statements are used to add one or
more rows to a table, update the data in one or more rows, and delete one or
more rows.
Chapter 19 How to work with a MySQL database 503
// get connection
Connection connection =
DriverManager.getConnection(dbURL, username, password);
} catch(SQLException e) {
for (Throwable t : e) {
System.out.println(t);
}
}
Description
•• Before you can get or modify the data in a database, you need to connect to it. To
do that, you use the getConnection method of the DriverManager class to return a
Connection object.
•• When you use the getConnection method of the DriverManager class, you must
supply a URL for the database. In addition, you usually supply a username and a
password, though you might not for an embedded database. This method throws a
SQLException.
•• With JDBC 4.0 and later, the SQLException class implements the Iterable interface. As
a result, you can use an enhanced for statement to loop through any nested exceptions.
•• With JDBC 4.0 and later, the database driver is loaded automatically. This feature is
known as automatic driver loading.
•• Prior to JDBC 4.0, you needed to use the forName method of the Class class to
load the driver. This method throws a ClassNotFoundException.
•• Although the connection string for each driver is different, the documentation for
the driver should explain how to write a connection string for that driver.
•• Typically, you only need to connect to one database for an application. However,
it’s possible to load multiple database drivers and establish connections to multiple
types of databases.
How to create a result set that contains multiple columns and rows
Statement statement = connection.createStatement();
ResultSet products = statement.executeQuery(
"SELECT * FROM Product ");
How to move the cursor to the first row in the result set
boolean productExists = product.next();
Description
To return a result set, you use the createStatement method of a Connection object to
create a Statement object. Then, you use the executeQuery method of the Statement
object to execute a SELECT statement that returns a ResultSet object.
By default, the createStatement method creates a forward-only, read-only result set.
This means that you can only move the cursor through it from the first row to the
last and that you can’t update it. Although you can pass arguments to the
createStatement method that create other types of result sets, the default is
appropriate for most applications.
When a result set is created, the cursor is positioned before the first row. Then,
you can use the methods of the ResultSet object to move the cursor. To move the
cursor to the next row, for example, you call the next method. If the row is valid,
this method moves the cursor to the next row and returns a true value. Otherwise, it
returns a false value.
The createStatement, executeQuery, and next methods throw a SQLException. As a
result, any code that uses these methods needs to catch or throw this exception.
Figure 20-3 How to return a result set and move the cursor through it
512 Section 5 Real-world skills
Code that uses indexes to return columns from the products result set
int productID = products.getInt(1);
String code = products.getString(2);
String description = products.getString(3);
double price = products.getDouble(4);
Code that creates a Product object from the products result set
Product p = new Product();
p.setId(productID);
p.setCode(code);
p.setDescription(description);
p.setPrice(price);
Description
•• The getXXX methods can be used to return all eight primitive types. For example,
the getInt method returns the int type and the getLong method returns the long
type.
•• The getXXX methods can also be used to return strings, dates, and times. For
example, the getString method returns an object of the String class, and the
getDate, getTime, and getTimestamp methods return objects of the Date, Time, and
Timestamp classes of the java.sql package.
Description
The executeUpdate method is an older method that works with most JDBC drivers.
Although there are some newer methods that require less SQL code, they may not
work properly with all JDBC drivers.
The executeUpdate method returns an int value that identifies the number of rows
that were affected by the SQL statement.
Warning
If you build a SQL statement from user input and use a method of the Statement
object to execute that SQL statement, you may be susceptible to a security
vulnerability known as a SQL injection attack.
A SQL injection attack allows a hacker to bypass authentication or to execute SQL
statements against your database that can read sensitive data, modify data, or delete
data.
To prevent most types of SQL injection attacks, you can use prepared statements as
described in the next figure.
To modify a row
String sql = "UPDATE Product SET "
+ " Code = ?, "
+ " Description = ?, "
+ " ListPrice = ?"
+ "WHERE Code = ?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, product.getCode());
ps.setString(2, product.getDescription());
ps.setDouble(3, product.getPrice());
ps.setString(4, product.getCode());
ps.executeUpdate();
To insert a row
String sql =
"INSERT INTO Product (Code, Description, ListPrice) "
+ "VALUES (?, ?, ?)";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, product.getCode());
ps.setString(2, product.getDescription());
ps.setDouble(3, product.getPrice());
ps.executeUpdate();
To delete a row
String sql = "DELETE FROM Product "
+ "WHERE Code = ?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, product.getCode());
ps.executeUpdate();
Description
When you use prepared statements in your Java applications, the database server
only has to check the syntax and prepare an execution plan once for each SQL
statement. This improves the efficiency of the database operations. In addition, it
prevents most types of SQL injection attacks.
To specify a parameter for a prepared statement, type a question mark (?) in the
SQL statement.
To supply values for the parameters in a prepared statement, use the set methods
of the PreparedStatement interface. For a complete list of set methods, look up the
PreparedStatement interface of the java.sql package in the documentation for the
Java API.
To execute a SELECT statement, use the executeQuery method. To execute an
INSERT , UPDATE, or DELETE statement, use the executeUpdate method.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
private DBUtil() {}
Description
•• To make it easier to get and close a connection to a database, you can use a utility
class like the one shown in this figure.
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import murach.business.Product;
The get method returns a Product object for a product that matches the
specified product code. To do that, it uses a prepared SQL statement to return
a result set. Then, it calls the next method of the result set to attempt to move
the cursor to the first row in the result set. If successful, this method continues
by reading the columns from the row, closing the result set, creating a Product
object from this data, and returning the Product object.
Unlike the getAll method, the result set used by the get method can’t be
created in the try-with-resources statement. That’s because before the result set
can be opened, the value of the parameter in the prepared statement must be set.
However, the prepared statement can still be created in the try-with-resources
statement, which means that it doesn’t have to be closed explicitly.
If no product row contains a product code that matches the specified code,
this method closes the result set and returns a null to indicate that the product
couldn’t be found. In addition, if a SQLException is thrown anywhere in this
method, this method creates a new exception from the DBException class and
throws this exception to the calling method. That way, the method that calls the
get method can throw or handle this exception.
As you review the get method, note that if the try block throws a
SQLException, the result set isn’t explicitly closed. In most cases, that’s not a
problem because the result set is automatically closed when the prepared state-
ment that was used to create the result set is closed. If you wanted to close the
result set explicitly, though, you could do that by adding a finally clause to the
try statement.
The add method begins by creating a prepared statement that can be used to
insert values into three columns of the Product table. Then, it sets the values of
the three parameters in the prepared statement to the values stored in the Product
object that’s passed to it. Finally, it calls the executeUpdate method of the
prepared statement. If a SQLException is thrown anywhere in this method, this
code stores that exception in a DBException and throws it to the calling method.
Chapter 20 How to use JDBC to work with databases 523
return p;
} else {
rs.close();
return null;
}
} catch (SQLException e) {
throw new DBException(e);
}
}
Figure 20-8 The database class for the Email List application (part 2 of 3)
524 Section 5 Real-world skills
Figure 20-8 The database class for the Email List application (part 3 of 3)
526 Section 5 Real-world skills
Description
You can use the static methods of the ProductDB class to map Product objects to
the rows of the Product table.
You can use the DBUtil class to close the database connection when the application exits.
Perspective
Now that you’ve finished this chapter, you should understand how to use
JDBC to store data in a database and to retrieve data from a database. Although
there’s much more to learn about working with databases, those are the essen-
tial skills. To enhance your database skills, you can learn more about database
management systems like MySQL or Oracle and the SQL that works with
them.
You should also understand that the JDBC API requires the developer to
write a significant amount of low-level code. This provides a good conceptual
background if you are new to Java and databases. In addition, many legacy
applications use JDBC. As a result, you may need to use it when working on
old applications.
However, for new development, you might prefer to use another data access
API such as JPA (Java Persistence API). This API handles much of the object to
database mapping automatically. As a result, it doesn’t require the developer to
write as much code, and the code that the developer does need to write is often
easier to maintain.
Summary
•• With JDBC 4.0 (Java 6) and later, the database driver that’s used to connect
the application to a database is loaded automatically. This is known as
automatic driver loading.
•• With JDBC 4.0 and later, you can loop through any exceptions that are
nested within the SQLException object.
•• A Java application can use one of four driver types to access a database. It’s
considered a best practice to use a type-4 driver if one is available for that
database.
•• You can use JDBC to execute SQL statements that select, add, update, or
delete one or more rows in a database. You can also control the location of
the cursor in the result set.
•• You can use prepared statements to supply parameters to SQL statements.
Since prepared statements provide better performance and security than
regular statements, you should use them whenever possible.
Chapter 20 How to use JDBC to work with databases 529
11. In the Main class, add code that gets the specified product from the database,
sets the new data in that product, and updates the database with the new data.
If successful, this should display a message like this:
12. Run this application to make sure this code works correctly.
21
How to develop a GUI
with Swing (part 1)
Up until now, all of the code you’ve been working with in this book has used a
console interface. However, most modern applications—such as word proces-
sors, spreadsheets, web browsers, and so on—use a graphical user interface,
often abbreviated as GUI. In this chapter and the next, you’ll learn the basics of
developing GUI applications with Swing, which is the most popular library for
developing GUI applications with Java.
Description
•• When creating GUIs with Java, you have several possible libraries that you can use.
Of these libraries, Swing is the most widely used.
Description
•• The Swing library is built upon the AWT library. In other words, Swing classes
often inherit AWT classes.
•• Most Swing classes begin with the letter J (for Java).
An empty frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | IllegalAccessException |
InstantiationException | UnsupportedLookAndFeelException e) {
System.err.println("Unsupported look and feel.");
}
frame.setVisible(true);
}
Description
•• A frame typically defines the main window of an application.
•• To set the title of a frame, you can use the constructor of the JFrame class. Or, you
can call the setTitle method of the JFrame object.
•• To set the size of a frame, you call the setSize method and send it the height and
width in pixels. Or, you can call the pack method to automatically size the window
so it is just large enough to hold all of its components.
•• To let the operating system set the location of a frame, you can call the setLocation-
ByPlatfrom method and send it a true value.
•• To exit the application when the user selects the close button, you can set the
default close operation. If you don’t, the application may keep running after the
window closes.
•• To set the look and feel to use the default platform look and feel, you call the
setLookAndFeel method of the UIManager class inside a try-catch block.
•• To make the frame visible, you call the setVisible method and pass it a true value.
Description
•• A panel is an invisible container that’s used to group other components.
•• To create a panel, you can create a JPanel object. Then, you can add it to a frame.
•• To create a button, you can create a JButton object. Then, you can add it to a frame
or a panel.
•• You should add all of the panels and components to the frame before calling
its setVisible method. Otherwise, the user interface may flicker when it’s first
displayed.
Description
•• To make a button do something when clicked, you add an action listener by calling
its addActionListener method.
•• The addActionListener method accepts an ActionListener object that includes an
actionPerformed method that accepts an ActionEvent object. Within the actionPer-
formed method, you write the code that’s executed when the button is clicked.
•• Prior to Java 8, it was common to write anonymous inner classes to handle actions.
However, with Java 8 or later, you can use a lambda expression, which is cleaner
and more concise.
Figure 21-5 How to handle the event that occurs when a button is clicked
542 Section 5 Real-world skills
Description
•• A layout manager determines how your components are placed in the container and
how they behave if the container is resized or if the font size changes.
•• By default, a JFrame uses the BorderLayout manager.
•• By default, a JPanel uses the FlowLayout manager.
Description
•• If the components don’t fit on one line, the FlowLayout manager wraps the compo-
nents to a new line.
•• The FlowLayout manager can align components to the left, right, or center. The
default is center.
Description
•• A BorderLayout has five areas: NORTH, SOUTH, EAST, WEST, and CENTER.
•• The default area is CENTER. As a result, if you don’t specify the area, the compo-
nent is added to the center.
•• The NORTH and SOUTH areas get their preferred height, which usually means
they are tall enough to hold whatever is placed in them. The preferred width is
ignored.
•• The WEST and EAST areas get their preferred width, which usually means they are
wide enough to hold whatever is placed in them. The preferred height is ignored.
•• The CENTER area gets whatever space is left over and expands or contracts as the
window is resized.
•• Each area of a BorderLayout can only hold one component. If you need to add
multiple components to an area, you can add them to a panel and then add the panel
to the area.
JTable terminology
Description
•• The easiest way to create a custom table model is to extend the AbstractTableModel
class.
•• At a minimum, you need to override the getRowCount, getColumnCount, and
getValueAt methods. In addition, it’s common to override the getColumnName
method.
•• When you update the database, you can call the fireTableDataChanged method to
refresh all data that’s displayed in the table.
•• The AbstractTableModel class contains other methods, such as
fireTableCellUpdated and fireTableRowsInserted, that you can call to update part of
a table. These methods can be much more efficient, especially for a large table. See
the API documentation for more information.
Figure 21-9 How to create a table model
550 Section 5 Real-world skills
import java.util.List;
import javax.swing.table.AbstractTableModel;
import mma.business.Product;
import mma.db.ProductDB;
import mma.db.DBException;
@SuppressWarnings("serial")
public class ProductTableModel extends AbstractTableModel {
private List<Product> products;
private final String[] COLUMN_NAMES = { "Code", "Description", "Price" };
public ProductTableModel() {
try {
products = ProductDB.getAll();
} catch (DBException e) {
System.out.println(e);
}
}
@Override
public int getRowCount() {
return products.size();
}
@Override
public int getColumnCount() {
return COLUMN_NAMES.length;
}
@Override
public String getColumnName(int columnIndex) {
return COLUMN_NAMES[columnIndex];
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return products.get(rowIndex).getCode();
case 1:
return products.get(rowIndex).getDescription();
case 2:
return products.get(rowIndex).getPriceFormatted();
default:
return null;
}
}
Part 2 of figure 21-10 shows two more methods of the table model. When
you write the code for an application, you can call these methods to work with
the data in the table. You’ll see how this works later in this chapter.
The getProduct method returns a Product object for the row at the specified
index. This lets you get the Product object for the row that’s selected by the user,
which is useful if you want to update or delete this product in the database.
The databaseUpdated method updates the old data in the table model with
new data from the database. Then, it calls the fireTableDataChanged method of
the table model. This notifies the JTable widget that the data in the model has
changed. This allows the JTable widget to display the new data. If you modify
the underlying data in the database, you can call this method to synchronize the
data that’s displayed in the table with the data that’s in the database.
Chapter 21 How to develop a GUI with Swing (part 1) 553
void databaseUpdated() {
try {
products = ProductDB.getAll();
fireTableDataChanged();
} catch (DBException e) {
System.out.println(e);
}
}
}
Description
•• When a row represents a business object such as a Product object, you can include
a method that returns an object for the specified row index.
•• To synchronize the data in the table with the data in the database, you can include
a method that updates the model with the data from the database and then calls the
fireTableDataChanged method. This causes the table to display the new data that’s
stored in the model.
ListSelectionModel values
Value Description
SINGLE_SELECTION Allows selecting only one row at a time.
SINGLE_INTERVAL_SELECTION Allows selecting multiple rows, but only if
they are contiguous.
MULTIPLE_INTERVAL_SELECTION Allows for selection of multiple rows at the
same time, even if they are not contiguous
Description
•• Once you have created a model for a table, you can create the table and set the
model in the table. Then, you can use the methods of the table to work with it.
ScrollPaneConstants
Value Description
HORIZONTAL_SCROLLBAR_AS_NEEDED Display the horizontal scrollbar only if the content is
wider than the view port and can’t all be displayed at
the same time. This is the default.
HORIZONTAL_SCROLLBAR_NEVER Never display the horizontal scrollbar. It’s still
possible to scroll left and right using the left and right
arrow keys on the keyboard.
HORIZONTAL_SCROLLBAR_ALWAYS Always display the horizontal scrollbar, whether it is
needed or not.
VERTICAL_SCROLLBAR_AS_NEEDED Display the vertical scrollbar only if the content is
longer than the viewport and can’t all be displayed at
the same time. This is the default.
VERTICAL_SCROLLBAR_NEVER Never display the vertical scrollbar. It’s still possible
to scroll the content up and down using the up and
down arrow keys and the page up / page down keys
on the keyboard.
VERTICAL_SCROLLBAR_ALWAYS Always display the vertical scrollbar, whether it is
needed or not.
scrollPane.setVerticalScrollBarPolicy(
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
Description
•• You can use a scroll pane to add scrollbars to any component that might not fit in a
window.
• By default, scroll panes only display the scrollbars if they are needed.
Figure 21-12 How to work with scroll panes
558 Section 5 Real-world skills
Description
•• To show a dialog box that displays a message, you use the static showMessage-
Dialog method of the JOptionPane class. This method has four parameters: (1) the
parent container, (2) the message, (3) the title, and (4) the type of dialog.
•• Java uses the parent container parameter to determine where to display the dialog.
On Windows, Java typically centers the dialog box on the parent container.
•• By default, the dialog box has a single OK button.
•• The dialog box is modal. This means that it is always on top of the rest of the appli-
cation. As a result, users can’t continue until they have responded to the dialog.
•• The appearance of the icons displayed by the dialogs varies depending on the look
and feel that the application is using. In addition, these icons may vary depending
on the locale.
Description
•• To display a dialog box that lets the user confirm or cancel an operation, you can
use the static showConfirmDialog method of the JOptionPane class.
•• The first three parameters of the showConfirmDialog method work the same as the
showMessageDialog method shown in the previous figure.
•• The fourth parameter determines the buttons that are displayed.
•• By default, the showConfirmDialog method displays a question icon. However, you
can specify another type of icon by supplying the fifth parameter.
•• To wrap a long message to a second line, you can use the line break character (\n).
Part 2 of figure 21-14 shows how to use the return value of the
showConfirmDialog method to determine which button the user selected. This
method can return any of the values listed in this figure. Of course, the possible
return values depend on the type of dialog. For example, a dialog box of the
YES_NO_OPTION returns the YES_OPTION or the NO_OPTION. In other
words, it never returns the CANCEL_OPTION or the OK_OPTION. However,
all dialog types can return the CLOSED_OPTION that indicates that the user
closed the dialog box without selecting any of the buttons.
The code example uses a switch statement to determine which button the
user selected. To do that, this switch statement provides one case for each
possible return value: the YES_OPTION, the NO_OPTION, and the
CLOSE_OPTION. Then, it prints a different message to the console depending
on which option the user selected. Alternately, it’s possible to use an if/else state-
ment instead of a switch statement. However, as a general rule, switch statements
are more efficient. In addition, for code like this, they’re easier to read.
Remember that the dialogs produced by JOptionPane are blocking. This
means that they halt the thread and prevent it from continuing until the user has
responded to the dialog. As result, the switch statement doesn’t run until the user
selects one of the dialog buttons or closes the dialog.
Chapter 21 How to develop a GUI with Swing (part 1) 563
switch (option) {
case JOptionPane.YES_OPTION:
System.out.println("You clicked the Yes button.");
break;
case JOptionPane.NO_OPTION:
System.out.println("You clicked the No button.");
break;
case JOptionPane.CLOSED_OPTION:
System.out.println("You closed the dialog.");
break;
}
Description
•• When the user selects an option from a dialog box, the showConfirmDialog method
closes the dialog box and returns an int value for the option.
•• To determine the option selected by the user, it’s common to use a switch state-
ment. However, it’s also possible to use an if/else statement.
Description
•• The main window for the Product Manager application is a frame that displays a
panel that contains three buttons, as well as a table that contains the data for several
products.
•• If the user selects the row for a product and clicks the Delete button, the application
displays a dialog box that allows the user to confirm the deletion.
•• If the user selects the Add or Edit buttons, the application displays a dialog box
that indicates that these features haven’t been implemented yet. You’ll learn how to
implement these features in the next chapter.
Figure 21-15 The user interface for the Product Manager application
566 Section 5 Real-world skills
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import mma.business.Product;
import mma.db.ProductDB;
import mma.db.DBException;
@SupressWarnings("serial")
public class ProductManagerFrame extends JFrame {
private JTable productTable;
private ProductTableModel productTableModel;
public ProductManagerFrame() {
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException |
IllegalAccessException | UnsupportedLookAndFeelException e) {
System.out.println(e);
}
setTitle("Product Manager");
setSize(768, 384);
setLocationByPlatform(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(buildButtonPanel(), BorderLayout.NORTH);
productTable = buildProductTable();
add(new JScrollPane(productTable), BorderLayout.CENTER);
setVisible(true);
}
After creating these three buttons, this code adds these three buttons to the
panel. Finally, the last statement in the buildButtonPanel method returns the
panel.
The next three methods are the event handler methods for the action
listeners. For now, the methods for the Add and Edit buttons just display a dialog
box with a message indicating the feature hasn’t been implemented yet. In the
next chapter, you’ll learn how to add code to these methods so the Add and Edit
buttons can be used to add new products or to edit existing products.
However, the method for the Delete button contains code that deletes the
selected product from the database. To start, this code uses the getSelectedRow
method of the JTable widget to get the index for the selected row. Then, this code
checks whether this index is equal to -1. If so, it displays a message dialog that
indicates that the user must select a product before clicking the Delete button.
Otherwise, it displays a dialog that contains Yes and No buttons that allow the
user to confirm the operation. If the user clicks the Yes button, this code uses the
delete method of the ProductDB class described in the previous chapter to delete
the product. Then, it calls the fireDatabaseUpdatedEvent method that’s coded
later in this class. In turn, this method calls the databaseUpdated method of the
table model to update the data that’s displayed by the JTable widget.
The code that calls the methods of the JOptionPane class specifies
the keyword named this as the first argument of the method. This tells the
JOptionPane class that the current object (the ProductManagerFrame object) is
the parent for the dialog box.
The buildProductTable method creates a ProductTableModel object and
assigns it to the productTableModel instance variable. Remember that the
constructor for ProductTableModel class makes a call to the ProductDB class
to get all of the records. As a result, this creates a model that contains a list of
products that corresponds with the products in the database.
After creating the model, this code creates a new JTable widget and sets its
model. To do that, it passes the productTableModel variable to the constructor of
the JTable class.
After creating the JTable widget, the next line of code sets the selection
mode of the table to a value of SINGLE_SELECTION. As a result, the user can
only select one row at a time.
Because this table is displayed in a JScrollPane widget, this code also sets
the border of the table to null. This makes sure that the Product Manager appli-
cation doesn’t display two borders: one for the table and one for the scroll pane.
Finally, this code returns the table. Remember that the constructor of this
class calls the buildProductTable method to get this table. Then, it adds this table
to a scroll pane, and it adds the scroll pane to the center area of the frame.
Chapter 21 How to develop a GUI with Swing (part 1) 569
return panel;
}
Perspective
In this chapter, you learned some essential skills for developing a GUI with
Swing, the most widely used GUI toolkit for Java. In particular, you learned
how to create the main window of an application. You learned how to add
buttons. You learned how to handle the events that occur when these buttons
are clicked. You learned how to work with a table that displays data from a
database. And you learned how to work with built-in dialog boxes. In the next
chapter, you’ll learn how to create data entry forms that allow you to add and
update data in a database.
Summary
•• Swing is the most commonly used GUI toolkit for Java.
•• An element of a GUI is called a component or a widget.
•• Swing provides pluggable look and feels that you can change.
•• A component that can contain other components is called a container. Three
commonly used containers are frames, panels, and scroll panes.
•• A JFrame widget usually serves as the main window of your application.
•• A JPanel widget is an invisible component that you can use to group other
components.
•• A JButton widget displays a button.
•• To handle the event that occurs when the user clicks a JButton widget, you
can use the addActionListener method to add an action listener, or event
listener.
•• An event handler is a method that responds to GUI events such as a button
click.
•• A layout manager lays out the components in a container and controls how
they respond to events such as resizing the window.
•• The BorderLayout and FlowLayout managers are two of the most commonly
used layout managers.
•• A JTable widget displays tabular data, such as tables from a database.
•• A table model provides tabular data for a JTable widget. The easiest way to
create a table model is to extend the AbstractTableModel class.
•• A JScrollPane adds scrollbars to a component such as a JTable widget so
that the user can scroll through the component if it doesn’t all fit in the
container.
•• You can use the methods of the JOptionPane class to displays a dialog box
that contains an informational message or a dialog box that confirms an
operation.
Chapter 21 How to develop a GUI with Swing (part 1) 571
Description
•• A JLabel component defines a label, which is a non-editable widget that typically
displays text that labels other components such as text fields.
•• Since you rarely need to call any methods from a JLabel object, it’s a common
practice to call the constructor of the JLabel class from within an add method. This
does not create a variable that refers to the JLabel object.
•• A JLabel object can also display an image. However, that’s not covered in this
book.
Description
•• A JTextField component defines a text field that displays text to the user and allows
the user to enter text. This type of component is also known as a text box.
Description
•• The GridBagLayout manager is more complicated than the layout managers
presented in the previous chapter. However, it’s also the most powerful and flexible
layout manager in Swing.
•• To lay out components in a grid, you can use the GridBagConstraints class with the
GridBagLayout class as shown in the next figure.
•• To specify the padding between components, you can use the Insets class with the
GridBagConstraints class as shown in figure 22-5.
Description
•• You can reuse the same GridBagConstraints object for multiple widgets. However,
you must reset any values you don’t want to use in the next widget.
you don’t reset values, you may end up accidentally reusing the values that were
set for a previous component, which may cause strange layout behavior. As a
result, you need to make sure to reset all values, or you need to create a new
GridBagConstraint object for each component.
// the rest of the code that adds the labels and text boxes
Description
•• If you forget the order of the parameters for the constructor of the Insets class, it
may help to remember that they start at the top and go counterclockwise.
Description
•• When a window is resized horizontally, components (especially text fields) can
sometimes collapse to a size of zero. This is a common problem.
this.add(new JLabel("Name:"));
this.add(dialogNameField);
this.add(okayButton);
this.add(cancelButton);
this.pack();
this.setVisible(true);
}
}
Description
•• A modal dialog prevents the user from interacting with other parts of the applica-
tion until they have responded to the dialog.
•• On most operating systems, a JDialog component is displayed on top of its parent
frame, has fewer window controls than a JFrame (for example, no maximize or
minimize buttons), and does not get its own entry in the taskbar.
Figure 22-7 How to create a custom dialog
588 Section 5 Real-world skills
At first glance, it might seem there aren’t that many differences between a
JFrame component and a JDialog component. However, on closer inspection,
there are few important differences. First, a dialog is designed to have a parent
window. As a result, a dialog is displayed on top of its parent window, even if
the dialog is not the active window. Second, on most operating systems, a dialog
has fewer window controls. On Windows, for example, a dialog has a close
button but no minimize, maximize, or restore buttons. Third, on most operating
systems, a dialog doesn’t get an entry in the taskbar or window list. As a result,
you can’t switch directly to the dialog using window switch commands. Instead,
you need to switch to the window that owns the dialog. Fourth, as described
earlier, a dialog can be modal.
Description
•• Within the dialog class, you can code a constructor that allows the main window to
set data in the dialog.
•• Within the class for the main window, you can code a method that allows the dialog
to return set data to the main window.
•• To close a dialog, you can call its dispose method. This closes the dialog object and
frees any resources that it’s using.
Figure 22-8 How to pass data between a dialog and its parent frame
590 Section 5 Real-world skills
Description
•• The Product Manager application uses the same dialog to add a new product or to
edit an existing product. The only difference in appearance is the title of the dialog
and the text that’s displayed on the first button.
•• When you add or edit a product, the Product form uses built-in dialogs to display
validation messages if the fields for the product are missing or not valid.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import mma.business.Product;
import mma.db.DBException;
import mma.db.ProductDB;
@SupressWarnings("serial")
public class ProductForm extends JDialog {
private JTextField codeField;
private JTextField descriptionField;
private JTextField priceField;
private JButton confirmButton;
private JButton cancelButton;
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
The next two lines of code create Dimension objects and assign them a
width of 100 pixels and 300 pixels respectively, with both having a height of
20 pixels. Then, the code sets the preferred size and minimum size of the code
and price text fields to the shorter Dimension object. It also sets the preferred
and minimum size of the description text field to the longer Dimension object.
In both cases, this prevents the pitfall described earlier in this chapter where the
text fields collapse to a width of zero if the user resizes the dialog.
The next section of the initComponents method creates the two buttons. To
start, it sets the text of the first button to “Cancel” and adds an action listener to
it that calls a method named cancelButtonActionPerformed that’s shown later
in this class. Then, it sets the text of the second button to “Add” and adds an
action listener to it that calls a method named confirmButtonActionPerformed.
However, if the user is editing an existing product instead of adding one, the
setText method call here is overridden by the setText method call in the second
constructor as discussed on the previous page.
The next section creates a new JPanel to store the text fields and their
corresponding labels. To start, this code sets the layout manager for the panel to
the GridBagLayout manager. Then, it adds the text fields and labels for the form
to the panel. To make working with the GridBagConstraints object easier, the
calls to the panel’s add method use a helper method called getConstraints that’s
shown later in this class. This method takes three parameters: An x coordinate
for the grid row, a y coordinate for the grid column, and an anchor value.
The next section creates another JPanel for the buttons. To start, this code
sets the layout manager to a FlowLayout manager with right alignment. Then, it
adds the confirm and cancel buttons to the layout.
The last section adds the panel that contains the labels and text fields to the
center area of the dialog’s BorderLayout manager. Then, it adds the panel that
contains the buttons to the south area of the dialog’s BorderLayout manager.
Like a JFrame component, a JDialog component uses the BorderLayout manager
by default. As a result, it isn’t necessary to explicitly set the layout. Finally, the
last statement uses the pack method to size the dialog by packing it so it’s just
large enough to hold all of the components.
Note that none of this code sets the location of this form or makes this form
visible. As a result, the parent frame must do that. For example, the main frame
of the Product Manager application could display the Add Product form like this:
ProductForm productForm = new ProductForm(this, "Add Product", true);
productForm.setLocationRelativeTo(this);
productForm.setVisible(true);
This displays a modal version of this form in the middle of the main window.
The getConstraints method creates and returns a GridBagConstraints
object with the specified parameters. This method begins by creating a new
GridBagConstraints object. Then, it sets the insets field to a new Insets object
that has five pixels of spacing on the top, left, and right, but no spacing on the
bottom. Next, it sets the gridx, gridy, and anchor fields of the GridBagConstraints
object to the corresponding parameters. Finally, it returns the new
GridBagConstraints object.
Chapter 22 How to develop a GUI with Swing (part 2) 595
cancelButton.setText("Cancel");
cancelButton.addActionListener((ActionEvent) -> {
cancelButtonActionPerformed();
});
confirmButton.setText("Add");
confirmButton.addActionListener((ActionEvent) -> {
confirmButtonActionPerformed();
});
// JButton panel
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
buttonPanel.add(confirmButton);
buttonPanel.add(cancelButton);
The next two methods in the class are the event handlers for the buttons. The
first event handler is called if the user presses the cancel button. The statement
within this method calls the dispose method of the dialog to close the dialog and
free its resources.
The second event handler is called if the user presses the confirm button. To
start, it uses an if statement that calls the validateData method shown later in this
class. This method makes sure the user entered all required data and that all of
the data is valid. If so, the event handler continues by calling the setData method
shown later in this class. This method gets the data from the form and sets that
data in the product instance variable.
The second if statement in the event handler checks whether the application
is editing an existing product or adding a new one. To do that, it checks the text
of the confirm button. If the text of the confirm button is “Add”, this code calls
the doAdd method shown later in this class. This method adds a new product to
the database. However, if the text of the button is not “Add”, this code calls the
doEdit method shown later in this class. This method updates an existing product
in the database.
The validateData method makes sure that the user has entered data for all
three text fields and that the user has entered a valid number for the product
price. To start, this code gets String objects for the product code, description, and
price variables by calling the getText methods on the corresponding text fields.
Then, this code uses an if statement to check whether all three fields in the form
contain values. If they don’t, the variables defined earlier are null or empty. In
that case, the code uses the JOptionPane class to display a dialog that contains a
message that asks the user to fill in all fields. Then, it returns a value of false.
This code also verifies that the price the user entered is a valid number. To
do this, it codes a statement that attempts to convert the price string to a double
value within a try statement. If this statement isn’t able to convert the string to a
double value, it throws a NumberFormatException, which causes the catch block
to be executed.
The catch block uses the JOptionPane class to display a dialog that contains
a message that informs the user that the data entered in the price field is not a
valid price. Then, it attempts to move the focus to the text field for the price.
However, this statement might not be able to move the focus. As a result, you
shouldn’t count on it working. Finally, the catch block returns a value of false.
If the user has entered data for all three fields, and the price is a valid
number, the validateData method returns a value of true. This indicates that the
data in the form is valid.
The setData method begins by getting the data contained in the form’s text
fields by calling their getText methods. Once again, to get a double value for the
price, this code needs to convert the String object returned by the getText method
to a double value. Then, this method sets this data in the instance variable for the
Product object by using its set methods.
For this method, the code doesn’t catch the NumberFormatException that
may be thrown by the parseDouble method because the validateData method
shown earlier has already made sure that the user has entered a valid number for
the price.
Chapter 22 How to develop a GUI with Swing (part 2) 597
The next two methods, doEdit and doAdd, are almost identical, except
that the doEdit method calls the update method of the ProductDB class, and
the doAdd method calls the add method of the ProductDB class. Then, these
methods both call the dispose method to close the dialog and free its resources.
Next, they call the fireDataBaseUpdatedEvent method.
The fireDatabaseUpdatedEvent notifies the main window that a new record
has been added to the database or that an existing record has been updated. In
turn, the main window notifies the table model that the table data needs to be
updated to reflect the changes made to the database as shown in the previous
chapter. To do this, the code begins by getting a reference to the parent window
of the dialog by calling the getOwner method. However, this method returns a
Window object. As a result, this code must cast it to the ProductManagerFrame
type before it can call its fireDatabaseUpdatedEvent method.
Chapter 22 How to develop a GUI with Swing (part 2) 599
A common problem
The first code example calls a method that could potentially take a long time
to complete. Because this method was called in response to the user pressing a
print button in the GUI, it runs on a special thread known as the event dispatch
thread, or EDT. All actions that are a result of an event run on the EDT, as do all
Swing operations that update the display, and respond to events.
Unfortunately, this means that the printProductList method also runs on the
EDT, which results in it becoming blocked until the method returns. As a result,
it can’t process other events, or redraw the screen if required. This causes the
application to become unresponsive to any other user events. In addition, the
display can become corrupt if it needs to be repainted, such as if it is resized, or
minimized and then restored.
At first, you might think you can solve this problem by running the print-
ProductList method on a new thread using the techniques shown in the second
code example. Unfortunately, it’s unsafe to perform any GUI operations outside
of the EDT, so this code causes a new problem, which is that this code runs the
JOptionPane dialog on a new thread rather than on the EDT, which can result in
display corruption.
Code that keeps the GUI responsive but shouldn’t update the GUI
private void doPrintButton() {
Thread printThread = new Thread() {
// This method runs on a background thread (not the EDT).
// As a result, the GUI remains responsive.
// However, it isn't safe to update the GUI from this thread.
@Override
public void run() {
printProductList(); // This method may take a long time to run.
JOptionPane.showMessageDialog(ProductManagerFrame.this,
"Product list has been printed."); // NOT safe!
}
};
printThread.start();
}
Code that keeps the GUI responsive and can update the GUI
private void doPrintButton() {
SwingWorker worker = new SwingWorker() {
// This method runs on a background thread (not the EDT).
// As a result, the GUI remains responsive.
@Override
protected Object doInBackground() throws Exception {
printProductList(); // This method may take a long time to run.
return null;
}
@Override
// This method runs on the EDT after the background thread finishes.
// As a result, it's safe to update the GUI from this method.
protected void done() {
JOptionPane.showMessageDialog(ProductManagerFrame.this,
"Product list has been printed."); // Safe!
}
};
worker.execute();
}
Description
•• Any code that runs in response to a Swing event runs on a special thread called the
event dispatch thread or EDT. All code that updates the GUI should run on this thread.
•• If you run a task that takes a long time on the EDT, the GUI becomes unresponsive.
•• If you use the techniques shown in chapter 18 to start a new thread, the GUI remains
responsive. However, you can’t safely update the GUI from this new thread.
• To allow the GUI to remain responsive while a long-running task runs and to be able
to update the GUI when that task finishes, you can use the SwingWorker class.
Perspective
In this chapter, you learned all of the remaining skills you need to know to
complete the Product Manager application. You learned how to use the JLabel
and JTextField classes to create labels and text fields for data entry forms. You
learned how to work with the GridBagLayout manager to create professional
looking forms. You learned how to use the JDialog class to create a modal data
entry form. And you learned how to pass data back and forth between two
windows in an application.
There’s still plenty more to learn about working with Swing. For example,
you may want to learn about other types of controls such as check boxes, radio
buttons, combo boxes, and lists. You may want to learn how to display photo-
graphs or other graphics in Swing. You may want to learn about other layout
managers. You may want to learn more about using the SwingWorker class to
create threads in Swing. Or, you may want to learn how to use a GUI builder
tool that’s available from your IDE. Whatever you decide to learn next about
Swing, the skills presented in the last two chapters are a solid foundation that
you can build on.
Summary
• You can use the JLabel class to create labels that label other components on a form.
•• You can use the JTextField class to create text fields, also known as text
boxes that allow a user to enter data.
•• You can use the GridBagLayout manager to create professional looking
form layouts that lay out the components in a grid. This class has two helper
classes: GridBagConstraints and Insets.
•• You can use the JDialog class to create a dialog that stays on top of its parent
window.
•• A dialog can be modal, which means it prevents users from interacting with
any other part of the application until they have responded to the dialog.
However, you should only use modal dialogs when the application cannot
complete an operation until the user responds to the dialog.
•• Any code that runs in response to a Swing event runs on a special thread
called the event dispatch thread or EDT.
•• To prevent the GUI from becoming unresponsive during long running tasks,
as well as make sure GUI updates happen safely on the EDT, you can use
the SwingWorker class.
Chapter 22 How to develop a GUI with Swing (part 2) 605
7. Add code to the initComponents method that initializes the frame and its
components. This method should:
•• Create the four text fields.
•• Modify the text fields for the area and perimeter so the user can’t edit
them.
•• Set the minimum and preferred dimension for all four fields.
•• Create the two buttons.
•• Create a panel that uses the GridBagLayout manager. Then, add the
four labels and text fields to this panel. To do that, you can use the
getConstraints method. Finally, add this panel to the center of the frame.
•• Create a panel that uses the FlowLayout manager with right alignment.
Then, add the two buttons to this panel. Finally, add this panel to the
bottom of the frame.
•• Pack the frame to set its size.
8. Run the application. This should display a frame that looks like the frame
shown above. However, if you click on one of the buttons, it should not
perform an action.
Handle the events that occur when the user clicks the buttons
9. Add action listeners to both of the buttons. These action listeners should call
the computeButtonClicked and resetButtonClicked methods.
10. Implement the computeButtonClicked method. This method should get the
text that the user entered into the text fields for the length and width and
attempt to convert this text to double values.
•• If the user enters an invalid length or width, this method should use a
dialog to display a user-friendly error message. Then, the user can try
again.
•• If the user enters a valid length and width, this method should calculate
the area and perimeter and set the corresponding text fields. To do that,
you can use the Rectangle class.
11. Implement the resetButtonClicked method. This method should set all four
text fields to empty strings.
Appendix A
How to set up Windows
for this book
This appendix shows how to install and configure the software that we recom-
mend for developing Java applications on a Windows system. For the first 18
chapters of this book, you only need to install the Java Development Kit (JDK),
the Eclipse IDE, and the source code for this book. However, for the last four
chapters in this book, you need to install MySQL and MySQL Workbench, and
you need to create the database for this book.
As you read this appendix, please remember that most websites are
updated constantly. As a result, some of the procedures in this appendix may
have changed since this book was published. Nevertheless, these procedures
should still be good guides to installing the software. And if there are signifi-
cant changes, we will post updates on our website (www.murach.com).
Procedure
1. Go to the download page for Java SE. If necessary, you can search the Internet to
find this page.
2. Click the Download button for Java. This button should have a label under it that
says something like Java Platform (JDK) 8u45.
3. Follow the instructions for downloading the installer program for your operating
system.
4. Save the installer program to your hard disk.
5. Run the installer program by double-clicking on it.
6. Respond to the resulting dialog boxes. When you’re prompted for the JDK folder,
use the default folder.
Notes
•• For more information about installing the JDK, you can refer to the Oracle website.
Procedure
1. Go to the download page for Eclipse. If necessary, you can search the Internet to
find this page.
2. Find the “Eclipse IDE for Java Developers” download.
3. Download the zip file for your version of Windows. This version must match the
version of the JDK you downloaded in the previous figure. For example, if you’re
using a 64-bit version of the JDK, you must use a 64-bit version of Eclipse.
4. When the download has finished, move the zip file to a suitable location on your
hard disk and unzip it.
5. Navigate to the eclipse folder that contains the eclipse.exe file.
6. Pin the eclipse.exe file to your taskbar. To do that, right-click on the eclipse.exe file
and select the Pin to Taskbar command.
Notes
•• For more information about installing Eclipse, you can refer to the Eclipse website.
•• If you get an error when you try to start Eclipse that indicates that Java failed to
start, you may have a 32-bit vs. 64-bit mismatch. You may be able to fix this issue
by uninstalling all versions of the JDK except the one you installed in the previous
figure.
Procedure
1. Go to www.murach.com.
2. Find the page for Murach’s Beginning Java with Eclipse.
3. If necessary, scroll down to the FREE Downloads tab.
4. Click the FREE Downloads tab.
5. Click the Download Now button for the exe file, and respond to the resulting pages
and dialog boxes. This should download an installer file named bjwe_allfiles.exe to
your hard drive.
6. Use Windows Explorer to find the exe file on your C drive.
7. Double-click this file and respond to the dialog boxes that follow. This should
install the files for this book in folders that start with C:\murach\java_eclipse
Figure A-3 How to install the source code for this book
614 Appendix A How to set up Windows for this book
Procedure
1. Find the download page for the MySQL Installer for Windows. This page is
currently available at the URL shown above. If necessary, you can search the
Internet for “MySQL Installer for Windows”.
2. Follow the instructions provided on that web page to download the installer file to
your hard drive.
3. Find the installer file on your hard drive and run it.
4. Respond to the resulting dialog boxes. You can accept most of the default options,
but you should specify a password for the root user. Make sure to remember the
password that you enter. If security isn’t a concern for you as you’re learning, we
recommend using “sesame” as the password.
5. To make sure that the database has been installed correctly, start MySQL
Workbench when the installation is finished. Then, use the password you entered in
the previous step to log in to the database server as the root user.
Notes
•• If you get a “status: failed” message when trying to install or upgrade to MySQL
Workbench 6.3 using the MySQL installer, you may need to install the Visual C++
2013 Redistributable Package. The MySQL Workbench Prerequisites page has
directions and links for doing that.
•• You can also install MySQL Server and MySQL Workbench separately. For more
information about that, you can visit the Downloads page of the MySQL website.
•• To make it easy to start MySQL Workbench, you may want to pin the program to
your taskbar or add a shortcut to your desktop.
Execute SQL
Script button
Description
•• For the create_database.sql file to run, the database server must be running. By
default, the database server is automatically started when you start your computer.
If it isn’t running on your system, you can use MySQL Notifier to start it.
Figure A-5 How to create and restore the database for this book
Appendix B
How to set up Mac OS X
for this book
This appendix shows how to install and configure the software that we recom-
mend for developing Java applications on a Mac OS X system. For the first 18
chapters of this book, you only need to install the Java Development Kit (JDK),
the Eclipse IDE, and the source code for this book. However, for the last four
chapters in this book, you need to install MySQL and MySQL Workbench, and
you need to create the database for this book.
As you read this appendix, please remember that most websites are
updated constantly. As a result, some of the procedures in this appendix may
have changed since this book was published. Nevertheless, these procedures
should still be good guides to installing the software. And if there are signifi-
cant changes, we will post updates on our website (www.murach.com).
Procedure
1. Go to the download page for Java SE. If necessary, you can search the Internet to
find this page.
2. Click the Download button for Java. This button should have a label under it that
says something like Java Platform (JDK) 8u45.
3. Follow the instructions for downloading the installer program for your operating
system.
4. Save the installer program to your hard disk.
5. Run the installer program by double-clicking on it.
6. Respond to the resulting dialog boxes. When you’re prompted for the JDK folder,
use the default folder.
Notes
•• For more information about installing the JDK, you can refer to the Oracle website.
Procedure
1. Go to the download page for Eclipse. If necessary, you can search the Internet to
find this page.
2. Find the “Eclipse IDE for Java Developers” download.
3. Download the tar.gz file for your operating system. This version must match the
version of the JDK that you downloaded in the previous figure. For example, if
you’re using a 64-bit version of the JDK, you must use a 64-bit version of Eclipse.
4. When the download has finished, use the Finder to move the tar.gz file to a suitable
location on your hard disk. Then, double-click on the tar.gz file to unzip it. This
should create a folder named eclipse that contains the Eclipse program.
5. Add the Eclipse program to the Dock. To do that, use the Finder to drag the icon for
the Eclipse program from the eclipse folder and drop it on the Dock.
Notes
•• For more information about installing Eclipse, you can refer to the Eclipse website.
•• If you get an error when you try to start Eclipse that indicates that Java failed to
start, you may have a 32-bit vs. 64-bit mismatch. You may be able to fix this issue
by uninstalling all versions of the JDK except the one you installed in the previous
figure.
Procedure
1. Go to www.murach.com.
2. Find the page for Murach’s Beginning Java with Eclipse.
3. If necessary, scroll down to the FREE Downloads tab.
4. Click the FREE Downloads tab.
5. Click the Download Now button for the zip file, and respond to the resulting pages
and dialog boxes. This should download a zip file named bjwe_allfiles.zip to your
hard drive.
6. Use the Finder to locate the zip file on your hard drive, and double-click on it to
unzip it. This creates the java_eclipse folder and its subfolders.
7. If necessary, use the Finder to create the murach folder directly on your hard drive.
8. Use the Finder to move the java_eclipse folder into the murach folder.
Figure B-3 How to install the source code for this book
626 Appendix B How to set up Mac OS X for this book
Description
•• You can use the MySQL preference pane to start and stop MySQL and to control
whether MySQL starts automatically when you start your computer.
•• To display the MySQL preference pane, use the Apple menu to display the System
Preferences dialog box. Then, click the MySQL icon.
Notes
•• Although you can use any names you want for the connections you create in
MySQL Workbench, “Local instance MySQL56” is the name of the default con-
nection that is created on a Windows system for MySQL version 5.6, and that’s the
name we use in this book.
•• To make it easy to start MySQL Workbench, you may want to keep this application
in your dock.
Execute SQL
Script button
Description
•• For the create_database.sql file to run, the database server must be running. By
default, the database server is automatically started when you start your computer.
If it isn’t running on your system, you start it as described in figure B-4.
Figure B-6 How to create and restore the database for this book
632 Appendix B How to set up Mac OS X for this book
Procedure
1. Start MySQL Workbench.
2. Connect as the root user to an instance of MySQL that’s running on the localhost
computer. To do that, click on the stored connection for the root user. Since a
password hasn’t been assigned to the root user, you don’t need to enter a password.
3. Open the update_root_password.sql file by clicking the Open SQL Script File
button in the SQL Editor toolbar and navigating to the /murach/java_ eclipse/db
folder.
4. Click the Execute SQL Script button. This should update the root password to
“sesame”.
5. Use the MySQL preference pane shown earlier in this appendix to stop and start the
MySQL server.
Description
•• By default, the root user doesn’t have a password. This is not secure.
•• For this book, you can run a script like the one shown in this figure to change the
password for the root user to “sesame”.
•• For a production system, you can modify the script shown in this figure to make the
password for the root user more secure.
Figure B-7 How to update the password for the root user
634 BLOB objects (Binary Large Objects)
Index
Adding records to tables, 500, 501
Addition operator, 174, 175
compound, 178, 179
Adjuster (date/time), 400, 401
anchor field (GridBagConstraints), 580, 581
And operator, 200, 201
- operator, 174-177 Android app, 12, 13
-- operator, 176, 177 Android Studio IDE, 18, 19
! operator, 200, 201 Annotation (@Override), 280, 281
!= operator, 81, 198, 199 Anonymous class, 338, 339
% operator, 174, 175 Anonymous functions (lambda), 378, 379
%= operator, 178, 179 API documentation, 68, 69
& operator, 200, 201 Append
&& operator, 200, 201 data to a file, 446, 447
* operator, 174, 175 data to a string, 54, 55, 234, 235
*= operator, 178, 179 append method (StringBuilder), 242, 243
/ operator, 174, 175 Applet, 10, 11
/= operator, 178, 179 Application, 8, 9
@author tag (javadoc), 346, 347 Argument, 38, 39, 66, 67
@Override annotation, 280, 281 sending to method, 112, 113
@param tag (javadoc), 346, 347 Arithmetic expression, 52, 53, 174, 175
@return tag (javadoc), 346, 347 Arithmetic operators, 52, 53, 174, 175
@version tag (javadoc), 346, 347 Array
| operator, 200, 201 assigning values to, 256, 257
|| operator, 200, 201 comparing, 266, 267
+ operator compared to a collection, 358, 359
numbers, 174-177 copying, 266, 267
strings, 54, 55 creating, 254, 255
++ operator, 176, 177 creating references to, 266, 267
+= operator, 178, 179 referring to elements, 256, 257
< operator, 81, 198, 199 Array list, 360, 361, 364, 365
<= operator, 81, 198, 199 Array of arrays, 262, 263
<> operator (generics), 362, 363 ArrayIndexOutOfBoundsException, 256, 257
<code> tag (HTML), 346, 347 ArrayList class (java.util), 360, 361, 364-369
-= operator, 178, 179 constructor, 364, 365
-> operator (lambda), 382, 383 Arrays class, 264, 265
== operator, 81, 198, 199 ASCII character set, 168, 169
> operator, 81, 198, 199 Assign
>= operator, 81, 198, 199 value to variable, 170, 171
values to array elements, 256, 257
A Assignment operator, 170, 171
Assignment statement, 48-51, 120, 121
Absolute path name, 436, 437 Asynchronous thread, 476, 477
abstract class, 298, 299 Augmented assignment operator, 178, 179
advantages, 310, 311 Autoboxing, 358, 359, 370, 371
compared to interfaces, 310, 311 AutoCloseable interface (java.lang), 416, 417
abstract keyword, 298, 299 Autoflush feature, 444, 445
abstract method, 298, 299 Automatic driver loading, 508, 509
Abstract Window Toolkit (AWT), 334, 335, 532-535 AWT (Abstract Window Toolkit), 334, 335, 532-535
AbstractTableModel class, 548, 549
Access modifier, 34, 35, 108, 109, 280, 281
Accessors (set and get), 108, 109
B
Action listener, 540, 541 Base class, 276, 277
ActionListener interface, 338, 339 BigDecimal class, 186-189
actionPerformed method, 540, 541 Binary file, 438, 439
add method (ArrayList), 366, 367 Binary operator, 174, 175
add method (BigDecimal), 186, 187 Binary stream, 438, 439
add method (BorderLayout), 546, 547 binarySearch method (Arrays class), 264, 265
add method (JFrame, JPanel), 538, 539 Bit, 168, 169
addActionListener method, 540, 541 BLOB objects (Binary Large Objects), 512, 513
Block comment Confirm an operation (JOptionPane) 635
doubleValue method (BigDecimal class), 186, 187 Exception, 72, 73, 220, 221, 410, 411
do-while loop, 214, 215 catching, 72, 73, 414, 415, 220-223
DriverManager class, 508, 509 chaining, 428, 429
Drivers (database), 506, 507 checked, 426, 427
DROP DATABASE statement (SQL), 496, 497 custom, 426-429
eating, 416
handling, 72, 73
E hierarchy, 220, 221
multi-catch, 420, 421
Eating exceptions, 416
propagation, 412, 413
Eclipse, 20-29
swallowing, 416
code editor, 42, 43
throwing, 72, 73, 412, 413, 422, 423
create class, 40, 41
try-with-resources, 416, 417
import project, 22, 23
unchecked, 426, 427
install on Mac, 622, 623
when to throw, 424, 425
install on Windows, 610, 611
Exception class (java.lang), 410, 411
Java source code, 42, 43
creating, 426-429
new project, 40, 41
Exception handler, 220- 222, 410- 413
packages, 136, 137
testing, 424, 425
syntax error, 46, 47
executeUpdate method, 514, 515
two or more projects, 28, 29
Execution (tracing), 154, 155
workbench, 20, 21
exists method (Files class), 434, 435
workspace, 20, 21
EXIT_ON_CLOSE value, 536, 537
EDT (event dispatch thread), 602, 603
Explicit cast, 182, 183
EE (Enterprise Edition), 4, 5
Extend a class, 276, 277, 282, 283
Elements
extends keyword, 282, 283, 316, 317
array, 254, 255
assigning values, 256, 257
Empty string, 54, 55
Encapsulation, 98, 99
F
End-of-line comment, 36, 37 Falls through (switch statement), 208, 209
endsWith method (String), 236, 237 Field,
Enhanced for loop (array), 260, 261 class, 98, 99, 102-105
Enum class (java.lang), 342, 343 database, 484, 485
enum keyword, 340, 341 file, 446, 447, 574, 575
Enumeration, 340, 341 File I/O, 438, 439
Enumeration type, 342, 343 FileNotFoundException (java.io), 442, 443
EOFException (java.io), 442, 443 FileReader class (java.io), 448, 449
Equality operator, 81, 198, 199 Files (working with), 434-437
equals method (Arrays class), 266, 267 Files class (java.nio.file), 434-437
equals method (Object class), 278, 279, 296, 297 FileWriter class (java.io), 444, 445
equals method (String class), 80, 81, 236, 237 fill method (Arrays class), 264, 265
equals method (overriding), 296, 297 final class, 300, 301
equalsIgnoreCase method (String class), 80, 81, 236, 237 final keyword, 172, 173, 300, 301
Error final method, 300, 301
coding, 150, 151 final parameter, 300, 301
compile-time, 152, 153 final variable, 172, 173
determining cause of, 152, 153 finally clause (try statement), 414, 415
Java, 150, 151 fireTableDataChanged method, 548, 549
logic, 152, 153 Fixed-width layout, 542, 543
runtime, 152, 153 float type, 168, 169
syntax, 150, 151 Floating-point number, 168, 169
Error class (java.lang), 410, 411 FlowLayout manager, 542-545
ERROR_MESSAGE (JOptionPane), 558, 559 constructor, 544, 545
Escape sequences, 56, 57 flush method (PrintWriter class), 446, 447
Event, 334, 335 flushing the buffer, 440, 441
handler, 540, 541 Folders (working with), 434-437
listener, 540, 541 for loop, 216, 217
Event dispatch thread (EDT), 602, 603 array, 258, 259
638 for statement INFORMATION_MESSAGE (JOptionPane)
K in an interface, 309
naming, 108, 109
Key-value pair, 360, 361 overloading, 122, 123
Keywords (Java), 46-48 overriding, 282, 283
signature, 122, 123
static, 66, 67
L Microsoft SQL Server, 484, 485
Middle tier, 132, 133
Label, 574, 575 min method (Math), 184, 185
Lambda expression, 378-383, 540, 541 minus method (LocalDateTime), 400, 401
lambda operator, 382, 383 minusWeeks method, 400, 401
last method (ResultSet), 510, 511 Mobile app, 12, 13
lastIndexOf method (String), 236, 237 Modal dialog box, 558, 559, 586, 587
Late binding, 284 Model (for table), 548, 549
Layering Modulus operator, 174, 175
input streams, 448, 449 compound, 178, 179
output streams, 444, 445 Month enumeration, 392, 393
streams, 440, 441 Multi-catch block, 420, 421
Layout manager, 542, 543, 578, 579 Multi-layered architecture, 132
Length (array), 254, 255 Multiple inheritance, 308
length field (array), 258, 259 MULTIPLE_INTERVAL_SELECTION, 554, 555
length method (String), 238, 239 Multiplication operator, 174, 175
length method (StringBuilder), 242, 243 compound, 178, 179
Less Than operator, 81, 198, 199 multiply method (BigDecimal class), 186, 187
Less Than Or Equal operator, 81, 198, 199 Multithreading, 464, 465
Libraries, 24, 25 Multi-tier architecture, 132
Life cycle of a thread, 468, 469 Mutable strings, 242, 243
Linked list, 360, 361 MySQL, 484, 485, 490-501
LinkedList class (java.util), 360, 361 install on Windows, 614, 615
List interface (java.util), 360, 361 install on Mac, 626, 627
Literal value, 50, 51 update password on Mac, 632, 633
LocalDate class, 392-401 MySQL preference pane (Mac), 626, 627
LocalDateTime class, 392-401 MySQL Workbench, 490-501
LocalTime class, 392-401 install on Mac, 628, 629
Locking objects, 476, 477 install on Windows, 614, 615
Locks (synchronized keyword), 476, 477
Logic error, 148, 149, 152, 153
Logical operators, 200, 201 N
long type, 168, 169
Loops, 212-219 Name elements (of a path), 434, 435
array, 258-261 name method (enumeration), 342, 343
Naming conventions
constants, 172, 173
M classes, 34, 35
variables, 48, 49, 170, 171
Main class, 34, 35 Narrowing conversion, 182, 183
main method, 14, 15, 34, 35 Native protocol all Java driver, 506, 507
declaration, 34, 35 Native protocol partly Java driver, 506, 507
Main thread, 464, 465 Negative sign operator, 176, 177
Main window, 536, 537 Nested
Many-to-many relationship, 486, 487 if statement, 84, 85, 204, 205
Map interface (java.util), 360, 361 loop, 262, 263
Math class, 184, 185 Net protocol all Java driver, 506, 507
max method (Math class), 184, 185 NetBeans IDE, 18, 19
ME (Micro Edition), 4, 5 new keyword, 110, 111
Members of a class, 102, 103 New state (thread), 468, 469
Method, 14, 15, 34, 35, 98, 99 newDirectoryStream method (Files class), 434, 435
calling, 66, 67, 112, 113 next method (ResultSet), 510, 511
calls, 120, 121 nextLine method (Scanner class), 70, 71
chaining, 76, 77 NIO.2, 436, 437
coding, 108, 109 NO_OPTION (JOptionPane), 562, 563
Not operator public keyword 641
Q S
Query (SQL), 498-501 Scale, 186, 187
Querying tables (SQL), 498, 499 Scanner class, 70, 71
QUESTION_MESSAGE (JOptionPane), 558, 559 Schema, 492, 493
Scientific notation, 168, 169
Scope of a class, 34, 35
R Scroll pane, 556, 557
Scrollbar, 556, 557
random method (Math class), 184, 185
ScrollPaneConstants, 556, 557
RDBMS (relational database management system), 484
SDK (Software Development Kit), 4, 5
Reader class hierarchy (java.io), 448, 449
SE (Standard Edition), 4, 5
Reading
Select database (MySQL), 496, 497
from console, 70, 71
SELECT statement (SQL), 496-501
from text files, 450, 451
Selection structure, 84, 202, 203
readLine method (BufferedReader class), 450, 451
Servlet, 10, 11
Read-only result set, 510, 511
set accessor, 108, 109
Record
Set interface (java.util), 360, 361
database, 484, 485
set method, 102, 103, 108, 109
file, 446, 447
ArrayList class, 368, 369
Rectangular array, 262, 263
setBorder method (JTable), 554, 555
Refactor, 136, 137
setCharAt method (StringBuilder), 244, 245
Reference type, 110, 111
setColumns method (JTextField), 576, 577
array, 266, 267
setDefaultCloseOperation method, 536, 537
compared to primitive type, 120, 121
setEditable method (JTextField), 576, 577
Referential integrity (MySQL), 490, 491
setEnabled method, 538, 539
Relational database, 484, 485
setHorizontalScrollBarPolicy, 556, 557
Relational operators, 80, 81, 198, 199
setLayout method, 542, 543
Relationships (between tables), 486, 487
setLookAndFeel method, 536, 537
Relative path name, 436, 437
setMaximumFractionDigits method, 76, 77
Remove a project (Eclipse), 28, 29
setMaximumSize method, 584, 585
remove method (ArrayList), 368, 369
setMinimumFractionDigits method, 76, 77
replace method (StringBuilder), 244, 245
setMinimumSize method (JTextField), 576, 577
Resizing problem, 584, 585
setModel method (JTable), 554, 555
Result set (SQL), 498-501, 510, 511
setPreferredSize method, 576, 577, 584, 585
get data from, 512, 513
setResizable method, 584, 585
ResultSet methods, 510, 511
setScale method (BigDecimal class), 186, 187
return statement, 108, 109
setSelectionMode method (JTable), 554, 555
Return type, 108, 109
setText method, 538, 539
Return value (of a method), 112, 113
JLabel, 574, 575
RIAs (rich Internet applications), 532, 533
JTextField, 576, 577
Rich Internet applications (RIAs), 532, 533
setToolTipText method, 538, 539
root user (update password), 632, 633
setVerticalScrollBarPolicy, 556, 557
round method (Math class), 184, 185
setVisible method, 538, 539
Rounding errors (fixing), 188, 189
Shallow copy (array), 266, 267
RoundingMode enumeration, 186, 187
short type, 168, 169
Row,
Short-circuit operators, 202, 203
database, 484, 485
showConfirmDialog method (JOptionPane), 560-563
file, 446, 447
showMessageDialog method (JOptionPane), 558, 559
Row pointer, 510, 511
Signature
Run a project (Eclipse), 26, 27
constructor, 106, 107
run method (Runnable interface), 466, 467
method, 122, 123
run method (Thread class), 466, 467, 471
Significant digits, 168, 169
Runnable interface (java.lang), 466, 467
SINGLE_INTERVAL_SELECTION, 554, 555
implementing, 474, 475
SINGLE_SELECTION, 554, 555
Runnable state (thread), 468, 469
Single-line comment, 36, 37
Runtime error, 148, 149, 152, 153
Single-precision number, 168, 169
Runtime exception, 148, 149
Size (array), 254, 255
RuntimeException class (java.lang), 220, 221, 410, 411
size method Thread scheduler 643
U
UIManager class, 536, 537
UML (Unified Modeling Language), 98, 99
Unary operator, 176, 177
Unchecked exception, 410, 411, 426, 427
Unicode character set, 168, 169
Unicode characters, 438, 439
Unified Modeling Language (UML), 98, 99
UPDATE statement (SQL), 500, 501, 514, 515
User thread, 470, 471
V
VALUES clause (SQL), 496, 497
Variable, 48, 49, 170, 171
array, 254, 255
initializing, 48, 49, 170, 171
numeric, 48, 49
string, 54-57
VERTICAL_SCROLLBAR_ALWAYS, 556, 557
VERTICAL_SCROLLBAR_AS_NEEDED, 556, 557
VERTICAL_SCROLLBAR_NEVER, 556, 557
void keyword, 108, 109
100% Guarantee
When you order directly from us, you must be satisfied. Our books must work better than
any other programming books you’ve ever used...both for training and reference...or you can send
them back within 60 days for a prompt refund. No questions asked!
Related
Books for database programmers
Book Murach’s MySQL (2nd Ed.) $54.50
Murach’s Oracle SQL and PL/SQL for Developers (2nd Ed.) 54.50
Murach’s SQL Server 2016 for Developers 57.50
Move on to Java Books for web developers
web programming
Murach’s HTML5 and CSS3 (3rd Ed.) $54.50
Thousands of Java developers Murach’s JavaScript and jQuery (3rd Ed.) 57.50
have used this book to learn
Murach’s PHP and MySQL (2nd Ed.) 54.50
web programming…you can
too! It builds on your core
Java skills to teach you how
Books for .NET programmers
to create web applications like Murach’s C# 2015 $57.50
a pro, using Java servlets and Murach’s ASP.NET 4.6 Web Programming with C# 2015 59.50
JavaServer Pages (JSPs). Murach’s Visual Basic 2015 $57.50
*Prices and availability are subject to change. Please visit our website or call for current information.
www.murach.com twitter.com/MurachBooks
1-800-221-5528 facebook.com/murachbooks
(Weekdays, 8 am to 4 pm Pacific Time)
linkedin.com/company/
[email protected]
mike-murach-&-associates
What software you need for this book
•• Java SE 8 (JDK 1.8) or later.
•• Eclipse IDE 4.4 or later.
•• MySQL 5.6 or later.
•• MySQL Workbench 6.3 or later.
•• You can download this software for free and install it as described in appendix A
(Windows) or appendix B (Mac OS X).
www.murach.com