Showing posts with label SCJP Certification. Show all posts
Showing posts with label SCJP Certification. Show all posts

Saturday, February 26, 2011

Some Last Words Before you take the SCJP Exam

Thank you for coming this far in the SCJP exam series in my blog. If you have read through and understood the articles in the SCJP exam series, you are now well equipped to crack the SCJP exam. Let me sign-off on this SCJP exam series with a few last words.

So, as usual, lets get started!!!

What This Series Is Not

This series of blog articles is not a beginners guide or a definitive guide to the Java programming language. The articles are written under the assumption that you are someone who knows a little bit of Java and are someone who aims at becoming SCJP certified. This is not the Java Complete reference and there are many advanced topics like RMI (Remote Method Invocation), JDBC (Database Connectivity) etc that we havent covered because, they arent on the exam.

Some Tips

Once you have completed reading all the chapters in this SCJP series, I suggest you do the following:
a. Re-visit all the quick review chapters and go through all the important points about the topics we have covered
b. Re-read all the Exam Tips that are present as Quotes in each chapter and remember them
c. Have someone quiz you with random questions from the self-test chapters
d. Re-visit the self-test chapters and try to answer all the questions (Without checking the answers) (I know you are mumbling Of Course pal, I know that. But still, it is my duty isnt it?)
e. Write java code and I mean lots of it. Coding is the best way to learn the language and nothing can beat it.

The Last Exam Tip:

It is a good practice to review all your answers once you are done answering the questions. It is also important that, you do not change your answers during the review, unless you know that your answer is wrong for sure. Only change an answer when you feel you may have misread or misinterpreted the question the first time. Nervousness may make you second-guess every answer and talk yourself out of a correct one.

Tips on Cracking the Exam

There are 72 questions on the 310-065 (SCJP Java 6) exam. You will need to get at least 47 of them correct to pass—around 65%. You are given over three hours to complete the exam. This information is subject to change. Always check with the Sun official website before taking the exam, at www.suned.sun.com.

Some More Tips:

a. You can answer questions in any order. So if you feel you arent able to answer a question, don't waste too much time on that question, just move on to the next one and you can come back and answer this bad boy later
b. Be careful & cautious on the code examples. Check for syntax errors first: count curly braces, semicolons, and parenthesis and then make sure there are as many left ones as right ones. Look for capitalization errors and other such syntax problems before trying to figure out what the code does.
c. The code may look almost fine and you may be tempted to choose an answer as the possible output, but the code might be missing a closing paranthesis which means it wouldn't compile and you would miss a easy no-brainer in your hurry to answer the question

Well, thank you again for being a patron of my articles and I sincerely hope they were useful and you pass the SCJP exam with flying colors.

All the very best.

Previous Chapter: Other Topics of Importance

Next Chapter: None. This is the last chapter in the SCJP Series. You can go to the first article of this series, if you want by "clicking here"

Friday, February 25, 2011

Chapter 61: Thread Interactions

The last thing we need to look at in our series of chapters on threads, is how threads can interact with one another to communicate about, among other things, their locking status. The Object class has three methods, wait(), notify(), and notifyAll() that help threads communicate about the status of an event that the threads care about.


This is exactly what we are going to see in this chapter.


So, lets get started!!!


Using Wait and Notify


For example, if one thread is a repair-car repair-car thread and one thread is a accept-car-for-service thread, the accept-car-for-service thread has to keep checking to see if there’s any car to accept for service. Using the wait and notify mechanism, the accept-car-for-service thread could check for cars, and if it doesn’t find any it can say, “Hey, I’m not going to waste my time checking for a car every few minutes. I’m going to go hang out, and when a customer drives in with a car for service, have him notify me so I can go back to runnable and do some work.” In other words, using wait() and notify() lets one thread put itself into a “waiting room” until some other thread notifies it that there’s a reason to come back out.


One key point to remember for the exam about wait/notify is this:


wait(), notify(), and notifyAll() must be called from within a synchronized context! A thread can’t invoke a wait or notify method on an object unless it owns that object’s lock.


Here we’ll present an example of two threads that depend on each other to proceed with their execution, and we’ll show how to use wait() and notify() to make them interact safely and at the proper moment.


Think of a computer-controlled Mechanic that repairs cars and the user comes to the garage to drop of his car to repair. The current version of the application has one thread, which loops, first getting the car from the user and then giving it to the mechanic for repair:


public void run(){

while(true){

// Get Car from user

// Analyse and identify faulty parts

// Fix em...

// Send user home happy...

}

}


This design is not optimal because the user can’t do anything while the mechanic is busy and while there are other parts to fix. We need to improve the situation.


A simple solution is to separate the processes into two different threads, one of them interacting with the user and another fixing the car. The user thread sends the instructions to the fixing thread and then goes back to interacting with the user immediately. The fixing thread receives the instructions from the user thread and starts directing the mechanic immediately. Both threads use a common object to communicate, which holds the current car being processed.
The following pseudocode shows this design:


public void keepUserEngagedLoop(){

while(true){

// Get car from user

// Pass car repair instructions to fixing thread

}

}


public void fixingLoop(){

while(true){

// Get car into garage

// start fixing it

}

}


The problem now is to get the fixing thread to process the car as soon as it is available. Also, the user thread should not disturb the car until it is sent to the garage. The solution is to use wait() and notify(), and also to synchronize some of the code.


The methods wait() and notify(), remember, are instance methods of Object. In the same way that every object has a lock, every object can have a list of threads that are waiting for a notification from the object. A thread gets on this waiting list by executing the wait() method of the target object. From that moment, it doesn’t execute any further instructions until the notify() method of the target object is called. If many threads are waiting on the same object, only one will be chosen (in no guaranteed order) to proceed with its execution. If there are no threads waiting, then no particular action is taken. Let’s take a look at some real code that shows one object waiting for another object to notify it:


1. class FirstThread {

2. public static void main(String [] args) {

3. SecondThread b = new SecondThread();

4. b.start();

5.

6. synchronized(b) {

7. try {

8. System.out.println("Waiting for b to complete...");

9. b.wait();

10. } catch (InterruptedException e) {}

11. System.out.println("Value is: " + b.value);

12. }

13. }

14. }

15.

16. class SecondThread extends Thread {

17. int value;

18.

19. public void run() {

20. synchronized(this) {

21. for(int i=0;i<10;i++) {

22. value += i;

23. }

24. notify();

25. }

26. }

27. }



This program contains two objects with threads: FirstThread contains the main thread and SecondThread has a thread that calculates the sum of all numbers from 0 through 9. As soon as line 4 calls the start() method, FirstThread will continue with the next line of code in its own class, which means it could get to line 11 before SecondThread has finished the calculation. To prevent this, we use the wait() method in line 9.


Notice in line 6 the code synchronizes itself with the object b, this is because in order to call wait() on the object, FirstThread must own a lock on b. For a thread to call wait() or notify(), the thread has to be the owner of the lock for that object. When the thread waits, it temporarily releases the lock for other threads to use, but it will need it again to continue execution. It’s common to find code like this:


synchronized(someObject) { // this has the lock on someObject

try {

someObject.wait();

// the thread releases the lock and waits

// To continue, the thread needs the lock,

// so it may be blocked until it gets it.

} catch(InterruptedException e){}

}



The preceding code waits until notify() is called on someObject.

synchronized(this) { notify(); }



This code notifies a single thread currently waiting on the this object. The lock can be acquired much earlier in the code, such as in the calling method. Note that if the thread calling wait() does not own the lock, it will throw an IllegalMonitorStateException. This exception is not a checked exception, so you don’t have to catch it explicitly. You should always be clear whether a thread has the lock of an object in any given block of code.

Notice in lines 7–10 there is a try/catch block around the wait() method. A waiting thread can be interrupted in the same way as a sleeping thread, so you have to take care of the exception:


try {

wait();

} catch(InterruptedException e) {

// Do something about it

}


In the car garage example, the way to use these methods is to have the fixing thread wait on the car to be available and the user thread to notify after it has finished giving the car. The fixing steps may comprise global steps, such as moving the car to the garage area, and a number of substeps, such as checking the engine, transmission. As an example they could be


int NumberOfCylindersInEngine;

int NumberOfGearsInTransmission;

Engine engineMake;

float[] tires;

etc..


It is important that the user thread does not modify the car details while the fixing thread is using them, so this reading and writing should be synchronized.


The resulting code would look like this:

class User extends Thread {

public void run(){

while(true){

// Get car from user

synchronized(this){

// identify details to fix the car

notify();

}

}

}

}


class Mechanic extends Thread {

User User; // assume this gets initialized

public void run(){

while(true){

synchronized(User){

try {

User.wait();

} catch(InterruptedException ie) {}

// Send Mechanic steps to fixing

}

}

}

}


The Mechanic thread, once started, will immediately go into the waiting state and will wait patiently until the User sends the first notification. At that point it is the User thread that owns the lock for the object, so the fixing thread gets stuck for a while. It’s only after the User thread abandons the synchronized block that the fixing thread can really start processing the Mechanic steps.


While one car is being processed by the mechanic, the user may interact with the system and specify another car to be serviced. When the user is finished with the car and it is time to repair it, the User thread attempts to enter the synchronized block, maybe blocking until the Mechanic thread has finished with the previous Mechanic steps. When the Mechanic thread has finished, it repeats the loop, going again to the waiting state (and therefore releasing the lock). Only then can the User thread enter the synchronized block and overwrite the Mechanic steps with the new ones.


Having two threads is definitely an improvement over having one, although in this implementation there is still a possibility of making the user wait. A further improvement would be to have many cars in a queue, thereby reducing the possibility of requiring the user to wait for the mechanic.


There is also a second form of wait() that accepts a number of milliseconds as a maximum time to wait. If the thread is not interrupted, it will continue normally whenever it is notified or the specified timeout has elapsed. This normal continuation consists of getting out of the waiting state, but to continue execution it will have to get the lock for the object:


