Frank Callahan

+ Follow
since Dec 30, 2010
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 Frank Callahan

Bit shifting does have it's place in fast numerical processing, but honestly, I've never had much occasion to use bitwise operations in the fifteen years I've been a business software developer. However, questions about converting primitive types in assignment statements are still fair game on the test, and the char to short, short to char assignments seem to be a potential gotcha. You can't assign either to the other without an explicit cast.
With char and short primitives, the thing to keep in mind is that neither can be assigned to the other without a cast. They are both 16 bit integer types, but their ranges overlap but do not coincide. char ranges from 0 to 65535, and short from −32768 to 32767. There are 65536 values in each type's range, including zero, but the two ranges only overlap from 0 to 32767.

As mentioned above, K&B pp. 50-51 go into some more detail.
Thanks to everyone who has participated in this thread for a very enjoyable and helpful learning experience. I'm taking the OCPJP 6 exam tomorrow afternoon, and being part of this exchange has gotten me psyched! Now I'm going to spend the rest of the morning doing the last of the 'Unlearned' Enthuware questions that I missed while taking the mock exams. Then tomorrow morning I'm going to review the APIs as a final prep for the test; I keep forgetting that String has no reverse() method...

Just to wrap up what this discussion has clarified about the access privileges of static inner classes, here's a sample program I put together:

The Outer Class, with a Non-Static and a Static Inner Class

Some code to exercise the above:

The Output:

One Outer Instance: I'm trying to hide, but can't hide from the inner non-static class!
Another Outer Instance: I'm trying to hide, but can't hide from the inner non-static class!
One Outer Instance: I'm trying to hide, but can't hide from the inner static class!
Another Outer Instance: I'm trying to hide, but can't hide from the inner static class!

The K&B book's section on static nested classes describes them as follows:

"You’ll sometimes hear static nested classes referred to as static inner classes, but they really aren’t inner classes at all, by the standard definition of an inner class. While an inner class (regardless of the flavor) enjoys that special relationship with the outer class (or rather the instances of the two classes share a relationship), a static nested class does not. It is simply a non-inner (also called “top-level”) class scoped within another. " (p. 680)

To me, the visibility to static inner classes of other private nested classes declared inside the same outer class scope is a major distinction between regular "top-level" classes and static inner classes. Saying that they are not really inner classes seems wrong to me at this point, since they share the major advantage of non-static inner classes -- access to everything declared in the enclosing class regardless of access modifiers. Of course, the static inner class can't see instance variables directly, since it is static, but it can declare a reference to the outer class and access private members of the outer class that way, and can declare references to private classes declared inside the outer class and access their private members.

I don't know how useful static inner classes are in a practical sense, but they do seem to be full fledged inner classes.
So. static inner classes are not just the same as top level classes. They have full access to all the members of the enclosing class.
Maybe I have this one figured out... Here's some code that does not compile, that moves the Parent class outside PrivateTest:

The rule seems to be that any member of any nested class is visible to any other nested class within the same enclosing class.

Update - Makes sense now, as Ankit explained above. Thanks Malte!

Another Update - code as originally copied would not compile due to two public classes in a file. Fixed that.
Hi Malte,
Just tried on Windows XP, and it works both in Eclipse and on command line:

D:\projects\scjp>java -version
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing)

D:\projects\scjp>java -cp bin PrivateTest$Child

Generally I work on an Ubuntu box, and that is where I can't get the code to run from the command line. So it looks like there is an issue with the 1.6.0_23-b05 JRE build for Linux, not some deeper issue that might show up on the exam.
Right, the real puzzle here is why the private instance method go() is visible through the Parent p reference declared in the Child main method. I understand that static methods can't be overridden so this might make sense if go was static (ignoring that it's private). Do all methods of static inner classes behave as if they are static? And why is the access modifier ignored? Very confusing.
Hi Malte,
Does it run from the command line, or in Eclipse or some other IDE? If on the command line, could you provide the details, including the java version and what you typed in?
java PrivateTest$Child ought to work on the command line but doesn't, and "Exception in thread "main" java.lang.NoSuchMethodError: main" is what I get too. It does run in Eclipse though... In Thinking In Java, pp. 292-293, (1998 edition, the copy I have), Bruce Eckel suggests that main methods declared inside static inner classes can be a good way to include unit tests inside the source code of a top level class so that you can discard the static test class' .class file when you ship the code. He says that the correct command line syntax would be similar to what we've tried (java TestBed$Tester). So, it looks like there could be an actual practical use of the static inner class main method, although you'd probably want to use jUnit these days. Oddly, if you add a main method to the enclosing class, the command line will result in that main being run instead of the Child main, without NoSuchMethodError:

