Here are my study notes for the Java SE 7 Programmer II to get the Oracle Certified Professional, Java SE 7 Programmer certification. This is based on the topics in Oracle published syllabus for the exam.
This page is a work in progress, so come back for more details as I go.
See also my Study Notes for Java SE 7 Programmer I OCA.
Note: I accept no liability for any inaccuracy or mistakes in this document. If you find any errors, please let me know so I can correct it!
Java Class Design
- Use access modifiers:
- private
- only accessible within class
- protected
- only accessible with package and subclasses
- public
- world accessible
- default
- package-private
- accessible within package
- private
- Override methods
- Don’t override Object.finalize as it’s not guaranteed to run
- Overload constructors and methods
- Overloaded method use the number and types of arguments to determine which version of the overloaded method to call
- Return type are not used to determine which overloaded method to call.
- If a class will be inherited, a no argument constructor should be supplied. This will be called when a subclass is instantiated.
- instanceof operator
- Comparison between object and specified type.
- Will return true when an object is:
- An instance of the specified class
- An instance of a subclass of the specified class
- An instance of a class that implements the specified interface
- Will return false when an object is:
- An instance of a parent class of the specified class
- A reference to null
- Will not compile if comparing neither a subtype or supertype
- Will produce compilation error: Unresolved compilation problem: Incompatible conditional operand types.
- Often over-used and can be replaced by polymorphism
- Casting
- Used with superclass reference types allow access to subclass properties and methods
- Uses syntax (MyClass)myInstance.
- Virtual method invocation
- Used when multiple subclasses override the same method
- The object type’s implementation of the overriden method is used, not the reference type method
- Important part of polymorphism
- Override methods from Object class:
- hashCode
- Must consistently return the same integer for the same object each time invoked, provided information used by equals method is not changed.
- If two objects are not equal they should not return the same integer value
- equals
- Compares two objects
- Must be reflexive, symmetric, transitive and consistent
- Comparing to null should return false
- toString
- Must return a string that represents the object as text
- Recommended that all subclasses override this method
- hashCode
- package statement
- The package statement must be the first executable line of the source file, preceding any import statements.
- Creates a package, put package statement with the name of the package at the top of every source file that contains types(classes, interfaces, enumerations and annotations) to be part of the package.
- Without a package statement the type becomes part of an unnamed package.
- import statement
- Import a package member using import package.Member;
- Import an entire package by using import package.*;
- Packages are not hierarchical, importing package.* will not import package.subpackage.*
- Where members of two or more imported packages have the same name, the fully qualified member name must be used.
- import static statement allows you to reference constants and static methods from a class without prefixing the class name.
Advanced Class Design
- Abstract classes
- Cannot be instantiated but can be subclassed
- May or may not include abstract methods
- Subclass must provide implementations for all abstract methods of parent, otherwise must also be abstract.
- static keyword
- Static methods must use object reference to access instance variables or methods.
- Static methods cannot use this keyword.
- Static methods can be hidden by a static method with the same signature
- Differs from overriding because the version of the static method that is invoked depends on the reference type from which it is invoked
- static keyword is used to declare a class variable, which is part of the class not the object instance
- Class variables are shared between all instances of the class
- final keyword
- Indicates that a field cannot change
- Used with methods to prevent them being overriden
- Create top-level classes
- Top level classes expected to be inherited by subclasses should have a default no-arg constructor.
- The default no-arg constructor cannot be used if the class has any constructors defined.
- Create nested classes
- Static Nested classes
- Declared using static keyword
- Do not have access to members of enclosing class
- Non-static nested classes
- Known as inner classes
- Have access to members of enclosing class, including private members
- Cannot define any static members
- May be private, public, protected or package-private
- Static Nested classes
- Enumerated types
- Allows a variable to be set equal to one of a set of predefined constant values.
- Is a class which extends java.lang.Enum.
- Constructor must be package-private or private.
- Java compiler adds a values() method at compile time which returns an array of values in the enum.
Object-Oriented Design Principles
- Interfaces
- Declaring
- Implementing
- Extending
- Interface inheritance or class inheritance
- Multiple interfaces can be implemented
- Multiple unrelated classes can inherit interfaces.
- Applying
- Cohesion
- The degree to which the elements of a class belong together
- Cohesion in a class is increased if the functions within a class have a lot in common and perform a small number of related tasks.
- Advantages:
- Reduced complexity
- Increased maintainability
- Increased reusability
- Low-coupling
- The degree to which each component uses and has knowledge of other components.
- Advantages:
- Components from a low-coupling system can be replaced with alternative implementations that provide the same functions.
- Components may be implemented with different platforms, using different languages, operating systems or build environments.
- IS-A
- Can be identified by a class using the extends or implements keywords.
- HAS-A relationship
- A class uses HAS-A relationship by composition, by having an instance of another class and using it.
- Cohesion
- Object composition principles
- Singleton design pattern
- Only one instance of the object is created.
- Possible implementations:
- Class with a private constructor and instance created as a private static member and a static method that returns that instance.
- An enum.
- Data Access Object(DAO) design pattern
- Consists of:
- A Data Access Object Interface
- A Data Access Object concrete class that implements the DAO interface
- A Model object, containing get/set methods for the data
- Consists of:
- Factory pattern
- Consists of:
- 1 or more concrete classes that implement a common interface
- A common interface
- A factory class which returns a new instance of one of the concrete classes
- Consists of:
Generics and Collections
- Generics allow the creation of classes, interfaces and methods where the type is specified as a parameter.
- Generic classes
- Declared using <> symbols
- Diamond for type inference
- Means that the new statement to instantiate the object and call the constructor doesn’t require repetition of the type(s) from the reference declaration.
- The compiler infers the type from the declaration.
- e.g. ArrayList<string> myList = new ArrayList<>();
- Raw types
- A raw type is a generic class or interface without a type parameter supplied
- A parameterized generic type may be assigned to it’s raw type
- Assigning a raw type to a parameterized type will produce a warning
- Using a raw type to invoke generic methods will produce a warning
- Collections using raw and generic types
- Wildcards
- Wrapper classes
- The type argument of a generic cannot be a primative type, they must be object types
- Always declare generics using object types.
- Using a primative type will cause a compile error
- Autoboxing
- Autoboxing will automatically convert a primative variable to the corresponding type wrapper.
- e.g. an int value can be assigned to ArrayList<Integer> myVals
- Unboxing
- Unboxing means that a type wrapper object value can be automatically converted to a primative value when assigning a value copied from the type wrapper object.
- Implementations of:
- List
- List interface members:
- add(E e); – appends to list
- add(int index, E e); – inserts into list at specified index
- ArrayList
- LinkedList
- List interface members:
- Set
- Deque
- Map
- Sorted Maps
- TreeMap
- NavigableMap
- HashTable
- HashMap
- Sorted Maps
- List
- Use java.util.Comparator
- Use java.lang.Comparable
- Must provide a method int compareTo(T o) which returns -1, or 1.
- Sort and search arrays and lists
- To be sorted in collections, the objects contained within must implement the Comparable interface.
String Processing
- Scanner
- Constructor may take File, InputStream, Path, Readable, ReadableBytChannel and String
- Can parse text into primitive types and strings using regular expressions
- useDelimiter method accepts a regular expression as a Pattern or a String to use as a delimiter between fields in the text
- has and next functions exist for each primitive type and some others
- nextLine advances to the next text line and returns the current one as a String.
- StringTokenizer
- Constructors:
- StringTokenizer(String str) – uses default delimiters – space, tab, newline, carriage return, form feed.
- StringTokenizer(String str, String delim) – Uses specified delimiter in delim
- StringTokenizer(String str, String delim, boolean returnDelims) – if returnDelims is true, include the delimiters in the tokens
- nextElement() returns the next token
- nextToken() returns the next token or thorws NoSuchElementException
- countToken() calculates the number of times nextToken can be called before an exception
- hasMoreTokens() returns true if there is at least one more token after current token
- Constructors:
- StringBuilder
- Constructors:
- StringBuilder() – creates a blank String Builder
- StringBuilder(CharSequence seq) – creates a StringBuilder with the same characters as the seq
- StringBuilder(int capacity) creates a StringBuilder with capacity set
- StringBuilder(String str) creates a StringBuilder with the contents of the String
- append(T x) methods exist for all primatives, CharSequence, String and StringBuffer
- charAt(int index) returns a char from the specified index
- delete(int start, int end) deletes characters from start to end.
- insert(int offset, T x) methods exist to insert primatives at an offset
- substring(int start) returns a String containing all characters from start to the end of the StringBuilder
- substring(int start, int end) returns a String containing characters from start to end.
- toString() returns the StringBuiler as a string.
- Constructors:
- String
- Formatter
- Interprets printf style format strings
- Example: Formatter formatter = new Formatter(sb, Locale.US);
- String processing with regular expressions
- Used by Pattern and Matcher classes.
- PatternSyntaxException indicates that a syntax error has occurred in a regular expression pattern.
- Syntax:
- ^ – matches beginning of line
- $ – matches end of line
- . – matches any single character except newline
- […] – matches any single character in brackets
- [^…]- matches any single character not in brackets
- \A – Beginning of entire string
- \z – End of entire string
- \Z – End of entire string except final line terminator
- a|b – matches either a or b
- \w – matches word characters
- \W – matches nonword characters
- \s – matches whitespace
- \S – matches non whitespace
- \d – matches digits, same as [0-9]
- \D – matches nondigits
- \n – matches newlines
- \t – matches tabs
- Format strings
- See Formatter javadoc
- %n is used for platform appropriate new line
- %d is used for a decimal integer
- %f is use for float
- a leading 0 after %d indicates use of leading zeroes
- a number flag indicates characters in width, e.g. 10.3 is ten characters wide with three places after decimal point
- + indicates use sign, positive or negative
- , indicates locale specific grouping characters
- – indicates left justified
- defaults to right justified
- To use a % sign in a formatted number for instance for a percentage, use %%.
Exceptions and Assertions
- Each try statement requires at least one catch or a finally block.
- catch statement
- Once one catch statement executes the otheres are bypassed.
- Exception subclasses must come before their superclasses. Otherwise an unreachable code error will occur at compile time.
- throw statement
- thrown object must be of type Thowable or a subclass of it.
- Execution immediately stops and control is passed to the nearest matching catch statement.
- throws statement
- Lists the exception types the method may throw.
- Required for all thrown exceptions except Error or RuntimeException and their subclasses.
- Multiple Exception types in single catch block
- Called multi-catch
- Use pipe symbol
- e.g. catch(FileNotFoundException | IOException e)
- try-with-resources statements
- finally statement
- Executes regardless of whether or not an exceptions has been thrown.
- If exception has been thrown executes after the relevant catch block.
- Custom exceptions
- Test invariants by using assertions
Java I/O Fundamentals
- Read and write data from the console
- Get a Console object with System.console() method.
- System.console().readPassword() retrieves user input without echoing typed characters.
- The Java platform supports three standard streams:
- Standard input – stdin – using System.in
- Standard output – stdout – using System.out
- System.setOut may be use to redirect output to a different stream
- Standard error – stderr – using System.err
- Can be read using BufferedReader or Scanner
- Using streams to read and write files with:
- BufferedReader
- Implements Closeable, AutoCloseable, Readable
- read() reads a single character – returns -1 if end of stream is reached
- ready() returns true or false
- skip(long n) skip n characters
- Methods throw IOException
- BufferedWriter
- File
- FileReader
- FileWriter
- Implements Closeable, Flushable, Appendable, AutoCloseable
- Defaults to overwrite an existing file use FileWriter(File file, boolean append) constructor with append set to true to append to an existing file.
- Inherits methods from Writer.
- RandomAccessFile
- Implements DataOutput, DataInput, Closeable
- readUTF reads the file into a String
- writeUTF writes a String to the file
- Maintains a cursor also known as a current file pointer marking the current location in the file.
- seek(long pos) sets the cursor location/file pointer, measured in bytes from beginning of file.
- read and write methods are provided for all primatives
- readLine reads bytes from the file, starting from current file pointer and ending at the end of the current line. Line terminating characters are not included.
- FileInputStream
- Implements Closeable, AutoCloseable
- read() reads a single byte or -1 if end of file
- read(byte[] b]) reads b.length bytes of data into an array of bytes
- read(byte[] b, int off, int len) reads len bytes starting at offset off into an array of bytes
- skip(long n) skips n bytes
- DataInputStream
- DataOutputStream
- ObjectOutputStream
- ObjectInputStream
- PrintWriter
- BufferedReader
- Serializable interface
- Enables a class to be serialized
- Always include a serialVersionUID field
- static and transient fields are not serialized
- Superclass fields are only serialized if the superclass also implements Serializable
Java File I/O (NIO.2)
- Path class
- Paths.get returns a Path object
- resolve(Path p) appends a relative path p to this path. If p is an absolute path then p is returned.
- relativize(Path p) returns a relative path from this path to path p
- getName(int index) returns the name of the component of the path at that index
- getRoot() returns root component
- Files class
- Atomic operations
- An atomic file operation cannot be interrupted or partially completed.
- Entire operation is completed or fails.
- move method supports atomic moves and replacing existing files by means of options provided
- Atomic operations
- Interfaces:
- BasicFileAttributes
- creationTime() returns creation time as a FileTime object
- fileKey() returns an object that uniquely identifies the file
- isDirectory() returns true if the file is a director, false otherwise
- isOther() returns true if the file not a regular file, directory or symbolic link
- isRegularFile() returns true if the file is a regular file
- isSymbolicLink() returns true if the file is a symbolic link
- lastAccessTime() returns the last access time as a FileTime object
- lastModifiedTime() returns the last modification time as a FileTime object
- BasicFileAttributeView
- readAttributes() method returns a BasicFileAttributes object
- setTimes() allows any or all of a file’s last modified time, last access time and create times to be updated.
- DosFileAttributes
- Provides ability to read legacy MS DOS file attributes
- Provides isArchive(), isHidden(), isReadOnly, isSystem() attributes
- DosFileAttributeView
- Provides readAttributes which returns a DosFileAttributes object
- Provides setArchive(boolean value), setHidden(boolean value), setReadOnly(boolean value), setSystem(boolean value)
- PosixFileAttributes
- Provides ability to read file attributes from POSIX operating system file systems. Typically these are Unix, Linux or Mac OS X systems.
- DirectoryStream
- FileVisitor
- PathMatcher
- Instantiate with for example:
- PathMatcher matcher = Filesystems.getDefault().getPathMatcher(“glob:*.{txt,doc}”);
- Uses glob patterns
- Instantiate with for example:
- WatchService
- Watches registered objects for changes and events.
- May be used to monitor directories or files for changes.
- If the file system does not support file change notifications the API will poll the file system for changes.
- BasicFileAttributes
Building Database Applications with JDBC
- JDBC Drivers must include Statement, ResultSet and Connection objects
- JDBC Driver Types:
- Type 1
- Not pure Java
- Require native libraries
- Use bridging to data source
- Type 4
- Are pure Java
- Use direct connections to data source
- Can use network protocols
- Type 1
- Core interfaces:
- Driver
- acceptsURL(String url) method checks whether the driver thinks it can open a connection to the url.
- connect(String url) is the most basic way to start a connection
- connect(String url, Properties info) method tries to start a connection
- connect(String url, String user, String password) also tries to start a connection
- url is in format: jdbc:subprotocol:subname
- getMajorVersion() and getMinorVersion() get the major and minor version numbers respectively
- SQLException is thrown for most database access errors.
- See Javadoc for other methods.
- Connection
- Connections are AutoCloseable
- Use DriverManager.getConnection() and DataSource.getConnection() to establish a connection using a JDBC driver
- Use setAutoCommit(false) to turn off auto commiting of updates
- Use commit() to commit updates when auto committing is off.
- Statement
- Statements default to being commited automatically
- ResultSet
- Maintains a pointer/cursor to the current row.
- next method moves to next row, but returns false if there a no more rows.
- Current row pointer is initially set before the first row, so will require a next to reach the first row.
- By default is only cursor only moves forward
- By default ResultSet is not updateable
- A ResultSet may be set to be updateable and scrollable.
- Driver
- Connect to database using DriverManager class
- Submit queries and read results
- Use JDBC transactions
- Disable auto-commit mode using setAutoCommit(false);
- Commit changes using commit();
- Rollback changes rollback() if a SQLException is thrown.
- setSavepoint() sets a Savepoint within the current transaction. Use rollback(Savepoint s) to rollback to that savepoint.
- Disable auto-commit only during transaction mode.
- Savepoint interface
- Represents a point that can be returned to by the Connection.rollback method.
- releaseSavepoint(Savepoint s) removes the Savepoint from the current transaction.
- Construct and Use RowSet objects with RowSetProvider class and RowSetFactory interface
- Get a RowSetFactory using RowSetFactory factory = RowSetProvider.newFactory();
- Get a JdbcRowSet using JdbcRowSet rs = factory.createJdbcRowSet();
- A JdbcRowSet can also be obtained by using JdbcRowSet rs = new JdbcRowSetImpl();
- CachedRowSet interfaces
- These are disconnected RowSets – connected only when reading data and propagating changes to the data source
- WebRowSet interface
- Allows a RowSet to be read or written in XML format.
- FilteredRowSet interface
- Allows disconnected filtering of a RowSet using a Predicate object
- Statement object
- Supports only simple SQL statements without parameters
- Support only a single result set open
- PreparedStatement object
- Supports only input parameters
- CallableStatement object
- Supports input and output parameters because they contain stored procedures
Threads
- Create and use Thread class and Runnable interface
- Implementing Runnable
- Requires a method call run()
- e.g. public void run()
- Must have an object of type Thread and instantiate it
- Thread constructors:
- Thread(Runnable threadOb, String threadName)
- Use start method of the Thread object to start the thread running.
- Requires a method call run()
- Extending Thread
- Implementing Runnable
- Manage and control thread lifecycle
- Threads may be paused in execution using Thead.sleep(long milliseconds) which throws an InterruptedException
- isAlive() method returns true if the thread is still running
- join() method waits for a thread to finish execution
- Synchronise thread access to shared data
- Identify code that may not execute correctly in a multi-threaded environment
Concurrency
- Collections from java.util.concurrent package
- BlockingQueue provides a first-in-first-out queue data structure
- ConcurrentMap interface has atomic operations to remove or replace a key-value pair if it’s present or add a key-value pair if it is absent. Has implementation ConcurrentHashMap.
- ConcurrentHashMap is similar to HashMap
- ConcurrentNavigableMap is sub-interface supporting approximate matches.
- Standard implementation is ConcurrentSkipListMap which is similar to TreeMap.
- These collections try to avoid Memory Consistency Errors using a happens-before relationship.
- Use
- Lock interface
- lock() acquires the lock
- unlock() releases the lock
- ReadWriteLock interface
- Separate locks for reading and writing
- Read lock may be held by multiple reader threads at the same time if there are no writers
- Write lock may only be held by one thread
- ReentrantLock
- Mutual exclusion lock – both reading and writing are locked.
- lock() returns immediately if the lock is acquired, disables thread and waits if lock is not available.
- Optional constructor Boolean fairness parameter, when set to true locks favour the longest-waiting thread.
- Executor interface
- execute(Runnable r) method creates a thread of Runnable object r.
- May use a worker thread or put Runnable object r in a queue waiting for a worker thread.
- ExecutorService subinterface of Executor
- Provides features to manage lifecycle of tasks and Executor
- Executors
- Factory and utility methods for Executor, ExecutorService, ScheduledExecutorService, ThreadFactory, Callable.
- Provides methods for creating a thread pool: newCachedThreadPool, newFixedThreadPool, newScheduledThreadPool, newSingleThreadExecutor, newSinglethreadScheduledExecutor, newWorkStealingPool.
- Allow separation of thread management and creation from the rest of application.
- Callable interface
- Implementations must define a method call with no arguments that returns a result of a generic type. May thrown an exception if unable to produce a result.
- Future interface
- Represents the result of an asynchronous computation.
- Provides method to check for completion, to wait and to retrieve results.
- Lock interface
- Use parallel Fork/Join Framework
- Implementation of ExecutorService interface
- Uses work-stealing algorithm
- Extend ForkJoinTask or a more specialised subclass such as RecursiveTask or RecursiveAction
- RecursiveTask returns a result.
- RecursiveAction does not return a result.
Localisation
- Read and set locale with Locale object
- Use Locale constructors
- Use constants in Locale class
- Use Locale.forLangaugeTag factory method
- Locale.Builder class
- Create a Locale variable with the Locale.Builder class: Locale loc = Locale.Builder().setLangauge(“en”).setScript(“Latn”).setRegion(“AU”).build();
- build method must be called to create a Locale object withtthe Locale.Builder class.
- Build a resource bundle for each locale
- Resource bundles stored in properties files using name=value pairs
- Properties files must be in the CLASSPATH
- There must be an individual properties file for each language supported
- Call a resource bundle from an application
- Identified by family name/base name and may have a two character language code.
- e.g. Sample_en_AU where en is the language code and AU is the country code for Australia
- Create a local object for the language, country and platform appropriate
- Load bundle using
- Locale myLocale = new Locale(“fr”, “CA”, “UNIX”)
- ResourceBundle myBundle = ResourceBundle.getBundle(“Sample”, myLocale);
- will search for classes in this order:
- Sample_fr_CA_UNIX
- Sample_fr_CA
- Sample_fr
- Sample_en_US
- Sample_en
- Sample
- Resource bundle may be stored in classes extending ListResourceBundle, PropertyResourceBundle or a properties file.
- Format dates, numbers and currency values with NumberFormat and DateFormat classes
- Use DateFormat myDateFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.US); to format a date to US format.
- Advantages of localising an application
- Define a locale with language and country codes