synchronized(a){ // The thread gets the lock on 'a'

a.wait(5000); // Thread releases the lock and waits for notify

// only for a maximum of five seconds, then goes back to Runnable

// The thread reacquires the lock

// More code here

}


Exam Tip:
When the wait() method is invoked on an object, the thread executing that code gives up its lock on the object immediately. However, when notify() is called, that doesn’t mean the thread gives up its lock at that moment. If the thread is still completing synchronized code, the lock is not released until the thread moves out of synchronized code. So just because notify() is called doesn’t mean the lock becomes available at that moment
Using notifyAll( )

In most scenarios, it’s preferable to notify all of the threads that are waiting on a particular object. If so, you can use notifyAll() on the object to let all the threads come out of the waiting area and back to runnable. This is especially important if you have several threads waiting on one object, but for different reasons, and you want to be sure that the right thread (along with all of the others) gets notified.


notifyAll(); // Will notify all waiting threads


All of the threads will be notified and start competing to get the lock. As the lock is used and released by each thread, all of them will get into action without a need for further notification.


As we said earlier, an object can have many threads waiting on it, and using notify() will affect only one of them. Which one, exactly, is not specified and depends on the JVM implementation, so you should never rely on a particular thread being notified in preference to other threads.


In cases in which there might be a lot more waiting, the best way to do this is by using notifyAll(). Let’s take a look at this in some code. In this example, there is one class that figures out a stocks current price and many stock traders that are waiting to receive the current value. At any given moment many traders may be waiting.


1. class Trader extends Thread {

2. StockPriceAnalyzer c;

3.

4. public Trader(StockPriceAnalyzer calc) {

5. c = calc;

6. }

7.

8. public void run() {

9. synchronized(c) {

10. try {

11. System.out.println("Waiting for calculation...");

12. c.wait();

13. } catch (InterruptedException e) {}

14. System.out.println("Value is: " + c.value);

15. }

16. }

17.

18. public static void main(String [] args) {

19. StockPriceAnalyzer StockPriceAnalyzer = new StockPriceAnalyzer();

20. new Trader(StockPriceAnalyzer).start();

21. new Trader(StockPriceAnalyzer).start();

22. new Trader(StockPriceAnalyzer).start();

23. StockPriceAnalyzer.start();

24. }

25. }

26.

27. class StockPriceAnalyzer extends Thread {

28. int value;

29.

30. public void run() {

31. synchronized(this) {

32. for(int i=0;i<10;i++) {

33. value += i;

34. }

35. notifyAll();

36. }

37. }

38. }


The program starts three threads that are all waiting to receive the finished calculation (lines 18–24), and then starts the StockPriceAnalyzer with its calculation. Note that if the run() method at line 30 used notify() instead of notifyAll(), only one Trader would be notified instead of all the Traders.


Apologies for the crappy code inside the stock market prize analyzer class. I cant probably put code that calculates the current price of any share in such a small place. So I just put in some code that does addition in a loop. As long as you understand the concept and not curse me for the example I am good!!!


Using wait( ) in a Loop


Actually both of the previous examples (Mechanic/User and Trader/StockPriceAnalyzer) had a common problem. In each one, there was at least one thread calling wait(), and another thread calling notify() or notifyAll(). This works well enough as long as the waiting threads have actually started waiting before the other thread executes the notify() or notifyAll(). But what happens if, for example, the StockPriceAnalyzer runs first and calls notify() before the Traders have started waiting? This could happen, since we can’t guarantee what order the different parts of the thread will execute in. Unfortunately, when the Traders run, they just start waiting right away. They don’t do anything to see if the event they’re waiting for has already happened. So if the StockPriceAnalyzer has already called notifyAll(), it’s not going to call notifyAll() again—and the waiting Traders will keep waiting forever. This is probably not what the programmer wanted to happen. Almost always, when you want to wait for something, you also need to be able to check if it has already happened. Generally the best way to solve this is to put in some sort of loop that checks on some sort of conditional expressions, and only waits if the thing you’re waiting for has not yet happened. Here’s a modified, safer version of the earlier Car & Mechanic example:


class User extends Thread {

Mechanic Mechanic; // assume this gets initialized

public void run() {

while (true) {

Car car = getCarFromUser();

MechanicInstructions job = processCarForInstructions(shape);

Mechanic.addCarForRepair(job);

}

}

}



The User will still keep on looping forever, getting more cars from users, calculating new instructions for those cars, and sending them to the Mechanic. But now the logic for notify() has been moved into the addCarForRepair() method in the Mechanic class:


class Mechanic extends Thread {

List jobs = new ArrayList();

public void addCarForRepair(MechanicInstructions job) {

synchronized (jobs) {

jobs.add(job);

jobs.notify();

}

}

public void run() {

while (true) {

synchronized (jobs) {

// wait until at least one car is available

while (jobs.isEmpty()) {

try {

jobs.wait();

} catch (InterruptedException ie) { }

}

// If we get here, we know that jobs is not empty

MechanicInstructions instructions = jobs.remove(0);

// Send Mechanic steps to garage

}

}

}

}


A Mechanic keeps a list of the jobs it’s scheduled to do. Whenever an User adds a new job to the list, it calls the addCarForRepair() method and adds the new job to the list. Meanwhile the run() method just keeps looping, looking for any jobs on the list. If there are no jobs, it will start waiting. If it’s notified, it will stop waiting and then recheck the loop condition: is the list still empty? In practice this double-check is probably not necessary, as the only time a notify() is ever sent is when a new job has been added to the list. However, it’s a good idea to require the thread to recheck the isEmpty() condition whenever it’s been woken up, because it’s possible that a thread has accidentally sent an extra notify() that was not intended.


There’s also a possible situation called spontaneous wakeup that may exist in some situations; a thread may wake up even though no code has called notify() or notifyAll().What this means is, when your thread wakes up from a wait(), you don’t know for sure why it was woken up. By putting the wait() method in a while loop and re-checking the condition that represents what we were waiting for, we ensure that whatever the reason we woke up, we will re-enter the wait() if and only if the thing we were waiting for has not happened yet. In the Mechanic class, the thing we were waiting for is for the jobs list to not be empty. If it’s empty, we wait, and if it’s not, we don’t.


Note also that both the run() method and the addCarForRepair() method synchronize on the same object, the jobs list. This is for two reasons. One is because we’re calling wait() and notify() on this instance, so we need to synchronize in order to avoid an IllegalThreadState exception. The other reason is, the data in the jobs list is changeable data stored in a field that is accessed by two different threads. We need to synchronize in order to access that changeable data safely. Fortunately, the same synchronized blocks that allow us to wait() and notify() also provide the required thread safety for our other access to changeable data. In fact this is a main reason why synchronization is required to use wait() and notify() in the first place, you almost always need to share some mutable data between threads at the same time, and that means you need synchronization. Notice that the synchronized block in addCarForRepair() is big enough to also include the call to jobs.add(job,)which modifies shared data. And the synchronized block in run() is large enough to include the whole while loop—which includes the call to jobs.isEmpty(), which accesses shared data.


The moral of the story here is (again value education stuff) that when you use wait() and notify() or notifyAll(), you should almost always also have a while loop around the wait() that checks a condition and forces continued waiting until the condition is met. And you should also make use of the required synchronization for the wait() and notify() calls, to also protect whatever other data you’re sharing between threads. If you see code which fails to do this, there’s usually something wrong with the code, even if you have a hard time seeing what exactly the problem is.


Exam Tip:
The methods wait() , notify(), and notifyAll() are methods of only java.lang.Object, not of java.lang.Thread or java.lang.Runnable. Be sure you know which methods are defined in Thread, which in Object, and which in Runnable (just run(), so that’s an easy one). Of the key methods in Thread, be sure you know which are static—sleep() and yield(), and which are not static—join() and start()

Key Thread Methods

To wrap up this chapter, we will take a look at the important thread methods and then we will call it a day!!!


Methods in the Object Class:
a. wait()

b. notify()

c. notifyAll()



Methods in the Thread Class:
a. start()

b. yield()

c. sleep()

d. join



Methods in the Runnable Interface:
a. run()


That's it folks. We are done with Threads!!! Ugh, that was pretty long and hard. Wasn't it? :-)

Previous Chapter: Chapter 60 - Synchronization

Next Chapter: Quick Review - Threads

Chapter 60: Synchronization

We have been using the term synchronizing multiple times over the course of the previous chapters. We have never cared to stop and explain what the term synchronizing or synchronization means. Well, here we are. This full chapter is dedicated to synchronization and how to synchronize our code.

So, lets get started!!!

Why do we need Synchronization?

Threads are a powerful concept that we explained in the previous few chapters. Just as in the case of any programming scenario, the code works on a set of data and processes it. Lets imagine a scenario:

Assume that I have borrowed Rs. 10000/- from you and another Rs. 10000/- from an anonymous Mr. X last month. Now, both of you are chasing me for the money and I give you cheques worth the money I owe you guys, each worth Rs. 10000/- so, now I have given cheques worth Rs. 20000/- for payment. Unfortunately for you both, my account has a balance of only Rs. 12000/- and fortunately for me the banking application of my bank does not care about synchronization. So here is what will happen in a hypothetical situation wherein both the cheques are going to be submitted for payment at the same time.

Bank A (Your bank) and Bank B (Mr. X’s bank) have both submitted the cheques for payment to my bank today morning at two different branches.

A teller is processing your cheque at branch 1 and another teller is processing Mr. X’s cheque at branch 2. Both the tellers are simultaneously initiating the cheque clearance activity. Here is how it works:

Step 1: Teller 1 initiates a transfer at 10:30 AM and Teller 2 initiates a transfer at 10:30 AM as well
Step 2: Teller 1’s system checks my bank balance at 10:31 AM and approves the payment because my account has Rs. 12,000 and Teller 2’s system does the same at the same time and approves the payment because the money in my account is more than the value of the cheque I have given.
Step 3: Since both systems feel that there is enough balance in my account, they successfully make the payment.

