Jamie MacDonald

+ Follow
since May 17, 2008
Cows and Likes
Total received
In last 30 days
Total given
Total received
Received in last 30 days
Total given
Given in last 30 days
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Jamie MacDonald

This is from Devaka Cooray's Exam Lab (Practice Exam 1, Question 72):

What is result of attempting to compile and run this program?

The "correct" answer given by ExamLab is Prints "ABC". The explanation includes commentary noting that the two synchronized blocks don't interfere with each other because they are synchronized on different objects. While I agree with the commentary, I don't agree with ExamLab as to the correct answer. While "ABC" should be the result almost every time the application is run, it is not guaranteed to be the result. The nature of threading means that the System.out.print(s); statement in XMap.run() is not guaranteed to be reached within 1 second of the thread starting. It probably will, and if you ran it a million times, you still are likely to get "ABC" every time. But the nature of threads is such that you cannot guarantee it. (This is why testing and debugging multi-threaded code is so difficult--just because something happens every time you ran it, doesn't mean it's the only thing that could happen.) However unlikely, it seems to me that the code as written could also result in "XYZ" being printed, if the assignment line in main is reached before the print statement in XMap.run(). Because of this possibility (however remote it may be) I would be inclined to give the answer to the question as "Result is unpredictable"

Can anyone either confirm or refute my argument?
A question from the K&B 6 mock exam (Q30 of 2nd mock exam):
Which are true? (Choose all that apply.)
A. To implement java.io.Serializable, a class must implement two methods.
B. When an object is serialized, if it has references to other objects, those objects must be serializable.
C. A serialized object can be deserialized only by the same JVM which was used to serialize it.
D. The values in the instance variables marked volatile will not survive serialization and deserialization.

The correct answer (according to the exam) is B.

However, to my thinking, if an object has references to other objects, those objects need not be serializable if they are marked transient. "Those objects must be serialzable" is therefore not true. Perhaps I differ on what "must" means in this context. Or perhaps the questioner meant "To serialize all members of an object" when they said "When an object is serialized".

Regardless, the problem here is not with my understanding of serialization, but rather my understanding of the meaning of the question. I'm not having trouble deciphering Java code, I'm having trouble deciphering the intent of the questioner's English. And this worries me since I have no way of preparing for that.

Have people encountered other questions like this, where figuring out the meaning of the questions themselves is the hurdle you have to overcome?
[ December 20, 2008: Message edited by: Jamie MacDonald ]
When you use <? extends MyClass>, the specific class replacing the generic must pass the is-a MyClass test. In your specific case, String is-a String. Since String can't be subclassed, the list in question must always be a list of String. So technically it's legal java, just really bad coding style.
Your code won't compile because Thread1 and Thread2 in your run() method have not been declared. The following code will compile (and that's about all it's good for):

As you noted, once one of the Threads attempts to join with the other, you will wait forever. You don't actually even need the synchronized block to create the deadlock condition--if you remove it, then each Thread will get to the join statement and then wait forever for the other Thread to complete.

I'm not clear what the goal of your code is once it actually does something, but join() is typically used when you want a Thread to complete before something else happens. So you would put the join outside the run method:

If you want two run() methods to be cooperating (for instance a Thread that gets user input and a Thread that processes it), you should use wait() and notify() to allow one to wait on the other while both are still active.
It is entirely possible that I am missing something. Can you tell me where the variable s in the 5th line of the code sample
is declared?

I agree that not using the parameter t will not cause a problem. I just noted that as it seemed possible that it might point to an error in transcription.
Recheck your code. The variable s in the addandDisp() method is undeclared. In addition, the parameter t is unused.
To override a method, the arguments must not change. Passing an argument which is a subtype is still a change in the argument. Therefore what you have is a case of overloading--NOT overriding. Which overloaded method is called is, as you point out, determined by the compiler at compile time. There is no overriding going on for the JVM to go picking a different method at run time.
The enhanced for loop is in the form of
for( declaration : expression ) { }
declaration declares a new variable (which typically will be used in the for loop)
expression must evaluate to an array of the type of the variable declared in declaration

