1 / 75

SCJP Exam Notes (Part IV)

SCJP Exam Notes (Part IV). By Maggie Zhou June, 2008. -- 7.4 -- Generic Types.

raiden
Download Presentation

SCJP Exam Notes (Part IV)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. SCJP Exam Notes(Part IV) By Maggie Zhou June, 2008

  2. -- 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.

  3. 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

  4. 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 • == List<Object> myList = new ArrayList<Object>();

  5. Generics and Legacy Code • Old • List myList = new ArrayList(); • Generic • generics as strictly a compile-time protection • NONE of this protection exists at runtime. • List<Integer> myList = new ArrayList<Integer>(); • public List<String> changeStrings(ArrayList<String> s) { } • The earlier non-generic version and performed a cast to get things out: • Integer i = (Integer) list.get(0); • ++No problem with put into, but put out and use it will cause problem • the problem of putting the wrong thing into a typed (generic) collection does not show up at the time you actually do the add() to the collection. It only shows up later, when you try to use something in the list and it doesn't match what you were expecting.

  6. Mixing Generic and Non-Generic Collections • In order to support legacy code, Java 5 allows your newer type safe code to make use of older code( is forced into ) • If the legacy insert() method try to add a object(may be a un-expect object), the compiler generated a warning: • javac TestBadLegacy.java • Note: TestBadLegacy.java uses unchecked or unsafe operations. • Note: Recompile with -Xlint:unchecked for details.  • javac -Xlint:unchecked • TestBadLegacy.java TestBadLegacy.java:17: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.List • list.add(new String("42")); • ^ 1 warning • ++Compiler warnings are NOT considered a compiler failure • for test, you just see it as successful compile • JVM has no type information • Even insert un-expect object, the program still run without problem. • All the generic code is strictly for the compiler

  7. Polymorphism and Generics • Polymorphic assignments applies only to the base type, not the generic type parameter. • For the type of the variable declaration, the generics type must be exactly match, even can not use supertype or subtype • Array is ok for accept the subtype • Array has runtime exception (ArrayStoreException) to prevent you from putting the wrong type of object into an array • CANNOT pass an ArrayList<subtype> to an argument of ArrayList<type> • ++JVM KNOWS the type of arrays, but does NOT know the type of the collections.

  8. Wildcard • ++ <? extends Xxx> • Can let anything pass • CanNOT add anything into this collection. • Use extends represents BOTH subclasses and interface implementations • <? supter Xxx> • accept Xxx and super types of Xxx • Can add Xxx • List<?> vs. List<Object> • <?> means any type + cannot add anything to it == <? Extends Object> • <Object> means can take only List of Object • ++ Only for reference declarations (including arguments, variables, return types, and so on). • ++ Cannot be used as the type parameter: new Xxx<type>, but not new Xxx<?>

  9. Generic Declarations (1) • public interface List<E> template • E = elements, used when the template is a collection • <T> type, uses for other main convention • ++Don’t forget: import java.util.*; • Create a Generic Class provide general template • public class xxxxGeneric<T> • Can specify the range: <T extends Xxx> • ++ Create a Generic Method • Declare the type variable BEFORE the return type of method • Public <T> void xxxXxx (T t) {} • If the type is declared by class, then it is ok without declare before return type

  10. 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> • ++ ? works when declaring a reference for a variable, • ++? does NOT work for generic class and method declarations • NO!  public class NumberHolder<?> ( ? aNum; } • Yes  public class NumberHolder<T> ( T aNum; } For class declaration • NO!  public class NumberHolder<T super Xxx> ( T aNum; } • Yes  public class NumberHolder<T extends Xxx> ( T aNum; }

  11. ++ <?extends Xxx> vs. <? super Xxx> • Decleration as <? super Xxx> • Specify the type in method call with Xxx or Xxx’s super type • Then, can add the specified type’s sub type (satisfy IS-A) • Decleration as <? extends Xxx> • Specify the type in method call with Xxx or Xxx’s sub type • Then, can not add any type into it. • But why? The reason is: • JVM doesn’t know the real specified type, but it knows which can be, so JVM gives you very strict condition: the adding type must suit all the sub type: which is no one can be.

  12. -- 8 --Inner Classes Inner classes Method-local inner classes Anonymous inner classes Static nested classes

  13. Inner Classes (1) • Inner classes let you define one class within another. • Special relationship" an inner class instance shares with an instance of the outer class • class MyOuter { • class MyInner { } • } • %javac MyOuter.java • MyOuter.class • MyOuter$MyInner.class • Only way you can access the inner class is through a live instance of the outer class • Within the Outer Class • MyInner mi = new MyInner(); • Outside the Outer Class Instance Code • ++ MyOuter.MyInner inner = new MyOuter().new MyInner();

  14. Inner Classes (2) • Within the Inner Class • The inner class use this. • this  reference of inner class • The outter class use NameOfOuterClass.this. • MyOuter.this  reference of outer class • 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.

  15. 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

  16. 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(); • } • }

  17. 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)

  18. 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() {};

  19. 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 • 12. interface Foo { void foof(); } • 15. class Bar { void doStuff(Foo f) {} }

  20. Static Nested Classes • a static member of the outer class • Aren't inner classes at all, due to doesn’t have special relationship with outer class • ++ CANNOT access instance variables and non-static member of outer class, be careful • Define • class BigOuter { • static class Nested { } • } • Implement: • Within outer class • Nested x = new Nested(); • Outside of the outer class • ++Outer.Nested() x = new Outer.Nested(); • Different with inner class, be careful

  21. Example • class BigOuter { • static class Nest { • void go() { System.out.println("hi"); } • } • } • class Broom { • static class B2 { • void goB2() { • System.out.println("hi 2"); • } • } • public static void main(String[] args) { • BigOuter.Nest n = new BigOuter.Nest(); // both class names • //differ from inner class: new BigOuter().new Nest(); • n.go(); B2 b2 = new B2(); // access the enclosed class • b2.goB2(); • } • }

  22. -- 9.1 --Defining, Instantiating, and Starting Threads 4.1 Write code to define, instantiate, and start new threads using both java.lang.Thread and java.lang. Runnable 4.4 Given a scenario, write code that makes appropriate use of wait, notify. or notifyAll.

  23. Basic concepts • The behavior is not guaranteed • single-threaded runtime environment: The next action can happen only when the previous one is finished • thread means: • An instance of class java.lang.Thread • A thread of execution • a thread of execution is an individual process that has its own call stack • one call stack per thread • main thread: main() method starts the whole ball rolling • create a new thread • a new stack materializes and methods called from that thread run in a separate call stack • When it comes to threads, very little is guaranteed • daemon threads • JVM shut down, regardless of the state of any daemon threads.

  24. 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() • Overriderun() 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

  25. Instantiating a Thread • Extended Thread class: • Create thread: MyThread t = new MyThread( ) • implement Runnable • ImplementRunnable: classMyRunnable 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)

  26. 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.

  27. Starting a Thread (2)

  28. 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.

  29. 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.

  30. 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) • ++public static void yield() • public final void setPriority(int newPriority) • static Thread.currentThread() • java.lang.Object class • ++public final void wait() throws InterruptedException(must be try/catch) • public final void notify() • public final void notifyAll() • java.lang.Runnable • run()

  31. -- 9.2 --Thread States and Transitions 4.2 Recognizethestatesin which a thread can exist, and identify ways in which a thread can transition from one state to another.

  32. Thread States (1) • New • In after the Thread instance has been created, • But the start() method has not been invoked on the thread. • Not Alive. • Runnable • In when it's eligible to run, • But the scheduler has not selected it to be the running thread. • After invoked start(), thread first enters the runnable state • OR return after either running or coming back from a blocked, waiting, or sleeping state. • Alive • Running • in when the thread scheduler selects it (from the runnable pool) to be the currently executing process. • Only one way to get to the running state: the scheduler chooses a thread from the runnable pool. • alive

  33. Thread States (2) • Waiting/blocked/sleeping • the thread is still alive, but is currently not eligible to run • ++Sleep(), yield() is static method, means only affect the current thread, not the instance calling them. • Alive • Dead • when its run() method completes. • It may still be a viable Thread object, but it is no longer a separate thread of execution. • Once a thread is dead, it can never be brought back to life! • ++If you invoke start() on a dead Thread instance, you'll get a runtime exception (not compiler). • IllegalThreadStateException • Not Alive

  34. 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

  35. 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.

  36. 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

  37. 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.

  38. 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

  39. -- 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.

  40. 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.

  41. 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

  42. 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()…

  43. Methods & locks • Give Up Locks • wait () (java.lang.Object ) • Keep Locks • notify() (java.lang.Object ) • join() • sleep() • yield()

  44. 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 • Deadlock occurs when two threads are blocked, with each waiting for the other's lock

  45. 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(); } }

  46. 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 Deal the problems: • the event waiting for has already happened • Putting the wait() method in a while loop and re-checking the condition that represents what we were waiting for • Always also have a while loop around the wait() that checks a condition and forces continued waiting until the condition is met • Always need synchronization for threads • almost always need to share some mutable data between threads at the same time

  47. -- 10.1 --Using the javac and java Commands 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. 7.2 Given an example of a class and a command-line, determine the expected runtime behavior. 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.

  48. Compiling with javac • javac command is used to invoke Java's compiler • javac [options] [source files(xxx.java)] • javac -help • doesn't compile any files, but prints a summary of valid options • Compiling with -d • By default, the compiler puts a .class file in the same directory as the .java source file • -d keep a .java files separated from .class files • javac -d ../classes classes xxx/xxx/MyClass.java • ++ if the destination directory you specify doesn't exist, you'll get a compiler error

  49. Launching Applications with java • invoke the Java virtual machine • java [options] class [args] • Must specify exactly one class file to execute • the java command assumes you're talking about a .class file • Using System Properties • java.util.Properties is used to access a system's persistent information: the current versions of the operating system, the Java compiler, and the Java virtual machine • java -Dname=value pair must follow immediately, no spaces allowed. • In class xxx: System.getProperty("aaa","bbb"); • ++ Java –Daaa=bbb xxxx.class • ++Handling Command-Line Arguments • Command-line arguments are always treated as Strings. • Arguments on the command line directly follow the class name • The first argument  args[0], the second argument  args[1]

  50. 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 override the classpath declared as an environment variable

More Related