2 cheques, each worth Rs. 10000/- got paid even though I had only Rs. 12000/- in my bank. Though I am happy about it, clearly the bank is not.

Guess what went wrong here?

There is no synchronization between the two tellers. Practically speaking, two tellers in two different branches don't need to talk to one another before processing a cheque but the banks application should handle such a situation.

All this happened because, the system allowed data related to one persons account to be accessed by two different processes(threads) and also allowed the data to be modified by both those processes at the same time.

This problem is known as a “race condition,” where multiple threads can access the same Car (typically an object’s instance variables), and can produce corrupted data if one thread “races in” too quickly before an operation that should be “atomic” has completed.

Practically speaking, only one of the cheques should have been cleared (whichever teller clicked “Transfer Funds” button first in milliseconds) and the other guys cheque must have bounced. This is exactly what would have happened if the first thread took a lock on the data and processed it, while all other threads that want access to the same data are in line “waiting”. So, by the time the second teller clicked “Transfer funds” his process would have to wait until Teller 1’s transfer is complete and then, the check balance logic would have come back stating “Hey buddy, this bum does not have enough cash to pay this cheque. Bounce this bad boy, will you?”
Now, I guess you know why we need synchronization (Only if you own a bank) but still, we now appreciate the need for synchronization. Lets now look at the details of implementation of this concept.

Preventing the Overpayment of Cheques:

So what can be done? The solution is actually quite simple. We must ensure that the two steps of the transfer—checking the balance and making the transfer—are never split apart. We need them to always be performed as one operation, step 1 and step 2! We call this an “atomic operation” because the operation, regardless of the number of actual statements (or underlying byte code instructions), is completed before any other thread code that acts on the same data.
You can’t guarantee that a single thread will stay running throughout the entire atomic operation. But you can guarantee that even if the thread running the atomic operation moves in and out of the running state, no other running thread will be able to work on the same data. In other words, If Teller 1 falls asleep after checking the balance, we can stop Teller 2 from checking the balance until after Teller 1 wakes up and completes her transfer.

So how do you protect the data? You must do two things:
• Mark the variables private.
• Synchronize the code that modifies the variables.

Remember, you protect the variables in the normal way using an access control modifier. It’s the method code that you must protect, so that only one thread at a time can be executing that code. You do this with the synchronized keyword.

We can solve all of Teller 2 and Teller 1’s problems by adding one word to the code. We mark the makeTransfer() method synchronized as follows:
private synchronized void makeTransfer(int amt) {
if (acct.getBalance() >= amt) {
System.out.println(Thread.currentThread().getName() +
" is going to Transfer");
try {
Thread.sleep(500);
} catch(InterruptedException ex) { }
acct.Transfer(amt);
System.out.println(Thread.currentThread().getName() +
" completes the transfer");
} else {
System.out.println("Not enough in account for "
+ Thread.currentThread().getName()
+ " to Transfer " + acct.getBalance());
}
}

Now we’ve guaranteed that once a thread (Teller 1 or Teller 2) starts the transfer process (by invoking makeTransfer()), the other thread cannot enter that method until the first one completes the process by exiting the method. The new output shows the benefit of synchronizing the makeTransfer() method:

Teller 2 is going to Transfer
Teller 2 completes the transfer
Teller 1 is going to Transfer
Teller 1 completes the transfer
Teller 2 is going to Transfer
Teller 2 completes the transfer
Teller 1 is going to Transfer
Teller 1 completes the transfer
Teller 2 is going to Transfer
Teller 2 completes the transfer
Not enough in account for Teller 1 to Transfer 0
Not enough in account for Teller 2 to Transfer 0
Not enough in account for Teller 1 to Transfer 0
Not enough in account for Teller 2 to Transfer 0
Not enough in account for Teller 1 to Transfer 0

Notice that now both threads, Teller 1 and Teller 2, always check the account balance and complete the transfer before the other thread can check the balance.

Synchronization and Locks

How does synchronization work? The Answer is simple “With locks”. Every object in Java has a built-in lock that only comes into play when the object has synchronized method code. When we enter a synchronized non-static method, we automatically acquire the lock associated with the current instance of the class whose code we’re executing. Acquiring a lock for an object is also known as getting the lock, or locking the object, locking on the object, or synchronizing on the object. We may also use the term monitor to refer to the object whose lock we’re acquiring. Technically the lock and the monitor are two different things, but here we refer to the same thing by those two words.

Since there is only one lock per object, if one thread has picked up the lock, no other thread can pick up the lock until the first thread releases or returns the lock. This means no other thread can enter the synchronized code until the lock has been released. Typically, releasing a lock means the thread holding the lock, in other words, the thread currently in the synchronized method exits the synchronized method. At that point, the lock is free until some other thread enters a synchronized method on that object. Remember the following key points about locking and synchronization:

• Only methods (or blocks) can be synchronized, not variables or classes.
• Each object has just one lock.
• Not all methods in a class need to be synchronized. A class can have both synchronized and non-synchronized methods.
• If two threads are about to execute a synchronized method in a class, and both threads are using the same instance of the class to invoke the method, only one thread at a time will be able to execute the method. The other thread will have to wait until the first one finishes its work. In other words, once a thread acquires the lock on an object, no other thread can enter any of the synchronized methods in that class for that object.
• If a class has both synchronized and non-synchronized methods, multiple threads can still access the class’s non-synchronized methods! If you have methods that don’t access the data you’re trying to protect, then you don’t need to synchronize them. Synchronization can cause a hit in some cases, so you should be careful not to overuse it.
• If a thread goes to sleep, it holds any locks it has—it doesn’t release them.
• A thread can acquire more than one lock. For example, a thread can enter a synchronized method, thus acquiring a lock, and then immediately invoke a synchronized method on a different object, thus acquiring that lock as well. As the methods complete, locks are released again. Also, if a thread acquires a lock and then attempts to call a synchronized method on that same object, no problem. The JVM knows that this thread already has the lock for this object, so the thread is free to call other synchronized methods on the same object, using the lock the thread already has.
• You can synchronize a block of code rather than a method.
Because synchronization does hurt concurrency, you don’t want to synchronize any more code than is necessary to protect your data. So if the scope of a method is more than needed, you can reduce the scope of the synchronized part to something less than a full method to just a block.

We call this, strangely, a synchronized block, and it looks like this:
class TestSyncdBlocks {
public void doSomething() {
System.out.println("not synchronized");
synchronized(this) {
System.out.println("synchronized");
}
}
}

When a thread is executing code from within a synchronized block, including any method code invoked from that synchronized block, the code is said to be executing in a synchronized context.

When you synchronize a method, the object used to invoke the method is the object whose lock must be acquired. But when you synchronize a block of code, you specify which object’s lock you want to use as the lock, so you could, for example, use some third-party object as the lock for this piece of code. That gives you the ability to have more than one lock for code synchronization within a single object.

Or you can synchronize on the current instance (this) as in the code above. Since that’s the same instance that synchronized methods lock on, it means that you could always replace a synchronized method with a non-synchronized method containing a synchronized block. In other words, this:

public synchronized void doSomething() {
System.out.println("synchronized");
}
is equivalent to this:
public void doSomething() {
synchronized(this) {
System.out.println("synchronized");
}
}

These methods both have the exact same effect, in practical terms. The compiled bytecodes may not be exactly the same for the two methods. The first form is shorter and more familiar to most people, but the second can be more flexible.

Static Methods and Synchronization

static methods can be synchronized. There is only one copy of the static data you’re trying to protect, so you only need one lock per class to synchronize static methods, a lock for the whole class. There is such a lock; every class loaded in Java has a corresponding instance of java.lang.Class representing that class. It’s that java.lang.Class instance whose lock is used to protect the static methods of the class (if they’re synchronized). There’s nothing special you have to do to synchronize a static method:

public static synchronized int getSomething() {
return count;
}

Again, this could be replaced with code that uses a synchronized block. If the method is defined in a class called MyClass, the equivalent code is as follows:
public static int getSomething() {
synchronized(MyClass.class) {
return count;
}
}

What’s that MyClass.class that we have used for the sync’d block? That’s called a class literal. It’s a special feature in the Java language that tells the compiler: get me the instance of Class that represents the class called MyClass. You can also do this with the following code:
public static void someMethod() {
Class cl = Class.forName("MyClass");
synchronized (cl) {
// do stuff
}
}

However that’s longer, trickier, and most importantly, not on the SCJP exam. But it’s quick and easy to use a class literal—just write the name of the class, and add .class at the end. No quotation marks needed. Now you’ve got an expression for the Class object you need to synchronize on.

What If a thread cannot get the Lock?

If a thread tries to enter a synchronized method and the lock is already taken, the thread is said to be blocked on the object’s lock. Essentially, the thread goes into a kind of pool for that particular object and has to wait there until the lock is released and the thread can again become runnable/running. Just because a lock is released doesn’t mean any particular thread will get it. There might be several threads waiting for a single lock, for example, and there’s no guarantee that the thread that has waited the longest will get the lock first.
When thinking about blocking, it’s important to pay attention to which objects are being used for locking.

• Threads calling non-static synchronized methods in the same class will only block each other if they’re invoked using the same instance. That’s because they each lock on this instance, and if they’re called using two different instances, they get two locks, which do not interfere with each other.
• Threads calling static synchronized methods in the same class will always block each other—they all lock on the same Class instance.
• A static synchronized method and a non-static synchronized method will not block each other, ever. The static method locks on a Class instance while the non-static method locks on the object instance, these actions do not interfere with each other at all.
• For synchronized blocks, you have to look at exactly what object has been used for locking. Threads that synchronize on the same object will block each other. Threads that synchronize on different objects will not.
A Synopsis of Thread related methods & Lock Availability:
Methods that give up the lock:
a. wait()