Compile command: javac -d classes src/misc/
Command line: java -cp classes misc.PrivateTest$Child
Output: In top main
java -version
java version "1.6.0_23"
Java(TM) SE Runtime Environment (build 1.6.0_23-b05)
Java HotSpot(TM) Server VM (build 19.0-b09, mixed mode)

I've set the same JDK as the default JRE in Eclipse, and there, the code runs as expected and prints Parent. I've been looking for an Eclipse feature that would generate a correct command line, but can't find one. This is frustrating for sure, but I don't think it will come up on the OCPJP exam when I take it this coming Monday. Hope so anyhow
Hi Abhisek,
When I saw your question (first part) I was puzzled too, and added some code to help me figure it out:

Here's the output I got when I ran it:

Created an A: A@12dacd1 Instance 1
Created a B: B@10385c1 Instance 1
set this.a: A@12dacd1
set this.b: B@10385c1
set aa to: A@12dacd1
Is aa == aa.b.a? true
set aa to null.
Nudged garbage collector.
Finalizing a B B@10385c1
Finalizing an A A@12dacd1

You can see that only 1 instance of A and 1 instance of B were instantiated, so there are only two objects to garbage collect after the aa reference to the instance of A is set to null in the GCTest main() method. When the A() constructor is called, it passes a reference to itself to the B(A a) constructor (this.b = new B(this);) and then the B constructor sets its internal A reference to point to the same object as the aa reference in the GCTest main method. So, before aa is set to null there is 1 A object with two references and 1 B object with 1 reference. From the output from the A and B finalizers, you can see that just 2 objects end up being gc'd.

Happy New Year and Regards,
Hi Darren,
Thanks for the encouragement, sometimes I need the help maintaining my morale. As soon as I've passed the test, I'm going to start a serious job hunt. If nothing else, I think that going through this OCPJP experience will get me past a few tech screen interviews. All this intensive review of the basics, and especially of the new generics stuff, has definitely honed my coding skills.

For example, I now know a "stupid Java trick" that allows me to run a class from a java command line without writing a main() method. Just write a call to a static method that kicks off the program inside a static initializer block. The class loader will find the class and run the static initializer before attempting to run the missing main method. You'll get a "NoSuchMethodError", but the program will run anyhow. Here's some code that demonstrates that:

On the topic of access to more books to help prepare for the test, and more than that, get a deeper understanding of Java, you can get a subscription to Safari Books Online for $23 a month for 10 book access, and $43 for unlimited access. I used to get a free subscription from work, but I got an individual subscription right after the layoff so that I could keep my bookworm habit going. The best thing is, you can search the entire library of more than 10,000 titles for just the information that you need, so you don't have to buy a $60 book and then find out that only a chapter or two turns out to be useful, or maybe even that the book is totally worthless. Here's a link:
"Memorizing a lot of the little rules of what you can and can't do" goes beyond challenging, it's a major pain in the butt . I'm used to Eclipse or RAD taking care of all that stuff and concentrating on getting the business requirements right instead of trying to be a human compiler. But, I guess that's what you have to put up with to pass the test... As far as the rule that you mentioned goes, that "you can't have a static methods in an abstract class", that's actually not the case. Here's an example that compiles and runs, showing that an abstract class can have a static method:

From what I've been able to get through my head, an abstract class can have anything that a concrete class can have, but it cannot be instantiated with the "new" operator, and of course, it can't be made final. If you wanted to do something totally warped, you could even declare a bunch of final public static constants in an abstract class and use the abstract class like an interface.

Well, that's it for now. I hope you're having a happy New Year's day, and that the year will bring good things and prosperity to all of us laboring, or hoping to go back to laboring, in the IT vineyard. May there be better times ahead for us all!



Hi Darren,

My situation is similar to yours. As the saying goes, I don't just feel your pain, I feel your pain. Back in October my job was "eliminated", along with the jobs of several hundred other highly experienced software engineers, architects, and project managers. I have about 11 years developing server side software in Java, 5 years before that working in C, C++, and Unix shell scripting, and have a long track record of accomplishments and successes to my name. Shortly after the axe fell, I decided to use some of my suddenly ample free time to prepare for the SCJP test that I'd never been able to get around to while I was working full time.

