
- •Contents at a Glance
- •Contents
- •About the Authors
- •About the Technical Reviewer
- •Acknowledgments
- •Introduction
- •Oracle Java Certifications: Overview
- •FAQ 1. What are the different levels of Oracle Java certification exams?
- •FAQ 4. Is OCPJP 7 prerequisite for other Oracle certification exams?
- •FAQ 5. Should I take the OCPJP 7 or OCPJP 6 exam?
- •The OCPJP 7 Exam
- •FAQ 7. How many questions are there in the OCPJP 7 exam?
- •FAQ 8. What is the duration of the OCPJP 7 exam?
- •FAQ 9. What is the cost of the OCPJP 7 exam?
- •FAQ 10. What are the passing scores for the OCPJP 7 exam?
- •FAQ 11. What kinds of questions are asked in the OCPJP 7 exam?
- •FAQ 12. What does the OCPJP 7 exam test for?
- •FAQ 13. I’ve been a Java programmer for last five years. Do I have to prepare for the OCPJP 7 exam?
- •FAQ 14. How do I prepare for the OCPJP 7 exam?
- •FAQ 15. How do I know when I’m ready to take the OCPJP 7 exam?
- •Taking the OCPJP 7 Exam
- •FAQ 16. What are my options to register for the exam?
- •FAQ 17. How do I register for the exam, schedule a day and time for taking the exam, and appear for the exam?
- •The OCPJP 7 Exam: Pretest
- •Answers with Explanations
- •Post-Pretest Evaluation
- •Essentials of OOP
- •FunPaint Application: An Example
- •Foundations of OOP
- •Abstraction
- •Encapsulation
- •Inheritance
- •Polymorphism
- •Class Fundamentals
- •Object Creation
- •Constructors
- •Access Modifiers
- •Public Access Modifier
- •Private Access Modifier
- •Protected and Default Access Modifier
- •Overloading
- •Method Overloading
- •Constructor Overloading
- •Overload resolution
- •Points to Remember
- •Inheritance
- •Runtime Polymorphism
- •An Example
- •Overriding Issues
- •Overriding: Deeper Dive
- •Invoking Superclass Methods
- •Type Conversions
- •Upcasts and Downcasts
- •Casting Between Inconvertible Types
- •Using “instanceof” for Safe Downcasts
- •Java Packages
- •Working with Packages
- •Static Import
- •Summary
- •Abstract Classes
- •Points to Remember
- •Using the “final” Keyword
- •Final Classes
- •Final Methods and Variables
- •Points to Remember
- •Using the “static” Keyword
- •Static Block
- •Points to Remember
- •Flavors of Nested Classes
- •Static Nested Classes (or Interfaces)
- •Points to Remember
- •Inner Classes
- •Points to Remember
- •Local Inner Classes
- •Points to Remember
- •Anonymous Inner Classes
- •Points to Remember
- •Enum Data Types
- •Points to Remember
- •Summary
- •Interfaces
- •Declaring and Using Interfaces
- •Points to Remember
- •Abstract Classes vs. Interfaces
- •Choosing Between an Abstract Class and an Interface
- •Object Composition
- •Composition vs. Inheritance
- •Points to Remember
- •Design Patterns
- •The Singleton Design Pattern
- •Ensuring That Your Singleton Is Indeed a Singleton
- •The Factory Design Pattern
- •Differences Between Factory and Abstract Factory Design Patterns
- •The Data Access Object (DAO) Design Pattern
- •Points to Remember
- •Summary
- •Generics
- •Using Object Type and Type Safety
- •Using the Object Class vs. Generics
- •Container Implementation Using the Object Class
- •Container Implementation Using Generics
- •Creating Generic Classes
- •Diamond Syntax
- •Interoperability of Raw Types and Generic Types
- •Generic Methods
- •Generics and Subtyping
- •Wildcard Parameters
- •Limitations of Wildcards
- •Bounded Wildcards
- •Wildcards in the Collections Class
- •Points to Remember
- •The Collections Framework
- •Why Reusable Classes?
- •Basic Components of the Collections Framework
- •Abstract Classes and Interfaces
- •Concrete Classes
- •List Classes
- •ArrayList Class
- •The ListIterator Interface
- •The LinkedList Class
- •The Set Interface
- •The HashSet Class
- •The TreeSet Class
- •The Map Interface
- •The HashMap Class
- •Overriding the hashCode() Method
- •The NavigableMap Interface
- •The Queue Interface
- •The Deque Interface
- •Comparable and Comparator Interfaces
- •Algorithms (Collections Class)
- •The Arrays Class
- •Methods in the Arrays Class
- •Array as a List
- •Points to Remember
- •Summary
- •Generics
- •Collections Framework
- •Processing Strings
- •String Searching
- •The IndexOf() Method
- •The regionMatches() Method
- •String Parsing
- •String Conversions
- •The Split() Method
- •Regular Expressions
- •Understanding regex Symbols
- •Regex Support in Java
- •Searching and Parsing with regex
- •Replacing Strings with regex
- •String Formatting
- •Format Specifiers
- •Points to Remember
- •Summary
- •Reading and Writing from Console
- •Understanding the Console Class
- •Formatted I/O with the Console Class
- •Special Character Handling in the Console Class
- •Using Streams to Read and Write Files
- •Character Streams and Byte Streams
- •Character Streams
- •Reading Text Files
- •Reading and Writing Text Files
- •“Tokenizing” Text
- •Byte Streams
- •Reading a Byte Stream
- •Data Streams
- •Writing to and Reading from Object Streams: Serialization
- •Serialization: Some More Details
- •Points to Remember
- •Summary
- •A Quick History of I/O APIs
- •Using the Path Interface
- •Getting Path Information
- •Comparing Two Paths
- •Using the Files Class
- •Checking File Properties and Metadata
- •Copying a File
- •Moving a File
- •Deleting a File
- •Walking a File Tree
- •Revisiting File Copy
- •Finding a File
- •Watching a Directory for Changes
- •Points to Remember
- •Summary
- •Introduction to JDBC
- •The Architecture of JDBC
- •Two-Tier and Three-Tier JDBC Architecture
- •Types of JDBC Drivers
- •Setting Up the Database
- •Connecting to a Database Using a JDBC Driver
- •The Connection Interface
- •Connecting to the Database
- •Statement
- •ResultSet
- •Querying the Database
- •Updating the Database
- •Getting the Database Metadata
- •Points to Remember
- •Querying and Updating the Database
- •Performing Transactions
- •Rolling Back Database Operations
- •The RowSet Interface
- •Points to Remember
- •Summary
- •Define the Layout of the JDBC API
- •Connect to a Database by Using a JDBC driver
- •Update and Query a Database
- •Customize the Transaction Behavior of JDBC and Commit Transactions
- •Use the JDBC 4.1 RowSetProvider, RowSetFactory, and RowSet Interfaces
- •Introduction to Exception Handling
- •Throwing Exceptions
- •Unhandled Exceptions
- •Try and Catch Statements
- •Programmatically Accessing the Stack Trace
- •Multiple Catch Blocks
- •Multi-Catch Blocks
- •General Catch Handlers
- •Finally Blocks
- •Points to Remember
- •Try-with-Resources
- •Closing Multiple Resources
- •Points to Remember
- •Exception Types
- •The Exception Class
- •The RuntimeException Class
- •The Error Class
- •The Throws Clause
- •Method Overriding and the Throws Clause
- •Points to Remember
- •Custom Exceptions
- •Assertions
- •Assert Statement
- •How Not to Use Asserts
- •Summary
- •Introduction
- •Locales
- •The Locale Class
- •Getting Locale Details
- •Resource Bundles
- •Using PropertyResourceBundle
- •Using ListResourceBundle
- •Loading a Resource Bundle
- •Naming Convention for Resource Bundles
- •Formatting for Local Culture
- •The NumberFormat Class
- •The Currency Class
- •The DateFormat Class
- •The SimpleDateFormat Class
- •Points to Remember
- •Summary
- •Introduction to Concurrent Programming
- •Important Threading-Related Methods
- •Creating Threads
- •Extending the Thread Class
- •Implementing the Runnable Interface
- •The Start( ) and Run( ) Methods
- •Thread Name, Priority, and Group
- •Using the Thread.sleep() Method
- •Using Thread’s Join Method
- •Asynchronous Execution
- •The States of a Thread
- •Two States in “Runnable” State
- •Concurrent Access Problems
- •Data Races
- •Thread Synchronization
- •Synchronized Blocks
- •Synchronized Methods
- •Synchronized Blocks vs. Synchronized Methods
- •Deadlocks
- •Other Threading Problems
- •Livelocks
- •Lock Starvation
- •The Wait/Notify Mechanism
- •Let’s Solve a Problem
- •More Thread States
- •timed_waiting and blocked States
- •waiting State
- •Using Thread.State enum
- •Understanding IllegalThreadStateException
- •Summary
- •Using java.util.concurrent Collections
- •Semaphore
- •CountDownLatch
- •Exchanger
- •CyclicBarrier
- •Phaser
- •Concurrent Collections
- •Apply Atomic Variables and Locks
- •Atomic Variables
- •Locks
- •Conditions
- •Multiple Conditions on a Lock
- •Use Executors and ThreadPools
- •Executor
- •Callable, Executors, ExecutorService, ThreadPool, and Future
- •ThreadFactory
- •The ThreadLocalRandom Class
- •TimeUnit Enumeration
- •Use the Parallel Fork/Join Framework
- •Useful Classes of the Fork/Join Framework
- •Using the Fork/Join Framework
- •Points to Remember
- •Summary
- •Using java.util.concurrent Collections
- •Applying Atomic Variables and Locks
- •Using Executors and ThreadPools
- •Using the Parallel Fork/Join Framework
- •Chapter 3: Java Class Design
- •Chapter 4: Advanced Class Design
- •Chapter 5: Object-Oriented Design Principles
- •Chapter 6: Generics and Collections
- •Chapter 7: String Processing
- •Chapter 8: Java I/O Fundamentals
- •Chapter 9: Java File I/O (NIO.2)
- •Chapter 10: Building Database Applications with JDBC
- •Chapter 11: Exceptions and Assertions
- •Chapter 12: Localization
- •Chapter 13: Threads
- •Chapter 14: Concurrency
- •OCPJP7 Exam (1Z0-804 a.k.a. Java SE 7 Programmer II) Topics
- •OCPJP 7 Exam (1Z0-805, a.k.a. Upgrade to Java SE 7 Programmer) Topics
- •Answers and Explanations
- •Answer Sheet
- •Answers and Explanations
- •Index