Methods that hold the lock:
a. notify()
b. join()
c. sleep()
d. yield()

When to Synchronize?

Synchronization can get pretty complicated, and you may be wondering why you would want to do this at all if you can help it. But remember the earlier “race conditions” example with Teller 1 and Teller 2 making transfers from their account. When we use threads, we usually need to use some synchronization somewhere to make sure our methods don’t interrupt each other at the wrong time and mess up our data. Generally, any time more than one thread is accessing changeable data, you synchronize to protect that data, to make sure two threads aren’t changing it at the same time. You don’t need to worry about local variables—each thread gets its own copy of a local variable. Two threads executing the same method at the same time will use different copies of the local variables, and they won’t trouble each other. However, you do need to worry about static and non-static fields, if they contain data that can be changed.

For changeable data in a non-static field, you usually use a non-static method to access it. By synchronizing that method, you will ensure that any threads trying to run that method using the same instance will be prevented from simultaneous access. But a thread working with a different instance will not be affected, because it’s acquiring a lock on the other instance. That’s what we want, threads working with the same data need to go one at a time, but threads working with different data can just ignore each other and run whenever they want to.

For changeable data in a static field, you usually use a static method to access it. And again, by synchronizing the method you ensure that any two threads trying to access the data will be prevented from simultaneous access, because both threads will have to acquire locks on the Class object for the class the static method’s defined in. Once again, that’s exactly what we want.
However, what if you have a non-static method that accesses a static field? Or a static method that accesses a non-static field (using an instance)? In these cases things start to get tricky quickly, and there’s a very good chance that things will not work the way you want. If you’ve got a static method accessing a non-static field, and you synchronize the method, you acquire a lock on the Class object. But what if there’s another method that also accesses the non-static field, this time using a non-static method? It probably synchronizes on the current instance instead. Remember that a static synchronized method and a non-static synchronized method will not block each other and they can run at the same time. Similarly, if you access a static field using a non-static method, two threads might invoke that method using two different this instances. Which means they won’t block each other, because they use different locks. Which means two threads are simultaneously accessing the same static field, which is exactly the sort of thing we’re trying to prevent.

It gets very confusing trying to imagine all the weird things that can happen here. To keep things simple: in order to make a class thread-safe, methods that access changeable fields need to be synchronized.

Access to static fields should be done from static synchronized methods. Access to non-static fields should be done from non- static synchronized methods. For example:

public class ConfuseMe {
private static int staticField;
private int nonstaticField;
public static synchronized int getStaticField() {
return staticField;
}
public static synchronized void setStaticField(int staticField) {
ConfuseMe.staticField = staticField;
}
public synchronized int getNonstaticField() {
return nonstaticField;
}
public synchronized void setNonstaticField(int nonstaticField) {
this.nonstaticField = nonstaticField;
}
}

What if you need to access both static and non-static fields in a method? Well, there are ways to do that, but it’s beyond what you need for the exam. So, for now, your are off the hook and don't need to bother much about this complicated thing that's going to make our lives harder than it already is…

Thread Safe Classes

When a class has been carefully synchronized to protect its data, we say the class is “thread-safe.” Many classes in the Java APIs already use synchronization internally in order to make the class “thread-safe.” For example, StringBuffer and StringBuilder are nearly identical classes, except that all the methods in StringBuffer are synchronized when necessary, while those in StringBuilder are not. Generally, this makes StringBuffer safe to use in a multithreaded environment, while StringBuilder is not. However, even when a class is “thread-safe,” it is often dangerous to rely on these classes to provide the thread protection you need. You still need to think carefully about how you use these classes, As an example, consider the following class.

import java.util.*;
public class ThreadSafeClass {
private List names = Collections.synchronizedList(new LinkedList());
public void addName(String name) {
names.addName(name);
}
public String removeName() {
if (names.size() > 0)
return (String) names.remove(0);
else
return null;
}
}

The method Collections.synchronizedList() returns a List whose methods are all synchronized and “thread-safe” according to the java API documentation. The question is, can the ThreadSafeClass class be used safely from multiple threads? It’s tempting to think that yes, since the data in names is in a synchronized collection, the ThreadSafeClass class is “safe” too. However that’s not the case—the removeName() may sometimes throw a NoSuchElementException. What’s the problem? Doesn’t it correctly check the size() of names before removing anything, to make sure there’s something there? How could this code fail? Let’s try to use ThreadSafeClass like this:

public static void main(String[] args) {
final ThreadSafeClass nl = new ThreadSafeClass();
nl.addName("Rocky");
class NameDropper extends Thread {
public void run() {
String name = nl.removeName();
System.out.println(name);
}
}
Thread t1 = new NameDropper();
Thread t2 = new NameDropper();
t1.start();
t2.start();
}

What might happen here is that one of the threads will remove the one name and print it, then the other will try to remove a name and get null. If we think just about the calls to names.size() and names.get(0), they occur in this order:

Thread t1 executes names.size(), which returns 1.
Thread t1 executes names.remove(0), which returns Rocky.
Thread t2 executes names.size(), which returns 0.
Thread t2 does not call remove(0).
The output here is
Rocky
null

However, if we run the program again something different might happen:

Thread t1 executes names.size(), which returns 1.
Thread t2 executes names.size(), which returns 1.
Thread t1 executes names.remove(0), which returns Rocky.
Thread t2 executes names.remove(0), which throws an exception because the list is now empty.

The thing to realize here is that in a “thread-safe” class like the one returned by synchronizedList(), each individual method is synchronized. So names.size() is synchronized, and names.remove(0) is synchronized. But nothing prevents another thread from doing something else to the list in between those two calls. And that’s when unexpected things can happen.
There’s a solution here: don’t rely on Collections.synchronizedList(). Instead, synchronize the code yourself:

import java.util.*;
public class ThreadSafeClass {
private List names = new LinkedList();
public synchronized void addName(String name) {
names.addName(name);
}
public synchronized String removeName() {
if (names.size() > 0)
return (String) names.remove(0);
else
return null;
}
}

Now the entire removeName() method is synchronized, and once one thread starts it and calls names.size(), there’s no way the other thread can cut in and steal the last name. The other thread will just have to wait until the first thread completes the removeName() method.
The moral of the story is (Like in the Value Education class in School) that just because a class is described as “thread-safe” doesn’t mean it is always thread-safe. If individual methods are synchronized, that may not be enough, you may be better off putting in synchronization logic yourself. Once you do that, the original synchronization may well become redundant.

I know that we never paid attention to the Value Education class in school, but my friend, here the moral is very important and you need to pay attention in order to pass the exam. So, do me a favor, go back to the paragraph above and read it once before you move ahead to the next topic…


Deadlocks

Perhaps the scariest thing that can happen to a Java program is deadlock. Deadlock occurs when two threads are blocked, with each waiting for the one another’s lock. Neither can run until the other gives up its lock, so they’ll sit there forever.

This can happen, for example, when thread A hits synchronized code, acquires a lock B, and then enters another method that’s also synchronized. But thread A can’t get the lock to enter this synchronized code block C because another thread D has the lock already. So thread A goes off to the “waiting for the C lock” pool, hoping that thread D will finish up its work and release the lock. But thread A will wait forever, because while thread D picked up lock C, it then entered a method synchronized on lock B. Obviously, thread D can’t get the lock B because thread A has it. And thread A won’t release it until thread D releases lock C. But thread D won’t release lock C until after it can get lock B and continue. And there they are – Stubbornly waiting for the other person to give up the lock. The following example demonstrates deadlock:

1. public class DeadlockExample {
2. private static class Car {
3. public int value;
4. }
5. private Car CarA = new Car();
6. private Car CarB = new Car();
7. public int read() {
8. synchronized(CarA) { // 1
9. synchronized(CarB) {
10. return CarB.value + CarA.value;
11. }
12. }
13. }
14.
15. public void write(int a, int b) {
16. synchronized(CarB) { // 2
17. synchronized(CarA) {
18. CarA.value = a;
19. CarB.value = b;
20. }
21. }
22. }
23. }

The lines marked with //1 and //2 are the places where we might end up with a deadlock.
Assume that read() is started by one thread and write() is started by another. If there are two different threads that may read and write independently, there is a risk of deadlock at line 8 or 16. The reader thread will have CarA, the writer thread will have CarB, and both will get stuck waiting for the other.

Code like this almost never results in deadlock because the CPU has to switch from the reader thread to the writer thread at a particular point in the code, and the chances of deadlock occurring are very small. The application may work fine most of the time.

The preceding simple example is easy to fix; just swap the order of locking for either the reader or the writer at lines 16 and 17 (or lines 8 and 9). More complex deadlock situations can take a long time to figure out and even longer to solve.

Regardless of how little chance there is for your code to deadlock, the bottom line is, if you get a deadlock, you’re dead. There are design approaches that can help avoid deadlock, including strategies for always acquiring locks in a particular order.

But that’s something you don't need for the exam.

Exam Tip:
Deadlocks are almost like stubborn fighting couples. Both parties are upset with each other and are silent and not willing to talk to one another. Unless one party speaks up and apologizes the other is going to stay silent. Fortunately we humans have emotions and most often one party apologizes and then the couples are happily married again. Unfortunately threads arent human and don't have any emotions. If one waits for the other to speak up, it waits and waits and waits. So, a smart programmer will take all possible steps to ensure that doesn't happen in his code, which I am sure you will!!!


Previous Chapter: Chapter 59 - Thread Prioritoes, yield and join methods

Next Chapter: Chapter 61 - Thread Interactions

Chapter 55: Static Inner Classes

In the chapter on Inner classes, I had promised that we will look in more detail about the different types of inner classes. Well here we are. This is the last and final type of inner classes. “Static” Inner Classes.

So, without any further delays, lets get Started!!!

Static Inner Classes