Initially, I thought that a fairly casual brushing up of my knowledge of basic Java SE would be enough for me to do well on the real exam, but the difficulty of passing, much less getting a high score on the mock exams, soon humbled me. My first mock exam scores left me bruised and frustrated, but determined to press on. Like you, my days now revolve around working through the K&B book yet another time, reading and rereading chapters of Mughal and Rasmussens's Programmer's Guide to the SCJP, and getting beat up by the Enthuware mock exam software, and by the truly brutal OCP Java SE 6 Programmer Practice Exams book by Bert Bates and Kathy Sierra. To supplement all that, I've spent a lot of time with the API javadocs, the Java Language specs, and also Oaks and Wong's Java Threads, Third Edition, and Naftalin and Wadler's Java Generics and Collections. On top of that, I've written many, many small programs to test and improve my understanding. Based on my recent mock exam scores, ranging from the high 80s to the mid 90s, all this work finally seems to be paying off... Of course, I won't know for sure until I take the actual OCPJP 6 exam, which I plan to do next week.

It seems to me that you are already doing what you need to do to prepare for the certification exam. One thing that I've learned from taking the mock exams that has helped me do better on them is that there are two basic ways that I can miss a question. First, I just don't know the answer. For that, the remedy is more studying and coding. Second, I fall for one of the misdirection traps designed to divert my attention away from the right answer that I do know, but don't see. For that, you need to analyze the wording of the questions that fooled you, make note of the deceptive patterns, and then take more mock exams armed with greater awareness of potential traps.

Just as one example of what I'm talking about, I recently missed a question where a List was loaded with superclass references to instances of the superclass itself and of subclasses, all of which had static methods with the same signatures. Then, the list was run through a foreach loop. Immediately, I thought that the output would be from the superclass version of the method, knowing that static methods cannot be overridden, and thinking that each iteration of the loop was invoking the superclass static method through a superclass reference. What I missed was that the actual method call was to the static method of the subclass that contained the main method being executed, like this:

My misbehaving brain rendered this as:

It's kind of like that old visual perception trick where "Paris in the the spring" is printed in a triangle and almost everyone who hasn't seen it before sees "Paris in the spring." The good news is that now that I'm aware of this particular mean trick, I probably won't fall for it if it comes up in the real exam. The bad news is that this is just one of the many mean tricks that the test designers have up their sleeves. So all you can do is take a lot of mock exams, learn as many of the misdirection patterns as you can, and try really hard to read the question that is there instead of the question that is not there that the wording intentionally misleads you to see.

I hope this helps, and please wish me luck, as I wish you,


Hmm, it looks like the Kindle version is different from the printed book. I typed in the exact code from the book. What explanation does the Kindle version give for -1 being the right answer?

Update - has a review of the Kindle version that explains what is going on:

This review is from: OCP Java SE 6 Programmer Practice Exams (Exam 310-065) (Kindle Edition)
I love the quality of McGraw Hills books and specially the ones to prepare the Java Certify exams. I'm also a Kindle user with very good experiences reading books in Kindle versions.

But this one is completely useless. As you may know, Kindle books are actually a kind of HTML code (with labels like: '<'html'>', '<'body'>', '<'p'>', etc.). Well, Java ALSO use these kind of labels for its GENERIC parameters, so when you open this book in Kindle version you lose every generic argument (and there are a lot of them in the exams) because the book reader thinks they are HTML labels and don't show them.
This problem also affects to EVERY comparation expression which uses the characters ">" or "<" or ">=" or "<="...

Hi Chandramohan,

Question 39 in the first exam in the OCPJP practice exam (page 77) reads as follows, at least in my copy:

The code does compile, and the output is -1, which is the correct answer as stated on page 121. There's some misdirection in the question that could lead you to answer as if the binary search had been made in a String[] sorted in reverse, i.e, [vail,t-ride,dillon,aspen], making C. 2 the right answer. But as the book explains, answer A. -1 is the most likely output, since the binarySearch method that is called is the two param version without a Comparator ref as the third param. Strictly speaking though, even if -1 is the actual output from the Oracle/Sun jdk1.6.0_23 version that I'm using, the javadocs for the java.util.Arrays class say that the result of a binary search in an unsorted (or not sorted in the natural ordering of the class) array is undefined:

public static int binarySearch(Object[] a, Object key)

Searches the specified array for the specified object using the binary search algorithm. The array must be sorted into ascending order according to the natural ordering of its elements (as by the sort(Object[]) method) prior to making this call. If it is not sorted, the results are undefined....

So, there is a conflict between the documentation and the observed behavior of the Arrays class, which may reliably produce a -1 index from running this code, but by the docs, could output any number at all, that is, the expected output is undefined. Use of the word likely in question 39 may be a way of getting at your experience of using binarySearch(), and not of just being familiar with the documentation. However, the question is kind of unfair in that if the word likely was removed, A, B, C and D could all be correct.