Title: Java Gotcha's
1Java Gotcha's
- Most of these examples are from this book
- Java Puzzlers Traps, Pitfalls, and Corner Cases
Author(s) Joshua Bloch and Neal Gafter
Publisher Addison Wesley Professional Date 24
June 2005
2- Every programming language has its quirks.
- Are you a code sleuth?
- Have you ever spent days chasing a bug caused by
a trap or pitfall in Java or its libraries? - Here are some diabolical puzzles
3Oddity
- // Does this method return true if n is odd?
- public boolean isOdd(int n)
- return n 2 1
-
4Ö
- Yes, but it's wrong when n is negative
- // Try this
- return n 2 ! 0
- // or bitmask with and operation '' (faster)
- return (n 1) ! 0
- // n 1 ands the rightmost bit with 1
- // if n 25, n 1 is
- // 00011001 00000001 00000001
- // Expression is 0 unless n is odd
- // if n 24, n 1 is
- // 00011000 00000001 00000000
5Simple Arithmetic
- _at_Test
- public void simpleArithmetic()
- // Does this assertion pass?
- assertEquals(444, 123 32l)
-
6Ö
- Eyes Deceive
- It is 123 32L, which is 155
- Use L instead of l for Long
7The laughs are on me
- _at_Test
- public void simpleChars()
- // Which, if any, of these 2 assertion pass?
- assertEquals("Ha", "H" "a") // a.
- assertEquals("Ha", 'H' 'a') // b.
-
8Ö
- Answer
- Only a.
- java.lang.AssertionError
- expectedltHagt but waslt169gt
-
9String constants interned
- _at_Test
- public void stringIntern()
- String pig "length 10"
- String dog "length " pig.length()
- // Which, if any, of these 2 assertion pass?
- assertEquals("Animals equal false",
- "Animals equal " pig dog)
- assertEquals("Animals equal true",
- "Animals equal " pig dog)
10Ö
- Neither
- goes before the actual value is
- ("Animals equal " pig) dog
11To intern or not to intern
- _at_Test
- public void testIntegerInterns()
- Integer a -128
- Integer b -128
- Integer c 127
- Integer d 127
- Integer e 345
- Integer f 345
- // 1. Which, if any, of these assertions fail?
- assertTrue(a b) // a.
- assertTrue(c d) // b.
- assertTrue(e f) // c.
12Ö
- java.sun.com/docs/books/jls/download/langspec-3.0.
pdf explicitly states that wrappers for values in
the range -128 to 127 will be interned by any
JVM.
13Are Doubles interned?
- _at_Test
- public void testEqualEquals()
- Double a 4.2
- Double b 4.2
- // 2. Which, if any, of these assertions
fail? - assertTrue(a gt b) // a.
- assertTrue(a lt b) // b.
- assertTrue(a.equals(b)) // c.
- assertTrue(a b) // d.
- assertTrue(a.compareTo(b) 0) // e.
- assertTrue(a.compareTo(4.2) 0) // f.
-
14Ö
- assertTrue(a b) // d. Does not pass
- The compares reference values, not the numeric
values
15Transitivity, what Transitivity?
- _at_Test
- public void testTransitivity()
- double a 4.2
- Double b a
- Double c a
- // 2. Which, if any, of these assertions fail?
- assertTrue(b a) // a.
- assertTrue(c a) // b.
- assertTrue(b c) // c.
16Ö
- Consistent?
- // Which, if any, of these lines does not compile
- int n2 0 // a.
- double x 0 // b.
- Integer n 0 // c.
- Double x 0 // d.
17Output from this program?
- \u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0020\u
0020\u0020 - \u0063\u006c\u0061\u0073\u0073\u0020\u0055\u0067\u
006c\u0079 - \u007b\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u
0020\u0020 - \u0020\u0020\u0020\u0020\u0073\u0074\u0061\u0074\u
0069\u0063 - \u0076\u006f\u0069\u0064\u0020\u006d\u0061\u0069\u
006e\u0028 - \u0053\u0074\u0072\u0069\u006e\u0067\u005b\u005d\u
0020\u0020 - \u0020\u0020\u0020\u0020\u0061\u0072\u0067\u0073\u
0029\u007b - \u0053\u0079\u0073\u0074\u0065\u006d\u002e\u006f\u
0075\u0074 - \u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e\u
0028\u0020 - \u0022\u0048\u0065\u006c\u006c\u006f\u0020\u0077\u
0022\u002b - \u0022\u006f\u0072\u006c\u0064\u0022\u0029\u003b\u
007d\u007d
18Ö
- Answer
- Hello World
- \u0070 in hexadecimal is 112 in decimal or the
character 'c' - Unicode not readable
- Suggest avoid Unicode unless you need it
- System.out.println("\u20ac" 123.45)
- 123.45
19 assertEquals('_at_', '\u0040') assertEquals('A',
'\u0041') assertEquals('B', '\u0042')
assertEquals('', '\u0060') assertEquals('a',
'\u0061') assertEquals('b', '\u0062')
assertEquals('', '\u20ac')
20What's the Output
- package edu.arizona.cs335
- public class WhatsUp
- public static void main(String args)
- System.out.println(WhatsUp.class.getName())
- System.out.println(
- WhatsUp.class.getName().replaceAll(".",
- "/") ".class")
-
-
- edu.arizona.cs335.WhatsUp.class
- What is output from 2nd println?
21Ö
- Answer
- /////////////////////////.class
- The first argument to replace all is a regular
expression - Try this instead
- replaceAll("\\.", "/")
- edu/arizona/cs335/WhatsUp.class
22A little regex
- Pattern p Pattern.compile(".....") // 5 of any
- Matcher m p.matcher("A string to look at.")
- m.find()
- assertEquals("A str", m.group())
-
- p Pattern.compile("1-9") // the first digit
- m p.matcher("first 2nd 3rd")
- m.find()
- assertEquals("2", m.group())
23Is true true?
- _at_Test
- public void trueOr()
- // Does this assertion pass?
- assertEquals("Compare 5 to 4", "true", 5 gt 4)
-
24Ö
- Answer
- No
- "true" is not true
- JUnit show this
- java.lang.AssertionError
- Compare 5 to 4 expectedlttruegt but waslttruegt
25Output?
- _at_Test
- public void simpleChars()
- int choice 2
- switch (choice)
- case 1
- System.out.println("one")
- case 2
- System.out.println("two")
- case 3
- System.out.println("three")
-
-
26Ö
- two
- three
- Add breaks
- int choice 2
- switch (choice)
- case 1
- System.out.println("one")
- break
- case 2
- System.out.println("two")
- break
- case 3
- System.out.println("three")
- break
-
27Java plus plus
- _at_Test
- public void simpleChars()
- int j 0
- for (int i 0 i lt 10 i)
- j j
- // Does this assertion pass
- assertEquals(10, j)
-
28Ö
- Answer No
- j j is postfix increment operator
- When you use a postfix operator as part of a
larger expression, the expression's value is
returned before the postfix operator is processed - Use j
29Output?
- int j 0
- int k 0
- System.out.println(j) //? _____
- System.out.println(k) //? _____
- System.out.println(j) //? _____
- int x 1, 2, 3
- int i 0
- System.out.println(i " " xi) //? _____
- System.out.println(i " " xi) //? _____
30Output?
- public class PuzzlersTrapsPitfallsCornerCases
- public static final int END
Integer.MAX_VALUE - public static final int START END - 100
- _at_Test
- public void simpleChars()
- int count 0
- for (int i START i lt END i)
- count
- System.out.println(count)
-
31Ö
- Answer No output
- Even with wraparound
- It never ends
- Frustrated?
- "I laughed, I cried, I threw up (my hands in
admiration)." - Tim Peierls, president, Prior Artisans LLC, and
member of the JSR 166 Expert Group How well do
you really know Java?
32Is there any Output?
- public class Huh
- public static void main(String args)
- new B()
-
-
- public class B
- int j
- String s
-
-
- System.out.println("Hello world " j " "
s) -
33Ö
- Answer Yes
- Hello world 0 null
- This is an initializer, a method with no heading
-
34Add to 0 three times
- _at_Test
- public void testBigInt()
- BigInteger five new BigInteger("5")
- BigInteger fifty new BigInteger("50")
- BigInteger fiveHundred new
BigInteger("500") - BigInteger total BigInteger.ZERO
- total.add(five)
- total.add(fifty)
- total.add(fiveHundred)
- // Does this assertion pass?
- assertEquals(555, total)
-
35Ö
- No
- BigInteger, like String is immutable
- This will pass
- BigInteger total BigInteger.ZERO
- total total.add(five)
- total total.add(fifty)
- total total.add(fiveHundred)
- // Does this assertion pass
- assertEquals(555, total)
36No Warning
- _at_Test
- public void testHashMap()
- HashMapltString, BigIntegergt hm
- new HashMapltString,
BigIntegergt() - hm.put("a", new BigInteger("123456"))
- hm.put("b", new BigInteger("1234567"))
- hm.put("c", new BigInteger("1234567"))
- hm.put("a", new BigInteger("654321"))
- BigInteger aBigInt hm.get("a")
- // Does this assertion pass?
- assertEquals(123456, aBigInt.intValue())
-
37Ö
- No, the first mapping was destroyed
- // Return old value null if there was a mapping
- hm.put("a", new BigInteger("123456"))
- BigInteger bi hm.put("a", new
BigInteger("9999")) - int actual bi.intValue()
- assertFalse(9999 actual)
- // Return null if there was no mapping with the
key - BigInteger bi2 hm.put("key", new
BigInteger("123")) - assertNull(bi2)
38Which is/are valid classes
- // in E.java
- public class E
- private class F
-
-
- // in A.java
- public class A
-
- // in B.java
- public static class B
-
- // in C.java
- public class C
- private static class D
-
39Ö
- A
- C and D
- E and F
- For B, you get this error because the top level
class in a file can not be static - Illegal modifier for the class B only public,
abstract final are permitted
40Which is/are valid classes?
- // in C.java
- public class C
- int n 0
- private class D
- public D()
- n
-
-
-
- // in C.java
- public class C
- int n 0
- private static class D
- public D()
- n
-
-
-
41Ö
- The right column
- The left column has an error at n
- Cannot make a static reference to the non-static
field n
42Output
- int n 0
- try
- n n / 0
- catch (Exception e)
- System.out.println("A")
- finally
- System.out.println("B")
-
- System.out.println("C")
43Ö
44Output
- int n 0
- try
- n n / 999
- catch (Exception e)
- System.out.println("A")
- finally
- System.out.println("B")
-
- System.out.println("C")
45Ö
46Output
- int n 0
- try
- n n / 999
- catch (Exception e)
- System.out.println("A")
- System.exit(0)
- finally
- System.out.println("B")
-
- System.out.println("C")
47Ö
48Output
- int n 0
- try
- n n / 0
- catch (Exception e)
- System.out.println("A")
- System.exit(0)
- finally
- System.out.println("B")
-
- System.out.println("C")
49Ö