Actually static inner classes aren’t inner classes at all, by the standard definition of an inner class. While an inner class enjoys that special relationship with the outer class (or rather the instances of the two classes share a relationship), a static MyStaticExInnerClass class does not. It is simply a non-inner (also called “top-level”) class scoped within another. So with static classes it’s really more about name-space resolution than about an implicit relationship between the two classes.

A static MyStaticExInnerClass class is simply a class that’s a static member of the enclosing class:
class MyExOuter {
static class StaticInner { }
}

The class itself isn’t really “static”; there’s no such thing as a static class. The static modifier in this case says that the MyStaticExInnerClass class is a static member of the outer class. That means it can be accessed, as with other static members, without having an instance of the outer class.

Instantiating and Using Static Inner Classes

You use standard syntax to access a static MyStaticExInnerClass class from its enclosing class. The syntax for instantiating a static MyStaticExInnerClass class from a non-enclosing class is a little different from a normal inner class, and looks like this:

class MyExOuter {
static class MyStaticExInner {void do() { System.out.println("hi"); } }
}
class Test {
static class B2 {void goB2() { System.out.println("hi 2"); } }
public static void main(String[] args) {
MyExOuter.MyStaticExInner n = new MyExOuter.MyStaticExInner();
n.do();
B2 b2 = new B2();
b2.goB2();
}
}
Which produces
hi
hi 2

Exam Tip:
Just as a static method does not have access to the instance variables and nonstatic methods of the class, a static Inner class does not have access to the instance variables and nonstatic methods of the outer class. Look for static Inner classes with code that behaves like a nonstatic (regular inner) class. Be careful to spot them and you’ll be scoring points in the question without any trouble…

Previous Chapter: Chapter 54 - Anonymous Inner Classes

Next Chapter: Quick Recap - Inner classes

Chapter 54: Anonymous Inner Classes

In the chapter on Inner classes, I had promised that we will look in more detail about the different types of inner classes. Well here we are. In the series of types of specialized inner classes our next stop is “Anonymous” ones.

So far we’ve looked at defining a class within an enclosing class (a regular inner class) and within a method (a method-local inner class). Finally, we’re going to look at the most unusual syntax you might ever see in Java; inner classes declared without any class name at all (probably you figured out why we call it anonymous).

So, lets get started!!!

Anonymous Inner Classes - Type One

Check out the following code:
class Ferrari {
public void drive() {
System.out.println("Ferrari");
}
}
class Car {
Ferrari p = new Ferrari() {
public void drive() {
System.out.println("anonymous Ferrari");
}
};
}

Let’s look at what’s in the preceding code:
• We define two classes, Ferrari and Car.
• Ferrari has one method, drive().
• Car has one instance variable, declared as type Ferrari. That’s it for Car. Car has no methods.

And here’s the big thing to get
The Ferrari reference variable refers not to an instance of Ferrari, but to an instance of an anonymous (unnamed) subclass of Ferrari.

Let’s look at just the anonymous class code:
2. Ferrari p = new Ferrari() {
3. public void drive() {
4. System.out.println("anonymous Ferrari");
5. }
6. };

Line 2

Line 2 starts out as an instance variable declaration of type Ferrari. But instead of looking like this:
Ferrari p = new Ferrari(); // notice the semicolon at the end

there’s a curly brace at the end of line 2, where a semicolon would normally be.
Ferrari p = new Ferrari() { // a curly brace, not a semicolon

You can read line 2 as saying,
Declare a reference variable, p, of type Ferrari. Then declare a new class that has no name, but that is a subclass of Ferrari. And here’s the curly brace that opens the class definition...

Line 3

Line 3, then, is actually the first statement within the new class definition. And what is it doing? Overriding the drive() method of the superclass Ferrari. This is the whole point of making an anonymous inner class—to override one or more methods of the superclass!

Line 4

Line 4 is the first statement within the overriding drive() method. Nothing special here.

Line 5

Line 5 is the closing curly brace of the drive() method. Nothing special here either.

Line 6

Here’s where you have to pay attention: line 6 includes a curly brace closing off the anonymous class definition (it’s the companion brace to the one on line 2), but there’s more! Line 6 also has the semicolon that ends the statement started on line 2—the statement where it all began—the statement declaring and initializing the Ferrari reference variable. And what you’re left with is a Ferrari reference to a brand-new instance of a brand-new, anonymous (no name) subclass of Ferrari.

Exam Tip: The closing semicolon is hard to spot. Watch for code like this:
2. Ferrari p = new Ferrari() {
3. public void drive() {
4. System.out.println("anonymous Ferrari");
5. }
6. } // Missing the semicolon needed to end
// the statement started on 2!
7. Interface1 f = new Interface1();

You’ll need to be especially careful about the syntax when inner classes are involved, because the code on line 6 looks perfectly natural. It’s rare to see semicolons following curly braces.

Anonymous Inner Classes and Polymorphism

Polymorphism is in play when anonymous inner classes are involved. Remember that, as in the preceding Ferrari example, we’re using a superclass reference variable type to refer to a subclass object. What are the implications? You can only call methods on an anonymous inner class reference that are defined in the reference variable type! This is no different from any other polymorphic references, for example,

class McLarenF1 extends F1Car{
void drive() { }
}
class F1Car {
void brake() { }
}
class Test {
public static void main (String[] args) {
F1Car h = new McLarenF1();
h.brake(); // Legal, class F1Car has an brake() method
h.drive(); // Not legal! Class F1Car doesn't have drive()
}
}

So on the exam, you must be able to spot an anonymous inner class that—rather than overriding a method of the superclass—defines its own new method. The method definition isn’t the problem, though; the real issue is how do you invoke that new method? The reference variable type (the superclass) won’t know anything about that new method (defined in the anonymous subclass), so the compiler will complain if you try to invoke any method on an anonymous inner class reference that is not in the superclass class definition.

Check out the following, illegal code:
class Ferrari {
public void drive() {
System.out.println("Ferrari");
}
}

class Car {
Ferrari p = new Ferrari() {
public void brake() {
System.out.println("anonymous sizzling Ferrari");
}
public void drive() {
System.out.println("anonymous Ferrari");
}
};

public void popIt() {
p.drive(); // OK, Ferrari has a drive() method
p.brake(); // Not Legal! Ferrari does not have brake()
}
}

Compiling the preceding code gives us something like,
Anon.java:19: cannot resolve symbol
symbol : method brake()
location: class Ferrari
p.brake();
^


Anonymous Inner Classes Type Two

The only difference between type one and type two is that type one creates an anonymous subclass of the specified class type, whereas type two creates an anonymous implementer of the specified interface type. In the previous examples, we defined a new anonymous subclass of type Ferrari as follows:

Ferrari p = new Ferrari() {

But if Ferrari were an interface type instead of a class type, then the new anonymous class would be an implementer of the interface rather than a subclass of the class. Look at the following example:
interface Drivable {
public void drive();
}
class Car {
Drivable c = new Drivable() {
public void drive() {
System.out.println("anonymous Drivable implementer");
}
};
}

The preceding code, like the Ferrari example, still creates an instance of an anonymous inner class, but this time the new class is an implementer of the Drivable interface. And note that this is the only time you will ever see the syntax

new Drivable()

where Drivable is an interface rather than a non-abstract class type. Because think about it, you can’t instantiate an interface, yet that’s what the code looks like it’s doing. But of course it’s not instantiating a Drivable object, it’s creating an instance of a new, anonymous, implementer of Drivable. You can read this line:

Drivable c = new Drivable() {

as, “Declare a reference variable of type Drivable that, obviously, will refer to an object from a class that implements the Drivable interface. But, oh yes, we don’t yet have a class that implements Drivable, so we’re going to make one right here, right now. We don’t need a name for the class, but it will be a class that implements Drivable, and this curly brace starts the definition of the new implementing class.”

One more thing to keep in mind about anonymous interface implementers—they can implement only one interface. There simply isn’t any mechanism to say that your anonymous inner class is going to implement multiple interfaces. In fact, an anonymous inner class can’t even extend a class and implement an interface at the same time. The inner class has to choose either to be a subclass of a named class—and not directly implement any interfaces at all—or to implement a single interface. By directly, we mean actually using the keyword implements as part of the class declaration. If the anonymous inner class is a subclass of a class type, it automatically becomes an implementer of any interfaces implemented by the superclass.

Exam Tip:
Don’t be fooled by any attempts to instantiate an interface except in the case of an anonymous inner class. The following is not legal,
Runnable r = new Runnable(); // can't instantiate interface

whereas the following is legal, because it’s instantiating an implementer of the Runnable interface (an anonymous implementation class):
Runnable r = new Runnable() { // curly brace, not semicolon
public void run() { }
};

Argument-Defined Anonymous Inner Classes

If you understood what we’ve covered so far in this chapter, then this last part will be a walk in the park. If you are still a little fuzzy on anonymous classes, however, then you should reread the previous sections.

Imagine the following scenario. You’re typing along, creating the Perfect Class, when you write code calling a method on a Class1 object, and that method takes an object of type Interface1 (an interface).

class MyComplicatedClass {
void do() {
Class1 b = new Class1();
b.doSomething(!!!);

//Actually the !!! mean nothing. We don't have any argument matching // the input required here so I put the !!! to make it logical

}
}
interface Interface1 {
void doSomethingElse();
}
class Class1 {
void doSomething(Interface1 f) { }
}

No problems here, except that you don’t have an object from a class that implements Interface1, and you can’t instantiate one, either, because you don’t even have a class that implements Interface1, let alone an instance of one. So you first need a class that implements Interface1, and then you need an instance of that class to pass to the Class1 class’s doSomething() method. Knowing the smart Java programmer that you are, you simply define an anonymous inner class, right inside the argument. That’s right, just where you least expect to find a class. And here’s what it looks like:

1. class MyComplicatedClass {
2. void do() {
3. Class1 b = new Class1();
4. b.doSomething(new Interface1() {
5. public void doSomethingElse() {
6. System.out.println("Hey!!!");
7. }
8. });
9. }
10. }
11.
12. interface Interface1 {
13. void doSomethingElse();
14. }
15. class Class1 {
16. void doSomething(Interface1 f) { }
17. }

All the action starts on line 4. We’re calling doSomething() on a Class1 object, but the method takes an instance that IS-A Interface1, where Interface1 is an interface. So we must make both an implementation class and an instance of that class, all right here in the argument to doSomething(). So that’s what we do. We write

new Interface1() {

to start the new class definition for the anonymous class that implements the Interface1 interface. Interface1 has a single method to implement, doSomethingElse(), so on lines 5, 6, and 7 we implement the doSomethingElse() method. Then on line 8 more strange syntax appears. The first curly brace closes off the new anonymous class definition. But don’t forget that this all happened as part of a method argument, so the close parenthesis, ), finishes off the method invocation, and then we must still end the statement that began on line 4, so we end with a semicolon. Study this syntax! You will see anonymous inner classes on the exam, and you’ll have to be very, very picky about the way they’re closed. If they’re argument local, they end like this:
});

but if they’re just regular anonymous classes, then they end like this:
};

