Java Puzzle 6: Chicken or the Egg - Solution
Mar 26, 2012Here's the solution to the Chicken or the Egg puzzle.
The constructor of Egg
throws a NullPointerException
if it's not given a (non-null) Chicken
, and vice versa for the Chicken
constructor. So how can you get a reference to either of them?
A common flaw that makes this possible (and even happen by accident) is calling a method that can be overridden in a subclass from a constructor. But that's not the case here. There's one method you can override that the constructor doesn't call, but Java calls eventually: finalize()
. That method is called before an object is garbage collected, to give it a chance to clean up its resources. It is called even if the constructor threw an exception, so by overriding it we can get a reference to an egg that wasn't fully created.
It's well known that the finalization mechanism has several problems, and there are better alternatives. There are multiple ways to defend against this listed on the this secure coding standard for Java. Another way is to throw the exception before calling the constructor from the Object
class. That means doing the work before calling super()
(or another constructor with this()
). Since Java 6, this guarantees that finalize()
won't be called. For example here we dereference mom.first
before calling this(Object)
to ensure you cannot create an egg without a mommy:
Congrats to the 17 people who found it. Matt Nathan was the first but it's still a mystery if he's a chicken, an egg or a null
.
P.S.: The puzzles are taking a short vacation. They'll continue in a few weeks.
18 comments
Nice one. Finally i figured out one ;-)
“First there was the null” :-)
Reason (and description how it works): https://www.securecoding.cert.org/confluence/display/java/OBJ11-J.+Be+wary+of+letting+constructors+throw+exceptions
My solution
BTW I’m really curious how Java8 (in case the standard annotations from the Checker framework will make it into javac this time…) will handle the case if you declare first to be @NonNull and perform such a stunt. Probably the nullness checks will only be performed at compilation time, just like Generics.
Easy peasy
The first Chicken was a Zombie…
Resurection is mainstream ;)
As the creator, we can create the chicken without the egg. But what was first remains unclear…
Cool puzzle :)
Thanks for this. Was aware of this from a banking project.
Here’s the code for a Creator class that does the job:
Easy:
Please dont take vacation. Publish more puzzles. They are awesome