
- •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
Exception Types
Until now, we have focused on explaining the language constructs related to exceptions: the try, catch, multi-catch, finally, and try-with-resources blocks. Some concepts won’t be clear to you yet. For example, you learned the throws clause where you declare that a method can throw certain exceptions. You saw that for some types of exceptions, you don’t need to declare them in the throws clause, but for certain other kinds of exceptions, you can declare them in the throws clause. Why? What are these different kinds of exceptions? To answer these questions and get a better idea about the exception handling support in the Java library, we’ll discuss types of exceptions in this section.
In Java, you cannot throw any primitive types as exception objects. This does not mean that you can throw any reference type objects as exceptions. The thrown object should be an instance of the class Throwable or one of its subclasses: Throwable is the apex class of the exception hierarchy in Java. Exception handling constructs such as the throw statement, throws clause, and catch clause deal only with Throwable and its subclasses. There are three important subclasses of Throwable that you need to learn in detail: the Error, Exception, and RuntimeException classes. Figure 11-2 provides a high-level overview of these classes.
|
java.lang.Object |
|
||
Base class of checked |
|
|
Base of exception |
|
exceptions such as |
java.lang.Throwable |
hierarchy;all |
||
ParseException and |
exceptions must |
|||
|
|
|||
IOException;you must |
|
|
extent this class. |
|
handle them! |
|
|
|
|
|
java.lang.Exception |
java.lang.Error |
|
java.lang.RuntimeException
Base class for representing programming errors such as IndexOutOFBoundsException.
JVM errors such as stackOverflowError; don’t
handle them!
Figure 11-2. Java’s exception hierarchy
The Exception Class
Exceptions of type Exception are known as checked exceptions. If code can throw an Exception, you must handle it using a catch block or declare that the method throws that exception, forcing the caller of that method to handle that exception. Consider Listing 11-12.
Listing 11-12. CheckedExceptionExample1.java
import java.io.*;
class CheckedExceptionExample1 {
public static void main(String []args) {
FileInputStream fis = new FileInputStream(args[0]);
}
}
336
Chapter 11 ■ Exceptions and Assertions
This program results in a compiler error.
CheckedExceptionExample1.java:5: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
FileInputStream fis = new FileInputStream(args[0]);
^
1 error
The constructor of FileInputStream declares that it throws the exception FileNotFoundException. This FileNotFoundException is derived from the Exception class, hence is a checked exception. With checked exceptions, Java forces you to think about failure conditions and how to handle them. Now, think about the code in Listing 11-13: you are trying to open the file given by the string args[0], which may not be present. If you don’t want to catch and handle the FileNotFoundException, you can declare the main() method to throw this exception.
Listing 11-13. CheckedExceptionExample2.java
import java.io.*;
class CheckedExceptionExample2 {
public static void main(String []args) throws FileNotFoundException {
FileInputStream fis = new FileInputStream(args[0]);
}
}
This program will compile fine without any errors. However, this code is still not satisfactory: if you pass the name of a file in the command line that does not exist in the search path, the program will crash after throwing this exception:
D:\ > java CheckedExceptionExample2 somefile.txt
Exception in thread "main" java.io.FileNotFoundException: somefile.txt (The system cannot find the file specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:138) at java.io.FileInputStream.<init>(FileInputStream.java:97)
at CheckedExceptionExample2.main(CheckedExceptionExample2.java:5)
A better way to handle the situation is to throw an error message to the user and inform her that she has to pass the file name as the first argument to the program, as in Listing 11-14.
Listing 11-14. CheckedExceptionExample3.java
import java.io.*;
class CheckedExceptionExample3 {
public static void main(String []args) {
try {
FileInputStream fis = new FileInputStream(args[0]);
} catch(FileNotFoundException fnfe) {
System.out.println("Error: There is no file that exists with name " + args[0]);
System.out.println("Pass a valid file name as commandline argument!");
}
}
}
337