Chapter 11 ■ Exceptions and Assertions
Note how you provided more than one catch handler by stacking them up: you provided specific (i.e., derived type) exception handlers followed by more general (i.e., base type) exception handlers. If you provide a derived exception type after a base exception type, you get a compiler error. You might not already know, but
NoSuchElementException is the base class of InputMismatchException! See what happens when you try to reverse the order of catch handlers for InputMismatchException and NoSuchElementException.
try {
System.out.println("The integer value scanned from string is: " + consoleScanner.nextInt());
} catch(NoSuchElementException nsee) {
System.out.println("Error: Cannot scan an integer from the given string"); } catch(InputMismatchException ime) {
System.out.println("Error: Cannot scan an integer from the given string");
}
This code segment will result in this compiler error:
ScanInt4.java:14: error: exception InputMismatchException has already been caught
}catch(InputMismatchException ime) {
^
1 error
When providing multiple catch handlers, handle specific exceptions before handling general exceptions. If you provide a derived class exception catch handler after a base class exception handler, your code will not compile.
Multi-Catch Blocks
You just saw that you cannot reverse the order of the catch handlers for InputMismatchException and NoSuchElementException. However, is it possible to combine these two catch handlers together? Java 7 provides a feature named multi-catch blocks in which you can combine multiple catch handlers (see Listing 11-6).
Listing 11-6. ScanInt5.java
// A program that illustrates multi-catch blocks
import java.util.*;
class ScanInt5 {
public static void main(String [] args) {
String integerStr = "";
System.out.println("The string to scan integer from it is: " + integerStr);
Scanner consoleScanner = new Scanner(integerStr);
try {
System.out.println("The integer value scanned from string is: " + consoleScanner.nextInt());
324

Chapter 11 ■ Exceptions and Assertions
} catch(NoSuchElementException | IllegalStateException multie) {
System.out.println("Error: An error occured while attempting to scan the integer");
}
}
}
Note how you combine the catch handlers together using the | (OR) operator here (the same operator you use for performing bit-wise OR operation on integral values) for combining the catch clauses of NoSuchElementException and IllegalStateException.
Unlike the combined catch clauses for NoSuchElementException and IllegalStateException, you cannot combine the catch clauses of NoSuchElementException and InputMismatchException. As we've already discussed, NoSuchElementException is the base class of InputMismatchException, and you cannot catch both of them in the multi-catch block. If you try compiling such a multi-catch clause, you’ll get this compiler error:
ScanInt5.java:11: error: Alternatives in a multi-catch statement cannot be related by subclassing } catch(InputMismatchException | NoSuchElementException exception) {
^
So what is the alternative? When you need such a catch handler for the exceptions where one exception is the base class of another exception class, providing the catch handler for the base class alone is sufficient (since that base class catch handler will handle the derived class exception if it occurs).
In a multi-catch block, you cannot combine catch handlers for two exceptions that share a baseand derived-class relationship. You can only combine catch handlers for exceptions that do not share the parent-child relationship between them.
How do you know if it is better to combine exception handling blocks or stack them? It is a design choice where you must consider the following aspects: a) Do the exceptions get thrown for similar reason or for different reasons?
(b) Is the handling code similar or different? If you answer “similar” for both the questions, it is better to combine them; if you say “different” for either one of these two questions, then it is better to separate them.
How about the specific situation in Listing 11-6? Is it better to combine or separate the handlers for the InputMismatchException and IllegalStateException exceptions? You can see that the exception handling is the same for both of the catch blocks. But the reasons for these two exceptions are considerably
different. The InputMismatchException gets thrown if you (or the user) type invalid input in the console. The IllegalStateException gets thrown because of a programming mistake when you call the nextInt() method after calling the close() method on Scanner. So, in this case, it is a better design choice to separate the handlers for these two exceptions.
General Catch Handlers
Did you notice that many exceptions can get thrown when you use APIs related to I/O operations? We just discussed that in order to call just one method, nextInt() of the Scanner class, you need to handle three exceptions: the
InputMismatchException, the NoSuchElementException, and the IllegalStateException. If you keep handling specific exceptions such as this that may not actually result in an exceptional condition when you run the program, most of your code will consist of try-catch code blocks! Is there a better way to say “handle all other exceptions”? Yes, you can provide a general exception handler.
325