Regardless, the syntax is not what you use in virtually any other part of Java, so be careful. Any question from any part of the exam might involve anonymous inner classes as part of the code.

Previous Chapter: Chapter 53 - Method Local Inner classes

Next Chapter: Chapter 55 - Static Inner classes

Chapter 53: Method Local Inner Classes

In the previous chapter I had promised that we will look in more detail about the different types of inner classes. Well here we are. In this chapter we are going to look at method local inner classes. In other words, classes declared inside the curly braces of a method.

So, lets get started!!!

Method Local Inner Classes

A regular inner class is scoped inside another class’s curly braces, but outside any method code (in other words, at the same level that an instance variable is declared). But you can also define an inner class within a method:
class MyExOuterClass {
private String x = "Outer";

void doSomething() {
class MyExInnerClass {
public void accesOuter() {
System.out.println("Outer x is " + x);
}
}
}

}

The preceding code declares a class, MyExOuterClass, with one method, doSomething(). But inside doSomething(), another class, MyExInnerClass, is declared, and it has a method of its own, accesOuter(). The code above is completely useless, however, because it never instantiates the inner class! Just because you declared the class doesn’t mean you created an instance of it. So to use the inner class you must make an instance of it somewhere within the method but below the inner class definition (or the compiler won’t be able to find the inner class).

Instantiating a Method Local Inner Class

The following code shows how to instantiate and use a method-local inner class:
class MyExOuterClass {
private String x = "Outer";
void doSomething() {
class MyExInnerClass {
public void accesOuter() {
System.out.println("Outer x is " + x);
}
}

MyExInnerClass mi = new MyExInnerClass();
mi.accesOuter();
}
}

What a Method-Local Inner Class Can and Cannot Do

A method-local inner class can be instantiated only within the method where the inner class is defined. In other words, no other code running in any other method—inside or outside the outer class—can ever instantiate the method-local inner class. Like regular inner class objects, the method-local inner class object shares a special relationship with the enclosing outer class object, and can access its private or any other members. However, the inner class object cannot use the local variables of the method the inner class is in.

If you ask me, Why not? Think about it. The local variables of the method live on the stack, and exist only for the lifetime of the method. You already know that the scope of a local variable is limited to the method the variable is declared in. When the method ends, the stack frame is destroyed and the variable is gone. But even after the method completes, the inner class object created within it might still be alive on the heap if, for example, a reference to it was passed into some other code and then stored in an instance variable. Because the local variables aren’t guaranteed to be alive as long as the method-local inner class object, the inner class object can’t use them. Unless the local variables are marked final! The following code attempts to access a local variable from within a method-local inner class.

class MyExOuterClass {
private String x = "Outer";
void doSomething() {
String z = "local variable";
class MyExInnerClass {
public void accesOuter() {
System.out.println("Outer x is " + x);
System.out.println("Local variable z is " + z);
// Won't Compile!
}
}
}
}

Compiling the preceding code makes the compiler spew out this error message:
MyExOuterClass.java:8: local variable z is accessed from within inner class;
needs to be declared final
System.out.println("Local variable z is " + z);
^

Marking the local variable z as final fixes the problem:
final String z = "local variable";

And just a reminder about modifiers within a method: the same rules apply to method-local inner classes as to local variable declarations. You can’t, for example, mark a method-local inner class public, private, protected, static, transient, and the like. For the purpose of the exam, the only modifiers you can apply to a method-local inner class are abstract and final, but as always, never both at the same time.

Exam Tip: Remember that a local class declared in a static method has access to only static members of the enclosing class, since there is no associated instance of the enclosing class. If you’re in a static method there is no this, so an inner class in a static method is subject to the same restrictions as the static method. In other words, no access to instance variables

Previous Chapter: Chapter 52 - Inner classes

Next Chapter: Chapter 54 - Anonymous Inner Classes

Chapter 52: Inner Classes

You’re an Java programmer, so you know that for reuse and flexibility/extensibility you need to keep your classes specialized. In other words, a class should have code only for the things an object of that particular type needs to do; any other behavior should be part of another class better suited for that job. Sometimes, though, you find yourself designing a class where you discover you need behavior that belongs in a separate, specialized class, but also needs to be intimately tied to the class you’re designing.

Inner classes are an integral part of any Java application. There are many types of Inner classes and features that they provide make them very useful for any application. In this chapter, we are going to take a look at these inner classes in detail.

So, lets get started!!!

A Normal Inner Class

We use the term normal to represent inner classes that are not
• Static
• Method-local
• Anonymous

Before you jump up and ask me what about these types of inner classes? Relax my friend, the subsequent chapters will be dedicated to them exclusively. So for this chapter, we will be looking at the normal or basic inner classes and their usage.

You define an inner class within the curly braces of the outer class:

class ExampleOuterClass {
class ExampleInnerClass { }
}

Piece of cake. And if you compile it,
%javac ExampleOuterClass.java

you’ll end up with two class files:
ExampleOuterClass.class
ExampleOuterClass$ExampleInnerClass.class

The inner class is still, in the end, a separate class, so a separate class file is generated for it. But the inner class file isn’t accessible to you in the usual way. You can’t say

%java ExampleOuterClass$ExampleInnerClass

in hopes of running the main() method of the inner class, because a regular inner class can’t have static declarations of any kind. The only way you can access the inner class is through a live instance of the outer class! In other words, only at runtime when there’s already an instance of the outer class to tie the inner class instance to. First, let’s put some more code inside these classes:

class ExampleOuterClass {
private int x = 7;

// inner class definition
class ExampleInnerClass {
public void accessOuter() { System.out.println("Outer x is " + x);
}

} // close inner class definition

} // close outer class

The preceding code is perfectly legal. Notice that the inner class is indeed accessing a private member of the outer class. That’s fine, because the inner class is also a member of the outer class. So just as any member of the outer class can access any other member of the outer class, private or not, the inner class, also a member can do the same.


Instantiating an Inner Class

To create an instance of an inner class, you must have an instance of the outer class to tie to the inner class. There are no exceptions to this rule: an inner class instance can never stand alone without a direct relationship to an instance of the outer class. NO EXCEPTIONS TO THIS RULE. You cannot instantiate an inner class without a valid outer class instance already being present.

Instantiating an Inner Class from Within the Outer Class

Most often, it is the outer class that creates instances of the inner class, since it is usually the outer class wanting to use the inner instance as a helper for its own use. We’ll modify the ExampleOuterClass class to create an instance of ExampleInnerClass:

class ExampleOuterClass {
private int x = 7;
public void instantiateInnerClass() {
ExampleInnerClass in = new ExampleInnerClass();
// make an inner instance
in.accessOuter();
}

class ExampleInnerClass {
public void accessOuter() {
System.out.println("Outer x is " + x);
}
}
}

You can see in the preceding code that the ExampleOuterClass code treats ExampleInnerClass just as though ExampleInnerClass were any other accessible class—it instantiates it using the class name (new ExampleInnerClass()), and then invokes a method on the reference variable (in.accessOuter()). But the only reason this syntax works is because the outer class instance method code is doing the instantiating. In other words, there’s already an instance of the outer class—the instance running the instantiateInnerClass() method.

You might be tempted to think that since we have already said that we cannot instantiate an inner class without an outer class instance, there is no other way of instantiating this darn inner class. But, don't lose hope just yet. We can actually instantiate an inner class outside the actual outer class within which it is coded.

Creating an Inner Class Object from Outside the Outer Class Code

If we want to create an instance of the inner class, we must have an instance of the outer class. You already know that, but think about the implications...it means that, without a reference to an instance of the outer class, you can’t instantiate the inner class from a static method of the outer class (because, don’t forget, in static code there is no this reference), or from any other code in any other class. Inner class instances are always handed an implicit reference to the outer class. The compiler takes care of it, so you’ll never see anything but the end result; the ability of the inner class to access members of the outer class. The code to make an instance from anywhere outside nonstatic code of the outer class is simple.

public static void main(String[] args) {
ExampleOuterClass oc = new ExampleOuterClass();
ExampleOuterClass.ExampleInnerClass ic = oc.new ExampleInnerClass();
ic.accessOuter();
}

The preceding code is the same regardless of whether the main() method is within the ExampleOuterClass class or some other class (assuming the other class has access to ExampleOuterClass, and since ExampleOuterClass has default access, that means the code must be in a class within the same package as ExampleOuterClass).

If you’re into one-liners, you can do it like this:
public static void main(String[] args) {
ExampleOuterClass.ExampleInnerClass inner = new ExampleOuterClass().new ExampleInnerClass();
inner.accessOuter();
}

You can think of this as though you’re invoking a method on the outer instance, but the method happens to be a special inner class instantiation method, and it’s invoked using the keyword new. Instantiating an inner class is the only scenario in which you’ll invoke new on an instance as opposed to invoking new to construct an instance.

