←Older revision |
Revision as of 19:21, 3 March 2011 |
Line 1: |
Line 1: |
| [[Ostrava]] is 3rd largest town in Czech Republic. I'll be in [[wikipedia:Ostrava|Ostrava]] at [http://java.cz/article/czjug-ostrava-brezen-2011 JUG meeting] on Mar 2nd, 2011. I'll talk about [[paradox]]es, in a shorter version of the [[ParadoxesVideo]]. Stop by and get a chance to win [[TheAPIBook]]. I am not sure what will be the final quiz to win [[TheAPIBook]], but I'd suggest following one: Can you write a code that throw ''NullPointerException'' directly from the following ''Interval'' class? | | [[Ostrava]] is 3rd largest town in Czech Republic. I'll be in [[wikipedia:Ostrava|Ostrava]] at [http://java.cz/article/czjug-ostrava-brezen-2011 JUG meeting] on Mar 2nd, 2011. I'll talk about [[paradox]]es, in a shorter version of the [[ParadoxesVideo]]. Stop by and get a chance to win [[TheAPIBook]]. I am not sure what will be the final quiz to win [[TheAPIBook]], but I'd suggest following one: Can you write a code that throw ''NullPointerException'' directly from the following ''Interval'' class? |
| | | |
- | <source lang="java"> | + | <source lang="java" snippet="interval.api"/> |
- | /** Quiz: Anyone can come up with a JUnit test to generate
| + | |
- | * {@link NullPointerException} directly from the code of
| + | |
- | * the <code>Interval</code> class?
| + | |
- | */
| + | |
- | public final class Interval {
| + | |
- | private final Date from, to;
| + | |
- |
| + | |
- | /** Constructs interval between two dates.
| + | |
- | *
| + | |
- | * @param from the 'sooner' date
| + | |
- | * @param to the 'later' date
| + | |
- | * @throws IllegalArgumentException if <code>from</code> is not less then <code>to</code>
| + | |
- | */
| + | |
- | public Interval(Date from, Date to) {
| + | |
- | if (from == null) {
| + | |
- | throw new IllegalArgumentException("'from' cannot be null!");
| + | |
- | }
| + | |
- | if (to == null) {
| + | |
- | throw new IllegalArgumentException("'to' cannot be null!");
| + | |
- | }
| + | |
- | // shield us from Date's mutability
| + | |
- | this.from = (Date) from.clone();
| + | |
- | this.to = (Date)to.clone();
| + | |
- | if (from.compareTo(to) >= 0) {
| + | |
- | throw new IllegalArgumentException("'from' must be lower than 'to'!");
| + | |
- | }
| + | |
- | }
| + | |
- |
| + | |
- | /** The length of the interval in milliseconds
| + | |
- | *
| + | |
- | * @return amount of milliseconds between 'from' and 'to' dates.
| + | |
- | */
| + | |
- | public long getLength() {
| + | |
- | return to.getTime() - from.getTime();
| + | |
- | }
| + | |
- | }
| + | |
- | </source>
| + | |
| | | |
- | I followed all the advices of [[TheAPIBook]]. I made the class final, I check for wrong arguments. My internal state is immutable. I guard myself against mutability of ''Date''. Is it really write bullet proof code? | + | I tried to follow all the [[good]] advices of [[TheAPIBook]]. I made the class final, I check for wrong arguments. My internal state is immutable. I guard myself against mutability of ''Date''. Is it really bullet proof code? |
| + | |
| + | Indeed it is not. As about five people during my [[Paradox]]es talk in [[Ostrava]] found out (and as few of you commented online), one can subclass ''Date'' and override ''clone'' method to return '''null''': |
| + | |
| + | <source lang="java" snippet="interval.exploit"/> |
| + | |
| + | This is an interesting way to break many solid [[API]]s. The trick has been invented by the [[HPAPIFest09|HP guys]] when they played their [[HPAPIFest09]]. I am glad [[Ostrava]] discovered the magic as well. |