Java™ Puzzlers, Episode VI: The PhantomReference Menace. ttac! of the "lone. Reven#e of the $hift.

Joshua Bloch Chief Java Archi ec !oogle "nc#
Session TS-2707
2007 JavaOneSM Conference | Session TS-2707 |

William Pugh Professor $niversi % of Mar%lan&

Introduction
( )igh more Java* +la form +u,,les
( ( ( ( ( Shor +rogram -i h curious .ehavior Wha &oes i +rin / 0mul i+le choice1 The m%s er% reveale& 2o- o fi3 he +ro.lem The moral

( Covers language4 core li.raries4 an& more

2007 JavaOneSM Conference | Session TS-2707 |

'

%. &The Jo' of $ets(
public class ShortSet { public static void main(String args[]) { Set<Short> s = new HashSet<Short>(); or (short i = !; i < "!!; i##) { s$add(i); s$remove(i % "); & S'stem$out$println(s$si(e()); & &

2007 JavaOneSM Conference | Session TS-2707 |

5

)hat *oes It Print+
public class ShortSet { public static void main(String args[]) { Set<Short> s = new HashSet<Short>(); or (short i = !; i < "!!; i##) { s$add(i); s$remove(i % "); & S'stem$out$println(s$si(e()); & &

0a1 "

0.1 "!! 0c1 Thro-s e3ce+ ion 0&1 7one of he a.ove
2007 JavaOneSM Conference | Session TS-2707 | 6

ut -e.ove The set contains Short values.re removin# )nteger values 2007 JavaOneSM Conference | Session TS-2707 | 8 . .1 "!! 0c1 Thro-s e3ce+ ion 0&1 7one of he a.)hat *oes It Print+ 0a1 " 0.

++ int%valued e.pression & S'stem$out$println(s$si(e()). s$remove(i * "). & & 2007 JavaOneSM Conference | Session TS-2707 | 7 . i < "!!.nother /oo! public class ShortSet { public static void main(String args[]) { Set<Short> s = new HashSet<Short>(). or (short i = !. i##) { s$add(i).

i < "!!. public abstract boolean remove(/b0ect o).pression & S'stem$out$println(s$si(e()).nother 0nother /oo! public class ShortSet { public static void main(String args[]) { Set<Short> s = new HashSet<Short>(). i##) { s$add(i). s$remove(i * "). & & public inter ace Set<->e. ++ int%valued e. $$$ & 2007 JavaOneSM Conference | Session TS-2707 | 9 . or (short i = !.ollection<-> { public abstract boolean add(.e).tends .

& S'stem$out$println(s$si(e()).1o.*o 2ou 3i4 It+ public class ShortSet { public static void main(String args[]) { Set<Short> s = new HashSet<Short>(). i < "!!. s$remove((short) (i * ")). i##) { s$add(i). or(short i = !. & & 2007 JavaOneSM Conference | Session TS-2707 | : .

ollection$contains4 1ap$get ( "n egral ari hme ic al-a%s resul s in int or long ( Avoi& mi3ing %+es ( Avoi& short= +refer int an& long ( Arra%s of short are he onl% com+elling use case 2007 JavaOneSM Conference | Session TS-2707 | .Moral • .ollection<->$remove a<es /b0ect4 no ( Also .0 .

ception { Set<345> avorites = new HashSet<345>(). 9http:++www$google$com9. & & 2007 JavaOneSM Conference | Session TS-2707 | . or (String url7ame : 3456781-S) avorites$add(new 345(url7ame)). 9http:++apache<%snort$s='bar$dreamhost$com9. . 9http:++www$cs$umd$edu9 &.5. public class 3rlSet { private static inal String[] 3456781-S = { 9http:++0avapu((lers$com9. 9http:++0avapu((lers$com9. &More Jo' of $ets( import 0ava$net$2. S'stem$out$println( avorites$si(e()).. 9http:++ indbugs$source orge$net9. public static void main(String[] args) throws 1al ormed345-.

9http:++www$cs$umd$edu9 &.1 6 0c1 8 0&1 7one of he a.0a1 5 )hat *oes It Print+ 0. S'stem$out$println( avorites$si(e()).2 . & & 2007 JavaOneSM Conference | Session TS-2707 | . 9http:++www$google$com9.ove import 0ava$net$2. 9http:++0avapu((lers$com9. or (String url7ame : 3456781-S) avorites$add(new 345(url7ame)). public class 3rlSet { private static inal String[] 3456781-S = { 9http:++0avapu((lers$com9.ception { Set<345> avorites = new HashSet<345>(). public static void main(String[] args) throws 1al ormed345-. 9http:++apache<%snort$s='bar$dreamhost$com9. 9http:++ indbugs$source orge$net9.

s e>uals and hash.)hat *oes It Print+ 0a1 5 0 %+icall%4 assuming %ou>re on he ne 1 0.' .ode are .1 6 0c1 8 0&1 7one of he a.ro!en 2007 JavaOneSM Conference | Session TS-2707 | .ove ? i varies from run o run 345.

9http:++0avapu((lers$com9. or (String url7ame : 3456781-S) avorites$add(new 345(url7ame)).nother /oo! 6%7 import 0ava$net$2. 9http:++www$google$com9. 9http:++www$cs$umd$edu9 &. S'stem$out$println( avorites$si(e()). Identical 9http:++ indbugs$source orge$net9. & & 2007 JavaOneSM Conference | Session TS-2707 | .ception { Set<345> avorites = new HashSet<345>(). 9http:++apache<%snort$s='bar$dreamhost$com9. public class 3rlSet { $ame IP ddress private static inal String[] 3456781-S = { 9http:++0avapu((lers$com9.5 . public static void main(String[] args) throws 1al ormed345-.

Bec s are eCual if he% have he same +ro ocol4 reference eCuivalen hos s4 have he same +or num.o h hos names eCual o null# Since hos s com+arison reCuires name resolu ion4 his o+era ion is a .6 .loc<ing o+era ion# 2007 JavaOneSM Conference | Session TS-2707 | .er on he hos 4 an& he same file an& fragmen of he file# T-o hos s are consi&ere& eCuivalen if .o h hos names can .e resolve&4 he hos names mus .e eCual -i hou regar& o case= or .e resolve& in o he same "P a&&resses= else if ei her hos name canD .nother /oo! 657 8 345 *ocumentation T-o $@A o.

9http:++www$cs$umd$edu9 &.8 . 9http:++ indbugs$source orge$net9.1o. S'stem$out$println( avorites$si(e()).ception { Set<34)> avorites = new HashSet<34)>(). public class 3riSet { private static inal String[] 34)6781-S = { 9http:++0avapu((lers$com9.*o 2ou 3i4 It+ import 0ava$net$2. 9http:++www$google$com9. or (String uri7ame : 34)6781-S) avorites$add(new 34)(uri7ame)). 9http:++apache<%snort$s='bar$dreamhost$com9.-. 9http:++0avapu((lers$com9. public static void main(String[] args) throws 34)S'nta. & & 2007 JavaOneSM Conference | Session TS-2707 | .

7 .ode aren> -ell &efine& ( The% &o no o.e% heir general con rac sF ( $se 34) ins ea& ( Ma<e 345 from 34) as necessar% • e>uals shoul& no &e+en& on environmen 2007 JavaOneSM Conference | Session TS-2707 | .Moral ( Eo no use 345 as a Set elemen or 1ap <e% • e>uals an& hash.

number##. number = ".er( public class ?est e. ?hread t = new ?hread(new 4unnable() { public void run() { assert->uals(<.ase { int number. number).ception { number = !. &Rac' /ittle :um. t$0oin().9 . t$start().9. & & 2007 JavaOneSM Conference | Session TS-2707 | . public void test() throws )nterrupted-.tends 0unit$ ramewor=$?est. & &).

?hread t = new ?hread(new 4unnable() { public void run() { assert->uals(<. 0c1 " al-a%s +asses & & 0&1 " al-a%s hangs . 0.tends 0unit$ ramewor=$?est.1o. public void test() throws )nterrupted-.1 " some imes +asses number##.: 2007 JavaOneSM Conference | Session TS-2707 | . number). & &). number = ".ase { int number. t$0oin().ception { number = !. 0a1 " al-a%s fails t$start()..ften *oes This Test Pass+ public class ?est e.

ften *oes This Test Pass+ 0a1 " 0.1 " 0c1 " 0&1 " al-a%s fails some imes +asses al-a%s +asses ? .1o.t #et a chance to see -hether assertion succeeds or fails 2007 JavaOneSM Conference | Session TS-2707 | 20 .u i ells us no hing al-a%s hangs J<nit doesn..

ase { int number.ception assert->uals(<. t$start(). ?hread t = new ?hread(new 4unnable() { public void run() { ++ @3nit never sees an' thrown e.tends 0unit$ ramewor=$?est. & & 2007 JavaOneSM Conference | Session TS-2707 | 2. & &). t$0oin(). . number##. number = ". number).ception { number = !.nother /oo! public class ?est e. public void test() throws )nterrupted-.

ception e. ++ ?riggers test case ailure i an' thread asserts public void tearAown() throws -. volatile -rror error.ception.ception B= null) throw e.1o.ception { i (error B= null) throw error. & ailed 2007 JavaOneSM Conference | Session TS-2707 | 22 .ception.*o 2ou 3i4 It+ 6%7 volatile -. i (e.

& & &).*o 2ou 3i4 It+ 657 ?hread t = new ?hread(new 4unnable() { public void run() { tr' { assert->uals(<. number). 2007 JavaOneSM Conference | Session TS-2707 | 2' . & catch(-rror e) { error = e.ception = e.1o. & catch(-.ception e) { e.

Moral ( J$ni &oes no su++or concurrenc% ( Gou mus +rovi&e %our o-n ( "f %ou &on> 4 %ou>ll ge a false sense of securi % ( Also see TS-2220 Tes ing Concurren Sof -are ( Eescri.frame-or< o .H'0 PM?2H'0 PM 2007 JavaOneSM Conference | Session TS-2707 | 25 .es ne.e er han&le his si ua ion ( Thurs&a%4 .

inal Eoolean lives() { return alive. private -lvis() { & private static private public inal Eoolean 5)D)7F = true. &Elvis /ives #ain( public class -lvis { ++ Singleton pattern: thereCs onl' one -lvis public static inal -lvis -5D)S = new -lvis(). & & 2007 JavaOneSM Conference | Session TS-2707 | 26 . & public static void main(String[] args) { S'stem$out$println(-5D)S$lives() G 9Hound Aog9 : 9Heartbrea= Hotel9).=. inal Eoolean alive = 5)D)7F.

inal Eoolean alive = 5)D)7F. & & 2007 JavaOneSM Conference | Session TS-2707 | 28 .)hat *oes It Print+ 0a1 Hound Aog 0. inal Eoolean lives() { return alive.1 Heartbrea= Hotel 0c1 " varies 0&1 7one of he a.ove public class -lvis { ++ Singleton pattern: thereCs onl' one -lvis public static inal -lvis -5D)S = new -lvis(). & public static void main(String[] args) { S'stem$out$println(-5D)S$lives() G 9Hound Aog9 : 9Heartbrea= Hotel9). private -lvis() { & private static private public inal Eoolean 5)D)7F = true.

ove ? hro-s 7ullHointer-.rea< 2o el 0c1 " varies 0&1 7one of he a. and auto>un.ception "lass initialization is tric!'.1 2ear .)hat *oes It Print+ 0a1 2oun& Eog 0.o4in# happens -here 'ou least e4pect it 2007 JavaOneSM Conference | Session TS-2707 | 27 .

private -lvis() { & private static private public inal Eoolean 5)D)7F = true.ingB 9Hound Aog9 : 9Heartbrea= Hotel9).nother /oo! public class -lvis { ++ 4ecursive class initiali(ation public static inal -lvis -5D)S = new -lvis(). inal Eoolean lives() { return alive. & & 2007 JavaOneSM Conference | Session TS-2707 | 29 . & public static void main(String[] args) { S'stem$out$println(-5D)S$lives() G ++ 8uto% unbo. ++ ?oo late inal Eoolean alive = 5)D)7F.

& public static void main(String[] args) { S'stem$out$println(-5D)S$lives() G 9Hound Aog9 : 9Heartbrea= Hotel9). inal Eoolean lives() { return alive.1o. & & 2007 JavaOneSM Conference | Session TS-2707 | 2: .*o 2ou 3i4 It+ public class -lvis { private -lvis() { & private static inal Eoolean 5)D)7F = true. ields ++ .reate singleton 2a ter2 initiali(ing other public static inal -lvis -5D)S = new -lvis(). private public inal Eoolean alive = 5)D)7F.

ception ( 7ever use Eoolean as a hree-value& re urn %+e ( Almos guaran ees 7ullHointer-.o3ing can occur -hen %ou leas e3+ec i ( " can cause 7ullHointer-.a ion '0 2007 JavaOneSM Conference | Session TS-2707 | .ime cons an s4 ei her ( Au o-un.a ion ( Cons ruc ins ances a en& of class ini iali.ception ( Wa ch ou for circulari ies in class ini iali.Moral ( Wra++e& +rimi ives aren> +rimi ives ( The% aren> com+ile.

S'stem$out$println( irst # last). int irst = in$read(). public class Fap { private static inal int F8H6S)I. in$s=ip(F8H6S)I-). Kile/utputStream out = new Kile/utputStream(tmp). out$write(<).ception { Kile tmp = Kile$create?empKile(9gap9.?. )nputStream in = new Eu ered)nputStream(new Kile)nputStream(tmp)). out$close(). public static void main(String args[]) throws )/-.= "! 2 "!<J. . out$write("). int last = in$read(). out$write(new b'te[F8H6S)I-]). &Mind the @ap( import 0ava$io$2. & & 2007 JavaOneSM Conference | Session TS-2707 | '. 9$t.t9).

public static void main(String args[]) throws )/-. public class Fap { private static inal int F8H6S)I. S'stem$out$println( irst # last). 9$t. Kile/utputStream out = new Kile/utputStream(tmp). int irst = in$read(). in$s=ip(F8H6S)I-). out$write(").0a1 . out$write(new b'te[F8H6S)I-]). int last = in$read(). )nputStream in = new Eu ered)nputStream(new Kile)nputStream(tmp)).1 ' 0c1 Thro-s e3ce+ ion 0&1 " varies import 0ava$io$2.t9).= "! 2 "!<J.ception { Kile tmp = Kile$create?empKile(9gap9. )hat *oes It Print+ 0. out$write(<). & & 2007 JavaOneSM Conference | Session TS-2707 | '2 . out$close().

lso it is difficult to use correctl'.1 ' 0c1 Thro-s e3ce+ ion 0&1 " varies from run o run 0accor&ing o s+ec1 s=ip returns a valueA i#nore it at 'our peril. 2007 JavaOneSM Conference | Session TS-2707 | '' . 0in +rac ice1 0.)hat *oes It Print+ 0a1 .

out$write(new b'te[F8H6S)I-]). Kile/utputStream out = new Kile/utputStream(tmp).= "! 2 "!<J. & & 2007 JavaOneSM Conference | Session TS-2707 | '5 . S'stem$out$println( irst # last). ++ 7ot guaranteed to s=ip entire gap int last = in$read(). in$s=ip(F8H6S)I-).t9). out$write(<).ception { Kile tmp = Kile$create?empKile(9gap9. out$write("). int irst = in$read(). 9$t.nother /oo! import 0ava$io$2. public static void main(String args[]) throws )/-. out$close(). public class Fap { private static inal int F8H6S)I. )nputStream in = new Eu ered)nputStream(new Kile)nputStream(tmp)).

i (s=ipped == !) throw new -/K-. long nE'tes) throws )/-.1o. while (remaining B= !) { long s=ipped = in$s=ip(remaining).ception(). & & 2007 JavaOneSM Conference | Session TS-2707 | '6 . remaining %= s=ipped.*o 2ou 3i4 It+ static void s=ipKull'()nputStream in.ception { long remaining = nE'tes.

ro<en4 -ra+ i ( Ior AP" &esigners ( Eon> viola e he +rinci+le of leas as onishmen ( Ma<e i eas% o &o sim+le hings 2007 JavaOneSM Conference | Session TS-2707 | '8 .Moral ( The s=ip me ho& is har& o use an& error +rone ( $se %our s=ipKull' ins ea& of s<i+ ( There is an @I) o a&& i o )nputStream ( More generall%4 if an AP" is .

public static void main(String[] args) { int[] histogram = new int[L]. int buc=et = 1ath$abs(pair$hash. S'stem$out$println(C.ode()) M histogram$length.B. 9pol'gene9. 9recommend9. 9lubricants9 &. histogram[buc=et]##.C # pair. or (int re> : histogram) pair. & & 2007 JavaOneSM Conference | Session TS-2707 | '7 .ount). &1isto#ram M'ster'( public class Histogram { private static inal String[] words = { 9)9.ount = !. & & int pair. or (String word" : words) { or (String word< : words) { String pair = word" # word<.ount #= re>.

ode()) M histogram$length. S'stem$out$println(C. 9lubricants9 &. public static void main(String[] args) { int[] histogram = new int[L]. int buc=et = 1ath$abs(pair$hash. 9recommend9. or (String word" : words) { or (String word< : words) { String pair = word" # word<. or (int re> : histogram) pair.)hat *oes It Print+ 0a1 NO 0. & & 2007 JavaOneSM Conference | Session TS-2707 | '9 .C # pair.ount). 9pol'gene9. histogram[buc=et]##.1 ."P 0c1 S 0&1 7one of he a.ove public class Histogram { private static inal String[] words = { 9)9.ount #= re>.ount = !. & & int pair.

ception 1ath$abs(int) can re urn a nega ive num.er4 an& so can he M o+era or 2007 JavaOneSM Conference | Session TS-2707 | ': ."P 0c1 S 0&1 7one of he a.)hat *oes It Print+ 0a1 NO 0.1 .ove ? hro-s 8rra'/ut/ Eounds-.

S'stem$out$println(C.C # pair.nother /oo! public class Histogram { private static inal String[] words = ++ . 9recommend9. int buc=et = 1ath$abs(pair$hash. histogram[buc=et]##.ode()) M histogram$length.are ull' chosenB { 9)9. or (String word" : words) { or (String word< : words) { String pair = word" # word<. ++ 9pol'genelubricants9$hash. or (int re> : histogram) pair.ount). & & int pair.ode() == )nteger$1)76D853public static void main(String[] args) { int[] histogram = new int[L]. & & 50 2007 JavaOne Conference | Session TS-2707 | SM . 9pol'gene9.ount = !.ount #= re>. 9lubricants9 &.

++ 1ath$abs ollows M histogram[buc=et]##. & int pair. S'stem$out$println(C. or (String word" : words) or (String word< : words) { String pair = word" # word<. int buc=et = 1ath$abs(pair$hash.ount #= re>. public static void main(String[] args) { int[] histogram = new int[L].C # pair.*o 2ou 3i4 It+ public class Histogram { private static inal String[] words = { 9)9. .ode() M histogram$length).ount = !.ount).1o. 9pol'gene9. 9lubricants9 &. 9recommend9. & & 2007 JavaOneSM Conference | Session TS-2707 | 5. or (int re> : histogram) pair.

R ) M buc=ets$length ( Or use +o-er-of.e nega ive ( To ransla e a signe& hash value o a .uc<e • 1ath$abs(hashDal M buc=ets$length) ( Or (hashDal >>> ") M buc=ets$length ( Or (hashDal Q !.Moral • 1ath$abs &oesnD guaran ee nonnega ive resul • )nteger$1)76D853.== %)nteger$1)76D853- ( The M o+era or is remain&er4 no mo&= can .-o leng h arra% (hashDal Q (buc=ets$length * ")) 2007 JavaOneSM Conference | Session TS-2707 | 52 .

& & 2007 JavaOneSM Conference | Session TS-2707 | 5' . S'stem$out$println(result). & $ea of Trou.les( public class Hamlet { public static void main(String[] args) { 4andom rnd = new 4andom(). boolean toEe = rnd$ne.C. 7umber result = (toEe SS BtoEe) G new )nteger(O) : new Kloat(").tEoolean().

boolean toEe = rnd$ne.1 "$! 0c1 Thro-s e3ce+ ion 0&1 7one of he a.ove 2007 JavaOneSM Conference | Session TS-2707 | 55 . S'stem$out$println(result).tEoolean(). 7umber result = (toEe SS BtoEe) G new )nteger(O) : new Kloat(").)hat *oes It Print+ public class Hamlet { public static void main(String[] args) { 4andom rnd = new 4andom(). & & 0a1 O 0.

ehavior -hen a++lie& o misma che& in egral -ra++er %+es 2007 JavaOneSM Conference | Session TS-2707 | 56 .)hat *oes It Print+ 0a1 O 0.oveH O$! The G : o+era or has s range .1 "$! 0c1 Thro-s an e3ce+ ion 0&1 7one of he a.

S'stem$out$println(result). & & 2007 JavaOneSM Conference | Session TS-2707 | 58 . boolean toEe = rnd$ne.nother /oo! public class Hamlet { public static void main(String[] args) { 4andom rnd = new 4andom().tEoolean(). 7umber result = (toEe SS BtoEe) G new )nteger(O) : new Kloat(").

then there are several cases: J "f one of he o+eran&s is of %+e .%97.oolean# ( "f one of he secon& an& hir& o+eran&s is of he null %+e an& he %+e of he o her is a reference %+e4 hen he %+e of he con&i ional e3+ression is ha reference %+e# ( .inar' numeric promotion 6D?.4 T21 0K. an& S2 res+ec ivel%# Ae T.oolean an& he %+e of he o her is of %+e Boolean4 hen he %+e of he con&i ional e3+ression is .e he %+e ha resul s from a++l%ing .o3ing conversion o S.%.le in %+e char4 hen he %+e of he con&i ional e3+ression is char# ( .#.% e or B% e an& he o her is of %+e shor or Shor 4 hen he %+e of he con&i ional e3+ression is shor # J "f one of he o+eran&s is of %+e T -here T is .e he %+e ha resul s from a++l%ing .%.% e# J "f one of he o+eran&s is of %+e Shor an& he o her o+eran& is a cons an e3+ression of %+e in -hose value is re+resen a.% e4 shor 4 or char4 an& he o her o+eran& is a cons an e3+ression of %+e in -hose value is re+resen a.5?7 The t'pe of a conditional e4pression is determined as follo-s: ( "f he secon& an& hir& o+eran&s have he same %+e 0-hich ma% .E7 to numeric t'pes.le in %+e . :ote that .01 o lu.E7 and value set conversion 6D?.o4in# conversion 6D?. ( O her-ise4 he secon& an& hir& o+eran&s are of %+es S.le 6D?.le in %+e shor 4 hen he %+e of he con&i ional e3+ression is shor # J "f one of he o+eran&s is of %+e Charac er an& he o her o+eran& is a cons an e3+ression of %+e in -hose value is re+resen a.%.B. .4 an& le T2 .2#2#71# 2007 JavaOneSM Conference | Session TS-2707 | 57 .ther-ise.e he null %+e14 hen ha is he %+e of he con&i ional e3+ression# ( "f one of he secon& an& hir& o+eran&s is of %+e .6#.o3ing conversion o S2# The %+e of he con&i ional e3+ression is he resul of a++l%ing ca+ ure conversion 0K6#.% e4 hen he %+e of he con&i ional e3+ression is .57 is applied to the operand t'pes. and the t'pe of the conditional e4pression is the promoted t'pe of the second and third operands.le in %+e T4 hen he %+e of he con&i ional e3+ression is T# J "f one of he o+eran&s is of %+e B% e an& he o her o+eran& is a cons an e3+ression of %+e in -hose value is re+resen a. if the second and third operands have t'pes that are converti.0T.nother /oo! 657 8 G: $pec 6J/$ %?.inar' numeric promotion performs un. .ther-ise.

i (toEe SS BtoEe) { result = new )nteger(O). 7umber result.tEoolean(). boolean toEe = rnd$ne. & S'stem$out$println(result).1o.*o 2ou 3i4 It+ public class Hamlet { public static void main(String[] args) { 4andom rnd = new 4andom(). & & 2007 JavaOneSM Conference | Session TS-2707 | 59 . & else { result = new Kloat(").

Moral ( Avoi& mi3ing %+es ( The G : o+era or has coun erin ui ive seman ics -hen use& -i h -o &ifferen -ra++er %+es ( "f %ou mus selec .e -een -o -ra++e& in egral %+es4 use i %else ins ea& of G : 2007 JavaOneSM Conference | Session TS-2707 | 5: .

E.t)nt(). & & 2007 JavaOneSM Conference | Session TS-2707 | 60 . &@round Round( public class 4ound { public static void main(String[] args) { 4andom rnd = new 4andom(). int i = rnd$ne. i (1ath$round(i) B= i) S'stem$out$println(9Fround 4ound9).

int i = rnd$ne. .1 Sel&om 0c1 Almos ever% ime i >s run 0&1 )ver% ime i >s run 2007 JavaOneSM Conference | Session TS-2707 | 6.t)nt(). & & 0a1 7ever 0. i (1ath$round(i) B= i) S'stem$out$println(9Fround 4ound9).ften *oes It Print Fround 4ound+ public class 4ound { public static void main(String[] args) { 4andom rnd = new 4andom()..1o.

1o..ften *oes It Print Fround 4ound+ 0a1 7ever 0.1 Sel&om 0c1 Almos ever% ime i >s run ? :8#7L of he imeF 0&1 )ver% ime i >s run Silen 4 loss% conversion from int o loat in com.ina ion -i h 1ath$round0 loat) is <illing us# 2007 JavaOneSM Conference | Session TS-2707 | 62 .

loat has E e4ponent . i (1ath$round(i) B= i) ++ i 9promoted9 to S'stem$out$println(9Fround 4ound9). 2ou lose a.out one .nother /oo! public class 4ound { public static void main(String[] args) { 4andom rnd = new 4andom(). & & loat public static int round( loat). ++ ?his one gets invo=ed public static long round(double). int i = rnd$ne.its.it of precision for each oneF 2007 JavaOneSM Conference | Session TS-2707 | 6' .t)nt().

& & 2007 JavaOneSM Conference | Session TS-2707 | 65 .*o 2ou 3i4 It+ public class 4ound { public static void main(String[] args) { 4andom rnd = new 4andom(). int i = rnd$ne.1o.t)nt(). i (1ath$round((double) i) B= i) S'stem$out$println(9Fround 4ound9).

Moral ( $ilent &-idenin#( conversion from int to loat is loss' and dan#erous ( Ei o for long o double ( The loat %+e is sel&om calle& forH use double ( Me ho& overloa&ing is &angerous4 +ar icularl% -hen com.ine& -i h une3+ec e& M-i&eningN 2007 JavaOneSM Conference | Session TS-2707 | 66 .

"onclusion ( Java +la form is reasona.l% sim+le an& elegan ( Bu i has a fe.a.ugs in his al<F ( Eon> co&e li<e m% .ro her 2007 JavaOneSM Conference | Session TS-2707 | 68 .l% &oesn> &o -ha %ou -an ( $se Iin&Bugs*= i fin&s all 9 .shar+ cornersOavoi& hemF ( Pee+ +rograms clear an& sim+le ( "f %ou aren> sure -ha a +rogram &oes4 i +ro.

$hameless "ommerce *ivision ( :6 +u..les ( 62 illusions ( Tons of fun 2007 JavaOneSM Conference | Session TS-2707 | 67 .

Joshua Bloch Chief Java Archi ec !oogle "nc# Session TS-2707 2007 JavaOneSM Conference | Session TS-2707 | William Pugh Professor $niversi % of Mar%lan& . Reven#e of the $hift. Episode VI: The PhantomReference Menace.Java™ Puzzlers. ttac! of the "lone.

Sign up to vote on this title
UsefulNot useful