Here’s a quick summary of the differences between inner class instantiation code that’s within the outer class and inner class instantiation code that’s outside the outer class:
• From inside the outer class instance code, use the inner class name in the normal way:
ExampleInnerClass mi = new ExampleInnerClass();
• From outside the outer class instance code (including static method code within the outer class), the inner class name must now include the outer class’s name:
ExampleOuterClass.ExampleInnerClass

To instantiate it, you must use a reference to the outer class:
new ExampleOuterClass().new ExampleInnerClass(); or outerObjRef.new ExampleInnerClass();
if you already have an instance of the outer class.

Referencing the Inner or Outer Instance from Within the Inner Class
How does an object refer to itself normally? By using the “this” reference. Here is a quick review of “this” keyword and its features:
• The keyword this can be used only from within instance code.
In other words, not within static code.
• The this reference is a reference to the currently executing object. In other words, the object whose reference was used to invoke the currently running method.
• The this reference is the way an object can pass a reference to itself to some other code, as a method argument:

public void myExMethod() {
MyExClass mc = new MyExClass();
mc.doSomething(this); // pass a ref to object running myExMethod
}

Within an inner class code, the this reference refers to the instance of the inner class, as you’d probably expect, since this always refers to the currently executing object. But what if the inner class code wants an explicit reference to the outer class instance that the inner instance is tied to? In other words, how do you reference the “outer this”? Although normally the inner class code doesn’t need a reference to the outer class, since it already has an implicit one it’s using to access the members of the outer class, it would need a reference to the outer class if it needed to pass that reference to some other code as follows:

class ExampleInnerClass {
public void accessOuter() {
System.out.println("Outer x is " + x);
System.out.println("Inner ref is " + this);
System.out.println("Outer ref is " + ExampleOuterClass.this);
}
}

If we run the complete code as follows:
class ExampleOuterClass {
private int x = 7;
public void instantiateInnerClass() {
ExampleInnerClass in = new ExampleInnerClass();
in.accessOuter();
}
class ExampleInnerClass {
public void accessOuter() {
System.out.println("Outer x is " + x);
System.out.println("Inner ref is " + this);
System.out.println("Outer ref is " + ExampleOuterClass.this);
}
}
public static void main (String[] args) {
ExampleOuterClass.ExampleInnerClass inner = new ExampleOuterClass().new ExampleInnerClass();
inner.accessOuter();
}
}

the output is something like this:
Outer x is 7
Inner ref is ExampleOuterClass$ExampleInnerClass@113708
Outer ref is ExampleOuterClass@33f1d7
So the rules for an inner class referencing itself or the outer instance are as follows:
• To reference the inner class instance itself, from within the inner class code, use this.
• To reference the “outer this” (the outer class instance) from within the inner class code, use NameOfOuterClass.this (example, ExampleOuterClass.this).
Member Modifiers Applied to Inner Classes
A regular inner class is a member of the outer class just as instance variables and methods are, so the following modifiers can be applied to an inner class:
• final
• abstract
• public
• private
• protected
• static—but static turns it into a static nested class not an inner class
• strictfp

Previous Chapter: Self Test - Chapters 38 to 51

Next chapter: Chapter 53 - Method Local Inner Classes

Self Test: Chapters 38 to 51

Below are some questions from the previous chapters that would help you practice for the SCJP examination.

All the best !!!

Questions:

Question 1.

Given:
public static void main(String[] args) {

// CODE HERE
for (int i = 0; i <= 10; i++) {

List < Integer > row = new ArrayList < Integer > ();

for (int j = 0; j <= 10; j++)

row.add(i * j);

table.add(row);

}

for (List < Integer > row : table)

System.out.println(row);

}

Which statements could be inserted at // CODE HERE to allow this code to compile and run? (Choose all that apply.)
A. List < List< Integer > > table = new List < List < Integer > >();
B. List < List< Integer > > table = new ArrayList < List < Integer > >();
C. List < List< Integer > > table = new ArrayList < ArrayList < Integer > >();
D. List < List, Integer > table = new List < List, Integer >();
E. List < List, Integer > table = new ArrayList < List, Integer >();
F. List < List, Integer > table = new ArrayList < ArrayList, Integer >();
G. None of the above

Question 2.

Which statements are true about comparing two instances of the same class, given that the equals() and hashCode() methods have been properly overridden? (Choose all that apply.)
A. If the equals() method returns true, the hashCode() comparison == might return false
B. If the equals() method returns false, the hashCode() comparison == might return true
C. If the hashCode() comparison == returns true, the equals() method must return true
D. If the hashCode() comparison == returns true, the equals() method might return true
E. If the hashCode() comparison != returns true, the equals() method might return true

Question 3.

Given:
public static void doSomething() {
Set set = new TreeSet();
set.add("2");
set.add(3);
set.add("1");
Iterator it = set.iterator();
while (it.hasNext())
System.out.print(it.next() + " ");
}

Which statements are true?
A. The doSomething() method will print 1 2
B. The doSomething() method will print 1 2 3
C. The doSomething() method will print three numbers, but the order cannot be determined
D. The doSomething() method will not compile
E. The doSomething() method will throw an exception at runtime

Question 4.

Given:
import java.util.*;
class TestMaps {
public static void main(String[] args) {
Map m = new HashMap();
Day t1 = new Day("Monday");
Day t2 = new Day("Monday");
Day t3 = new Day("Tuesday");
m.put(t1, "goToGym");
m.put(t2, "visitMom");
m.put(t3, "goShopping");
System.out.println(m.size());
}
}
class Day{
String day;
Day(String d) { day = d; }
public boolean equals(Object o) {
return ((Day)o).day == this.day;
}
// public int hashCode() { return 9; }
}

Which is correct? (Choose all that apply.)
A. As the code stands it will not compile
B. As the code stands the output will be 2
C. As the code stands the output will be 3
D. If the hashCode() method is uncommented the output will be 2
E. If the hashCode() method is uncommented the output will be 3
F. If the hashCode() method is uncommented the code will not compile

Question 5.

Given:
12. public class BankAppManager {
13. private Map allBalances = new HashMap();
14. private int corpus;
15.
16. public int calcAccBalance(String custName) {
17. Integer total = (Integer) allBalances.get(custName);
18. if (total == null)
19. total = Integer.valueOf(0);
20. return total.intValue();
21. }
23. public void updateAccBalance(String custName, int amount) {
24. allBalances.put(custName, Integer.valueOf(amount));
25. }
26. }

This class is to be updated to make use of appropriate generic types, with no changes in behavior (for better or worse). Which of these steps could be performed? (Choose three.)
A. Replace line 13 with
private Map < String, int > allBalances = new HashMap < String, int >();
B. Replace line 13 with
private Map < String, Integer > allBalances = new HashMap < String, Integer >();
C. Replace line 13 with
private Map < String< Integer > > allBalances = new HashMap < String< Integer > >();
D. Replace lines 17–20 with
int total = allBalances.get(custName);
if (total == null)
total = 0;
return total;
E. Replace lines 17–20 with
Integer total = allBalances.get(custName);
if (total == null)
total = 0;
return total;
F. Replace lines 17–20 with
return allBalances.get(custName);
G. Replace line 24 with
allBalances.put(custName, amount);
H. Replace line 24 with
allBalances.put(custName, amount.intValue());

Question 6.

Given:
interface Drivable< E > { void driveee(E x); }
interface Car extends Drivable< E > {}
interface Van extends Drivable< E > {}
abstract class SomethingElse {}
class Xxxxxx extends SomethingElse {}
abstract class Something {}
class SuzukiSwift extends Something implements Van {
public void driveee(SuzukiSwift x) {}
}
class VwJetta extends Something implements Car {
public void driveee(SuzukiSwift x) {}
}