In your first example, n is declared as a single dimensional array and the expression is a two dimensional array--which is an array of single dimensional arrays--so this meets the enhanced for loop specification.

In the second example, the expression "i[2]" is a single dimensional int array and n2 is an int, so again you are fine as far as the compiler is concerned. You will however get a runtime exception (ArrayIndexOutOfBoundsException) since i is only of length 2 (contains 2 int arrays) and therefore the maximum array index is 1.
Yay Mario--first post!

If you look at the section entitled parseXxx() and valueOf() 2 pages before the table it shows some more examples of using parseXxx with a radix and also mentions throwing a NumberFormatException if the String argument is not properly formed. The String is not a properly formed number if it contains any character that does not comprise a number of the specified radix (or a decimal--base 10--number is no radix is specified). So a string containing the letter "z" would always cause the exception, and a string with a "3" would cause the exception if the radix were 2 since binary numbers contain only "0" and "1".
Hmmm...well technically the statement is true because it is true in some cases, but you are right--it is poorly worded. Trying to apply a programmer's need for precision to the English language is always fraught with peril.
The wrapper classes are listed across the top of the table. Each column shows whether that wrapper has the methods listed down the left side of the table. The parseXxx methods refer to the static methods which convert a String to a the primitive type associated with that wrapper. The Xxx is the primitive type that is returned (only capitalized to fit the Java naming conventions). If you are looking at the Float column, the method would be parseFloat(); If you are looking at the Integer column, the method would be parseInt(). If the wrapper has that method, there will be an "X" in the appropriate row for that column. So if you look at the row for the method doubleValue(), you will see that the Boolean wrapper class does not have that method, but the Byte wrapper class does.

[As an aside, the Java 6 version of K&B is out and has sufficient revisions to make the page numbers different. It would be helpful to note which edition of the book you are referencing.]
Compile time errors are a completely different beast. If your code won't compile, you can't run it so you will never get any exceptions of any sort.

The Errors and Exceptions referred to in that table are all run time events. In some cases they may be the result of faulty program logic, but the code must have compiled to get you that far.

In your every day coding, Exceptions thrown programmatically are typically the ones you will need to handle. However in the case of the table you referenced, all of the Exceptions are RuntimeExceptions and therefore none of them need to be checked. Errors do not need to be checked either, so nothing in the table is subject to the "handle or declare" rule.

So in the case of the table, the distinction between what is thrown programmatically and what is thrown by the JVM can only be stated as specifically as the section on page 367 (K&B Java 5) called "Where Exceptions Come From". The distinction is in the words "thrown explicitly" in the description of programmatic exceptions. This means that somewhere in your Java code or in the Java code that you are calling (including the code in the Java API) there is actually a line of code that says "throw Xxx", where Xxx is the Exception listed in the left column of the table.

[As an aside, the Java 6 version of K&B is out and has sufficient revisions to make the page numbers different. It would be helpful to note which edition of the book you are referencing.]
To invoke the long method:


There is no short-cut for byte equivalent to the L notation. To invoke the byte method you will have to explicitly cast the parameters:

[I assume you are referring to int (the primitive type) and not Integer (the wrapper object. In that case...]

An int variable, holds the actual int value, not a reference to an object on the heap. In the examples above, the int is equivalent to the object reference, not the object itself. So just as the bit pattern representing the object reference changed when you assigned a reference to a new string, the bit pattern representing the int value changes when you assign a different int value to the variable.
You are trying to apply the statement ("It is legal to omit either the catch clause or the finally clause, but not both.") to a different context from the one in which it is intended. If you have a try clause, you must have either a catch, or a finally clause, or both. That is necessary, but not sufficient to make the compiler happy. (The compiler is only happy if you obey all its rules, not just one of them.) You must still follow the "catch or declare" rules for checked exceptions.