Chapter 11 ■ Exceptions and Assertions
Now, when passed with a name of the file that does not exist, the program will terminate and show this useful error message to the user:
D:\ > java CheckedExceptionExample3 somefile.txt
Error: There is no file that exists with name somefile.txt Pass a valid file name as commandline argument!
If you have some code that can throw a checked exception from a method, you can choose between the two alternatives. You can either handle that exception by providing a catch block or declare that method to throw that exception. If you don’t catch or declare the method to throw that exception, your code won’t compile.
Table 11-1 summarizes the important subclasses of the Exception class.
Table 11-1. Important Subclasses of the Exception Class
|
|
Class |
Short Description |
CloneNotSupportedException |
Thrown when the clone() method is invoked on an object whose class |
|
does not implement a Cloneable interface. |
IOException |
Thrown when an Input/Output operation fails (say because of an |
|
interrupted call). |
EOFException |
Thrown when end-of-file (EOF) is reached unexpectedly; subclass of |
|
IOException. |
FileNotFoundException |
Thrown when the runtime is not able to locate or open the given file; |
|
derived class of IOException. |
ReflectiveOperationException |
Thrown when a reflection operation fails; superclass of reflection |
|
related exceptions such as NoSuchMethodException and |
|
InvocationTargetException. |
RuntimeException |
Superclass of unchecked exceptions (discussed in the next section in this |
|
chapter). |
SQLException |
Thrown when a database access or related operations fail; superclass of |
|
database-related exceptions such as SerialException. |
ParseException |
Thrown when the parsing fails (for example, while processing locale- |
|
sensitive information such as dates and times in the Format class). |
|
|
The RuntimeException Class
RuntimeException is a derived class of the Exception class. The exceptions deriving from this class are known as unchecked exceptions. Let’s first discuss an example of a RuntimeException. Recollect Listing 11-14 in the context of FileNotFoundException (we’ve renamed the class in Listing 11-15).
338

Chapter 11 ■ exCeptions and assertions
Listing 11-15. UnCheckedExceptionExample1.java
import java.io.*;
class UnCheckedExceptionExample1 {
public static void main(String []args) throws FileNotFoundException { FileInputStream fis = new FileInputStream(args[0]);
}
}
What happens if you run the program without passing any arguments to this program? It will crash after throwing an ArrayIndexOutOfBoundsException.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at UnCheckedExceptionExample1.main(UnCheckedExceptionExample1.java:5)
In this program, without checking the length of args (to see if it contains any values), you attempt indexing args in the expression args[0]. In other words, you assume that the user will always provide the name of the file to open as a command-line argument, and when no argument is provided, it becomes an exceptional condition. Hence, it
is a programming mistake. Note that though the expression args[0] can throw ArrayIndexOutOfBoundsException, you did not catch this exception or declare it in the throws clause of the main() method. This is because
ArrayIndexOutOfBoundsException is a RuntimeException, so it is an unchecked exception.
it is optional to handle unchecked exceptions. if a code segment you write in a method can throw an unchecked exception, it is not mandatory to catch that exception or declare that exception in the throws clause of that method.
How can you fix the problem in Listing 11-15? How about the following change in the program to handle the
ArrayIndexOutOfBoundsException (shown in Listing 11-16)?
Listing 11-16. UnCheckedExceptionExample2.java
import java.io.*;
class UnCheckedExceptionExample2 {
public static void main(String []args) throws FileNotFoundException { try {
FileInputStream fis = new FileInputStream(args[0]); } catch (ArrayIndexOutOfBoundsException aioobe) {
System.out.println("Error: No arguments passed in the commandline!"); System.out.println("Pass the name of the file to open as commandline argument");
}
}
}
339

Chapter 11 ■ Exceptions and Assertions
When run, this program prints the following:
D:\> java UnCheckedExceptionExample2
Error: No arguments passed in the commandline!
Pass the name of the file to open as commandline argument
Yes, showing the error message and telling the user the right thing to do is good. However, this approach of catching a runtime exception such as ArrayIndexOutOfBoundsException is a bad practice! Why? Runtime exceptions such as ArrayIndexOutOfBoundsException indicate likely programming errors, and you should fix the code instead of catching and handling the exceptions. So, how do you fix the program here? You can check the length of args before attempting to access the array member (see Listing 11-17).
Listing 11-17. UnCheckedExceptionExample3.java
import java.io.*;
class UnCheckedExceptionExample3 {
public static void main(String []args) throws FileNotFoundException {
// if any argument is passed, it would be greater than or equal to one
if(args.length >= 1) {
FileInputStream fis = new FileInputStream(args[0]);
} else {
System.out.println("Error: No arguments passed in the commandline!"); System.out.println("Pass the name of the file to open as commandline argument");
}
}
}
The output is the same if no argument is passed to the program, but the code is better: it checks if it is possible to perform array indexing before actually indexing the array and thus is programmed defensively.
It is a good practice to perform defensive checks and avoid raising unnecessary runtime exceptions.
Table 11-2 summarizes the important subclasses of the RuntimeException class.
340