Which of the following changes (taken separately) would allow this code to compile? (Choose all that apply.)
A. Change the Car interface to
interface Car extends Drivable< E > {}
B. Change the Van interface to
interface Van extends Drivable< E > {}
C. Change the SuzukiSwift class to
class SuzukiSwift extends Something implements Van {
public void driveee(Xxxxxx x) {}
}
D. Change the SuzukiSwift class to
class SuzukiSwift extends SomethingElse implements Car {
public void driveee(VwJetta x) {}

E. Change the VwJetta class to
class VwJetta extends Something implements Van {
public void driveee(Xxxxxx x) {}
}
F. No changes are necessary

Question 7.

Which collection class(es) allows you to grow or shrink its size and provides indexed access to its elements, but whose methods are not synchronized? (Choose all that apply.)
A. java.util.HashSet
B. java.util.LinkedHashSet
C. java.util.List
D. java.util.ArrayList
E. java.util.Vector
F. java.util.PriorityQueue

Question 8.

Given a method declared as
public static < e extends Number > List < E > process(List < E > nums)

A programmer wants to use this method like this
// PUT CODE HERE

output = process(input);

Which pairs of declarations could be placed at // PUT CODE HERE to allow the code to compile? (Choose all that apply.)
A. ArrayList < Integer > input = null;
B. ArrayList < Integer > output = null;
C. ArrayList < Integer > input = null;
D. List < Integer > output = null;
E. ArrayList < Integer > input = null;
F. List < Number > output = null;
G. List < Number > input = null;
H. ArrayList < Integer > output = null;
I. List < Number > input = null;
J. List < Number > output = null;
K. List < Integer > input = null;
L. List < Integer > output = null;
M. None of the above

Question 9.

Given the proper import statement(s), and
13. PriorityQueue < String > pq = new PriorityQueue < String >();
14. pq.add("2");
15. pq.add("4");
16. System.out.print(pq.peek() + " ");
17. pq.offer("1");
18. pq.add("3");
19. pq.remove("1");
20. System.out.print(pq.poll() + " ");
21. if(pq.remove("2")) System.out.print(pq.poll() + " ");
22. System.out.println(pq.poll() + " " + pq.peek());

What is the result?
A. 2 2 3 3
B. 2 2 3 4
C. 4 3 3 4
D. 2 2 3 3 3
E. 4 3 3 3 3
F. 2 2 3 3 4
G. Compilation fails
H. An exception is thrown at runtime

Question 10.

Given:
3. import java.util.*;
4. public class ConfuseMe {
5. public static void main(String[] args) {
6. Object o = new Object();
7. // insert code here
8. s.add("o");
9. s.add(o);
10. }
11. }

And these three fragments:
I. Set s = new HashSet();
II. TreeSet s = new TreeSet();
III. LinkedHashSet s = new LinkedHashSet();

When fragments I, II, or III are inserted, independently, at line 7, which are true? (Choose all that apply.)
A. Fragment I compiles
B. Fragment II compiles
C. Fragment III compiles
D. Fragment I executes without exception
E. Fragment II executes without exception
F. Fragment III executes without exception

Question 11.

Given:
3. import java.util.*;
4. class Dog {
5. int size;
6. public Dog(int s) { size = s; }
7. public boolean equals(Object o) { return (this.size == ((Dog)o).size); }
8. // insert code here
9. }
10. public class DogTest {
11. public static void main(String[] args) {
12. LinkedHashSet< Dog > t = new LinkedHashSet< Dog >();
13. t.add(new Dog(1)); t.add(new Dog(2)); t.add(new Dog(1));
14. System.out.println(t.size());
15. }
16. }



And these two fragments:
I. public int hashCode() { return size/5; }
II. // no hashCode method declared

If fragment I or II is inserted, independently, at line 8, which are true? (Choose all that apply.)
A. If fragment I is inserted, the output is 2
B. If fragment I is inserted, the output is 3
C. If fragment II is inserted, the output is 2
D. If fragment II is inserted, the output is 3
E. If fragment I is inserted, compilation fails
F. If fragment II is inserted, compilation fails

Question 12.

Given the proper import statement(s), and:
13. TreeSet< String > s = new TreeSet< String >();
14. TreeSet< String > subs = new TreeSet< String >();
15. s.add("a"); s.add("b"); s.add("c"); s.add("d"); s.add("e");
16.
17. subs = (TreeSet)s.subSet("b", true, "d", true);
18. s.add("g");
19. s.pollFirst();
20. s.pollFirst();
21. s.add("c2");
22. System.out.println(s.size() +" "+ subs.size());

Which are true? (Choose all that apply.)
A. The size of s is 4
B. The size of s is 5
C. The size of s is 7
D. The size of subs is 1
E. The size of subs is 2
F. The size of subs is 3
G. The size of subs is 4
H. An exception is thrown at runtime

Question 13.

Given:
3. import java.util.*;
4. public class TestMe {
5. public static void main(String[] args) {
6. TreeMap myMap = new TreeMap();
7. myMap.put("a", "apple"); myMap.put("d", "date");
8. myMap.put("f", "fig"); myMap.put("p", "pear");
9. System.out.println("1st after mango: " + // sop 1
10. myMap.higherKey("f"));
11. System.out.println("1st after mango: " + // sop 2
12. myMap.ceilingKey("f"));
13. System.out.println("1st after mango: " + // sop 3
14. myMap.floorKey("f"));
15. SortedMap sub = new TreeMap();
16. sub = myMap.tailMap("f");
17. System.out.println("1st after mango: " + // sop 4
18. sub.firstKey());
19. }
20. }

Which of the System.out.println statements will produce the output 1st after mango: p? (Choose all that apply.)
A. sop 1
B. sop 2
C. sop 3
D. sop 4
E. None; compilation fails
F. None; an exception is thrown at runtime

Question 14.

Given:
3. import java.util.*;
4. class Car { }
5. class Ferrari extends Car { }
6. class F550Barchetta extends Ferrari { }
7. public class DriveAround {
8. ArrayList< Ferrari > go() {
9. // insert code here
10. }
11. }

Which, inserted independently at line 9, will compile? (Choose all that apply.)
A. return new ArrayList < F550Barchetta >();
B. return new ArrayList < Ferrari >();
C. return new ArrayList < Object >();
D. return new ArrayList < Car >();

Question 15.

Given:
3. import java.util.*;
4. class Shoe { int size; Shoe(int s) { size = s; } }
5. public class FirstGrade {
6. public static void main(String[] args) {
7. TreeSet < Integer > i = new TreeSet < Integer >();
8. TreeSet < Shoe > d = new TreeSet < Shoe >();
9.
10. d.add(new Shoe(1)); d.add(new Shoe(2)); d.add(new Shoe(1));
11. i.add(1); i.add(2); i.add(1);
12. System.out.println(d.size() + " " + i.size());
13. }
14. }

What is the result?
A. 1 2
B. 2 2
C. 2 3
D. 3 2
E. 3 3
F. Compilation fails
G. An exception is thrown at runtime

Answers:

Answer 1.

B is correct.

A is incorrect because List is an interface, so you can’t say new List() regardless of any generic types. D, E, and F are incorrect because List only takes one type parameter (a Map would take two, not a List). C is tempting, but incorrect. The type argument < List< Integer >> must be the same for both sides of the assignment, even though the constructor new ArrayList() on the right side is a subtype of the declared type List on the left.

Answer 2.

B and D. B is true because often two dissimilar objects can return the same hashcode value. D is true because if the hashCode() comparison returns ==, the two objects might or might not be equal.

A, C, and E are incorrect. C is incorrect because the hashCode() method is very flexible in its return values, and often two dissimilar objects can return the same hash code value. A and E are a negation of the hashCode() and equals() contract.

Answer 3.

E is correct. You can’t put both Strings and ints into the same TreeSet. Without generics, the compiler has no way of knowing what type is appropriate for this TreeSet, so it allows everything to compile. At runtime, the TreeSet will try to sort the elements as they’re added, and when it tries to compare an Integer with a String it will throw a ClassCastException. Note that although the doSomething() method does not use generics, it does use autoboxing. Watch out for code that uses some new features and some old features mixed together.

Answer 4.

C and D are correct. If hashCode() is not overridden then every entry will go into its own bucket, and the overridden equals() method will have no effect on determining equivalency. If hashCode() is overridden, then the overridden equals() method will view t1 and t2 as duplicates.

Answer 5.

B, E, and G are correct.

A is wrong because you can’t use a primitive type as a type parameter. C is wrong because a Map takes two type parameters separated by a comma. D is wrong because an int can’t autobox to a null, and F is wrong because a null can’t unbox to 0. H is wrong because you can’t autobox a primitive just by trying to invoke a method with it.

Answer 6.

B is correct. The problem with the original code is that SuzukiSwift tries to implement Van and Van declares that its type parameter E can be any type that extends SomethingElse. Since a SuzukiSwift is not a SomethingElse, Van makes no sense—the type SuzukiSwift is outside the allowed range of Van’s parameter E. Only solutions that either alter the definition of a SuzukiSwift or alter the definition of Van will be able to fix this. So A, E, and F are eliminated. B works, changing the definition of an Van to allow it to eat SuzukiSwift solves the problem. C doesn’t work because an Van must have a driveee(SomethingElse) method, not driveee(Xxxxxx).
And D doesn’t work, because in D we made SuzukiSwift extend SomethingElse, now the VwJetta class breaks because its driveee(SuzukiSwift) method no longer fulfills the contract of Car.

Answer 7.

D is correct. All of the collection classes allow you to grow or shrink the size of your collection. ArrayList provides an index to its elements. The newer collection classes tend not to have synchronized methods. Vector is an older implementation of ArrayList functionality and has synchronized methods; it is slower than ArrayList.

A, B, C, E, and F are incorrect based on the logic described above; Notes: C, List is an interface, and F, PriorityQueue does not offer access by index.

Answer 8.

B, E, and F are correct.

The return type of process is definitely declared as a List, not an ArrayList, so A and D are wrong. C is wrong because the return type evaluates to List< Integer >, and that can’t be assigned to a variable of type List< Number >. Of course all these would probably cause a NullPointerException since the variables are still null—but the question only asked us to get the code to compile.

Answer 9.

B is correct. For the sake of the exam, add() and offer() both add to (in this case), naturally sorted queues. The calls to poll() both return and then remove the first item from the queue, so the if test fails.

Answer 10.

A, B, C, D, and F are all correct.

Only E is incorrect. Elements of a TreeSet must in some way implement Comparable.

Answer 11.

A and D are correct. While fragment II wouldn’t fulfill the hashCode() contract (as you can see by the results), it is legal Java. For the purpose of the exam, if you don’t override hashCode(), every object will have a unique hashcode.

Answer 12.

B and F are correct. After "g" is added, TreeSet s contains six elements and TreeSet subs contains three (b, c, d), because "g" is out of the range of subs. The first pollFirst() finds and removes only the "a". The second pollFirst() finds and removes the "b" from both TreeSets (remember they are backed). The final add() is in range of both TreeSets. The final contents are [c,c2,d,e,g] and [c,c2,d].


Answer 13.

A is correct. The ceilingKey() method’s argument is inclusive. The floorKey() method would be used to find keys before the specified key. The firstKey() method’s argument is also inclusive.

Answer 14.

B is correct.

A is incorrect because polymorphic assignments don’t apply to generic type parameters. C and D are incorrect because they don’t follow basic polymorphism rules.

Answer 15.

G is correct. Class Shoe needs to implement Comparable in order for a TreeSet (which keeps its elements sorted) to be able to contain Shoe objects.

Previous Chapter: Quick Review - Chapters 38 to 51

Next Chapter: Chapter 52 - Inner Classes
© 2013 by www.inheritingjava.blogspot.com. All rights reserved. No part of this blog or its contents may be reproduced or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without prior written permission of the Author.

ShareThis

Google+ Followers

Followers