This post contains a collection of notes that I have made when I was preparing for the Java SE 7 Programmer II exam. For tips on how to prepare for this exam please see my other post.
Java SE 7 Programmer II notes
String processing
- The delimiter string itself doesn’t act as a delimiter but each character in the delimiter String acts as a delimiter. So StringTokenizer(“abcde”, “bd”) will return a, c, and e and not abcde because b and d both act as a delimiter.
- When using “\s” as tokenizer, don’t forget to add additional backslash to escape the “\”, i.e., you should use “\\s”.
- The word boundary is indicated by “\\b” and includes spaces, tabs, special characters and beginning and end of the line.
- When using explicit index (e.g., %1$) the index number always starts with 1.
- String is immutable while StringBuilder and StringBuffer are not.
- For regular expressions the word boundary token “\b” does not actually match any character. For example the matches differ if you match with \btest\b or with \stest\s for the string “test test test test”. The first pattern will give 4 matches while the second will give only 1 match (the second “test”).
- When using split(String regex) the trailing empty strings won’t be included.
- The default precision for floating point number is 6.
- When padding is specified the width needs to be specified as well, otherwise an exception is thrown.
- The parameter %f only accepts floats or doubles, it doesn’t accept booleans, integers, chars or anything else.
- When using Scanner there are many hasNextXXX and nextXXX methods, except for hasNextCharacter and nextCharacter, they do not exist!
- Note that for word boundaries (when using \b as pattern) the parts before and after a word are also considered as word boundaries, even if there is no visible boundary such as white space. This means that when you use the pattern \b\w*\b on “someword” it gives someword back as a match.
- Calendar has three important methods:
- Add(int aField, int amount).
- Roll(int aField, int amount), is quite similar to add(…). However, it does not modify the “larger” fields, i.e., if you add 11 months to the date in March 2014 then it would yield Februari 2014 and not Februari 2015, hence the larger fields (in this case year) is not modified.
- Set(int aField, int value).
Casts
- Casting is something that is done during run time, hence when a method is invoked always the non-casted version of the instance is used.
- When casting always pay attention to the actual object that is being casted. If the actual object is not casted properly it may throw a runtime exception.
- When casting and calling the invoked method of an object the actual object is being used. However, when field is directly accessed the class reference is used.
JDBC
- All Rowsets are scrollable and updateable by default.
- A Callable statement is easier to build than a PreparedStatement since you don’t have to write SQL query code.
- PreparedStatement supports additional SQL column types like BLOB and CLOB.
- The method rollback has two flavors: rollback() and rollback(SavePoint sp).
- commit() can be used to commit SQL updates. Note that the commit() method is not located in the Statement class.
- Loading drivers with “class.forName(String driverName)” is no longer needed for JDBC 4.0
- When using ResultSet the column indices start at 1.
- Column names for the getter methods in ResultSet (e.g., ResultSet.getString(String aColumnName) are case insensitive and returns only the results of the first matching column in case there are multiple columns with the same name.
- getConnection(String aDbUrl) implements a Factory pattern. It creates a connection based on the information provided by the driver that was specified in the “aDbUrl”.
- The ResultSet is usually a read-only object, in general you can’t update rows with a ResultSet.
- RowSetProvider.newFactory() provides a instance of RowSetFactory.
Localization
- To get a localization instance you can for example use:
- Locale myLocale = new Locale(“ru”, “RU”); Note that country is always indicated with two capital letters.
- Locale myLocale = Locale.US.
- Locale myLocale = Locale.getDefault().
- To obtain instance of DateFormat use for instance the following:
- DataFormat().getDateInstance().
- DataFormat().getDateInstance(int aDateStyle).
- DataFormat().getDateInstance(int aDateStyle, Locale aLocale).
- DataFormat().getInstance().
- Comments in property file start with #.
- Once a ResourceBundle is created it is not possible to change the locale for this object. There is no such method like ResourceBundle.setLocale(Locale aLocale).
- When using SimpleDateFormat use “y” (lower case) for years. Upper case “Y” is used for week years and may not always give the year you expect.
- Important letters for dates:
- m: minutes.
- M: Month in a year (July, jul, 07).
- d: day in a month (number).
- y: year (number).
- s: seconds in a minute (number).
- S: milliseconds (number).
- h: hour (1-12 am/pm).
- H: hour (0-23).
- z: time zone (time zone in text).
- When using extending ListResourceBundle the key-value pairs are used for Object[][] getContents(). The key values must be String objects and the values can be any type of object.
- ResourceBundle has a getStringArray(String aKey) method to return an array of String objects for given key.
- MissingResourceException is thrown when object for given key in a resourcebundle can’t be found.
Switch statements
- For strings the comparison is done in similar fashion as String.equals(), hence if string itself is null then it will throw NullPointerException.
- When using switch statements use break to prevent “fallthrough”, if case is matched it will stop only after it has encountered a break. It will execute all lines between the matched case and break (including cases without break statements).
- The type of Switch expression and the type of case label should be the same.
- The case labels must be constants, i.e., non-final variables are not allowed.
Classes & OO Design principles
- Anonymous classes do not have a constructor.
- Anonymous classes can never be static.
- You can’t have static fields in an Anonymous class.
- Fields can never be overridden.
- If superclasses do not contain a no-argument constructor the compiler will start to complain if it’s being called by subclasses which don’t have a constructor. The compiler provides a default no-argument constructor using the no-argument constructor of the superclass.
- A non static inner class can have static members if they are final.
- Anonymous inner classes can be created for classes as well, not only for interfaces or abstracts.
- When an anonymous inner class is created for a class then that class is implicitly extended. When interface is used for an anonymous class then the interface is implicitly implemented and Object class is extended.
- Although anonymous classes are not allowed to have a constructor they can have initialization parameters if the class they implicitly extend have a appropriate constructor.
- A class defined inside an interface is implicitly static.
- Inner class is defined as a non-static class inside a class.
- Static nested class refers to class declaration inside the body of a class or interface.
- If equals() method returns true, then hashcode() must return true for both objects as well. Note that the reverse is not required! A hascode may return 0 for instance for all objects while both objects are not equal.
- Enums can’t be defined inside a method or constructor.
- Package level class (or top-level class) can’t be defined static, only a nested class can.
- Notice the difference in new AClass().BClass() and new AClass.BClass(). The first one create a BClass instance with outer instance of AClass while the second creates a BClass instance without outer instance of AClass.
- A factory pattern always follows the “program to an interface” principle since a factory method return type is an interface.
- For classes and their subclasses the variables are being shadowed and the methods are being overridden. The class declaration specifies which class’s field is being used. The actual object that is being referenced specifies the overridden method that will be used.
- When using the equals method reflexive refers to the fact that x.equals(x) should always returns true.
- Symmetric means that if x.equals(y) returns true then y.equals(x) should return true as well.
- Transitive means that if x.equals(y) returns true and y.equals(z) returns true then x.equals(z) should also return true.
- Consistent refers to the fact that the equals method always returns the same result for the reference value used for the equals method.
- Automatic variables are variables defined inside a method class while instance variables are variables defined within a class.
- From Java 5 onwards it is possible to use co-variant return types for methods that are overridden. This means that the overriding method can return a sub-class as its return type instead of the base class itself. Note this only holds for classes, not for primitives. For example you can’t return an int type for the overridden method if the base method returns a long type.
- Generally when using a factor design pattern the “new” keyword shouldn’t be used for creating objects. Usually a method like getInstance() should be used.
- When using import com.* it will only import all the classes in the ‘com’ package, i.e., the classes of the subpackage are not imported.
- Clone() method of an Object is protected. Usually when cloning needs to be applied a public method is made, such that it can be accessed by all classes.
- A top-level class can only have public or no access modifier while a field can have private, package, protected and public access modifier.
- Local nested classes (i.e. inside a method) cannot be declared static, hence static classes are not allowed to access instance variables.
- An abstract class can never be final since it eventually needs to be extended.
- Natural order of enums is the order in which the elements are defined, e.g.:
enum TEST{C,A,Z} will have a natural order of C, A and Z and not A, C, Z. This natural order is of importance when for example a TreeSet is used. The elements in a TreeSet will be stored in the same order as the order of the enums. - An iterator can be obtained from an iterable by doing iterable.iterator()
- For-each loop can only be applied on iterables. When having an iterator a while loop with iterator.hasNext() and iterator.next() should be used.
- When creating DAO do two things: create and implement interface. Interface should contain CRUD (Create, Read, Update, Delete) methods.
- When there is a super class and a sub class and the super class defines a constructor with an argument then the default no-argument constructor won’t be inserted by the compiler. This means that compile errors start to occur when the super’s no-argument constructor is not defined, since Super() is called by default within the constructors defined in the sub classes.
- The no-argument constructor is not called for serializable classes. If a class implements a serializable class and it’s super class doesn’t implement it, then the super class no-argument constructor is called. Usually this fails if this class has a no no-argument constructor defined in the class by design or by the compiler (if there already is a argument constructor available).
- When using an interface all fields are automatically final, public and static.
- Hiding a field occurs when a field’s subclass has the same name (irrespective of type) as its super class. Within the subclass the only the field can be accessed and its field from the super class can only be called by using the keyword “super”.
- A local class is a class within a method and is defined non-static. They are non-static because they have access to instance members of enclosing block.
- Know the meaning of reflexive (X.equals(X)) ⇒ true ), symmetric (X.equals(Y)==Y.equals(X) ⇒ true) and transitive (X.equals(Y), X.equals(Z) ⇒equals(Z))
- In co-variant return types you can provide derived class as return type when overriding a method.
- All methods of a final class are implicitly final, i.e., can’t be overridden.
Exceptions
- In a multi-catch block you can’t throw exceptions that are related to each other through inheritance.
- If an exception is thrown in a try-with-resource block then that is the exception the caller get. After this the resource is closed. If any other exceptions are thrown when closing the resource then those exceptions will be added as a suppressed exception.
- FileNotFoundException is a checked exception and subclass of IOException
- An overriding method can throw the exception or its subclasses of the exception that are defined in the overridden method. Furthermore, an overriding method may have no exceptions at all.
- In a multi-catch clause the exception is implicitly final. Therefore, the exception parameter can’t be reassigned.
- If there are exceptions thrown by both the catch and explicit finally (without using try-with-resource statement) block then the exception of the finally block will eventually be thrown. The one of the catch block gets lost and won’t be added to the suppressed exceptions list.
- The resources for the try-with-resource statement are closed in reverse order of creation.
- The resources in the try-with-resource statement must include the AutoCloseable interface.
- The Closeable interface extends AutoCloseable interface. This Closeable interfae is often used by standard classes like BufferedReader, BufferedWriter.
- AutoCloseable .close() throws an Exception while the Closeable.close() throws an IOException. Note, the AutoCloseable interface is more general than the Closeable interface.
Assertions
- In “Assert value==true : <expression>;” the expression can’t be void, but can be null.
- Assertions can be enabled selectively for each class and package.
- To enable or disable assertions for a class use “java –ea:<class> <yourMainClassfile>”. For disable use “java –da:<class> <yourMainClassfile>.”
- For enabling (-ea) or disabling (-da) assertions for packages use “…”:
java –ea:<packageName>… <yourMainClassfile>
To enable or disable for default packages (the package in your working directory) you can use:
java –ea: … <yourMainClassfile> - Input parameters of public methods should not be validated by using assertions. Public methods should throw exceptions. Only assertions for input parameters of private methods could be used.
- The assert keyword is reserved for assertions you cannot use it as identifier for a method, i.e., you can’t define public void assert (…) {} for instance.
- To enable assertions at system level class use the following:
- –esa
- esa
- –enablesystemassertions
- enablesystemassertions
Threads and concurrency
- The methods wait(), notify() and notifyAll() should always be called inside a synchronization method. By doing this you ensure the current thread owns the monitor of the object.
- Daemon threads are supportive threads. They are well suited for garbage collector for instance. A program ends when all non-daemon threads end.
- You can set daemon threads with setDaeom(true).
- Synchronization keyword can only be applied to non-abstract methods or a block of code. It can’t be applied to class’s fields or methods defined in an interface.
- When using the yield() it temporarily pauses current thread and allows other threads to be executed. It is used to indicate that the calculations that are done in current thread are not important. This however is not guaranteed, yield only gives a hint to the JVM.
- Tasks that are used by ExecutorService.submit() are created by implementing the Callable interface.
- A Callable should return the actual data object that is defined in the generic type specification.
- No modifications can be applied on the iterator retrieved from CopyOnWriteArrayList, since this iterator only contains a copy.
- If thread’s priority is not specified then the thread gets the same priority as the thread that created it.
- The default thread priority is NORM_PRIORITY. NORM_PRIORTIY has a priority of level 5 (the levels range from 1 to 10).
- The thread method interrupt () is only applicable to the thread who has invoked the method wait(), join() or sleep(). Otherwise only the interrupted flag is set to true. The Thread class has an isInterrupted() method.
- Use RecursiveTask instead of RecursiveAction if you want to return a value
- ForkJoinPool extend from thread and implement Executor.
- HashTable methods are synchronized. The performance will be compromised when multiple threads are using those methods.
- HashMap methods are NOT synchronized!
- For multithreaded designs use ThreadLocalRandom.current().nextX(startValue, endValueExclusive), here nextX can be NextInt, NextLong etc…
- An IllegalMonitorStateException is thrown if the thread calls notify() on a object of which it doesn’t have the lock (i.e. it didn’t call wait() on this object).
- By using “notify” the thread is allowed to go into runnable state, but it doesn’t have to run. Before going into runnable state the thread first needs to obtain the monitor of the object.
- A Runnable does something similar as Callable. However, a Runnable does not return a result and can’t throw a checked exception.
- You can use the ExecutorService.submit for Runnables as well: Future<?> submit(Runnable task). Future.get() will return null upon successful completion.
- ConcurrentHashMap does not accept null values while HashMap, ArrayList, CopyOnWriteArrayList do support this
- The ScheduledExecutorService supports scheduleAtFixedRate(…) and scheduleWithFixedDelay(…). Where scheduleWithFixedDelay(…) will start with a delay after previous task has been fully executed while scheduleAtFixedRate(…) will start after a specific period. When using scheduleAtFixedRate(…) and a task is already running the subsequent task may start late, but never start concurrent.
- The Thread.interrupted clears the interrupt status while Thread.isinterrupted only retrieves its interrupt status, it does not change the interrupt flag.
Format
- When using four or more pattern letters for SimpleDateFormat() the full name is used.
- When using printf the %s has an implicit counter, i.e., System.out.printf(“This is %s %2$s %s”, “what”,”it”,”is”) will give “This is what it it”.
- Using a b (boolean) conversion char for any value will always give true, unless it is “false” or null.
- Once a DataFormat or a NumberFormat is created the Locale can’t be set or changed anymore.
- DateFormat is an abstract class. In order to obtain an instance use DateFormat.getDateInstance() methods like getDateInstance(), getDateInstance (int Style), getDateInstance(int Style, Locale aLocale), getInstance().
- The getDateInstance() provides date and time using SHORT style and the getInstance() uses default style.
Collections
- When adding a duplicate key in a Treemap it gets replaced by the latest one.
- Before using binarySearch method first call sort method to make sure the searching is done correctly. The sort method is available in java.util.Collectionsutil.Arrays, don’t forget the additional s!
- ConcurrentHasMap does not accept null keys or values.
- Only Vector and Hashtable are thread safe in the java.util package.
- Natural order of string elements is: space, number, upper case, lower case
- The keys of a TreeMap must be mutually comparable, since the TreeMap is ordered (and unique).
- The CopyOnWriteArrayList is thread safe. Multiple threads can add and remove objects from the list.
- The class CopyOnWriteArrayList provides a copy of the iterator. Therefore, no exception will be thrown when the list is modified during iteration.
- You can’t use diamond operator inside generic type specification, e.g., <Object,<>> is not allowed. So for type interferencing use single <> instead.
- Wrapper class for int is Integer and not Int!
- In Java collections terminology “ordered” always refers to the insertion order. The term “sorted” refers to sorting the collection based on lexicography or on numbers.
- When using a TreeSet the added elements must implement the comparable interface and compareTo() method correctly. If this interface is not implemented correctly then a ClassCastException is thrown.
- An Iterable is not the same as an interator. You can obtain an iterator from an iterable by doing iterable.iterator(). An iterable can be seen as a factory for iterators.
- Type safety of generics is only checked at compile time.
- A HashMap allows both keys and values to be Null.
- sort(List<T>) makes use of Comparable interface, i.e., every object in the collection must implement the comparable interface and should be comparable with each other. The objects need to be of the same type to be comparable with each other.
- When Arrays.binarySearch() method is used and key is not contained in the list then the following index is returned: (-insertion_point_index -1). The insertion_point_index is the index of the key in case the key did exist.
- Vectors and Hashtables are threadsafe.
- A Comparator is used to define how the comparison should be done for collections. A Comparable is defined for each class and defines how it should be compared with an object of the same class.
- You can declare fields of a specific generic type, but a static field can’t have a generic type.
Enumerations
- From an enum’s constructor it is not possible to access non-final static fields, only constants are supported.
- Enum can’t extend from anything else since it already implicitly extends from java.lang.Enum.
- An enumerator can’t be constructed in a constructor class or method.
- You can’t invoke an enum constructor yourself. Enum constructors are always private.
- An enum is implicitly declared public.
- You can’t extend an enum since it is declared implicitly final.
- An enum is allowed to implement interfaces
- An enum maintains one instance of its constant, therefore you can’t clone them. The clone method is made final by java.lang.Enum
- During compile time the compiler provide an enum with two static methods, namely the values() and valueOf(String aString) methods.
- The valueOf(String aString) method is case sensitive. If enum constant can’t be found then an IllegalArgumentException is thrown.
- The ordinal() method returns the index of the enum constant.
- An enum can be added to the sorted collections (e.g., TreeSet, TreeMap) since it implements java.lang.Comparable.
IO & NIO
- RandomAccesFile need mode argument like “rws”.
- Be careful when using “Path.getName()”! The indices start at 0 and the root is not included.
- File objects are immutable, i.e. it is not possible to change file or directory after a file class has been instantiated.
- An IllegalArgumentException is thrown when inappropriate arguments are used for Path.getName(). You can’t use negative indices or indices that are larger than the number of elements.
- When using the FileVisitResult class the SKIP_SIBLINGS constant is used to skip visiting siblings of a file or directory. The constant SKIP_SUBTREE is used to continue without visiting the entries in the currently visited directory.
- BufferedReader can only be created wrapping around a Reader or FileReader.
- The Reader and FileReader class do not support higher level methods like readLine().
- Files().newDirectorystream(dir, String aGlobPattern) returns Path entries when iterating and uses a glob string for its pattern.
- You don’t need to specify the OVERFLOW event when registering a watchable. You can receive this event without registering since it is already done automatically.
- The counts for ENTRY_CREATE and ENTRY_DELETE are always 1 while for ENTRY_MODIFY and OVERFLOW the its count can be greater than 1
- TRUNCATE_EXISTING throws NoSuchFileException if it the file does not exist.
- CREATE_NEW will throw FileAlreadyExistException if file already exist.
- The combination READ and TRUNCATE_EXISTING is not possible, since you need to open a file that allows writing a file. The same for READ and WRITE/APPEND/DELETE_ON_CLOSE/SYNC. For the READ & SYNC combination there is nothing to sync when reading.
- For a directory structure you need File.mkdirs()
- The WatchService has two methods for obtaining a WatchKey, namely take() and poll(). The first method take() doesn’t return null, but keeps waiting until the key becomes available. The second method poll can return null and do not wait for ever.
- readPassword() always returns char[].
- In the File class you can use two methods to list files, namely list() and listFiles(). The first method returns String[] and the second returns File[].
- OutputStream only writes bytes, you can’t write primitives. When you want to write primitives you should use DataOutputStream, which support methods like writeInt, writeChar, writeDouble.
- To get the root of a file system either use:
- File [] roots = File.listRoots()
- Iterable<Path> roots = FileSystems.getDefault.getRootDirectories()
- When using the copy method to copy directories only the directory itself is copied without its contents.
- You can’t chain a Reader to a Writer or vice versa.
- When deserializing the constructors of serializable classes are not called.
- subPath(1,1) will give IllegalArgumentException, the begin index and end index should not be the same! The same for negative index and indices that are larger than the number of elements.
- A glob pattern with a single * takes into account directories as boundaries. When ** is used as pattern the directory boundaries are not taken into account, e.g., **.java as glob will return test.java when searching in “misc/test/test.java”.
- Auto-close variables defined in a try-with-resources are implicitly final and can’t be reassigned.
- NoSuchFileException is thrown by classes coming from the java.nio package while the java.io package uses FileNotFoundException.
- reset() may throw IOException if stream never have been marked.
- mark(int readAheadLimit) marks the stream at current position, where readAheadLimit is the amount of bytes after which the mark becomes invalid. Stream object does not remember the mark after the readAheadLimit number of chars has been reached in a stream.
- When using copy(…) and REPLACE_EXISTING as copy option then the copy fails if a non-empty directory already exists, as a result a FileAlreadyExistsException is thrown.
Pingback: Preparing for the Java SE 7 Programmer II (1Z0-804) exam « Personal « Brett Rijnders
Thanks, it’s helpful. I have a plan to take the exam. Do you have any practice exams? If so, would you please email me. Thank you for your time and concern.
You are welcome Bisrat! Unfortunately, I don’t have any practice exams. You could get them when you buy the book “The book Oracle Certified Professional Java SE 7 Programmer Exams 1Z0-804 and 1Z0-805: A Comprehensive OCPJP 7 Certification Guide” or use Enthuware/Whizlabs to practice some exam questions. Good luck with your preparation!