SCJP Boot Camp: (Part IV)
SCJP Boot Camp: (Part IV)
(Part IV)
June, 2009
-- 7.4 --
Generic Types
6.3 Write code that uses the generic versions of the Collections API, in particular the
Set, List, and Map interfaces and implementation classes. Recognize the limitations
of the non-generic Collections API and how to refactor code to use the generic
versions.
6.4 Develop code that makes proper use of type parameters in class/interface
declarations, instance variables, method arguments, and return types; and write
generic methods or methods that make use of wildcard types and understand the
similarities and differences between these two approaches.
Basic concepts
• <> means generics new feature in Java 5
• Parameterized type
• generics means more type safety
• More problem are caught at compile time instead of runtime
• aren't just for collections
• Create Generics
• List<xxxx> xxxxList = new ArrayList<xxxx>()
• Method: void foo(List<xxxx> list)
• X.foo(xxxList)
• type safe (generic) and non-type safe (non-
generic/pre-Java 5) collections to still work together
• mixing non-generic and generic code together
3
Non-generic / Generic collection
• List myList = new ArrayList(); //old style
• A non-generic collection can hold any kind of object
• A non-generic collection is quite happy to hold anything that is NOT
a primitive.
• Having no way to guarantee collection type
• Get objects out of the collection could have only one kind of
return type—java.lang.Object
• ++ Always need cast it
• The cast could fail at runtime due to non-guarantee type
• List<String> myList = new ArrayList<String>();
• // JAVA 5 generic style
• generic collection guarantees put IN and comes OUT
• Do not need cast
• Can declare a type parameter for a method argument
• void takeListOfstrings(List<String> strings)
• Old style compare the generic code
• List myList = new ArrayList(); // old-style, non-generic 4
9
Generic Declarations (2)
• Also can be used in: / declaration:
• Variable: T an_instance_Variable
• Constructor Arg: Foo(T constructor_Arg) {}
• Method Arg: void bar(T method_Arg) {}
• Method return: T bar() {}
• can use more than one parameterized type in a declaration: <T,
X>
• Member Modifiers
• All the access keywords + strictfp, except static
• final / abstract / public / private / protected / default
• Static - static turns it into a static nested class not
an inner class.
14
Method-Local Inner Classes
• Define: an inner class within a method
• Can access all the member of outer class
• But CANNOT use the local variable of the method (final local
variable can be used)
• Member Modifiers
• CAN mark as abstract and final
• CANNOT mark as public, private, protected, static, transient
• Instance:
• Within the method
• but Below the inner class definition
• ++ Declared in a static method
• Can only access to static members of the enclosing class
• No access to instance variable
15
Example
• class MyOuter {
• private String x = "Outer";
• void doStuff() {
• String y = “method”;
• class MyInner {
• public void seeOuter() {
• System.out.println("Outer x is " + x);
• //can not use the y, which defined within method
• } // close inner class method
• } // close inner class definition
• MyInner mi = new MyInner();//only way to use it
• mi.seeOuter();
• }
• }
16
Anonymous Inner Classes (1)
• Inner classes declared without any class name at all
• 1. Create an anonymous subclass of the specified
class type (subclass of Popcorn class )
• 1. class Popcorn{… pop() …}
• 2. Class food {
• 3. Popcorn p = new Popcorn() {
• 4. public void pop() {
• 5. System.out.println("anonymous
popcorn");
• 6. }
• 7. ++ };
• 8. }
• ++ Use a superclass(Popcorn) reference variable
type to refer to a subclass object
• Only can overriding method of the superclass
• Even created new method, you can not use it (only has
superclass reference) 17
Anonymous Inner Classes (2)
• 2. Create an anonymous implementer of the specified interface
type
• 1.interface Cookable { … cook() ...}
• ……
• 2. Cookable c = new Cookable() {
• 3. public void cook() {
• 4. System.out.println("");
• 5. }
• 6. ++ };
• ++ Same as normal class: implement all the abstract methods
• ++ Just one: Can extend exactly one class or implement
exactly one interface
• Remember interface can not be instantiated, only create an
anonymous implementer you can see: new xxxable() {};
18
Anonymous Inner Classes (3)
• 3. Argument-Defined Anonymous Inner Classes
• make both an implementation class and an instance of that
class in the method argument
• 1. class MyWonderfulClass {
• 2. void go() {
• 3. Bar b = new Bar();
• 4. b.doStuff (
• new Foo() {
• 5. public void foof() {
• 6. System.out.println("foofy");
• 7. } // end foof method
• 8. } // end inner class def,
• ); // end b.doStuff
• 9. } // end go()
• 10. } // end class
23
Defining Thread
• java.lang.Thread
• start() / yield() / sleep() / run() / join()
• Two way to define and instantiate a thread
• Extend the java.lang.Thread class.
• Implement the java.lang.Runnable interface.
• public void run(): job always starts from a
run()
• Override run() method: it will executed in a separate
call stack after the call start()
• ++ threadInstance.run() is legal, But won’t start at a new
call stack, goes onto the current call stack 24
Instantiating a Thread
• Extended Thread class:
• Create thread: MyThread t = new MyThread( )
• implement Runnable
• Implement Runnable: class MyRunnable implements Runnable {}
• Create Runnable: MyRunnable r = new MyRunnable();
• Target Runnable: Thread t = new Thread(r);
• Can pass a single Runnable instance to multiple Thread objects
• means that several threads of execution will be running the very same job
• Thread class itself implements Runnable (no need)
• means that you could pass a Thread to another Thread's constructor
• Thread t = new Thread(new MyThread());
• All the constructor:
• Thread(): no-arg constructor for extend thread class
• Thread(Runnable target): the constructor that takes a Runnable
• Thread(Runnable target, String name)
• Thread(String name) 25
Starting a Thread (1)
• isAlive() / getstate()
• Alive: Once the start() method is called, the
thread is considered to be alive/ runnable
• Dead: thread is considered dead (no longer
alive) after the run() method completes
• start(): threadInstance.start();
• A new thread of execution starts (with a new
call stack).
• The thread moves from the new state to the
runnable state.
• When the thread gets a chance to execute, its
target run() method will run.
26
Starting a Thread (2)
27
Multiple Threads
• Each thread will start, and each thread will run to completion.
• A thread is done being a thread when its target run() method
completes.
• Once a thread has been started, it can never be started again
• Call second time will throw RuntimeException:
IllegalThreadStateException
• getName() / setName() of Thread class to identify threads
• To help check the which thread executing that Runnable object
• Thread.currentThread()
• Current executing thread
• getld() return a positive, unique, long number will be the
thread’s only ID for the thread’s entire lifespan.
28
Thread Scheduler
• Cannot be controlled, often be native threads on the
underlying OS
• The order in which runnable threads are chosen to
run is not guaranteed
• Decides which thread should run at any given
moment
• Thread in the runnable state can be chosen by the
scheduler to be the one and only running thread
• Actions (if all thread priorities being equal )
• Pick a thread to run, and run it there until it blocks or completes.
OR
• Time slice the threads in the pool to give everyone an equal
opportunity to run.
29
Controlling thread scheduling
• java.lang.Thread class
• ++ public static void sleep(long millis) throws
InterruptedException (must be try/catch)
• ++ public final void join() throws InterruptedException (must be
try/catch)
• java.lang.Object class
• ++ public final void wait() throws InterruptedException (must
be try/catch)
33
public static void sleep(long millis)
• ++ static method, affect on current executing
thread
• public static void sleep(long millis) throws
InterruptedException
• static method of Thread class
• ++ Wrap calls to sleep() in a try/catch
• Guaranteed to cause the current thread to stop executing for at
least the specified sleep duration
• Can not get a perfectly accurate timer
• Still lock the object
34
public static yield()
• ++ Static method, affect the current executing thread
• promote graceful turn-taking among equal-priority
threads
• make the currently running thread head back to namable to
allow other threads of the same priority to get their turn
• ++ Not guaranteed
• Never relay on thread priorities to do precise behavior
• If the priorities are equal, JVM is free to do give threads in the
pool an equal opportunity to run.
35
public final void join()
• public final void join() throws InterruptedException
• non-static method
• ++ Wrap calls to join() in a try/catch
• Join the current running thread, and put the current running
thread to the end
• Thread t = new Thread();
• t.start();
• t.join();
• Guaranteed to cause the current thread to stop executing until
the thread it joins with completes,
• Join(milisenconds) the thread takes time longer than this
parameter, the thread will stop waiting and back to runnable
• If the thread it's trying to join with is not alive, the current thread
won't need to back out
36
Three ways to control thread
• A call to sleep() ,
• A call to yield()
• A call to join()
• Other reasons of state change
• Dead: run() method completes,
• A call to wait() on an object (not from thread)
• Thread can't acquire the lock on the object whose method code
it's attempting to run
• The thread scheduler can decide to move the current thread
from running to runnable in order to give another thread a
chance to run.
37
Thread Priorities
• Threads always run with some priority, between 1
and 10
• Thread.setPriority(1~10);
• static final variables
• Thread.MIN_PRIORITY (1)
• Thread.NORM_PRIORITY (5)
• Thread.MAX_PRIORITY (10)
• Default priority is 5
• Runnable thread with highest priority will be chosen
to run
• Still cannot rely on thread priorities to guarantee
behavior
38
-- 9.3 --
Synchronizing
Code
4.3 Given a scenario, write code that makes appropriate use of
object locking to protect static or instance variables from
concurrent access problems.
Problem: Race condition
• Race condition
• multiple threads can access the same resource
• AND can produce corrupted data if one thread "races in"
too quickly before an operation has completed.
• To solve problem
• guarantee the related steps (atomic operation) won’t be
aparted
• CANNOT guarantee that a single thread will stay
running throughout the entire atomic operation
• CAN guarantee no other running thread will be able to
act on the same object
• Mark the variables private.
• Synchronize the code that modifies the variables.
40
Synchronization
• Only methods or blocks can be synchronized, not
variables or classes
• Method: private synchronized XXXX() {}
• Block: synchronized ( someObject ) { /* crucial code */ }
• ++ Block: synchronized(this) {} == Method: private
synchronized XXXX() {}
• static methods can also be synchronized
• ++ Method is same == Block:
synchronized(xxxClass.class) use class literal: the
name of the class, and add .class at the end
• Each object has just one lock.
• A class can have both synchronized and non-
synchronized methods
• Once a thread acquires the lock on an object, no
other thread can enter any of the synchronized
methods in that class
• A thread can acquire more than one lock 41
Locks
• Non-static synchronized method:
• invoked using the same instance block each other
• using two different instances not interfere
• static synchronized methods:
• will always block each other calling in the same class
• static synchronized method and a non-static
synchronized method will not block each other
• ++ synchronized blocks
• have to look at exactly what object has been used for locking
• What's inside the parentheses after the word synchronized
• Be sure if the synchronized on which object, then
the locked object can call wait(), notify()…
42
Methods & locks
• Give Up Locks
• wait () (java.lang.Object )
• Keep Locks
• notify() (java.lang.Object )
• join()
• sleep()
• yield()
43
Thread-Safe
• Goal: avoid multiple thread change the protect data
at the same time
• Don’t need to worry about local variable – each thread gets own
copy
• Watch: Static and non-static field which contain changeable
data.
• Avoid two methods accessing the same static field
• Access to static fields should be done from static synchronized
methods.
• Access to non-static fields should be done from non-static
synchronized methods
• Avoid to mix them
• Thread-Safe class
• "thread-safe" doesn't mean it is always thread-safe
• thread-safe" class has individual synchronized method, far from
enough
• Better to do synchronize between different methods
• Thread Deadlock 44
• Deadlock occurs when two threads are blocked, with each
Thread Interaction (1)
• wait(), notify(), and notifyAll() must be called from within a
synchronized context. A thread can’t invoke a wait() or notify()
on a object unless it owns that object’s lock.
• Wait() means "add me to your waiting list."
• notify() is used to send a signal to only one thread that are
waiting in that same object's waiting pool.
• notifyAll() sends the signal to all of the threads waiting on the
object.
• An object can have many threads waiting on it, and using
notify() will affect only one of them, not specify
• Object A :
• synchronized(anotherObject) {
• try {
• anotherObject.wait( ) ; // the thread releases the lock and waits
• // To continue, the thread needs the lock,
• } catch(InterruptedException e){}
• }
• Object B:
• anotherObject { synchronized(this) { notify(); } } 45
Thread Interaction (2)
• A thread to call wait() or notify(), the thread has to be the owner of the
lock for that object
• ++ if the thread calling wait() does not own the lock, it will
throw an IllegalMonitorStateException (unchecked exception)
• Wait (long millis) define a maximum time to wait
• notify() is called doesn't mean the lock becomes available at that
moment.
• notifyAll() the threads that are waiting on a particular object
49
Java and javac basic search algorithm
• Both have the same list of places (directories) they search, to
look for classes.
• Both search through this list of directories in the same order.
• As soon as they find the class they're looking for, they stop
searching for that class.
• If their search lists contain two or more files with the same
name, the first file found will be the file that is used.
• The first place they look is in the directories that contain the
classes that come standard with J2SE.
• The second place they look is in the directories defined by
classpaths
• Classpaths should be thought of as "class search paths." They
are lists of directories in which classes might be found.
• Two places where classpaths can be declared:
• A classpath can be declared as an operating system
environment variable. The classpath declared here is used by
default, whenever java or javac are invoked.
• A classpath can be declared as a command-line option for either
java or javac. Classpaths declared as command-line options 50
override the classpath declared as an environment variable
Declaring and Using Classpaths
• Classpaths consist of a variable number of directory
locations, separated by delimiters
• -classpath /com/foo/acct:/com/foo (separator is the colon (:))
• specify a subdirectory, NOT specifying the directories above it
• Most of the path-related questions on the exam will
use Unix conventions.
• In Windows, directories will be declared using backslashes (\)
and the separator character is a semicolon (;)
• Tell java or javac to search in the current directory is
to add a dot (.) to the classpath
• classpaths are searched from left to right
• -cp == - classpath , but not always
• ++ Be careful, you need make sure you can get the
file you are compiling/executing and the related files,
all of them
51
Packages and Searching
• Once a class is in a package, the package
part of its fully qualified name.
• A classpath is a collection of one or more
paths. Each path is either an absolute path or
a relative path
• Relative Paths:
• The path to the directory has to be correct relative to the
current directory.
• A relative path is one that does NOT start with a slash
• Absolute Paths:
• from the root (the file system root, not the package root).
• An absolute path in Unix begins with a forward slash (/)
(on Windows it would be something like c: \)
52
-- 10.2 --
JAR Files
7.5 Given the fully-qualified name of a class that is deployed inside and/or
outside a JAR file, construct the appropriate directory structure for that
class. Given a code example and a classpath, determine whether the
classpath will allow the code to compile successfully.
JAR Files
• JAR files are used to compress data (similar to ZIP files) and to
archive data
• a single JAR file contains all of the class files in App, and also
maintains App's directory structure
• Can be moved from place to place, and from machine to machine
• Create jar file: jar –cp MyJar.jar myApp
• ++ Check content: jar -tf MyJar.jar
• Create META-INF directory automatically
• Create MENIFEST.MF file automatically
• Search:
• similar to finding a package file
• ++ must include the name of the JAR file at the end of the path
• javac -classpath xxx/myApp.jar UseStuff.java
• ++ an import statement can import only a single package
• import java. util. * NOT getting the java.util.jar classes or java.util.regex
packages 54
Using …/jre/lib/ext with JAR Files
• jre/lib/ext
• If you put JAR files into the ext subdirectory, java and
javac can find them, and use the class files they contain
• don't have to mention these subdirectories in a
classpath statement
• Better use this feature only for your own internal testing
and development, and not for software that you intend
to distribute.
• JAVA_HOME or $JAVA_HOME
• means "That part of the absolute classpath up to the
directories we're specifying explicitly."
• Can assume that the JAVA_HOME literal means this,
and is pre-pended to the partial classpath you see.
55
-- 10.3 --
Using Static
Imports
7.1 Given a code example and a scenario, write code that uses the
appropriate access modifiers, package declarations, and import
statements to interact with (through access or inheritance) the
code in the example.
Static Imports
• Static imports can be used when you want to use a
class's static members
• import static java.lang.System.out;
• import static java.lang.Integer.*;
• public class TestStaticImport {
• public static void main(String[] args) {
• out.println(MAX_VALUE);
• out.println(toHexString(42));
• }
• }
• import static followed by the fully qualified name of
the static member you want to import, or a wildcard
• Watch out for ambiguously named static members.
• if you do a static import for both the Integer class and the Long
class, referring to MAX_VALUE will cause a compiler error
• You can do a static import on static object
references, constants and static methods.
57
Exam Watch
The tricks the examiner will
use,
Be careful
Code style
• exam creators are trying to jam as
much code as they can into a small
space
• Use chained methods
• StringBuilder.append(“xxx").reverse().insert(3, “xxx”);
• Directly output return:
• System.out.println(file.createNewFile());
59
Compile
Be sure you know the difference between
"compilation fails"
"compiles without error“
"compiles without warnings"
"compiles with warnings."
In most questions on the exam, you care only about
compiles vs. compilation fails—compiler warnings
don't matter for most of the exam.
But when you are using generics, and mixing both
typed and untyped code, warnings matter.
•
60
Static
+++++ DON’T DON’T directly call non-static method in static
method
static methods and variables are invoked base on the reference
type.
static, it is not related to object, so you can use it directly
static methods and member variables do not have this
static and this never can go together
static methods and member variables are not overridden, they
are just hidden.
static nested class - actually is a top level nested class, it can
not use any variable from its enclosing class
Only instance methods can be overriden, not for the static
mehods.
Static method cannot override as non-static method, vice versa
Static method go with the reference, the non-static method go
with the real object in heap
61
Access levels
Top level class only can use public or default
private method -- let subclass free to do
anything (because it is invisible)
top level class must be public/default
native only for method, volatile/transient all
for variable
Be careful with the protected, must be
extends or within same package
local variable only can use final
62
euqals() and hashCode()
Wrapper and String has own equals() and
hashcode(), cannot be overrided
StringBuffer/StringBuilder do not have equals(), so
the equals() means ==
If do not override hashCode(), every entry get its own
bucket, And the overridden equals() is no useful.
equals() only take: primitive -- primitive, or object --
object
Override equals() need make sure arg is Object and
it is public
boolean array can not be sorted
Arrays.equals(a,b) compare the value, a.equals(b)
only compare the object
63
collections (1)
List can remove the object or the index. Map only
remove key, Set only remove object
All the sorted collection, For primitive, always be
increasing order
Real exam question: When the loop is iterating
through the queue, can not poll() or offer() since it
changes the contents of the data structure.
non-generic compile will pass, but TreeSet can not
compare different types, so throw
ClassCastException.
TreeSet/TreeMap must must override equals() and
hashCode() for object entry
binarySearch must use the same sort, don’t forget it.
64
collections (2)
• Collections do not work with primitive
• Set:
• the output ordering is not known since Set
doesn't maintain ordering
65
generic
The "?" cannot be used along with the new
operator.
missing the () after < String >, real exam
question
can't add anything to a List reference that
has a "?" ( unless it has a super keyword
followed by a class name )
be carful with the return type
CANNOT use instanceof for two classes
which are not in inherit tree
66
Type / casting / boxing
Reference type >= real object type
method is chosen by JVM (not from reference)
int[] and int... are same signatures.
Boxing constructor only take corresponding type,
new Byte(1) is wrong --> new Byte((byte)1)
CANNOT do boxing then widening: short can not go
Integer
any int can fit into double-sized variable (double,
float), no cast is needed
be carful the primitive used + will always get a int,
you need cast it to the require type
the result of arithmetic operation will be int
67
Casting
• super reference sub object
• Method
• Overridden method the real object
• Overloaded method the reference + input type
• Static method the reference
• Variable the reference
• short cannot Integer
• int cannot Long
• +++++ Down casting won’t be compile
error, it throws ClassCastException
68
Flow control
• Enhanced for-loop:
• no possible to declare the loop variable outside
• no possible to find the index of the current pointer
• no possible to traverse backward
• Legal for-loop:
• Can declare variable outside
• switch
• case statement only can use: final int/ byte/ short/ char,
can not be long, object such as Integer
69
scope
Scope can be a really trick
method return variable must be
initialized before return
pass a object into method, only give a
copy of reference to the method, so the
related object can be change in the
method, even keep the change out of
the method.
static import a package produce
compilation errors
70
Inner class
• Nested class (static inner):
• can access the outer instance reference
71
Initial sequence
• Static variable/ block, from top down
Initial variable
Initial block (even initial block is
before the initial variable)
Constructor
72
import
• import java.io.*;
• import java.util.*;
• import java.text.*;
• import static …
73
(3)
+++++ Polymorphism is only for method, so variable
is still with reference
+++++ Be careful with the class HAS-A objects, those
objects also should consider to GC
Becareful the static variable, it is not easy to be GC
wait(), sleep(), join() all throw the checked exception:
interruptedException
++ and - - have higher priority than /
++ Boolean: All Object converse to boolean always
be true, except null;
++ the Boolean take the true, false by ignoring the
case (doesn’t matter upcase or lowcase).
+++++ Instanceof check the real object not the
reference 74
(4)
Error can be caught
+++++ IO need import java.io.* even you only throw
IOException
antonymic inner class do not have a constructor
method can be overridden, attributes cannot
Coupling is not used to evaluate classes within the
same inheritance tree
if there is unreachable code, will be complie error.
if the superclass only has the arg constructor, you
must create a constructor to call the super(xxx);
otherwise compile error
%s automatically invokes the toString() method of
the class and even if there isn’t one it should print
object@1234 or something like that.
null can not autobox to 0 75