Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Java Puzzlers OOP 2009 Optional Tirgul #2 Josh Bloch & Neal Gafter http://www.javapuzzlers.com http://video.google.com/videoplay?docid=9214177555401838409 What are puzzlers? • Short Java programs • They appear simple, but it is hard to guess what the outcome of the program is: – some do not compile – some throw exception when executed – some hang – some print incorrect result – some have varying or unpredictable output Example: Oddity public static boolean isOdd(int i) { return i % 2 == 1; } Method result is: 1. true all the time 2. false all the time 3. true half the time, false half the time 4. true quarter of the times Example: Oddity public static boolean isOdd(int i) { return i % 2 == 1; } Method result is: 1. true all the time 2. false all the time 3. true half the time, false half the time 4. true quarter of the times Example: Oddity public static boolean isOdd(int i) { return i % 2 == 1; } Method result is: true quarter of the times – half of integers are negative, for all negative integers i % 2 returns -1, therefore isOdd returns false. To fix the problem, return i % 2 != 0 Time For A Change public class Change { public static void main(String args[]) { System.out.println(2.00 - 1.10); } } What is the outcome? 1. prints 0.9 2. prints 0.90 3. prints 0.9000000000000000 4. prints something else In The Loop public class InTheLoop { public static final int END = Integer.MAX_VALUE; public static final int START = END - 100; public static void main(String[] args) { int count = 0; for (int i = START; i <= END; i++) count++; System.out.println(count); What is the outcome? } 1. prints 100 } 2. prints 101 3. prints nothing 4. throws an exception Real life bug public class IdGenerator { public synchronized long getNewAndReserve(int interval) { long value; if (low + interval >= MAX_VALUE) { high = getNewHighValue(); low = 0; } value = getNewId(high, low); low += interval; return value; } } A Strange Saga of Suspicious Sort public class SuspiciousSort { public static void main(…) { Random rnd = new Random(); Integer[] arr = new Integer[100]; for (int i = 0; i < arr.length; i++) arr[i] = rnd.nextInt(); Comparator<Integer> cmp = new Comparator<Integer>() { public int compare( Integer i1, Integer i2) { return i2 - i1; } What is the outcome? }; 1. arr is always entirely sorted Arrays.sort(arr, cmp); 2. arr is usually entirely sorted } 3. arr usually not entirely sorted 4. throws an exception Real life bug public class Node implements Comparable { private long id; … public int compareTo(Object obj) { if (obj instanceof Node) { Node tmp = (Node) obj; return (int)(id - tmp.id); } return -1; } What is the outcome } of new Node(12884902889L).compareTo( new Node(4294968297L ) ) (1) 1 (2) 0 (3) -1 (4) other News: nearly all binary searches and merge-sorts are broken (2006) int mid =(low + high) / 2; The sum overflows to a negative value, and the value stays negative when divided by two. This bug can manifest itself for arrays whose length (in elements) is 230 or greater (roughly a billion elements). http://googleresearch.blogspot.com/2006/06/e xtra-extra-read-all-about-it-nearly.html Null and Void public class Null { public static void greet() { System.out.println("Hello world!"); } public static void main(String[] args) { ((Null) null).greet(); } } What is the outcome? 1. 2. 3. 4. Prints “Hello World” Does not compile NullPointerException Something else Confusing constructor public class Confusing { private Confusing(Object o) { System.out.println("Object"); } private Confusing(double[] d) { System.out.println(“Double array"); } public static void main(…) { What is the outcome? new Confusing(null); 1. Object } 2. Double array } 3. Does not compile 4. NullPointerException What’s The Point class Point { protected final int x, y; private final String name; public Point(int x, int y) { this.x = x; this.y = y; name = makeName(); } protected String makeName() { return "[" + x + "," + y + "]"; } public final String toString() { return name; } } public class ColorPoint extends Point { private final String color; public ColorPoint(int x, int y, String color) { super(x, y); this.color = color; } protected String makeName() { return super.makeName() + ":" + color; } public static void main(String[] args) { System.out.println(new ColorPoint(4, 2, "purple")); } } What is the outcome? 1. [4,2]:purple 2. [4,2] 3. Something else Indecision public class Indecisive { public static void main(String[] args) { System.out.println(decision()); } static boolean decision() { try { return true; What is the outcome? } finally { return false; 1. prints true } } 3. does not compile } 2. prints false 4. throws an exception Hello, Goodbye public class HelloGoodbye { public static void main(String[] args) { try { System.out.println("Hello world"); System.exit(0); } finally { System.out.println("Goodbye world"); } } } 1. Hello world What is the outcome? 2. Hello world Goodbye world Shades of Gray class C { String Z = "White"; 1. Prints “Black” } 2. Prints “White” class X { static class Y { 3. Does not compile static String Z = "Black"; 4. Something else } static C Y = new C(); } public class ShadesOfGray { public static void main(String[] args){ System.out.println(X.Y.Z); } } What is the outcome? It’s Absurd, It’s a Pain, It’s a Super-class public class Outer { class Inner1 extends Outer {} class Inner2 extends Inner1 {} } Why doesn’t it compile? It’s Absurd, It’s a Pain, It’s a Super-class public class Outer { class Inner1 extends Outer { public Inner1() { super(); //invokes Object() constructor } } class Inner2 extends Inner1 { public Inner2() { super(); //invokes Inner1() constructor } } } It’s Absurd, It’s a Pain, It’s a Super-class public class Outer { class Inner1 extends Outer { public Inner1() { super(); } } class Inner2 extends Inner1 { public Inner2() { this.super(); } } } Outer Inner1 Inner2 It’s Absurd, It’s a Pain, It’s a Super-class public class Outer { class Inner1 extends Outer { public Inner1() { super(); } } class Inner2 extends Inner1 { public Inner2() { Outer.this.super(); } } } It’s Absurd, It’s a Pain, It’s a Super-class More on that: • Scope ambiguities between outer and super • On the Interaction of Method Lookup and Scope with Inheritance and Nesting (pdf) The Moral • Careful design is great. • Testing is great. • Formal methods are great. • Code reviews are great. • Static analysis is great. But none of these things alone are sufficient to eliminate bugs: they will always be with us. We must program carefully, defensively, and remain ever vigilant. Josh Bloch