Chapter 11 ■ Exceptions and Assertions
Here is the code snippet that shows only the try-catch blocks for the class ScanInt3 from Listing 11-4, enhanced with a general exception handler:
try {
System.out.println("You typed the integer value: " + consoleScanner.nextInt());
}catch(InputMismatchException ime) {
//if something other than integer is typed, we'll get this exception, so handle it
System.out.println("Error: You typed some text that is not an integer value...");
}catch(Exception e) {
//catch IllegalStateException here which is unlikely to occur...
System.out.println("Error: Encountered an exception and could not read an integer from the console... ");
This code provides a catch handler for the base exception of the type Exception. So, if the try block throws any other exception than the InputMismatchException, and if that exception is a derived class of the Exception class, this general catch handler will handle it. It is recommended practice to catch specific exceptions, and then provide a general exception handler to ensure that all other exceptions are handled as well.
Chained Exceptions
When you want to catch an exception and throw another exception, you can “chain” the first exception to the thrown exception. In other words, when throwing an exception, you can associate another exception that caused it.
When creating an exception object you can use a constructor that takes another exception as an argument; this passed argument is the exception chained to the exception object being created. There is also an overloaded constructor that takes a description message as an additional argument. For example, the following are two overloaded constructors of the Exception class:
Exception(Throwable cause)
Exception(string detailMsg, throwable cause)
Similar constructors are available for other classes such as Throwable, Error, and RuntimeException. The following program illustrates chained exceptions:
class ChainedException {
public static void foo() {
try {
String [] str = { "foo" };
System.out.println("About to throw ArrayIndexOutOfBoundsException");
// following statement has out-of-bounds access
String functionName = str[10];
} catch(ArrayIndexOutOfBoundsException oob) {
System.out.println("Wrapping ArrayIndexOutOfBoundsException into a RuntimeException");
throw new RuntimeException(oob);
}
}
326

Chapter 11 ■ Exceptions and Assertions
public static void main(String []args) {
try {
foo();
} catch(Exception re) {
System.out.println("The caught exception in main is: " + re.getClass());
System.out.println("The cause of the exception is: " + re.getCause());
}
}
}
When executed, this program prints the following:
About to throw ArrayIndexOutOfBoundsException
Wrapping ArrayIndexOutOfBoundsException into a RuntimeException The caught exception in main is: class java.lang.RuntimeException
The cause of the exception is: java.lang.ArrayIndexOutOfBoundsException: 10
Methods related to chained exceptions are the getCause() and initCause() methods defined in the
Throwable class.
The getCause() method returns a Throwable object. It returns an exception chained to the exception object on which this method is invoked. This chained exception is the original exception that caused this exception. If no exception is chained to this exception, this method returns null.
The initCause(Throwable causeException) method sets the chained exception for the exception object on which this method is called. If the chained exception has already been set when creating the exception object, calling this method will result in throwing an IllegalStateException. This method can be called only once; any attempt to call it more than once will result in throwing an IllegalStateException.
Note that exceptions can be chained to any level of depth.
Finally Blocks
There is a close() method provided in the Scanner class, and you need to close it. In the classes ScanInt1, ScanInt2, and ScanInt3 (Listings 11-2, 11-3, and 11-4, respectively), note that you opened a Scanner object but did not close it. So, these programs have a resource leak! The word “resource” refers to any of the classes that acquire some
system sources from the underlying operating system, such as network, file, database, and other handles. But how do you know which classes need to be closed? Well, nice question. The answer is that if a class implements java.io.Closeable, then you must call the close() method of that class; otherwise, it will result in a resource leak.
The garbage collector (GC) is responsible for releasing only memory resources. If you are using any class that acquires system resources, it is your responsibility to release them by calling the close() method on that object.
ScanInt6 (Listing 11-7) calls the close() method of the Scanner object in its main() method; you want to shorten the code, so you’ll use a general exception handler for handling all exceptions that can be thrown within the try block.
327
Chapter 11 ■ Exceptions and Assertions
Listing 11-7. ScanInt6.java
import java.util.*;
class ScanInt6 {
public static void main(String [] args) {
System.out.println("Type an integer in the console: ");
Scanner consoleScanner = new Scanner(System.in);
try {
System.out.println("You typed the integer value: " +
consoleScanner.nextInt());
System.out.println("Done reading the text... closing the Scanner");
consoleScanner.close();
} catch(Exception e) {
// call all other exceptions here ...
System.out.println("Error: Encountered an exception and could not read an integer from the console... ");
System.out.println("Exiting the program - restart and try the program again!");
}
}
}
Let’s see if this program works.
D:\> java ScanInt6
Type an integer in the console: 10
You typed the integer value: 10
Done reading the text... closing the Scanner
Because the program printed "Done reading the text... closing the Scanner", and completed the execution normally, you can assume that the statement consoleScanner.close(); has executed successfully. What happens if an exception gets thrown?
D:\> java ScanInt6
Type an integer in the console: ten
Error: Encountered an exception and could not read an integer from the console...
Exiting the program - restart and try the program again!
As you can see from the output, the program did not print "Done reading the text... closing the Scanner", so the statement consoleScanner.close(); has not executed. How can you fix it? One way is to call consoleScanner. close() in the catch block as well, like this:
try {
System.out.println("You typed the integer value: " + consoleScanner.nextInt()); System.out.println("Done reading the text... closing the Scanner");
consoleScanner.close();
}catch(Exception e) {
//call all other exceptions here ...
consoleScanner.close();
328

Chapter 11 ■ exCeptions and assertions
System.out.println("Error: Encountered an exception and could not read an integer from the console... ");
System.out.println("Exiting the program - restart and try the program again!");
}
This solution will work but is not elegant. You know you can have multiple catch blocks and you have to provide calls to consoleScanner.close(); in all the catch blocks! Is there a better way to release the resources? Yes, you can use release resources in a finally block (see Listing 11-8).
Listing 11-8. ScanInt7.java
import java.util.*;
class ScanInt7 {
public static void main(String [] args) { System.out.println("Type an integer in the console: "); Scanner consoleScanner = new Scanner(System.in);
try {
System.out.println("You typed the integer value: " + consoleScanner.nextInt());
} catch(Exception e) {
// call all other exceptions here ...
System.out.println("Error: Encountered an exception and could not read an integer from the console... ");
System.out.println("Exiting the program - restart and try the program again!"); } finally {
System.out.println("Done reading the integer... closing the Scanner"); consoleScanner.close();
}
}
}
In this case, a finally block is provided after the catch block. This finally block will be executed whether an exception has occurred or not. So, the finally block is a good place to call the close() method on the Scanner object to ensure that this resource is always released.
if you call System.exit() inside a method, it will abnormally terminate the program. so, if the calling method has a finally block, it will not be called and resources may leak. For this reason, it is a bad programming practice to call System.exit() to terminate a program.
Now, let’s see if the scanner is closed both in the case when the program completes normally (i.e., without throwing an exception) and when the program terminates after throwing an exception.
D:\> java ScanInt7
Type an integer in the console: 10
You typed the integer value: 10
Done reading the integer... closing the Scanner
329