close

Вход

Забыли?

вход по аккаунту

?

Head First Java 2nd-edition

код для вставкиСкачать
Beginner's Guide
"WPJEFNCBSBTTJOH
00NJTUBLFT
'PPMBSPVOEJO
UIF+BWB-JCSBSZ
)FBE'JSTU
+BWB
-FBSOIPXUISFBET
DBODIBOHFZPVSMJGF
.BLF+BWBDPODFQUT
TUJDLUPZPVSCSBJO
,BUIZ4JFSSB#FSU#BUFT
#FOEZPVSNJOE
BSPVOE
+BWBQV[[MFT
:PVS#SBJOPO+BWB"-FBSOFST(VJEF
ND%DITION#OVERS*AVA
.BLFBUUSBDUJWF
BOEVTFGVM(6*T
ix
i
Intro
Your brain on Java. (EREYOUARETRYINGTOLEARNSOMETHINGWHILEHEREYOURBRAIN
ISDOINGYOUAFAVORBYMAKINGSURETHELEARNINGDOESNTSTICK9OURBRAINSTHINKINGh"ETTER
LEAVEROOMFORMOREIMPORTANTTHINGSLIKEWHICHWILDANIMALSTOAVOIDANDWHETHERNAKED
SNOWBOARDINGISABADIDEAv3OHOWDOYOUTRICKYOURBRAININTOTHINKINGTHATYOURLIFE
DEPENDSONKNOWING*AVA
Who is this book for? xxii
What your brain is thinking xxiii
Metacognition xxv
Bend your brain into submission xxvii
What you need for this book xxviii
Technical editors xxx
Acknowledgements xxxi
Table of Contents (summary)
Intro xxi
1 Breaking the Surface: a quick dip 1
2 A Trip to Objectville: yes, there will be objects 27
3 Know Your Variables: primitives and references 49
4 How Objects Behave: object state affects method behavior 71
5 Extra-Strength Methods: flow control, operations, and more 95
6 Using the Java Library: so you don’t have to write it all yourself 125
7 Better Living in Objectville: planning for the future 165
8 Serious Polymorphism: exploiting abstract classes and interfaces 197
9 Life and Death of an Object: constructors and memory management 235
10 Numbers Matter: math, formatting, wrappers, and statics 273
11 Risky Behavior: exception handling 315
12 A Very Graphic Story: intro to GUI, event handling, and inner classes 353
13 Work on Your Swing: layout managers and components 399
14 Saving Objects: serialization and I/O 429
15 Make a Connection: networking sockets and multithreading 471
16 Data Structures: collections and generics 529
17 Release Your Code: packaging and deployment 581
18 Distributed Computing: RMI with a dash of servlets, EJB, and Jini 607
A Appendix A: Final code kitchen 649
B Appendix B: Top Ten Things that didn’t make it into the rest of the book 659
Index 677
Table of Contents (the full version)
x
You Bet
Shoot Me
2
A Trip to Objectville
I was told there would be objects. )N#HAPTERWEPUTALLOFOURCODE
INTHEMAINMETHOD4HATSNOTEXACTLYOBJECTORIENTED3ONOWWEVEGOTTOLEAVETHAT
PROCEDURALWORLDBEHINDANDSTARTMAKINGSOMEOBJECTSOFOUROWN7ELLLOOKATWHAT
MAKESOBJECTORIENTED//DEVELOPMENTIN*AVASOMUCHFUN7ELLLOOKATTHEDIFFERENCE
BETWEENACLASSANDANOBJECT7ELLLOOKATHOWOBJECTSCANIMPROVEYOURLIFE
1
Breaking the Surface
Java takes you to new places.
&ROMITSHUMBLERELEASETOTHEPUBLICASTHE
WIMPYVERSION*AVASEDUCEDPROGRAMMERSWITHITSFRIENDLYSYNTAXOBJECTORIENTED
FEATURESMEMORYMANAGEMENTANDBESTOFALLTHEPROMISEOFPORTABILITY7ELLTAKEAQUICK
DIPANDWRITESOMECODECOMPILEITANDRUNIT7ERETALKINGSYNTAXLOOPSBRANCHINGANDWHAT
MAKES*AVASOCOOL$IVEIN
The way Java works 2
Code structure in Java 7
Anatomy of a class 8
The main() method 9
Looping 11
Conditional branching (if tests) 13
Coding the “99 bottles of beer” app 14
Phrase-o-matic 16
Fireside chat: compiler vs. JVM 18
Exercises and puzzles 20
Method Party()
0 aload_0
1 invokespe-
cial #1 <Method java.lang.Object()>
4 return
Compiled bytecode
Virtual
Machines
Chair Wars (Brad the OO guy vs. Larry the procedural guy) 28
Inheritance (an introduction) 31
Overriding methods (an introduction) 32
What’s in a class? (methods, instance variables) 34
Making your fi rst object 36
Using main() 38
Guessing Game code 39
Exercises and puzzles 42
xi
pass-by-value means pass-by-copy
3
Know Your Variables
Variables come in two flavors: primitive and reference. 4HERESGOTTABEMORETOLIFETHANINTEGERS3TRINGSANDARRAYS7HATIFYOUHAVEA0ET/WNER
OBJECTWITHA$OGINSTANCEVARIABLE/RA#ARWITHAN%NGINE)NTHISCHAPTERWELLUNWRAP
THEMYSTERIESOF*AVATYPESANDLOOKATWHATYOUCANDECLAREASAVARIABLEWHATYOUCANPUT
INAVARIABLEANDWHATYOUCANDOWITHAVARIABLE!NDWELLFINALLYSEEWHATLIFEISTRULYLIKE
ONTHEGARBAGECOLLECTIBLEHEAP
Dog reference
D
o
g
o
b
j
e
c
t
size
24
int
fido
4
How Objects Behave
State affects behavior, behavior affects state. 7EKNOWTHATOBJECTS
HAVESTATEANDBEHAVIORREPRESENTEDBYINSTANCEVARIABLESANDMETHODS.OWWELLLOOK
ATHOWSTATEANDBEHAVIORARERELATED!NOBJECTSBEHAVIORUSESANOBJECTSUNIQUESTATE
)NOTHERWORDSMETHODSUSEINSTANCEVARIABLEVALUES,IKEhIFDOGWEIGHTISLESSTHAN
POUNDSMAKEYIPPYSOUNDELSEv,ETSGOCHANGESOMESTATE
00000111
int
X
00000111
int
Z
copy of x
foo.go(x);void go(int z){ }
Declaring a variable (Java cares about type) 50
Primitive types (“I’d like a double with extra foam, please”) 51
Java keywords 53
Reference variables (remote control to an object) 54
Object declaration and assignment 55
Objects on the garbage-collectible heap 57
Arrays (a fi rst look) 59
Exercises and puzzles 63
Methods use object state (bark different) 73
Method arguments and return types 74
Pass-by-value (the variable is always copied) 77
Getters and Setters 79
Encapsulation (do it or risk humiliation) 80
Using references in an array 83
Exercises and puzzles 88
xii
5
Extra-Strength Methods
Let’s put some muscle in our methods. 9OUDABBLEDWITHVARIABLES
PLAYEDWITHAFEWOBJECTSANDWROTEALITTLECODE"UTYOUNEEDMORETOOLS,IKE
OPERATORS
!ND
LOOPS
-IGHTBEUSEFULTO
GENERATERANDOMNUMBERS
!ND
TURN
A3TRINGINTOANINT
YEAHTHATWOULDBECOOL!NDWHYDONTWELEARNITALLBYBUILDING
SOMETHINGREALTOSEEWHATITSLIKETOWRITEANDTESTAPROGRAMFROMSCRATCH
-AYBEA
GAME
LIKE3INKA$OT#OMSIMILARTO"ATTLESHIP
6
Using the Java Library
Java ships with hundreds of pre-built classes. 9OUDONTHAVETO
REINVENTTHEWHEELIFYOUKNOWHOWTOFINDWHATYOUNEEDFROMTHE*AVALIBRARYCOMMONLY
KNOWNASTHE
*AVA!0)
9OUVEGOTBETTERTHINGSTODO)FYOUREGOINGTOWRITECODEYOU
MIGHTASWELLWRITEONLYTHEPARTSTHATARECUSTOMFORYOURAPPLICATION4HECORE*AVALIBRARY
ISAGIANTPILEOFCLASSESJUSTWAITINGFORYOUTOUSELIKEBUILDINGBLOCKS
!
"
#
$
%
&
'
!SK-ECOM
0ETSCOM
'OCOM
We’re gonna build the Sink a Dot Com game
h'OODTOKNOWTHERESAN!RRAY,ISTIN
THEJAVAUTILPACKAGE"UTBYMYSELFHOW
WOULD)HAVElGUREDTHATOUTv
- Julia, 31, hand model
Building the Sink a Dot Com game 96
Starting with the Simple Dot Com game (a simpler version) 98
Writing prepcode (pseudocode for the game) 100
Test code for Simple Dot Com 102
Coding the Simple Dot Com game 103
Final code for Simple Dot Com 106
Generating random numbers with Math.random() 111
Ready-bake code for getting user input from the command-line 112
Looping with for loops 114
Casting primitives from a large size to a smaller size 117
Converting a String to an int with Integer.parseInt() 117
Exercises and puzzles 118
Analying the bug in the Simple Dot Com Game 126
ArrayList (taking advantage of the Java API) 132
Fixing the DotCom class code 138
Building the real game (Sink a Dot Com) 140
Prepcode for the real game 144
Code for the real game 146
boolean expressions 151
Using the library (Java API) 154
Using packages (import statements, fully-qualifi ed names) 155
Using the HTML API docs and reference books 158
Exercises and puzzles 161
xiii
Some classes just should not be instantiated 200
Abstract classes (can’t be instantiated) 201
Abstract methods (must be implemented) 203
Polymorphism in action 206
Class Object (the ultimate superclass of everything) 208
Taking objects out of an ArrayList (they come out as type Object) 211
Compiler checks the reference type (before letting you call a method) 213
Get in touch with your inner object 214
Polymorphic references 215
Casting an object reference (moving lower on the inheritance tree) 216
Deadly Diamond of Death (multiple inheritance problem) 223
Using interfaces (the best solution!) 224
Exercises and puzzles 230
7
Better Living in Objectville
Plan your programs with the future in mind. 7HATIFYOUCOULDWRITE
CODETHATSOMEONEELSECOULDEXTENDEASILY7HATIFYOUCOULDWRITECODETHATWASFLEXIBLE
FORTHOSEPESKYLASTMINUTESPECCHANGES7HENYOUGETONTHE0OLYMORPHISM0LANYOULL
LEARNTHESTEPSTOBETTERCLASSDESIGNTHETRICKSTOPOLYMORPHISMTHEWAYSTOMAKE
FLEXIBLECODEANDIFYOUACTNOWABONUSLESSONONTHETIPSFOREXPLOITINGINHERITANCE
8
Serious Polymorphism
Inheritance is just the beginning. 4OEXPLOITPOLYMORPHISMWENEED
INTERFACES7ENEEDTOGOBEYONDSIMPLEINHERITANCETOFLEXIBILITYYOUCANGETONLYBY
DESIGNINGANDCODINGTOINTERFACES7HATSANINTERFACE!ABSTRACTCLASS7HATSAN
ABSTRACTCLASS!CLASSTHATCANTBEINSTANTIATED7HATSTHATGOODFOR2EADTHECHAPTER
Make it Stick
2OSESAREREDVIOLETSAREBLUE
3QUARE)3!3HAPETHEREVERSEISNTTRUE
2OSESAREREDVIOLETSAREDEAR
"EER)3!$RINKBUTNOTALLDRINKSAREBEER
/+YOURTURN-AKEONETHATSHOWSTHEONE
WAYNESSOFTHE)3!RELATIONSHIP!NDREMEM
BERIF8EXTENDS98)3!9MUSTMAKESENSE
Object o = al.get(id);
Dog d = (Dog) o;
d.bark();
Object
o
D
o
g
o
b
j
e
c
t
Dog
d
cast the Object back to a Dog we know is there.
Object
Understanding inheritance (superclass and subclass relationships) 168
Designing an inheritance tree (the Animal simulation) 170
Avoiding duplicate code (using inheritance) 171
Overriding methods 172
IS-A and HAS-A (bathtub girl) 177
What do you inherit from your superclass? 180
What does inheritance really buy you? 182
Polymorphism (using a supertype reference to a subclass object) 183
Rules for overriding (don’t touch those arguments and return types!) 190
Method overloading (nothing more than method name re-use) 191
Exercises and puzzles 192
xiv
9
Life and Death of an Object
Objects are born and objects die. 9OUREINCHARGE9OUDECIDEWHENAND
HOWTOCONSTRUCTTHEM9OUDECIDEWHENTOABANDONTHEM4HE'ARBAGE#OLLECTORGC
RECLAIMSTHEMEMORY7ELLLOOKATHOWOBJECTSARECREATEDWHERETHEYLIVEANDHOWTO
KEEPORABANDONTHEMEFFICIENTLY4HATMEANSWELLTALKABOUTTHEHEAPTHESTACKSCOPE
CONSTRUCTORSSUPERCONSTRUCTORSNULLREFERENCESANDGCELIGIBILITY
10
Numbers Matter
Do the Math.
4HE*AVA!0)HASMETHODSFORABSOLUTEVALUEROUNDINGMINMAXETC
"UTWHATABOUTFORMATTING9OUMIGHTWANTNUMBERSTOPRINTEXACTLYTWODECIMALPOINTS
ORWITHCOMMASINALLTHERIGHTPLACES!NDYOUMIGHTWANTTOPRINTANDMANIPULATEDATES
TOO!NDWHATABOUTPARSINGA3TRINGINTOANUMBER/RTURNINGANUMBERINTOA3TRING
7ELLSTARTBYLEARNINGWHATITMEANSFORAVARIABLEORMETHODTOBESTATIC
‘d’ is assigned a new Duck object, leaving the original (first) Duck object abandoned. That first Duck is toast..
D
u
c
k
o
b
j
e
c
t
Heap
d
D
u
c
k
o
b
j
e
c
t
When someone calls the go() method, this Duck is abandoned. His only reference has been reprogrammed for a different Duck.
kid instance one
kid instance two
static variable: iceCream
Static variables are shared by all instances of a class.
instance variables: one per instance
static variables: one per class
The stack and the heap, where objects and variables live 236
Methods on the stack 237
Where local variables live 238
Where instance variables live 239
The miracle of object creation 240
Constructors (the code that runs when you say new) 241
Initializing the state of a new Duck 243
Overloaded constructors 247
Superclass constructors (constructor chaining) 250
Invoking overloaded constructors using this() 256
Life of an object 258
Garbage Collection (and making objects eligible) 260
Exercises and puzzles 266
Math class (do you really need an instance of it?) 274
static methods 275
static variables 277
Constants (static fi nal variables) 282
Math methods (random(), round(), abs(), etc.) 286
Wrapper classes (Integer, Boolean, Character, etc.) 287
Autoboxing 289
Number formatting 294
Date formatting and manipulation 301
Static imports 307
Exercises and puzzles 310
xv
11
Risky Behavior
Stuff happens. 4HEFILEISNTTHERE4HESERVERISDOWN.OMATTERHOWGOODA
PROGRAMMERYOUAREYOUCANTCONTROLEVERYTHING7HENYOUWRITEARISKYMETHODYOUNEED
CODETOHANDLETHEBADTHINGSTHATMIGHTHAPPEN"UTHOWDOYOUKNOWWHENAMETHODIS
RISKY7HEREDOYOUPUTTHECODETOHANDLETHEEXCEPTIONALSITUATION)NTHISCHAPTERWERE
GOINGTOBUILDA-)$)-USIC0LAYERTHATUSESTHERISKY*AVA3OUND!0)SOWEBETTERFINDOUT
12
A Very Graphic Story
Face it, you need to make GUIs. %VENIFYOUBELIEVETHATFORTHERESTOFYOUR
LIFEYOULLWRITEONLYSERVERSIDECODESOONERORLATERYOULLNEEDTOWRITETOOLSANDYOULL
WANTAGRAPHICALINTERFACE7ELLSPENDTWOCHAPTERSON'5)SANDLEARNMORELANGUAGE
FEATURESINCLUDING%VENT(ANDLINGAND)NNER#LASSES7ELLPUTABUTTONONTHESCREEN
WELLPAINTONTHESCREENWELLDISPLAYAJPEGIMAGEANDWELLEVENDOSOMEANIMATION
class with a risky method
t
h
r
o
w
s
a
n
e
x
c
e
p
t
i
o
n
b
a
c
k
class Cow {
void moo() {
if (serverDown){
explode();
}
}
}
your code
class Bar {
void go() {
moo();
} int stuff() {
x.beep();
}
}
calls risky method
1
2
class MyOuter {
class MyInner {
void go() {
}
} } The outer and inner objects are now intimately linked.
These two objects on the heap have a special bond. The inner can use the outer’s variables (and vice-versa).
i
n
n
e
r
o
u
t
e
r
Your fi rst GUI 355
Getting a user event 357
Implement a listener interface 358
Getting a button’s ActionEvent 360
Putting graphics on a GUI 363
Fun with paintComponent() 365
The Graphics2D object 366
Putting more than one button on a screen 370
Inner classes to the rescue (make your listener an inner class) 376
Animation (move it, paint it, move it, paint it, move it, paint it...) 382
Code Kitchen (painting graphics with the beat of the music) 386
Exercises and puzzles 394
Making a music machine (the BeatBox) 316
What if you need to call risky code? 319
Exceptions say “something bad may have happened...” 320
The compiler guarantees (it checks) that you’re aware of the risks 321
Catching exceptions using a try/catch (skateboarder) 322
Flow control in try/catch blocks 326
The fi nally block (no matter what happens, turn off the oven!) 327
Catching multiple exceptions (the order matters) 329
Declaring an exception (just duck it) 335
Handle or declare law 337
Code Kitchen (making sounds) 339
Exercises and puzzles 348
xvi
13
Work on your Swing
Swing is easy. 5NLESSYOUACTUALLYCAREWHEREEVERYTHINGGOES3WINGCODELOOKS
EASYBUTTHENCOMPILEITRUNITLOOKATITANDTHINKhHEYTHATSNOTSUPPOSEDTOGOTHEREv
4HETHINGTHATMAKESITEASYTOCODEISTHETHINGTHATMAKESITHARDTOCONTROLTHE
,AYOUT
-ANAGER
"UTWITHALITTLEWORKYOUCANGETLAYOUTMANAGERSTOSUBMITTOYOURWILL)N
THISCHAPTERWELLWORKONOUR3WINGANDLEARNMOREABOUTWIDGETS
14
Saving Objects
Objects can be flattened and inflated. /BJECTSHAVESTATEANDBEHAVIOR
"EHAVIORLIVESINTHECLASSBUTSTATELIVESWITHINEACHINDIVIDUALOBJECT)FYOURPROGRAM
NEEDSTOSAVESTATEYOUCANDOITTHEHARDWAYINTERROGATINGEACHOBJECTPAINSTAKINGLY
WRITINGTHEVALUEOFEACHINSTANCEVARIABLE/RYOUCANDOITTHEEASY//WAYYOUSIMPLY
FREEZEDRYTHEOBJECTSERIALIZEITANDRECONSTITUTEDESERIALIZEITTOGETITBACK
Components in the east and west get their preferred width.
Things in the north and south get their preferred height.
The center gets whatever’s left.
Swing Components 400
Layout Managers (they control size and placement) 401
Three Layout Managers (border, flow, box) 403
BorderLayout (cares about five regions) 404
FlowLayout (cares about the order and preferred size) 408
BoxLayout (like flow, but can stack components vertically) 411
JTextField (for single-line user input) 413
JTextArea (for multi-line, scrolling text) 414
JCheckBox (is it selected?) 416
JList (a scrollable, selectable list) 417
Code Kitchen (The Big One - building the BeatBox chat client) 418
Exercises and puzzles 424
Saving object state 431
Writing a serialized object to a file 432
Java input and output streams (connections and chains) 433
Object serialization 434
Implementing the Serializable interface 437
Using transient variables 439
Deserializing an object 441
Writing to a text file 447
java.io.File 452
Reading from a text file 454
Splitting a String into tokens with split() 458
CodeKitchen 462
Exercises and puzzles 466
serialized
deserialized
Any questions?
xvii
15
Make a Connection
Connect with the outside world. )TSEASY!LLTHELOWLEVELNETWORKING
DETAILSARETAKENCAREOFBYCLASSESINTHEJAVANETLIBRARY/NEOF*AVASBESTFEATURESIS
THATSENDINGANDRECEIVINGDATAOVERANETWORKISREALLYJUST)/WITHASLIGHTLYDIFFERENT
CONNECTIONSTREAMATTHEENDOFTHECHAIN)NTHISCHAPTERWELLMAKECLIENTSOCKETS7ELL
MAKESERVERSOCKETS7ELLMAKECLIENTSANDSERVERS"EFORETHECHAPTERSDONEYOULLHAVEA
FULLYFUNCTIONALMULTITHREADEDCHATCLIENT$IDWEJUSTSAYMULTITHREADED
Socket connection to port 5000 on the server at 196.164.1.103
Socket connection back to the client at 196.164.1.100, port 4242
Server
Client
Chat program overview 473
Connecting, sending, and receiving 474
Network sockets 475
TCP ports 476
Reading data from a socket (using BufferedReader) 478
Writing data to a socket (using PrintWriter) 479
Writing the Daily Advice Client program 480
Writing a simple server 483
Daily Advice Server code 484
Writing a chat client 486
Multiple call stacks 490
Launching a new thread (make it, start it) 492
The Runnable interface (the thread’s job) 494
Three states of a new Thread object (new, runnable, running) 495
The runnable-running loop 496
Thread scheduler (it’s his decision, not yours) 497
Putting a thread to sleep 501
Making and starting two threads 503
Concurrency issues: can this couple be saved? 505
The Ryan and Monica concurrency problem, in code 506
Locking to make things atomic 510
Every object has a lock 511
The dreaded “Lost Update” problem 512
Synchronized methods (using a lock) 514
Deadlock! 516
Multithreaded ChatClient code 518
Ready-bake SimpleChatServer 520
Exercises and puzzles 524
xviii
17
Release Your Code
It’s time to let go. 9OUWROTEYOURCODE9OUTESTEDYOURCODE9OUREFINEDYOURCODE
9OUTOLDEVERYONEYOUKNOWTHATIFYOUNEVERSAWALINEOFCODEAGAINTHATDBEFINE"UTIN
THEENDYOUVECREATEDAWORKOFART4HETHINGACTUALLYRUNS"UTNOWWHAT)NTHESEFINAL
TWOCHAPTERSWELLEXPLOREHOWTOORGANIZEPACKAGEANDDEPLOYYOUR*AVACODE7ELLLOOK
ATLOCALSEMILOCALANDREMOTEDEPLOYMENTOPTIONSINCLUDINGEXECUTABLEJARS*AVA7EB
3TART2-)AND3ERVLETS2ELAX3OMEOFTHECOOLESTTHINGSIN*AVAAREEASIERTHANYOUTHINK
MyApp.jar
classes
com
foo
101101 10 110 1 0 11 0 001 10 001 01 MyApp.class
JWS
Web Server
Lorper iure eugue tat vero conse euguero-
MyApp.jnlp
MyApp.jar
MyApp.jar
Deployment options 582
Keep your source code and class fi les separate 584
Making an executable JAR (Java ARchives) 585
Running an executable JAR 586
Put your classes in a package! 587
Packages must have a matching directory structure 589
Compiling and running with packages 590
Compiling with -d 591
Making an executable JAR (with packages) 592
Java Web Start (JWS) for deployment from the web 597
How to make and deploy a JWS application 600
Exercises and puzzles 601
16
Data Structures
Sorting is a snap in Java. 9OUHAVEALLTHETOOLSFORCOLLECTINGANDMANIPULATING
YOURDATAWITHOUTHAVINGTOWRITEYOUROWNSORTALGORITHMS4HE*AVA#OLLECTIONS
&RAMEWORKHASADATASTRUCTURETHATSHOULDWORKFORVIRTUALLYANYTHINGYOULLEVERNEED
TODO7ANTTOKEEPALISTTHATYOUCANEASILYKEEPADDINGTO7ANTTOFINDSOMETHINGBY
NAME7ANTTOCREATEALISTTHATAUTOMATICALLYTAKESOUTALLTHEDUPLICATES3ORTYOURCO
WORKERSBYTHENUMBEROFTIMESTHEYVESTABBEDYOUINTHEBACK
Collections 533
Sorting an ArrayList with Collections.sort() 534
Generics and type-safety 540
Sorting things that implement the Comparable interface 547
Sorting things with a custom Comparator 552
The collection API—lists, sets, and maps 557
Avoiding duplicates with HashSet 559
Overriding hashCode() and equals() 560
HashMap 567
Using wildcards for polymorphism 574
Exercises and puzzles 576
0 1 2 3
List
Set
Map
“Ball” “Fish” “Car”
“Ball1” “Ball2” “Fish” “Car”
xix
18
Distributed Computing
Being remote doesn’t have to be a bad thing. 3URETHINGSAREEASIER
WHENALLTHEPARTSOFYOURAPPLICATIONAREINONEPLACEINONEHEAPWITHONE*6-TORULE
THEMALL"UTTHATSNOTALWAYSPOSSIBLE/RDESIRABLE7HATIFYOURAPPLICATIONHANDLES
POWERFULCOMPUTATIONS7HATIFYOURAPPNEEDSDATAFROMASECUREDATABASE)NTHIS
CHAPTERWELLLEARNTOUSE*AVASAMAZINGLYSIMPLE2EMOTE-ETHOD)NVOCATION2-)7ELL
ALSOTAKEAQUICKPEEKAT3ERVLETS%NTERPRISE*AVA"EANS%*"AND*INI
Java Remote Method Invocation (RMI), hands-on, very detailed 614
Servlets (a quick look) 625
Enterprise JavaBeans (EJB), a very quick look 631
Jini, the best trick of all 632
Building the really cool universal service browser 636
The End 648
Server
Client
S
e
r
v
i
c
e
o
b
j
e
c
t
C
l
i
e
n
t
o
b
j
e
c
t
C
l
i
e
n
t
h
e
l
p
e
r
S
e
r
v
i
c
e
h
e
l
p
e
r
RMI STUB
RMI SKELETON
B
Appendix B
The Top Ten Things that didn’t make it into the book. 7ECANTSEND
YOUOUTINTOTHEWORLDJUSTYET
7EHAVEAFEWMORETHINGSFORYOUBUTTHISISTHEENDOFTHE
BOOK!NDTHISTIMEWEREALLYMEANIT
Top Ten List 660
A
Appendix A
The final Code Kitchen project. !LLTHECODEFORTHEFULLCLIENTSERVERCHAT
BEATBOX9OURCHANCETOBEAROCKSTAR
!NDYGROOVE
#HRISGROOVEREVISED
.IGELDANCEBEAT
DANCEBEAT
BeatBoxFinal (client code) 650
MusicServer (server code) 657
i
Index
677
howtouse
thO
ISbook
Intro
IY\
-this
stl.
bOf\I
'Wt.
.lYlS'Ht:Y
-the
bl>Yl\i,,~,~tiOf\:
'So,
whY
DID
\:h<'1
f.t
Wl,••
J•••
\""~,.~-;~
boo\<r"
xxi
howtousethisbook
Whoisthisbookfor?
If
youcananswer"yes"to
all
ofthese:
E!)"
Haveyoudonesomeprogramming?
®
®
Do
youwant
to
learnJava?
Doyoupreferstimulatingdinnerparty
conversationtodry,dull,technical
lectures?
ThisisNOTareference
book.HeadFirstJavaisa
bookdesignedfor'earning,
notanencyclopediaof
Javafacts.
this
book
is
for
you.
WhoshouldprobablybackawayfrotHthisbook?
Ifyoucananswer
"yes"
to
anyone
of
these:
Isyourprogrammingbackgroundlimited
toHTMLonly,withnoscriptinglanguage
experience?
(If
you'vedoneanythingwithlooping,orif/then
logic,you'lldofinewiththisbook,but
HTML
taggingalonemightnotbeenough.)
this
bookisnotforyou.
®
®
Areyouakick-butt
C++
programmer
lookingfora
reference
book?
Areyouafraidtotrysomethingdifferent?
Wouldyouratherhavearootcanalthan
mixstripeswithplaid?Doyoubelieve
thanatechnicalbookcan't
be
seriousIf
there'sapictureofaduckinthememory
managementsection?
I
xxii
intro
the
intra
Wek.,owwhatyou"re
thittkhtg.
A.,d
we
kt10wwhat
your
brain
isthittkittg.
Yourbraincravesnovelty.It'salwayssearching,scanning,
waiting
for
somethingunusual.
It
was
builtthatway,andithelpsyoustayalive.
Today,
you'relesslikely
to
be
a
tigersnack.Butyourbrain'sstill
looking.You
justneverknow.
So
whatdoesyourbraindowithalltheroutine,ordinary,
normal
thingsyouencounter?Everythingit
can
to
stop
themfrom
interferingwiththebrain'srealjotr-recordingthingsthat
matter.
It
doesn'tbothersavingtheboringthings;theynevermakeitpastthe
"thisisobviouslynotimportant"filter.
Howdoes
yourbrain
know
what'simportant?Supposeyou'reoutfor
a
day
hikeandatigerjumpsinfrontofyou,whathappensinsideyour
head?
Neuronsfire.Emotionscrankup.
ChemicalssuW
Andthat'showyourbrainknows...
ThismustbeImportantlDon'tforget
ItI
Butimagineyou'reathome,orinalibrary.It'sasafe,warm,tiger-free
zone.You'restudying.
Gettingreadyforanexam.Ortryingtolearn
sometoughtechnicaltopicyourbossthinkswilltakeaweek,ten
days
atthemost,
Justoneproblem.Yourbrain'stryingtodoyou
a
bigfavor.It's
trying
tomakesurethatthis
obviou.sly
non-importantcontent
doesn't
clutter
upscarceresources.Resourcesthatarebetter
spentstoringthereallybigthings.Liketigers.Likethedangerof
fire.Likehowyoushouldneveragainsnowboardinshorts.
Andthere'snosimplewaytotellyourbrain,
"Hey
brain,thank
youverymuch,butnomatterhowdull
this
bookis.andhow
little
I'mregisteringontheemotionalrichterscaleright
now,
I
really
do
wantyou
to
keepthisstuffaround.
h
"Howcan
this
beaseriousJavaprogrammingbook?"
"What'swithall
thegraphics?"
"CanIactually
learn
itthisway?"
"DoIsmellpizza?"
you
arehere
~
xxiII
howtousethisbook
We
tlUn1
of
a
"!leadFll'StJava"
readeras
a
learner.
-
SowhatdoesIttaketo
learn
something?First,youhaveto
get
It,thenmakesure
you
don't
forgetll
It'snotaboutpushingfactsIntoyourhead.Basedonthe
latestresearchIncognltJvescience,neurobiology,andeducatJonalpsychology,
learning
takesalotmorethantextonapage.Weknowwhatturnsyourbrainon.
RMI"'(loo~
~ite
Useaconversationalandpersonalizedstyle,Inrecentstudies,
studentsperformedupto
40%
betteronpost-learningtestsifthecontentspoke
directlyto
thereader,usingaflrst-person,conversationalstyleratherthan
takingaformal
tone.Tellstoriesinsteadoflecturing.Usecasuallanguage.Don't
takeyourselftooseriously.Whichwould
you
paymoreattentionto:astimulating
dinnerpartycompanion,or
a
lecture?
SomaoftheHeadFirstlearningprinciples:
o
o
MakeItvisual.Imagesarefarmorememorablethanwords
alone,andmakelearningmuchmoreeffective(Upto89%
Improvementinrecall
andtransferstudies).Italsomakes
thingsmoreunderstandable.
Putthewordswithin
ornearthegraphicstheyrelateto,ratherthanonthe
bottomoronanotherpage,andlearners
will
beupto
twice
aslikelytosolveproblemsrelatedtothecontent.
Itre4l1y
SlJcksto
~
<III
Qbstl"<lct
m~tkod.
You
don'theve
Q
body.
Getthelearnertothinkmoredeeply.
In
otherwords,unless
youactivelyflexyourneurons,nothingmuch
happensinyourhead.
A
readerhastobemotivated,engaged,curious,andinspiredto
solveproblems,drawconclusions,andgeneratenewknowledge.
Andforthat,you
needchallenges,exercises,andthought-
provokingquestions,andactlvltiesthatinvolvebothsides
ofthebrain,
andmultiplesenses.
~0llll10
;
~,-.A
'l>o41'∙
,~
t
tl4~i-
~
;Ie.
Oet-andkee,,-,hereader'sattention.
We've
all
had
the"'reallywanttolearnthisbutIcan'tstayawakepast
pageone"experience.Yourbrainpaysarrentlontothingsthatareout
oftheordinary,interesting,strange,eye-catching,unexpected.Learninganew,
tough,technicaltopicdoesn'thavetobeboring.YourbrainwilllearnmuchmoreqUicklyjfit'snot.
Touchtheiremotlon8.WenowknowthatyourabilitytoremembersomethingIslargely
dependentonItsemotionalcontent.Yourememberwhatyoucareabout.Yourememberwhen
you
feel
somethIng.Nowe'renottalkingheart-wrenchingstoriesaboutaboyandhIsdog.
We're
talkingemotionslikesurprise,curiosity,fun,"whatthe...
T",
andthefeelingof"IRulel"
thatcomes
whenyousolveapuzzle,learnsomethingeverybodyelsethinksIshard,orrealize
youknowsomething
that∙"mmoretechnicalthanthou'Bobfromengineering
doe$n't.
XXiv
intra
theintro
Metacogtlitiott:thittkittgaboutthittki"Q.
o
o
If
youreallywanttolearn,andyouwanttolearnmorequicklyandmoredeeply,
pay
attentiontohowyoupayattention.Thinkabouthowyouthink,Learnhow
youlearn.
Most
ofusdidnottakecoursesonmetacognitionorlearningtheorywhenwewere
growingup.Wewere
expected
tolearn,butrarely
taught
tolearn.
Butweassume
that
if
you'reholdingthisbook,youwanttolearnJava.Andyou
probably
don'twanttospendalotoftime.
To
getthemostfromthisbook,or
any
bookorlearningexperience,take
responsibilityfor
yourbrain.Yourbrain
00
thai
content.
Thetrickistogetyourbraintoseethenewmaterialyou'relearning
asReallyImportant.Crucialtoyourwell-being.
As
importantas
atiger.Otherwise,
you'reinforaconstantbattle,withyourbrain
doing
its
besttokeeptilenewcontentfromsticking.
SoJusthowDOyougetyourbraintotreatJavalikeIt
wasahungrytiger?
There'stheslow,tediousway,orthefaster,moreeffectiveway.The
slowwayisaboutsheerrepetition.Youobviouslyknowthatyou
are
abletolearnandremembereventhedullestoftopics,
if
youkeeppounding
onthesamething.Withenoughrepetition,yourbrain
says,
"This
doesn'tfeel
importanttohim,buthekeepslookingatthesamething
over
and
over
and
over,
so
I
supposeitmustbe."
Thefasterwayistodo
anything
that
increases
brain
activity,
especiallydifferent
types
ofbrainactivity.Thethingsonthepreviouspageareabigpartofthesolution,
andthey'reallthingsthathavebeenproventohelpyourbrainworkinyourfavor.
Forexample,studiesshow
thatputtingwords
within
thepicturestheydescribe(as
opposedtosomewhereelse
in
thepage,likeacaptionorinthebodytext)causes
yourbrainto
try
tomakessenseofhowthewordsandpicturerelate,andthis
causes
moreneuronstofire.Moreneuronsfiring
=
morechancesforyourbrain
to
get
thatthisissomethingworthpayingattentionto,andpossiblyrecording.
Aconversationalstylehelpsbecausepeopletendtopaymoreattentionwhenthey
perceive
thatthey'reinaconversation,sincethey'reexpectedtofollowalongand
holduptheirend.Theamazingthingis,yourbraindoesn'tnecessarily
care
that
the"conversation"isbetweenyouandabook!Ontheotherhand,
if
thewriting
styleisformal
anddry,yourbrainperceivesitthesamewayyouexperiencebeing
lecturedtowhilesittinginaroomfulofpassiveattendees.Noneedtostayawake.
Butpictures
andconversationalstylearejustthebeginning.
youarehere
~
xxv
howtousethisbook
Here"swhatWE
did:
Weused
pidures,
becauseyourbrainistunedfor
visuals,
not
text
As
fur
asyour
brain'sconcerned,apicturereallyssworth1024words.Andwhen
text
andpictures
worktogether,we
embeddedthetext
in
thepicturesbecauseyourbrainworks
moreeffectivelywhenthetext
is
wiihin
thethingthetextrefersto,asopposedtoin
acaption
orburiedinthetextsomewhere.
Weused
repetitUm,
sayingthesamethingindifferentwaysandwithdifferentmedia
types,and
multiplesenses,
to
increasethechancethatthecontent
gets
codedcoded
intomorethanoneareaofyourbrain.
We
usedconceptsandpicturesin
~ways
becauseyourbrainistunedfor
novelty,
andweusedpicturesandideaswithatleast
SO'1M
emf>tional
content,
because
yourbrainis
tunedtopayattentiontothebiochemlstryofemotions.Thatwhich
causesyouto
feel
somethingismorelikelytoberemembered.even
if
thatfeelingis
nothingmorethanalittle
humor;
SU1"f1rise,
or
interest.
Weusedapersonalized,
conversational
style,
becauseyourbrain
is
tunedtopaymore
attentionwhenitbelievesyou'reinaconversationthan
if
itthinksyou'repassively
listeningtoapresentation.Yourbraindoesthisevenwhen
you're
reading.
Weincludedmorethan50
~
,becauseyourbrain
is
tunedtolearnand
remembermorewhenyou
do
thingsthanwhenyou
read
aboutthings.Andwe
madetheexerciseschallenging-yet-do-able,becausethat'swhatmost
pet1J/.e
prefer.
Weused
multiplelearning
styles,
because
you
mightpreferstep-by-stepprocedures,
while
someoneelse
wants
tounderstandthebigpicturefirst,whilesomeoneelse
just
wants
toseeacodeexample.Butregardlessofyourownlearningpreference,
everyone
benefitsfromseeingthesamecontentrepresented
in
multipleways.
Weinclude
contentfor
both
rides
of
your
brain;
becausethemoreofyourbrainyou
engage,the
morelikelyyouaretolearnandremember,andthelongeryoucan
stayfocused.Sinceworking
onesideofthebrainoftenmeansgivingtheotherside
a
chancetorest,youcanbemoreproductiveatlearningforalongerperiodof
time.
Andwe
included
storie:
andexercisesthatpresent
J'TUWe
than
one
point
ofview,
becauseyourbrain
is
tuned
to
learnmoredeeplywhenit'sforced
to
make
evaluations
andjudgements.
Weincluded
chaIknges,
withexercises,and
by
asking
qrustions
thatdon'talwayshave
astraightanswer,becauseyourbrainis
tunedtolearnandrememberwhenithas
to
work
atsomething(justasyoucan'tgetyour
body
inshape
by
watchingpeople
at
the
gym).
Butwedidourbesttomakesurethatwhenyou'reworkinghard,it's
onthe
right
things:That
you'renot
spending
one
exITa
denLfrile
processingahard-to-
understandexample,orparsingdifficult,jargon-Iaden,orextremelytersetext.
Weusedan
80/20
approach.Weassumethat
if
you'regoingforaPhD
in
java,
thiswon't
be
youronlybook.Sowedon't
talk
about
everything.
Justthestuffyou'll
actually
use.
xxvi
Intra
~8\"
Barlle"
theintra
Listentoyourbrain.
Payattentiontowhetheryourbrainisgetting
overloaded.
If
youfindyourselfstartingtoskim
thesurfaceorforgetwhatyoujustread,it's
timefora
break.Onceyougopastacertain
point,youwon'tlearnfasterbytryingtoshove
morein,andyoumightevenhurttheprocess.
TalkaboutIt.Outloud.
Speakingactivatesadifferentpartof
thebrain.
If
you'retryingtounderstand
something,orincreaseyourchanceof
remembering
it
later,
say
itoutloud.Better
still,
try
toexplainitoutloud
to
someone
else.You'lllearnmorequickly,andyoumight
uncoverideasyouhadn'tknownwerethere
whenyouwerereadingaboutit.
Drinkwater.LotsofIt.
Yourbrainworksbestinanicebathoffluid.
Dehydration(whichcanhappenbeforeyou
everfeelthirsty)decreasescognitivefunction.
•
Herelswhat
YOU
ca.,dotobe.,d
your
brah1i"tosubltdssiot1.
Dotheexercises.Writeyour
own
notes.
Weputthemin,but
if
wedidthemforyou,
thatwouldbelikehavingsomeoneelse
do
yourworkoutsforyou.Anddon'tjust
look
attheexercises.Usea
pencil.
There's
plentyofevidencethatphysicalactivity
while
learningcanincreasethelearning.
Readthe"ThereareNoDumbQuestions"
Thatmeansallofthem.They'renot
optionalside-bars-they're
part
ofthecore
contentlSometimesthequestionsaremore
usefulthantheanswers.
~
.Slowdown.Themoreyouunderstand,
thelessyouhavetomemorize.
Don'tjust
'read.
Stopandthink.Whenthe
bookasksyouaquestion,don'tjustskipto
theanswer.Imaginethatsomeonereally
is
askingthequestion.Themoredeeplyyou
force
yourbraintothink,thebetterchance
youhaveoflearningandremembering.
So,wedidourpart.Therestisuptoyou.Thesetipsarea
startingpoint;Listento
yourbrainandfigureoutwhatworks
for
youandwhatdoesn't.
Try
newthings.
lki.
-this
OUt
dhd
sf.itk
't
Oh
yOlJ.'r
l'"e+l'"
id
9
tt"ak.
I
._ - - _._ - - - - - - - - - - - ~
-----------------------------------------------------------
•
Don'tdoallyourreadingInoneplace.
Stand-up,stretch,movearound.change
chairs,changerooms.It'llhelpyourbrain
feel
something,andkeepsyourlearningfrom
beingtooconnectedtoaparticularplace.
Makethisthelastthingyoureadbefore
bed.OratleastthelastchallengIngthing.
Partofthelearning(especiallythetransfer
tolong-termmemory)
happens
afleryou
put
thebookdown.Yourbrainneedstimeon
its
own,todomoreprocessing.
If
youputin
somethingnewduringthatprocessing-time,
someofwhatyoujustlearnedwillbelost.
•Feelsomethlngl
Yourbrainneedstoknowthatthis
mauers.
Get
involvedwiththestories.Makeupyour
0\\>11
captionsforthephotos.Groaningoverabad
jokeis
still
betterthanfeelingnothingatall.
..Type
andrunthecode.
Typeandrunthecodeexamples.Thenyou
canexperimentwithchangingandimproving
thecode(orbreakingit,whichissometimes
thebestwaytofigurealitwhat'sreally
happening).ForlongexamplesorReady-bake
code,youcan
downloadthesourcefilesfrom
headfirstjava.corn
youarehere.xxvII
howtousethisbook
What
you
heed
forthis
book:
Youdo
not
needanyotherdevelopmenttool.such
as
anIntegrated
DevelopmentEnvironment(IDE).Westronglyrecommendthatyou
not
useanythingbut
a-
basictexteditoruntilyoucompletethisbook(and
especially
notuntilafterchapter16).
An
IDEcanprotectyoufromsomeof
thedetailsthatreallymatter.soyou'remuchbenerofflearningfromthe
command-lineandthen.onceyoureallyunderstandwhat'shappening.
movetoatoolthatautomatessomeoftheprocess.
SmlNGUPJAVA------------------,
•Ifyoudon'talreadyhavea1.5orgreaterJava
2
StandardEdition
SDK
(Software
DevelopmentKit),youneed
it.
Ifyou'reonLinux,Windows,orSolaris,youcangelltfor
free
fromjava.sun.com(Sun'swebsileforJavadevelopers).
It
usuallytakesnomorethantwoclicks
fromthemainpagetogel
to
theJ2SEdownloadspage.Getthelatest
non-beta
versionposted.
TheSDKincludeseverythingyouneedtocompileandrunJava.
Ifyou'rerunningMacOS
X
10.4.theJavaSDKisalreadyinstalled.It's
part
ofOS
X,
andyou
don'thavetodo
anything
else.Ifyou'reonanearlierversionofOS
X.
youhaveanearlier
versionofJavathatwillwor1<for95%ofthecodeinthisbook.
Note:ThisbookisbasedonJava1.5,butforstunninglyunclearmar1<etingreasons,shortly
beforerelease,SunrenamedItJava
5,
whilestillkeeping
"1.5"
astheversionnumberforthe
developer's
kit
So,ifyouseeJava1.5orJava
5
orJava5.0,
or
"Tiger"(version5'soriginal
code-name),
theyallmeanthe
same
thing.
TherewasneveraJava3.0or
4.Q--it
jumpedfrom
version1.4to5.0,bu1youwillstillfindplaceswhereit'scalled1.5insteadof
5.
Don'lask.
(Oh
,
andjust
10
make
il
moreentertaining,Java
5
andtheMacOS
X
10.4werebothgiventhe
samecode-nameof"Tiger",andsinceOS
X
10.4istheversionoftheMacOSyouneedtorun
Java
5,vou'llhear
peopletalkabout"TigeronTIger".
II
justmeansJava5onOS
X
10.4).
•
TheSDKdoes
not
includethe
API
documentatIon,andyouneedthat!Gobacktojava.sun.
comandgettheJ2SEAPrdocumentation.YoucanalsoaccesstheAPIdocsonline,without
downloadingthem,butthaI'sapain.Truslus,irsworth
the
download.
•Youneed
a
texteditor.Virtuallyanytexteditorwilldo(vi,emacs,
pica),
includingtheGUIones
thatcomewithmostoperatingsystems.Nolepad,Wordpad,TextEdlt,etc.allwork,aslongas
youmakesuretheydon'lappend
a
".txt"
ontotheendofyoursourcecode.
•
Onceyou'vedownloadedandunpackedfzippedfwhatever(dependsonwhichversionand
for
whichOS).youneed
to
addanentrytoyour
PATH
environmentvariablethatpointstothe
fbln
directoryinsidethemainJavadirectory.Forexample,
if
theJ2SDKputs
a
directoryonyour
drivecalled"j2sdk1.5,O',lookinsidethatdirectoryandyou'lIfindthe"bin"directorywherethe
Javabinaries(thetools)live.ThebindirectoryistheoneyouneedaPATHto,sothaI
when
you
type:
%
javac
atthecommand-line,yourterminalwillknowhowtofindthe
javac
compiler.
Note:
if
youhavetroublewithyouinstallation,werecommendyougotojavaranch.com,andjoin
theJava-Beginningforum!
Actually,
youshoulddothatwhetheryouhavetrouble
or
not.
Nole:muchofthecodefromthisbookIsavailableatwlckedlysmart.com
xxvlll
intra
Last...tMinutethhtgsyouneedtoknow:
This
is
alearningexperience,notareferencebook.Wedeliberately
strippedouteverythingthatmightgetinthewayoflmrningwhateverit
iswe'reworkingonat
thatpointinthebook.Andthefirsttimethrough,
youneedtobeginatthebeginning,becausethebookmakesassumptions
aboutwhatyou'vealreadyseenandLearned.
WeusesimpleUML.-IIkediagrams.
Ifwe'dused
pure
UML,you'dbeseeingsomethingthat
looks
likeJava,but
with
syntax
that'sjustplain
1UTfYflf;.
SoweuseasimplifiedversionofUML
thatdoesn'tconflictwithJava
syntax.
Ifyoudon'talreadyknow
UML.
you
won'thavetoworryaboutleamingJava
and
UMLatthesametime.
Wedon'tworryaboutorganizingandpackagingyourown
codeuntiltheendofthebook.
Inthisbook,youcangetonwiththebusinessoflearningJava,without
stressingover
someoftheorganizationaloradministrativedetailsof
deveLopingJavaprograms.You
will,
intherealworld,needtoknow-and
use--thesedetails,sowecoverthemindepth.Butwesavethemfortheend
ofthebook(chapter17).RelaxwhileyoueaseintoJava,gently.
Theend-of-chapter
exercises
aremandatory;puzzlesare
optional.Answersforbothareattheendofeachchapter.
Onethingyouneedtoknowaboutthepuzzles-tmy
'repuxxles.
As
inLogic
puzzles,brainteasers,crosswordpuzzles,etc.The
exercises
areheretohelp
}'oupracticewhatyou'velearned,andyoushoulddothemall.Thepuzzles
areadifferentstory,andsomeofthemarequitechallengingina
puzzle
way.Thesepuzzlesaremeantfor
pualets,
andyouprobablyalreadyknow
if
youareone.
If
you'renotsure,wesuggestyougive
some
ofthema
try,
but
whateverhappens,don'tbediscouraged
if
you
can't
solveapuzzleorifyou
simply
can'tbebotheredtotakethetimetoworkthemout.
The'SharpenYourPencil'exercisesdon'thaveanswers.
Notprintedinthebook,anyway.Forsomeofthem,there
is
noright
answer,
andfortheothers,partofthelearningexperiencefortheSharpen
activitiesisfor
you
todecide
if
andwhenyouranswersare
right,
(Someof
our
suggested
answersareavailableonwickedlysman.com)
Thecodeexamplesareasleanaspossible
It'sfrustratingtowadethrough200linesofcodelookingforthetwolines
you
needtounderstand.Mostexamplesinthisbookareshownwithinthe
smallestpossiblecontext,so
thatthepartyou'retryingtolearnisclearand
simple.Sodon'texpectthecodetoberobust,orevencomplete.That's
Jour
assignmentforafteryoufinishthebook.Thebookexamplesare
writtenspecificallyfor
learning,
andaren'talwaysfully-functional.
the
intro
Dog
size
barkQ
eatO
chaseCatQ
-
youarehere
~
xxix
techediting:
JessicaandValentin
fecht-ticalEditors
Vjj\el'lt,i,,'s∙be
Valentin
ValentinCreuazhasaMastersdegree
inInformationandComputerSciencefrom
theSwissFederalInstituteofTechnologyin
Lausanne(EPFL).Hehasworkedasasoftware
engineerwithSRIInternational(MenloPark,
CA)
andasaprincipalengineerintheSoftware
EngineeringLaboratoryofEPFL.
Valentinis
theco-founderandCTOofCondris
Technologies,acompanyspecializinginthe
developmentofsoftwarearchitecturesolutions.
Hisresearch
anddevelopmentinterests
includeaspect-orientedtechnologies,design
andarchitecturalpatterns,webservices,and
softwarearchitecture.Besidestakingcareof
hiswife.gardening,reading.anddoingsome
sport,ValentinmoderatestheSCBCDand
SCDJWSforumsatJavaranch.com.Heholds
theSCJP,SCjD,SCBCD,
scwco,
andSCD]WS
certifications.
Hehasalsobadthe
opporruniry
toserveasaco-authorforWhizlabsSCBCD
ExamSimulator.
(We'restillinshockfrom
seeinghimina
tie.)
Jess
worksatHewlett-PackardontheSelf-
HealingServicesTeam.ShehasaBachelor's
in
ComputerEngineeringfromVillanova
University,
has
herSCPJ1.4andSCWCD
certifications,
andisliterallymonthsaway
fromreceiving
herMastersinSoftware
EngineeringatDrexelUniversity(whewl)
Whenshe'snotworking,studyingor
motoringinherMINICooperS,jesscan
befoundfightinghercatfor
yam
as
she
completesherlatestknittingorcrochet
project(anybodywantahat?)Sheis
originallyfromSaltLakeCity,
Utah(no,
she'snotMormon...yes,youweretoo
goingtoask)andiscurrentlylivingnear
Philadelphiawithherhusband.Mendra,and
twocats:ChaiandSake.
You
cancatchhermoderatingtechnical
forumsacjavaranch.com.
"Creditgoestoall,
butmistakesarethesalereponsibilityofthe
author...",Doesanyonereallybelievethat?Seethe
two
peopleon
thispage?Ifyoufindtechnical
problems,it'sprobablytheirfaulL:)
XXX
intra
theintra
$OfrIe
~
0"....
Java
!')I.~t
....
t....
!vi~e
....s...
Our
intrepid
beta
testers
and
reviewer
team:
Ourtophonorsandthanksgotothedirectorofourjavaranch
techreview
team.johannesdeJong.
This
is
your
fifth
timearound
with
us
onaHeadFirstbook,
and
we'rethrilledyou'restillspeaking
to
us,
Jeff
Cumps
isonhisthirdbook
with
us
nowandrelentless
aboutfindingareaswhereweneededtobemoreclearorcorrect.
CoreyMcGlone,
yourock.Andwethinkyougivetheclearest
explanations
onjavaranch,
You'llprobablynoticewestoleoneor
two
ofthem.
Jason
Menard
savedourtechnicalbuttsonmore
thanafewdetails,and
Thomas
Paul,asalways,g-aveusexpert
feedbackandfoundthesubtleJavaissuestherestofusmissed.
JaneGriscti
hasherJavachops(andknowsa
thing
ortwoabout
",-riting)
anditwasgreattohaveherhelpingonthenewedition
alongwithlong-timejavarancher
Barry
Gaunt
:\farilyn
de
Queiroz
gaveusexcellenthelpon
both
editionsofthe
book.
Chris
Jones,Jobn
Nyquist,
James
Cubeta,TerriCubeta,
and
Ira
Becker
gaveusatonofhelponthefirstedition.
Specialthankstoafew
oftheHeadFirsterswho'vebeenhelping
usfromthebeginning:AngeloCeleste,
Mikalai
Zaikin,and
ThomasDuff(twduff.corn).Andthankstoourterrificagent,David
Roge1berg
ofStudioB(butseriously,whataboutthe
movie
rights?)
t\'"~dit
Otherpeopleto
b~e:
•41O'Reilly:
OurbiggestthankstoMikeLoukidesatO'Reilly,fortakinga
chanceonthis,andhelpingtoshapetheHeadFirstconceptinto
abook(and
series).
As
thissecondeditiongoestoprintthere
arenowfiveHeadFirstbooks,andhe'sbeenwith
us
all
the
way.
To
TimO'Reilly,
forhiswillingness
10
launchintosomething
completely
newanddifferent.Thankstotheclever
KyleHart
for
figuring
outhowHeadFirstfitsintotheworld,andforlaunching
the
series.
Finally,to
Edie
Freedman
fordesigningtheHeadFirst
"emphasizethe
head"
cover.
youarehere
~
xxxi
"
stillmoreacknowledgements
Justwhet1youthoughttherewouldt1'tbeat1Y
tMoreackt1owledgetMet1ts*.
MoreJavatechnical
experts
woo
helpedoutonthefirstedition(inpseudo-random
order):
EmikoHori,MichaelTaupitz,MikeGallihugh,ManishHatwalne,JamesChegwidden,
ShwetaMathur,
MohamedMazahim,JohnPaverd,JosephBih,SkulratPatanavanich,
SunilPalicha,Suddhasatwa
Ghosh,RamkiSrinivasan,AlfredRaouf,AngeloCeleste,
MikalaiZaikin
,JohnZoetebier,JimPleger,BarryGaunt,andMarkDielen.
The
firsteditionpuzzleteam:
DirkSchreckmann,Mary'JavaCrossChampion"Leners,Rodney
J.
Woodruff,GavinBong,
andJasonMenard.Javaranchisluckytohaveyouallhelpingout.
Otherco-conspiratorsto
thank:
PaulWheaton,thejavaranchTrailBossforsupportingthousandsofJavalearners.
Solveig
Haugland,mistressofJ2EEandauthorof"DatingDesignPatterns".
Authors
DonSmithandTomNegrino(backupbrain.com),forhelpingusnavigatethe
techbookworld.
OurHeadFirstpartnersincrime,EricFreemanandBethFreeman(authorsofHeadFirst
DesignPatterns),forgivingus
the
Bawls"
tofinishthisontime.
SherryDorris,forthethingsthatreallymatter.
BraveEarlyAdoptersof
the
HeadFirstseries:
JoeLitton,RossP.Goldberg,DominicDaSilva,honestpuck,DannyBromberg,Stephen
Lepp,EltonHughes,EricChristensen,VulinhNguyen,MarkRau,Abdulhaf,Nathan
Oliphant,MichaelBradly,AlexDarrow,MichaelFischer,SarahNottingham,TimAllen,
BobThomas,andMikeBibby(thefirst).
"ThelargenumberofacknOWledgementsisbecausewe'retestingthetheorythateveryonementionedin
abookacknowledgementwillbUyatleastonecopy,probablymore,whatwithrelativesandeverything.If
you'dliketobeintheacknowledgementofour
next
book,andyouhavealargefamily,writetous.
xxxiiintro
1
diveinAQuickDip
BreakingtheSurface
Comeon,thewater's
great!We'lldive
rightinand
writesomecode,thencompileand
run
it.We'retalkingsyntax,looping
andbranching,andalook
atwhat
makes
J
aliasocool.You'llbe
codinginno
time.
Javatakesyoutonewplaces.
Fromitshumblereleasetothe
publicasthe
(wimpy)version1.02,JavaseducedprogrammerswithItsfriendlysyntax,object-orlentedfeatures,
memorymanagement,andbestofaU-thepromiseofportability.Thelureof
wrlte-once/run-
anywhere
Isjusttoostrong.Adevotedfollowlnqexploded,asprogrammersfoughtagainstbugs,
limitations,and,
on
yeah,thefactthatitwasdogslow.Butthatwasagesago.Ifyou'rejuststartingin
Java,
you'relucky.
Someofushadtowalkfivemilesinthesnow,uphillbothways(barefoot),to
geteventhemosttrivialapplettowork.Butyou,why,yovgettoride
the
sleeker,faster.
much
morepowerful
Javaoftoday......".--..•.
thisisanewchapter1
theway
Java
works
fheWayJavaWorks
ThegoalIstowriteoneapplication(inthis
example,aninteractivepartyInvitation)andhave
Itworkonwhateverdeviceyourfriendshave.
sourcecode(or
theInteractive
partyhwltaUon.----..
Source
o
Createasource
document.Usean
establishedprotocol
(Inthiscase,
theJava
language).
2
chapter
1
COIMpiler
Runyourdocument
throughasourcecode
complier.Thecomplier
checksforerrorsand
won'tletyoucompile
untilIt'ssatisfiedthat
everythingwillrun
correctly.
MethodPany()
Oalo;l<'-O
1
invobspe-
clal#1<Method
java.lang.Obf&dO>
4
rerum
Output
(code)
Thecompilercreatesa
newdocument,coded
intoJava
bytecode.
Anydevicecapableof
runningJava
will
beable
toInterpret/translate
thisfile
intosomething
Itcanrun.Thecomplied
bytecodeisplatform-
Independent.
Virtual
Machh'u
Yourfriendsdon'thave
aphysicalJavaMachine,
buttheyallhavea
virtual
Javamachine
(implementedIn
software)
runninginside
theirelectronicgadgets.
Thevirtualmachinereads
and
runs
thebytecode.
What
you'lldo
in
Jav~
You'lltypeasourcecodefile,compileItusingthe
Javaccomplier,
thenrunthe
compliedbytecode
on
a.Javavirtualmachine.
diveInAQuickDip
java.awl∙;
r:.pon
java.awtevenL∙;
:tass
Party(
pc.;b!icvoid
bu~dlnvlte()
(
Fl3me
r
=
IlllW
FtameO;
Labell
=
newLabellParty
at
Tlm's1;
Bttonb=newButIoI'I('You
ber);
Button
C
=
te«
Button("Shoolme'):
Panel
p
=newPanelO;
p.addO):
}II
more
codehere...
)
Source
o
Typeyoursourcecode.
Saveas:
Party.Java
Method
Party()
o
aload_O
1Invokespedal#1<Method
Java,lang.ObjedO>
4
return
MethodvoidbulidInviteO
o
new
#2
<Classjava.aWl.Frame>
3dup
4
Invokespec1al
#J
<Method
Java.aWl.FrameQ>
Output
(code)
Compliedcode:
Party.dass
PartY
at
Tim's1
Virtual
MachlttU
o
Runtheprogramby
startingtheJavaVirtual
Machine(JVM)
withthe
Party.doss
file.TheJVM
translatesthe
bytecode
intosomethingthe
underlyingplatform
understands,andruns
yourprogram.
(NoU:
U,isis
~
....
e.l"t
to
be
d
h-kial...
'101<'11
bt
'OI\'"H:i~
Yedl
tildeilla....OIO'O\t,
bl.t
.f~
MW,'olejll1t
wa,,-t:
'fO'J.
U>
~tt
d
.fccl
.f~
how
it
all
.fib
~etkcYJ
youarehere
~
3
AverybriefhistoryofJava
~
>
«l
~
'0
~
.s
01
:c
~
3500
I!
~
3000
'!
lIlI
2500
"a
c
S
2000
lill
~
>
1500
CII
.,
G)
.z:.
1000
..
.5
1ft
500
G)
1ft
1ft
0
lIlI
U
Java
1.02
250classes
Slow.
Cutenameandlogo.
Funtouse.Lotsof
bugs.
Applets
are
theBigThing.
500
classes
A
little
faster.
Morecapable,
friendlier.
Becomingvery
popultJr.
BetterGUIcode.
Java
2
(wnloKs
1.2..
t~)
2300dasses
Much
faster.
Can(sometimes)runat
nativespeeds.Serious,
powerful.
Comesinthree
flavors:
MicroEdition(J2ME),
StandardEdition
(J2SE)and
EnterpriseEdition
(J2EE).
Becomes
the
langutlge
of
chola
fornewenterprise
(especially
web-based)and
mobileapplications.
Java
5.0
(wrsloKs
1.5
attdup)
3500
classes
Morepower,
~/e,
to
develop
with.
Besidesaddingmorethana
thousandadditionalclasses,
Java5.0(knownas"Tiger"')
added
majorchangesto
thelanguageitself,making
iteasier(atleastintheory)
forprogrammersand
giving
it
newfeaturesthatwere
popularin
otherlanguages.
....
'-
2
a.
III
s:
o
~
LookhoweasyIt
istowrite
Java.
diveInAQuickDip
TrytoguesswhateachlineofcodeIsdoinq.;
(answersareonthenextpage),
.intsize
=
27;
Stringname
=
UFido";
Dog
rnyDog
=
newDog(name,size);
x
=
size-
5j
if
(x
<
15)
rnyDog.bark(8);
while(x
>
3){
myDog.play();
}
.int[]nurnList
=
{2,4,6,S};
System.out.print(
u
Be110");
System.out.print(UDog:
U
+
name);
Stringnurn
=US";
intZ
=
Integar.parselnt(nurn);
-:.....-y{
readTheFila(UrnyFile.txt
H
);
}
catch(FileNotFoundExceptionex){
syetem.out.print(UFilenotfound.");
}
Q..:
I
seeJava
2andJava5.0,but
was
therea
Java
3
-.d
41
And
why
IsItJava
5.0
butnotJava
2.07
:The
joys
ofmarketing...whentheversionofJava
ed
from
1.1
to
1.2,
thechangestoJavawereso
rnatic
thatthemarketersdecidedweneededawhole
"name:so
theystartedcallingIt
Java
2,
eventhough
actualversionofJavawas
1.2.
Butversions
1.3
and
1.4
ftfe
stillconsidered
Java
2.
Therenever
was
aJava
3
or
~_
Be9inningwithJavaversion1.5,themarketersdecided
onceagain
thatthechangesweresodramaticthata
newnamewasneeded(andmostdevelopersagreed),so
theylookedattheoptions.ThenextnumberInthename
sequencewouldbe
∙3:butcaIIingJava1.5
Java
3
seemed
moreconfusing,so
theydecidedtonameIt
Java
5.0
to
matchthe
"5~
inversion
"l.S~
So,
theoriginalJavawasversions
1.02
(thefirstofficial
release)
through
1.1
werejust
"Java"
Versions
1,2,1.3,
and
1.4
were"Java
2~
Andbeginningwithversion
1.5,
Javais
called"Java
5.0~
Butyou'llalsoseeitcalled"Java
5∙
(without
the
",0")
and"Tiger"(itsoriginalcode-name).Wehaveno
idea
whatwillhappenwiththe
next
release...
youarehere
~
5
.'
whyJavaIscool
pen
your
pencil
answers
lookhoweasyIt
IstowriteJava.
intsize::;
27;
String
name
=
#FidoHj
Dog
myDog::;newDog(name,
size);
x
=
size-
5;
if
(x
<
15)
myDog.bark(8);
while(x
>
3){
myDog.play(
l;
}
intl]numList
=
{2,4,6,8};
System.out.print(HHello
R
);
System.out.print(HDogl
U
+
name);
Stringnum::;
US";
fntz
=
Integer.parselnt(num);
try{
}
catch(FileNotFoundExceptionex){
System.out.print(HFilenotfound.");
}
6
chapter1
Don'twotryaboutwhether
you
understandanyofthis
yeti
EverythinghereIsexplainedingreatdetall!nthebook,most
withinthe
first
40pages).IfJavaresemblesalanguageyou've
usedinthepast,someofthiswill
be
simple.Ifnot,don'tworry
about
it.
We'llgetthere...
dett.rt
~ ~~
of
l~,)lW1"aridbl,
Nlr.ed
'~
..
c'
~r.d ~i'"
it
~
."Iot
"Fido'
du.lm
.1_
D~ v~blc
'..
yD~'
a.v:l
~U ~
_
D~ 1Iii~ (~'
..
rod
'siu'
wbu-att".fro,.
2.1(.,,,Iot
of
'siu')
~,J
it
to
~ y~bl,
...a",«l'1.'
try
to
do
~i~
...
~ybc ~ thi~
'IlI('l"t
try~
isJ,'t
~.lI'.Ued
to
~
..
~ ~
tot
fileIIolMCll"..yFile.bi∙
(ar
.Ii.
lustTRy'
1;0
~e.ld ~
fild
..lIS!bethe
erod
of
~"I:.h~
to
try",
so
r
~lOC.U
'f'"
te<Jd
&-y
Md~Y th~
..
this
~
be
wkrt
Oil
fi,.oNt
~
u.e
tho
h-led
did,,'i
warle._
~
!he
I:.hi~
'Ill(
u-ied
t~iled,
rri"t
"Fil,
root
fOllNl"
out
at
the
~-liM
locks
li~ t"Icryl:.hi~
i"
the{}
is
wlIat
to
do
~
the
'fry'
did,,'t
~
...
Codestructure
i.,
Java
Put
aclassinasourcefile.
Put
methodsinaclass.
PutstatementsInamethod.
Whatgoesina
source
file?
Asourcecodefile(withthe
.java
extension)holdsone
class
defini-
tion.The
class
representsa
piece
ofyourprogram,althoughavery
tinyapplication
might
need
just
a
single
class.
The
class
mustgo
withina
pairofcurlybraces.
Whatgoes
ina
class?
A
classhas
oneormore
methods.
IntheDogclass,the
bark
method
willholdinstructionsforhowthe
Dogshould
bark.
Yourmethods
must
be
declared
insideaclass
(inotherwords,withinthecurly
braces
ofthe
class).
WhatgoesIna
method?
Withinthecurlybracesof
a
method,writeyourinstructions
forhow
thatmethodshould
be
performed.Method
code
is
basi-
callyasetofstatements,andfor
nowyoucan
thinkofamethod
kindoflikeafunctionorproce-
dure.
diveInAQuickDip
publicclass
Dog{
class
publicclassDog{
voidbark(){
tttefho~
publicclassDog
l
voidbark(){
sta
temen
tl;
sta
temen
t2;
}
sfafetttet1fs
youarehere•7
aJavaclass
Attafottty
ofaclass
WhenthejVMstartsrunning,itlooksfortheclassyougive
it
atthecom-
mandline.Then
it
startslookingforaspecially-Writtenmethodthatlooks
exactlylike:
publicstaticvoidmain(String()argsl(
II
yourcodegoeshere
Next,theJVMrunseverythingbetweenthecurlybraces{}ofyourmain
method.EveryJavaapplicationhastohaveatleastoneclass.andatleast
onemainmethod(notonemainperclass;justonemainper
applU:ation).
DOI'l'i
warry
aW
",e"'O'riz.j..
~
a..
yt.hiIl9
\"'i~ht
l'IOW...
this
tholf'W"
is
}st
to
~d
yC'J.
sta....ud.
8
chapter
1
diveInAQuickDip
Writi"Qaclasswithamain
InJava,everythinggoesinaclass.You'lltypeyoursourcecodefile(witha
.java
extension),thencompileitintoanewclassfile(witha.
class
extension).
Whenyourunyourprogram,you'rereallyrunninga
class.
RunningaprogrammeanstellingtheJava
VIrtual
Machine
(JVM)
to"Loadthe
Hello
class,
then
start
executingits
main()
method.Keeprunning
'til
allthe
codeinmain
is
finished."
In
chapter
2.
wegodeeperintothewhole
class
thing,butfornow,allyouneedto
think
is,
how
cUJ
1
writeJava
code
$0
thatit
will
run
1
Andit
all
beginswith
mainf).
The
mamO
methodiswhereyourprogramstartsrunning.
No
matterhowbigyourprogramis(inotherwords,nomatterhowmanyclasses
yourprogramuses),there'sgot
to
be
a
mainO
methodtogettheballrolling.
MyFlrstApp.Java
~~
-
4t...
,,\~
t
''''''
MyFlratApp.clau
-
public
class
MyFirst.Aflp(
publicstatic
void
main
(strinq[]
arqs)
Systall.out.priJ)t1n("I
Ma!H);
System.
out.
println
('''l.'be
World");
)
o
Save
MyFirstApp.java
o
Compile
javacMyFirstApp.java
E)Run
~
%java
MyFirstApp
I
Rule!
TheWorld
you
arehere
~
9
statements,
looping,
branching
Whatca.,yousayI.,the",al.,",ethod1
Onceyou'reinsidemain(or
any
method),the
fun
begins.Youcan
say
allthe
normalthings
that
yousay
inmostprogramminglanguagesto
make
the
computer
do
something.
Yourcodecantellthe
JVM
to:
o
dosolttethi.,g
Statements:declaratlons,assignments.
methodcalls.etc,
intx
~
3;
Stringname
=
~Dirk";
x
=
x
*
17;
System.ouc.print("xis"
+
x);
double
d
=
Math.random();
II
thisis
a
comment
e
dosolttethlttQagal.,andagal"
Loops:(orandwhile
while
(x
>
12)
x
=)(
-1;
Syntax
Fun
..Eachstatementmustendina
semicolon.
x=x+1;
II
thislinedisturbsme
..Mostwhitespacedoesn'tmaner.
x
=
22;
3
x
..Asingle-linecommentbegins
withtwoforwardslashes.
intweight;
Iitype:
int,
name:
weight
..Variablesaredeclaredwitha
nameanda
type
(you'lllearnabout
alltheJava
types
Inchapter3).
for(intx
ee
0;
x
<
10;
x
=
x
+
1)(
System.out.print("xisnow
II
+
x);
if
«x
<
3)
&
(name.equals("Dirk
ll
»))
System.out.println(~Gently");
e
dosolttethlttQuttderthisCO.,dltlon
Branching:
If/else
tests
if
(x
==
10)
1
System.out.print("xmUStbe
10");
else{
System.out.print("xisn't
lOll);
System.out.print("thislinerunsnomatterwhat
ll
);
..Classesandmethodsmustbe
deflned
withinapairofcurlybraces.
publicvoidgo()(
II
amazingcodehere
}
10chapter1
dive
InAQuickDip
Youcandoasimplebooleantestbychecking
thevalueofavariable,usinga
comparison
operator
including:
<
(lessthan)
>
(greaterthan)
=
(equality)(yes,that's
two
equalssigns)
Noticethedifferencebetween
the
assignment
operator(a
single
equalssign)andthe
equals
operator
(two
equalssigns).
Lots
ofprogrammers
accidentally
type•
whentheywant-.(Butnot
you.)
iotx
~
4;
II
assign4tox
while
(x
>3){
II
loopcode
will
runbecause
II
x
is
greaterthan3
x
=
x-I;
II
orwe'dloopforever
ShMplebooleantests
incz
=
27;
II
while(z
=~
17)
II
loopcodewill
not
runbecause
II
zis
not
equalto17
.»
Loopit1g
a.,d
loopi.,g
at'd...
while
(more
Balls
==
true){
keepJugg/ing();
}
The
syntax
(not
to
mentionlogic)is
so
simple
you'reprobablyasleepalready.
As
longassome
conditionistrue,youdoeverythinginsidethe
loop
block.
Theloopblockisboundedbyapairof
curlybraces,sowhateveryouwanttorepeatneeds
tobeinsidethatblock.
Thekeyto
a
loopisthe
conditional
test.
lnJava,a
conditionaltestis
an
expressionthatresultsin
a
boolean
vaJue-inotherwords,somethingthatis
either
true
or
false.
lfyousaysomethinglike,"While
i.aCnamlnTMTub
is
true;
keepscooping",youhaveaclearboolean
test.
Thereeither
is
icecreaminthecuborthere
isn't.
Butifyouwereto
say.
"While
Bob
keep
scooping",youdon'thaveareal
test,
Tomake
that
work,you'dhavetochangeittosomething
like."WhileBobissnoring...
~
or"WhileBobis
not
wearing
plaid..."
Java
hasthreestandardLoopingconstructs:
uihile;
do-iahile,
and
for.
You'llgetthe
full
loopscooplater
inthebook,butnotforawhile,solet'sdo
whi~for
now.
youarehere
~
11
Javabasics
Q:
Whydoeseverythinghave
to
beIna
dass7
A:
~ava
isanobject-oriented
(00)language.It'snotIikethe
olddayswhenyouhadsteam-
drivencompliersand
wroteone
monolithicsourcefilewithapile
ofprocedures.Inchapter
2
you'll
learn
thataclassIs
a
blueprintfor
an
object,andthatnearlyevery-
thinginJavaIsanobject.
Q:
DoIhavetoputamainIn
everyclassIwrite1
A:
Nope.AJavaprogram
mightusedozensofclasses(even
hundreds),
butyoumightonly
have
one
withamaInmethod-
theonethatstartstheprogram
running.You
mightwrItetest
classes,
though,thathavemain
methodsfortestingyour
other
classes,
Q:
InmyotherlanguageIcan
doaboolean
testonanInteger.
InJava,
canIsaysomethinglike:
intx..
1;
while
(J&:)(
A:
No.A
boolean
andan
integer
arenotcompatibletypesIn
Java.Since
theresultofacondi-
tional
test
must
beaboolean,the
onlyvarIableyoucandirectlytest
(withoutusingacomparisonop-
erator)Is
a
boolean.
Forexample,
youcansay:
booleanisBot•true;
while(llIHot)()
12
chapter1
Exall1ple
of
a
while
loop
publicclassLoopy{
publicstaticvoidmain(String[]args)(
int
x..
1;
System.out.println("BeforetheLoop");
while
(x
<
4){
System.out.println("Intheloop");
System.out.prlntln("Valueof
x
is"
+
x);
x
=
x
+
1;
)
System.out.println("Thisisaftertheloop");
%
java
Loopy
Beforethe
Loop
Intheloop
Va.lue
ot
xis
1
Intheloop
Va.lue
ofx
i8
2
In
th8
loop
Value
of
x
is3
Thisisaft.r
the
loop
,------BULLD
POI~
----------,
•Statementsendinasemicolon;
•Codeblocksaredefined
by
apairof
cu~y
braces{}
•
Declarean
int
variablewithanameanda
type:
Intx;
•Theassignment
operator
Is
one
equalssign
=
•Theequalsoperatoruses
two
equalssigns
==
•A
while
loop
runseverythingwithin
its
block(defined
by
cu~y
braces)aslongasthe
conditionaltest
Istrue.
•If
theconditionaltestis
fa1S8,
the
while
loopcodeblockwon't
run,andexecutionwillmovedowntothecodeImmediately
efter
theloopblock.
•PutabooleantestInsideparentheses:
while(x
=
4)(}
Conditlo"albra"chl"Q
Java,an
if
testisbasicallythesameasthebooleantestina
'le
loop-exceptinstead
of
saying,
~UJhile
there's
still
beer.,",
u']]
say,
~ifthere's
still
beer.,"
cLass
If
Test(
publicstaticvoidmain(String[)args){
int
x
=
3;
if
(x
==
3)
System.out.println("xmustbe
3
H
);
System.out.println("Thisrunsnomatterwhat");
,javaIf'rest
JI:
must
be
3
Thisrunsnomatterwhat
Thecodeaboveexecutesthelinethatprints
"x
mustbe3"only
if
thecondition
(x
isequalto3)
is
true.Regardlessofwhether
it'strue,though,thelinethatprints,"Thisrunsnomatterwhat"
~ill
run.
So
dependingonthevalueof
x;
eitheronestatement
ortwo
will
printout.
Butwe
canaddan
else
tothecondition,sothatwecan
saysomethinglike,
"Iftbere's
stillbeer,keepcoding,
else
(otherwise)getmorebeer,andthencontinueon..."
::lassIfTest2{
publicstaticvoidmain(String!)
a
rqs)(
int
x
=
2;
if
(x==
3)
System.out.println("xmust
be
3
H
);
else(
System.out.println("xisNOT
JH);
System.out.println("Thisrunsnomatterwhat");
,javaIf'l'est2
II
is
~
3
'1'hi1
runsnomatter
what
diveInAQuickDip
Glv~n
the
output:
%javaDooBee
DooBeeDooBeeDo
FJIIln
th~
missingcode:
publicclassDooBee{
publicstaticvoidmain(StringOargs)I
intx=l;
while
(x
<__}{
System.out.
("Doo");
System.out.
(MBee");
x
=
x
+
1;
}
If(x==__}{
System.out.pri
nt("Do
H
};
I
}
}
youarehere
~
13
serious
Java
app
CodingaSeriousfushtess
Applicatfott
Let'sput
all
your"newJavaskillstogooduse
with
somethingpractical.Weneeda
class
with
a
mains);
an
int
anda
String
variable.a
whik
loop,andan
if
test.Alittle
morepolish,andyou'llbebuildingthatbusinessback-
endinnotime.But
beJoreyou
lookatthecodeonthis
page,
thinkforamomentabouthow
you
wouldcode
that
classicchildren'sfavorite,"99bottlesofbeer."
pUblicclassBeerSong(
publicstaticvoidmain(String[)args)(
intbeerNum99;
Stringword
~
"bottles";
while(beerNum>
0)I
if(beerNum
==
1)(
word-"bottle
H
;
II
singular,as
in
ONE
bottle.
System.out.println(beerNum
+"
H
+
word
+"
ofbeeronthewall
H
);
System.out.println(beerNum
+"
H
+
word
+"
ofbeer.");
System.out.println("Takeonedown.
H
);
System.out.println("Pass
it
around.");
beerNum
=
beerNum-
1;
if(beerNum
>
0)(
System.out.println(beerNum
+"
H
+
word
+"
of
beeronchewall
H
);
else(
System.out.println("Nomorebottlesofbeeronthewall
H
);
)II
end
else
f
II
endwhileloop
)II
endmainmethod
II
en~
class
There'sstilionelittleflawInour
code.
It
compliesandruns.
butthe
outputIsn't100%perfect.See
If
youcanspottheflaw,andfixIt.
14
chapter1
diveInAQuickDip
Bob'salarmclockringsat8:30Mondaymorning,justlikeeveryotherweekday.
ButBob
had
a
wild
weekend,andreachesfortheSNOOZEbutton.
Andthat'swhentheactionstarts,andtheJava-enabledappliances
cometolife.
(
-
First,thealarmclocksendsamessagetothecoffeemaker*"Hey,thegeek's
sleepinginagain,delaythecoffee
12
minutes."
ThecoffeemakersendsamessagetotheMotorola'>'
toaster,
"Holdthetoast,Bob'ssnoozing."
ThealarmclockthensendsamessagetoBob's
NokiaNavigator™cellphone,"CallBob's9
o'clock
andtellhimwe'rerunningalittlelate."
Finally,the
alarmclocksendsamessageto
Sam's
(Sam
isthedog)wirelesscollar,withthetoo-familiarsignalthat
means,"Getthepaper,butdon'texpectawalk."
His
toast
istoasted.
A
fewminuteslater,thealarmgoesoffagain.And
again
Bob
hits
SNOOZEandtheappliancesstartchattering.Finally,
the
alarmringsathirdtime.ButjustasBobreachesforthe
snoozebutton,theclocksendsthe
"jumpandbark"signaltoSam's
collar.Shockedto
full
consciousness,Bobrises,gratefulthathisJava
skillsanda
Little
trip
to
RadioSbackn<haveenhancedthedaily
routines
of
his
life.
His
coffeesteams.
His
paper
awaits.
Justanotherwonderfulmorning
in
TheJava--ErUlbled
HOMSB.
You
can
have
aJava~enabled
home.
StickwithasensiblesolutionusingJava,
Ethernet,
andJinitechnology.Bewareofimitationsusingotherso-called"plug
andplay"(whichactuallymeans"plugandplaywithitforthenextthreedays
trying
to
getittowork")or"portable"platforms.Bob'ssisterBerryDiedoneof
those
others,
andtheresultswere,well,notveryappealing,orsafe.
Bit
ofashameaboutherdog,too...
Couldthisstorybetrue?Yesandno.Whilethere
are
versionsofJavarunninginde-
vicesIncludingPDAs,cellphones
(especially
cellphones),pagers,rings,smartcards,
andmore
-you
mightnotfindaJavatoasterordogcollar.Buteven
jf
youcan't
findaJava-enabledversionofyourfavoritegadget.youcanstilirunitas
if
it
were
a
JavadevicebycontrollingitthroughsomeotherInterface
(say,yourlaptop)that
is
runnIngJava.This
Is
knownastheJini
surrogatearchitecture.
Y~
youcon
havethat
geekdreamhome.
∙IPmulticast
Ifyou'regonnabeallpickyaboutprotocol
youarehere
~
15
let'swriteaprogram
Try
mynew
phrase-a-maticand
you'llbe
a
slicktalker
justlikethebossor
thoseguysinmarketing.
publicclassPhraseQlatic(
publicstatic
voidmain(String(l
args){
//iliaD
thNt
sets
of
words
to
choosefrom.
leWyoar
own!
String[]wordListOne:::{"24/7"/'multi-
Tiar","30,OOOfoot","B-to-B","win-win","front-
end",
"web-based",
"pervasive","smart","six-
sigma",
"critical-path",
"dynamic"}
j
Strinq[]wordListTwo:::
I
"empowered",
"sticky",
"value-added.",
"oriented",
"centric","distributed",
"clustered","branded","outaide-the-box",''positioned'',
"networked","focused"/"leveraged","aligned",
"targeted",
"shared"/
"cooperative","accelerated"};
OK,sothebeersongwasn't
really
aserious
businessapplication.Still
needsomething
practicaltoshowtheboss?Checkoutthe
Phrase-O-Matlccode.
16chapter
1
Strinq[]wordListThree
=
{"process",
"tipping-
point","solution",
"architecture",
"core
competency",
"strategy","mindshare","portal",
"apace"/"vision",
'~adigm",~ssion"};
//find
out
!low
many
word.
aN
In...d11bt
iotone.Lenqth'"wordListOne.
length;
int
twoLength'"wordListTwo.length;
intthreeLength
=
wordListThree.lenqthj
//generate....
randomnumbers
intrandl
:lII
(int)
(Math.random()'"ooeLenqth)
j
int
rand2:::(int)(Math.randomO•twoLength);
intrand3'"(int)(Math.randa:n()"threeLength);
O
//
now
buildapllrue
Stringphrase'"
wordListOne[randl]
+""
+
wordListTwo[rand2]
+""+
wordListTbree[rand3];
//print
oat
the
phra..
Sys.tem.out.println("What
we
needisa"
+
phrase);
}
Phrase...O...Matlc
low
Itworks,
In
anutshell,theprogrammakesthreelistsofwords,thenrandomlypicksoneword
fromeach
of
thethree
lists;
andprintsouttheresult,Don'tworry
if
youdon'tunder-
m.nd
exactly
what'shappeningineachline.Forgoshsakes,you'vegotthewholebook
~d
ofyou,sorelax.
This
isjustaquicklookfroma30,000footoutside-the-box
a.rgetedleveragedparadigm.
i.
Thefirststep
is
tocreatethreeStringarrays-thecontainersthat
will
hold
all
the
-..ords.
Declaringandcreatinganarrayiseasy;here'sasmallone:
bch
wordisinquotes(asallgoodStringsmustbe)andseparatedbycommas.
•
Foreachofthethree
lists
(arrays),thegoal
is
to
pickarandomword,sowehave
knowhowmanywords
areineachlist,
If
thereare14wordsina
list,
thenweneed
randomnumberbetween0and13(Javaarraysarezero-based,sothefirstwordisat
ition0,
thesecondwordpositionI,andthelastwordisposition13ina14-element
~').
Quitehandily,
ajava
array
is
morethanhappytotellyouitslength.Youjust
toask.Inthepetsarray,we'dsay.
satz
=:
pets.length;
z
wouldnowholdthevalue3.
,.Weneedthree
rand~m
numbers.Javashipsout-of-the-box,off-the-shelf,
shrink-
pped,andcorecompetentwithasetofmathmethods(fornow,thinkofthemas
ctions).
The
random()
methodreturnsarandomnumberbetween0andnot-
'te-l,sowehavetomultiplyitby
thenumberofelements(thearraylength)inthe
we'reusing.Wehavetoforcetheresulttobeaninteger(nodecimalsallowed!)so
putinacast(you'llgetthedetailsinchapter4).It'sthesameasifwehadanyfloat-
pointnumberthatwewantedtoconverttoaninteger.
~t
z•(int)24.6;
owwegettobuildthephrase,
by
pickingawordfromeachofthethree
lists,
smooshingthemtogether(alsoinsertingspacesbetweenwords).Weusethe
,,+n
rator,which
concatenaus
(wepreferthemoretechnical'
S1TU>OShes')
theStringobjects
ether.To
getanelementfromanarray,yougivethearraytheindexnumber(posi-
-n)
ofthethingyouwantusing:
SUinqs'"
pet.
[0
l://
sisnowtheString"FiOO"
....+""+
"isa
dog";//•
is
now
"Fido
ill
a
dog"
5.
Finally,weprintthephrasetothecommand-lineand...voila
I
Wen
inmarketing.
diveInAQuickDip
what
we
need
hereIsa•••
pervasivetargeted
process
dynamicoutside-
the-boxtipplng-
point
smartdistributed
core
competency
24/1empowered
mindshare
30,000fool
win-win
vision
stx-slqrna
net-
worked
portal
youarehere
~
17
thecomplierandtheJVM
FiresideChats
~
Ton1gb.t'sTalk:Thecompller
and
~e
JVM
battleover
the
question.
"Who'smore
lmportaJlU"
!he
Java
VlrtualMachine
What,areyoukidding?
HELLO.
IamJava.
I'mtheguywhoactuallymakesaprogram
run.
Thecompilerjustgivesyoua
file.
That's
it.
Justafile.You
can
printitoutanduseit
for
wall
paper,kindling,liningthebirdcage
whateuer,
butthefiledoesn't
do
anythingun-
less
I'mthere
La
run
it.
Andthat'sanotherthing.thecompilerhas
nosenseofhumor.Thenagain.
if
ycm
had
to
spend
all
daycheckingnit-pickylittle
syntax
violations...
I'mnotsayingyou're,like,
complmly
useless.
Butreally,what
is
itthatyoudo?Seriously.I
havenoidea.A
programmercouldjustwrite
bytecodeby
hand,andI'dtake
it.
Youmight
beoutofajobsoon,buddy.
(Irestmycaseon
thehumorthing.)Butyou
still
didn'tanswermyquestion,what
do
you
actuallydo?
18
chapter1
The
Complier
I
don'tappreciatethattone.
Excuseme,
butwithout
me,
whatexactly
wouldyourun?
There's
aTMSonJavawas
designedtouseabytecodecompiler,foryour
information.
If
Javawereapurelyinterpreted
language,where-s-atruntime-s-thevirtual
machinehadtotranslatestraight-from-a-text-
editorsourcecode,
a
javaprogramwould
runat
aludicrouslyglacial
pace.
java's
hada
challengingenoughtimeconvincingpeople
thatit'sfinallyfastandpowerfulenoughfor
mostjobs.
Excuseme,butthat'squiteanignorant(not
tomention
arrogant)
perspective.Whileit
is
true
that-tJuoretically--you
canrunany
properlyformattedbytecodeeven
if
it
didn't
comeoutofaJavacompiler,inpracticethat's
absurd.A
programmerwritingbytecodeby
handislikedoingyourwordprocessingby
writingrawpostscript.
AndIwouldappreciate
it
if
youwould
not
refer
to
meas"buddy."
TheJavaVirtualMachine
Butsomestillgetthrough!
I
canthrowClass-
CastExceptions
andsometimesIgetpeople
tryingtoputthewrongtypeofthinginan
array
thatwasdeclaredtoholdsomething
else,and-
OK.Sure.Butwhatabout
security?
Lookatall
thesecuritystuff
I
do,andyou'relike,what,
checkingfor
semicolons?
Oooohhhbigsecurity
risk!
Thankgoodnessforyoul
Whatever.
I
havetodothatsamestuff
too,
though,justtomakesurenobodysnuckin
afteryouandchangedthebytecodebefore
runningit.
Oh,youcancounton
it.
Buddy.
dive
InAQuickDip
TheCompiler
RememberthatJavaisastrongly-typedlan-
guage,
andthatmeansIcan'tallowvariables
to
holddataofthewrongtype.Thisisa
crucialsafety
feature,andI'mabletostopthe
vastmajorityofviolationsbeforetheyeverget
toyou.And
I
also-
Excuseme,but
I
wasn'tdone.Andyes,there
are
somedatatypeexceptionsthatcanemerge
atruntime,butsomeofthosehavetobe
allowedto
supportoneofJava'sotherimpor-
tantfeatures--dynamicbinding.Atruntime,
aJavaprogramcanincludenewobjectsthat
weren'teven
known
totheoriginalprogram-
mer,so
I
havetoallowacertainamountof
flexibility.Butmyjobistostopanythingthat
would
never-could
never-succeedatrun-
time.Usually
I
cantellwhensomethingwon't
work,
forexample,ifaprogrammeracciden-
tally
triedtouseaButtonobjectasaSocket
connection,
I
woulddetectthatandthus
protecthimfromcausingharmatruntime.
Excuseme,
butIamthefirstlineofdefense,
astheysay.Thedatatypeviolations
I
previous-
ly
describedcouldwreakhavocinaprogram
if
theywereallowedtomanifest.
I
amalso
theonewhopreventsaccessviolations,such
ascodetryingtoinvokeaprivatemethod,or
changeamethodthat-forsecurityreasons
-mustneverbechanged.Istoppeoplefrom
touchingcodethey'renotmeanttosee,
includingcodetryingtoaccessanotherclass'
critical
data.Itwouldtakehours,perhapsdays
even,todescribe
thesignificanceofmywork.
Ofcourse,butas
I
indicatedpreviously,ifI
didn'tpreventwhatamountstoperhaps
99%
ofthepotentialproblems,youwouldgrindto
ahalt.
Anditlookslikewe'reoutoftime,so
we'llhavetorevisitthisina
laterchat.
youareh
ere
~
19
•
exercise:CodeMagnets
CodeMagnets
AworkingJavaprogramisallscrambledup
onthefridge.Canyourearrangethecode
snippetstomakea
workingJavaprogram
thatproducesthe
outputlistedbelow?
Some
ofthecurlybracesfellonthefloor
andtheyweretoosmalltopickup,sofeel
freetoaddasmanyofthoseasyouneed!
if(
JC
<:<:
1)(
SYSt.,~
......OUt.
∙Pr.lnt("d"
JC....)•
...-1:'
if
(x
==
2){
class
Shuftlel(
publicstaticVoid
main(String
I)
args)(
if
pc.
>
2){
sygtem.out.print(~a~);
intx
3;
>r..
x-I;
System.
Out.
.pr.l
nt(,,_,,);
while(x
>
0){
~
'I.,
javaShufflel
a-bc-d
"BE
the
oomriler
Each
of
the
JIlVll
filesonthispage
represents
11
completesourcefile.
Yourjob
is
to
pIa}'
cotJ1Piler
and
determinewhethereach
of
these
fileswillcottlPile.
If-they
won't
cottlPile.how
woald
you
l"lX
them?
A
diveInAQuickDip
B
publicstaticvoidmain(String[]args)
int
x
=
5;
while(x
>
1)
x
=
x-I;
if(
x
<
3){
System.out.println(~small X~)i
c
~_ass
Exerciselb{
publicstaticvoidmain(String[)args)
intx'"
Ii
while(x
<
10
if(
x
>
3)(
systam.out.println(~big
X")i
classExerciselb{
int
x•
5;
while(x
>
1)
x
=
x-
Ii
if(
x
<
3)(
System.out.println(~small x~);
youarehere
~
21
puzzle:crossword
Ja~Cr~ss
t.
O
let'sgiveyourrightbrainsomethIngtodo.
It'syourstandardcrossword,butalmostall
of
thesolutionwordsarefromchapter1.Just
tokeepyouawake,wealsothrewin
a
few
(non-Java)wordsfromthehigh-techworld.
Across
4.
Command-lineinvoker
6.Back
again?
8.
Can'tgobothways
9.
Acronym
for
yourlaptop'Spower
12.
numbervariabletype
13.Acronym
fora
chip
14.
SaysomethIng
18.Quiteacrewofcharacters
19.Announce
a
new
class
ormethod
21.
What's
a
promptgoodfor?
22
chapter
1
12
J
4
S
I
f-
II
~
'---
8
-
9
10
~
l..-
2
I-
-
f-
~
I--
13
4
5
6
--
-
-
~
18
9
I-
-
20
L-
'--
bL
1
21
\
Down
1.Not
aninteger(or__your
boat)
2.
Come
back
empty-handed
3.Open
house
5.
'ThIngs'holders
7.Until
attitudesimprove
10.Sourcecodeconsumer
11.Can'tpinitdown
13.
Dept.
ofLANJockeys
1S.Shockingmodifier
16.Justgonahaveone
17.Howtogetthingsdone
20.Bytecode
consumer
AshortJavaprogramislistedbelow.Oneblockoftheprogram
ismissing.Yourchallengeisto
matchthecandidateblockof
code
(onthe
left),withtheoutput
thatyou'dseeiftheblock
wereinserted.Notallthelinesof
outputwillbeused,andsome
ofthelinesof
output
might
beusedmorethanonce.Drawlines
connectingthecandidateblocksof
code
withtheirmatching
command-line
output.(Theanswersareattheend
of
thechapter).
diveInAQuickDip
classTest{
publicstaticvoidmain(String[)args)
int
x
0;
int
y
=
0;
whilex
<
5)
System.out.print(x
+""
+
y
+"");
x
=
x
+
1;
candidates:Possibleoutput:
0011213242
lJ.
21324253
00112336410
0214253641
you
arehere
~
23
puzzle:
PoolPuzzle
}
if(
x
<
1){
if(){
while(){
classPoolPu2zleOne{
publicstaticvoidmain(String
(I
arga){
intx
=
OJ
P~l
puzzle
Your
job
istotakecodesnippetsfromthe
poolandplacethem
intotheblank
linesinthecode.Youmay
notusethe
samesnippetmorethanonce,and
you
won'tneedtouseallthesnip-
pets.Your
goal
istomakeacia
5S
that
willcompileandrunandproducethe
outputlisted.Don'tbefooled-thisone's
harderthanitlooks.
Output
}
if(
x
1){
}
System.out.println("");
%javaPoolPuzzleOne
anoise
annoys
anoyster
}
if
)
{
Note:Eachsnippet
fromthepoolcanbe
used
onlyoncel
}
}
24
chapter1
A
diveInAQuickDip
classExercise1b{
publicstaticvoidmain(StringI]
arqs){
int
x
=
1;
while(x
<
10)
x=x+l;
if(
x
>
3){
System.out.println("bigx")j
eMagnets:
__
~ss
Shuftlel{
~~lic
staticvoidmain(String
(J
args){
int
x
=
3;
....nile
(x
>
0){
}
Thiswillcompileandrun(nooutput),but
without
Q
lineaddedtotheprogram,it
wouldrunforeverinaninfinite'while'loop!
if
(x
>
2){
Systern.out.print(Ua")i
}
x
=
x-
Ij
System.out.print("-");
if
(x
==
2){
systern.out.print(Nbe")j
}
if
(x
==
1),{
Systern.out.print("d")j
x
=
x-
Ij
}
}
java
Shuffle!
a-bc-d
classFoo{
publicstaticvoidmain(String
I]
args){
intx
=
s;
while(x
>
1)
x
=
x-
Ii
B
if(
x
<
3){
system.out.println("small
x");
Thisfilewon'tcompilewithout
0
}class
d~c1Qratlon,
and
don't
forget
)thematchingcurlybrace!
classExerciss1b{
publicstatic
void
main(String
U
args){
intx
=
Sj
while(x
>
1
x..x-
1;
C
if(
x
<
3)
System.out.println(~small
X∙]i
}
The'while'loopcodemustbein-
sidea
method.
It
can't
justbe
hanging
out
insidetheclass.
youarehere
~
25
puzzleanswers
classPoolPuzzleOne{
publicstaticvoidmain(String(]args){
intx
==
0;
while(X•4){
System.out.prlntf'Q'');
if(
x
<
1){
System.out.prirrt("):
}
System.out.prlrrt(n");
if(X>l){
System.out.prfnt('oyster");
x
=
x
+
2;
fF
IV
P
•
s
'L
-
J
A
V
A
00
p
U
,,-
-
R
W
.E-
I
B
IS
B
AIN
It
'V
-
R
C
H
A
D
l
1:
'"-
A
N
T
0
A
I
-
--
It
Y
L
M
R
t
's
y
sir
E
8
M
a
u
T
P
R
r
N
T
L.
T
A
I
A
~
--
-
-
~
A
I
L
B
M
18
S
T
R
I
N
G
9
D
E
C
L
A
R
e
I
R
E
T
f--
~J
f--
C
H
'----
-
-
V
0
11
C
0
MM
A
N
D
classTesc
I
publicscat:ic
void
main(Scring
[1
args)(
inc
l<
~
0;
incy-0;
whiIe(x
<
5l(
}
if(
x
==
1){
Syscern.ouc.print(x∙-"•y.-"I;
x
=
x
+
1;
System.
out.
prfnt('noysj;
}
if(
X•1){
Syst£ln.
out.prlnt('olsej;
}
System.out.println(UU);
32U53
"""slbleoutput:
.I.f
IY
<
5)
II-X
+
1,
UIy<3
:It-
x-II
)
1.•
Y.
+
2.
'y
java
PoolPuzzlcOne
Ct
noise
ann o~'s
an
o ~'s t e r
X
=
X
+
1;
}
}
}
26
chapter1
2 classes and objects
this is a new chapter
27
I was told there would be objects. )NCHAPTERWEPUTALLOFOURCODEINTHE
MAINMETHOD4HATSNOTEXACTLYOBJECTORIENTED)NFACTTHATSNOTOBJECTORIENTEDATALL7ELL
WEDIDUSEAFEWOBJECTSLIKETHE3TRINGARRAYSFORTHE0HRASE/-ATICBUTWEDIDNTACTUALLY
DEVELOPANYOFOUROWNOBJECTTYPES3ONOWWEVEGOTTOLEAVETHATPROCEDURALWORLDBEHIND
GETTHEHECKOUTOFMAINANDSTARTMAKINGSOMEOBJECTSOFOUROWN7ELLLOOKATWHATMAKES
OBJECTORIENTED//DEVELOPMENTIN*AVASOMUCHFUN7ELLLOOKATTHEDIFFERENCEBETWEEN
ACLASSANDANOBJECT7ELLLOOKATHOWOBJECTSCANGIVEYOUABETTERLIFEATLEASTTHEPROGRAM
MINGPARTOFYOURLIFE.OTMUCHWECANDOABOUTYOURFASHIONSENSE7ARNINGONCEYOUGET
TO/BJECTVILLEYOUMIGHTNEVERGOBACK3ENDUSAPOSTCARD
A Trip to Objectville
We’re going to Objectville! We’re leaving this dusty ol’ procedural town for good. I’ll send you a postcard.
once upon a time in Objectville
28
chapter 2
the spec
NCEUPONATIMEINASOFTWARESHOPTWO
PROGRAMMERSWEREGIVENTHESAMESPECANDTOLDTO
hBUILDITv4HE2EALLY!NNOYING0ROJECT-ANAGER
FORCEDTHETWOCODERSTOCOMPETE
BYPROMISINGTHATWHOEVERDELIVERS
lRSTGETSONEOFTHOSECOOL!ERON©
CHAIRSALLTHE3ILICON6ALLEYGUYSHAVE
,ARRYTHEPROCEDURALPROGRAMMERAND
"RADTHE//GUYBOTHKNEWTHISWOULD
BEAPIECEOFCAKE
,ARRYSITTINGINHISCUBETHOUGHTTO
HIMSELFh7HATARETHETHINGSTHISPROGRAM
HASTODO7HATPROCEDURESDOWENEEDv
!NDHEANSWEREDHIMSELFhROTATEAND
PLAY3OUNDv3OOFFHEWENTTOBUILDTHE
PROCEDURES!FTERALLWHATISAPROGRAMIFNOT
APILEOFPROCEDURES
"RADMEANWHILEKICKEDBACKATTHECAFE
ANDTHOUGHTTOHIMSELFh7HATARETHETHINGS
INTHISPROGRAMWHOARETHEKEYPLAYERSv(E
lRSTTHOUGHTOF4HE3HAPES/FCOURSETHERE
WEREOTHEROBJECTSHETHOUGHTOFLIKETHE5SER
THE3OUND
ANDTHE#LICKINGEVENT"UTHEALREADYHADALIBRARYOFCODE
FORTHOSEPIECESSOHEFOCUSEDONBUILDING3HAPES2EAD
ONTOSEEHOW"RADAND,ARRYBUILTTHEIRPROGRAMSAND
FORTHEANSWERTOYOURBURNINGQUESTIONh3OWHOGOTTHE
!ERONv
Chair Wars
(or How Objects Can Change Your Life)
the chair
At Brad’s laptop at the cafe
"RADWROTEA
CLASS
FOREACHOFTHETHREESHAPES
In Larry’s cube
!SHEHADDONEAGAZILLIONTIMESBEFORE,ARRY
SETABOUTWRITINGHIS)MPORTANT0ROCEDURES
(EWROTEROTATEANDPLAY3OUNDINNOTIME
rotate(shapeNum) {
// make the shape rotate 360º
}
playSound(shapeNum) {
// use shapeNum to lookup which
// AIF sound to play, and play it
}
}
}
}
O
you are here4
classes and objects
29
Therewillbeanamoebashape
onthescreen,withtheothers.
Whentheuserclicksonthe
amoeba,itwillrotatelikethe
others,andplaya.hifsoundfile
But wait! There’s been a spec change.
h/+TECHNICALLYYOUWERElRST,ARRYvSAIDTHE-ANAGERhBUTWEHAVETOADDJUSTONE
TINYTHINGTOTHEPROGRAM)TLLBENOPROBLEMFORCRACKPROGRAMMERSLIKEYOUTWOv
h)F)HADADIMEFOREVERYTIME)VEHEARDTHATONEvTHOUGHT,ARRYKNOWINGTHATSPEC
CHANGENOPROBLEMWASAFANTASYh!NDYET"RADLOOKSSTRANGELYSERENE7HATSUPWITH
THATv3TILL,ARRYHELDTIGHTTOHISCOREBELIEFTHATTHE//WAYWHILECUTEWASJUST
SLOW!NDTHATIFYOUWANTEDTOCHANGEHISMINDYOUDHAVETOPRYITFROMHISCOLD
DEADCARPALTUNNELLEDHANDS
Larry thought he’d nailed it. He could almost feel the rolled steel of the Aeron beneath his...
what got added to the spec
Back in Larry’s cube
4HEROTATEPROCEDUREWOULDSTILLWORKTHECODEUSED
ALOOKUPTABLETOMATCHASHAPE.UMTOANACTUAL
SHAPEGRAPHIC"UTPLAY3OUNDWOULDHAVETOCHANGE
!NDWHATTHEHECKISAHIFlLE
playSound(shapeNum) {
// if the shape is not an amoeba,
// use shapeNum to lookup which
// AIF sound to play, and play it
// else
// play amoeba .hif sound
}
)TTURNEDOUTNOTTOBESUCHABIGDEALBUTITSTILL
MADEHIMQUEASYTOTOUCHPREVIOUSLYTESTEDCODE/F
ALLPEOPLEHESHOULDKNOWTHATNOMATTERWHATTHE
PROJECTMANAGERSAYSTHESPECALWAYSCHANGES
At Brad’s laptop at the beach
"RADSMILEDSIPPEDHISMARGARITAANDWROTEONE
NEWCLASS3OMETIMESTHETHINGHELOVEDMOST
ABOUT//WASTHATHEDIDNTHAVETOTOUCHCODE
HEDALREADYTESTEDANDDELIVEREDh&LEXIBILITY
EXTENSIBILITYvHEMUSEDREmECTINGONTHE
BENElTSOF//
Amoeba
rotate() {
// code to rotate an amoeba }
playSound() {
// code to play the new // .hif file for an amoeba
}
once upon a time in Objectville
30
chapter 2
AmeobarotationpointinLarry
andBrad’sversion:
Wheretheamebarotation
pointshouldbe:
What the spec conveniently
forgot to mention
(AH3OMUCHFORTHATFOOFY//NONSENSE"UTTHESMIRKON,ARRYSFACEMELTEDWHENTHE
2EALLY!NNOYING0ROJECT-ANAGERSAIDWITHTHATTONEOFDISAPPOINTMENTh/HNOTHATSNOT
HOWTHEAMOEBAISSUPPOSEDTOROTATEv
4URNSOUTBOTHPROGRAMMERSHADWRITTENTHEIRROTATECODELIKETHIS
1) determine the rectangle that surrounds the shape
2) calculate the center of that rectangle, and rotate the shape around that point.
"UTTHEAMOEBASHAPEWASSUPPOSEDTOROTATEAROUNDAPOINTONONEENDLIKEACLOCKHAND
h)MTOASTvTHOUGHT,ARRYVISUALIZINGCHARRED7ONDERBREAD
©
h!LTHOUGHHMMMM)COULD
JUSTADDANOTHERIFELSETOTHEROTATEPROCEDUREANDTHENJUSTHARDCODETHEROTATIONPOINT
CODEFORTHEAMOEBA4HATPROBABLYWONTBREAKANYTHINGv"UTTHELITTLEVOICEATTHEBACKOF
HISHEADSAIDh"IG-ISTAKE$OYOUHONESTLYTHINKTHESPECWONTCHANGEAGAINv
Larry snuck in just moments ahead of Brad.
Back in Larry’s cube
(ElGUREDHEBETTERADDROTATIONPOINTARGUMENTS
TOTHEROTATEPROCEDURE!LOTOFCODEWASAFFECTED
4ESTINGRECOMPILINGTHEWHOLENINEYARDSALLOVER
AGAIN4HINGSTHATUSEDTOWORKDIDNT
rotate(shapeNum, xPt, yPt) {
// if the shape is not an amoeba,
// calculate the center point
// based on a rectangle,
// then rotate
// else
// use the xPt and yPt as
// the rotation point offset
// and then rotate
}
At Brad’s laptop on his lawn chair at the Telluride Bluegrass Festi val
7ITHOUTMISSINGABEAT"RADMODIlEDTHEROTATE
METHODBUTONLYINTHE!MOEBACLASS(ENEVER
TOUCHEDTHETESTEDWORKING
COMPILEDCODEFORTHEOTHER
PARTSOFTHEPROGRAM4O
GIVETHE!MOEBAAROTA
TIONPOINTHEADDEDAN
ATTRIBUTETHATALL!MOEBAS
WOULDHAVE(EMODI
lEDTESTEDANDDELIVERED
WIRELESSLYTHEREVISED
PROGRAMDURINGASINGLE
"ELA&LECKSET
Amoeba
int xPoint
int yPoint
rotate() {
// code to rotate an amoeba
// using amoeba’
s x and y }
playSound() {
// code to play the new // .hif file for an amoeba
}
you are here4
classes and objects
31
So, Brad the OO guy got the chair, right?
.OTSOFAST,ARRYFOUNDAmAWIN"RADSAPPROACH!ND
SINCEHEWASSURETHATIFHEGOTTHECHAIRHEDALSOGET,UCY
INACCOUNTINGHEHADTOTURNTHISTHINGAROUND
,!2299OUVEGOTDUPLICATEDCODE4HEROTATE
PROCEDUREISINALLFOUR3HAPETHINGS
"2!$)TSA
METHOD
NOTAPROCEDURE!NDTHEYRE
CLASSES
NOTTHINGS
,!2297HATEVER)TSASTUPIDDESIGN9OUHAVETO
MAINTAINFOURDIFFERENTROTATEhMETHODSv(OWCANTHAT
EVERBEGOOD
"2!$/H)GUESSYOUDIDNTSEETHElNALDESIGN,ETME
SHOWYOUHOW//
INHERITANCE
WORKS,ARRY
What Larry wanted
(figured the chair would impress her)
They’re Shapes,and they all rotate and
playSound.So I abstracted out the
common features and put them into a
new class called Shape.
Shape
rotate()
playSound()
Triangle
Square
Circle
Amoeba
Shape
rotate()
playSound()
superclass
subclasses
Then I linked the other f
our shape classes to the new Shape class, in a relationship called inheritance. Triangle
rotate()
playSound()
Square
rotate()
playSound()
Circle
rotate()
playSound()
I looked at what all four
classes have in common.
Amoeba
rotate()
playSound()
1
2
3
You can read this as, “Square inherits from Shape”, “Circle inherits from Shape”, and so on. I removed rotate() and playSound() from the other shapes, so now there’s only one copy to maintain.
The Shape class is called the superclass of the other four classes. The other four are the subclasses of Shape. The subclasses inherit the methods of the superclass. In other words, if the Shape class has the functionality, then the subclasses automatically get that same functionality.
once upon a time in Objectville
32
chapter 2
What about the Amoeba rotate()?
,!2297ASNTTHATTHEWHOLEPROBLEMHERETHATTHEAMOEBASHAPE
HADACOMPLETELYDIFFERENTROTATEANDPLAY3OUNDPROCEDURE
"2!$-ETHOD
,!2297HATEVER(OWCANAMOEBADOSOMETHINGDIFFERENTIF
IThINHERITSvITSFUNCTIONALITYFROMTHE3HAPECLASS
"2!$4HATSTHELASTSTEP4HE!MOEBACLASSOVERRIDESTHE
METHODSOFTHE3HAPECLASS4HENATRUNTIMETHE*6-KNOWSEXACTLY
WHICHROTATEMETHODTORUNWHENSOMEONETELLSTHE!MOEBATOROTATE
O
v
e
r
r
i
d
e
N
o
w
A
s
k
M
e
H
o
w
I made the Amoeba class override
the rotate() method of the
superclass Shape.
Overriding just means that a
subclass redefines one of its
inherited methods when it needs
to change or extend the behavior
of that method.
4
Triangle
Square
Circle
Amoeba
rotate()
//amoeba-specific
//rotate code
playSound()
//amoeba-specific
//sound code
Shape
rotate()
playSound()
superclass
(more abstract)
subclasses
(more specific)
Overriding methods
,!229(OWDOYOUhTELLvAN!MOEBATO
DOSOMETHING$ONTYOUHAVETOCALLTHE
PROCEDURESORRYMETHODANDTHENTELLIT
WHICHTHINGTOROTATE
"2!$4HATSTHEREALLYCOOLTHINGABOUT//
7HENITSTIMEFORSAYTHETRIANGLETOROTATE
THEPROGRAMCODEINVOKESCALLSTHEROTATE
METHODONTHETRIANGLEOBJECT4HERESTOFTHE
PROGRAMREALLYDOESNTKNOWORCAREHOWTHE
TRIANGLEDOESIT!NDWHENYOUNEEDTOADD
SOMETHINGNEWTOTHEPROGRAMYOUJUSTWRITE
ANEWCLASSFORTHENEWOBJECTTYPESOTHENEW
OBJECTSWILLHAVETHEIROWNBEHAVIOR
I can take care of myself. I know how an Amoeba is supposed to rotate and play a sound.
I know how a Shape is supposed to behave. Your job is to tell me what
to do, and my job is to make it happen. Don’t you worry your little program-
mer head about how
I do it.
I made the Amoeba class override the rotate() and playSound() methods of the superclass Shape. Overriding just means that a subclass redefines one of its inherited methods when it needs to change or extend the behavior of that method.
{
{
{
{
you are here4
classes and objects
33
metacognitive tip
If you’re stuck on an exercise,try talking about
it out loud.Speaking (and hearing) activates
a different part of your brain.Although it
works best if you have another person to
discuss it with,pets work too.That’s how
our dog learned polymorphism.
The suspense is killing me. Who got the chair?
!MYFROMTHESECONDmOOR
UNBEKNOWNSTTOALLTHE0ROJECT
-ANAGERHADGIVENTHESPECTO
THREEPROGRAMMERS
“It helps me design in a more natural way. Things have a way of evolving.” -Joy, 27, software architect
“Not messing around with code I’ve already tested, just to add a new feature.” -Brad, 32, programmer
“I like that the data and the methods that oper-
ate on that data are together in one class.” -Josh, 22, beer drinker
“Reusing code in other applications. When I write a new class, I can make it fl exible enough to be used in something new, later.” -Chris, 39, project manager
“I can’t believe Chris just said that. He hasn’t written a line of code in 5 years.” -Daryl, 44, works for Chris
“Besides the chair?” -Amy, 34, programmer
What do you like about OO?
4IMETOPUMPSOMENEURONS
9OUJUSTREADASTORYBOUTAPROCEDURAL
PROGRAMMERGOINGHEADTOHEADWITHAN//
PROGRAMMER9OUGOTAQUICKOVERVIEWOFSOME
KEY//CONCEPTSINCLUDINGCLASSESMETHODSAND
ATTRIBUTES7ELLSPENDTHERESTOFTHECHAPTER
LOOKINGATCLASSESANDOBJECTSWELLRETURNTO
INHERITANCEANDOVERRIDINGINLATERCHAPTERS
"ASEDONWHATYOUVESEENSOFARANDWHATYOU
MAYKNOWFROMAPREVIOUS//LANGUAGEYOUVE
WORKEDWITHTAKEAMOMENTTOTHINKABOUT
THESEQUESTIONS
7HATARETHEFUNDAMENTALTHINGSYOUNEEDTO
THINKABOUTWHENYOUDESIGNA*AVACLASS7HAT
ARETHEQUESTIONSYOUNEEDTOASKYOURSELF
)FYOUCOULDDESIGNACHECKLISTTOUSEWHEN
YOUREDESIGNINGACLASSWHATWOULDBEONTHE
CHECKLIST
YiX`e
gfn\i
34
chapter 2
thinking about objects
ShoppingCart
cartContents
addToCart()
removeFromCart()
checkOut()
knows
does
Button
label
color
setColor()
setLabel()
dePress()
unDepress()
knows
does
Alarm
alarmTime
alarmMode
setAlarmTime()
setAlarm()
isAlarmSet()
snooze()
knows
does
When you design a class, thi nk about the objects that wi l l be created from that class type. Thi nk about:
Nthings the object knows
Nthings the object does
Thi ngs an object knows about i tself are cal led
Ninstance variables
Thi ngs an object can do are cal led
Nmethods
Song
title
artist
setTitle()
setArtist()
play()
instance
variables
(state)
methods
(behavior)
knows
does
4HINGSANOBJECTKNOWSABOUTITSELFARECALLEDINSTANCE
VARIABLES4HEYREPRESENTANOBJECTSSTATETHEDATAAND
CANHAVEUNIQUEVALUESFOREACHOBJECTOFTHATTYPE
Think of instance as another way of saying object. 4HINGSANOBJECTCANDOARECALLEDMETHODS7HENYOU
DESIGNACLASSYOUTHINKABOUTTHEDATAANOBJECTWILLNEED
TOKNOWABOUTITSELFANDYOUALSODESIGNTHEMETHODS
THATOPERATEONTHATDATA)T
SCOMMONFORANOBJECTTO
HAVEMETHODSTHATREADORWRITETHEVALUESOFTHEINSTANCE
VARIABLES&OREXAMPLE!LARMOBJECTSHAVEANINSTANCE
VARIABLETOHOLDTHEALARM4IMEANDTWOMETHODSFOR
GETTINGANDSETTINGTHEALARM4IME
3OOBJECTSHAVEINSTANCEVARIABLESANDMETHODSBUTTHOSE
INSTANCEVARIABLESANDMETHODSAREDESIGNEDASPARTOFTHE
CLASS
Sharpen your pencil
&ILLINWHATATELEVISIONOBJECT
MIGHTNEEDTOKNOWANDDO
Alarm
alarmTime
alarmMode
setAlarmTime()
getAlarmTime()
isAlarmSet()
snooze()
knows
does
you are here4
classes and objects
35
What’s the difference between a class and an object? !CLASSISABLUEPRINTFORANOBJECT)TTELLSTHE
VIRTUALMACHINEHOWTOMAKEANOBJECTOFTHAT
PARTICULARTYPE%ACHOBJECTMADEFROMTHAT
CLASSCANHAVEITSOWNVALUESFORTHE
INSTANCEVARIABLESOFTHATCLASS&OR
EXAMPLEYOUMIGHTUSETHE"UTTON
CLASSTOMAKEDOZENSOFDIFFERENT
BUTTONSANDEACHBUTTONMIGHTHAVE
ITSOWNCOLORSIZESHAPELABELANDSOON
A class is not an object.
(but it’s used to construct them)
class
JVM
Look at it this way...
/NEANALOGYFOROBJECTSISAPACKETOFUNUSED2OLODEX
»
CARDS
%ACHCARDHASTHESAMEBLANKFIELDSTHEINSTANCEVARIABLES7HEN
YOUFILLOUTACARDYOUARECREATINGANINSTANCEOBJECTANDTHE
ENTRIESYOUMAKEONTHATCARDREPRESENTITSSTATE
4HEMETHODSOFTHECLASSARETHETHINGSYOUDOTOAPARTICULARCARD
GET.AMECHANGE.AMESET.AMECOULDALLBEMETHODSFOR
CLASS2OLODEX
3OEACHCARDCANDOTHESAMETHINGSGET.AMECHANGE.AME
ETCBUTEACHCARDKNOWSTHINGSUNIQUETOTHATPARTICULARCARD
!NOBJECTISLIKEONEENTRYINYOURADDRESSBOOK
36
chapter 2
class DogTestDrive {
public static void main (String[] args) {
Dog d = new Dog();
d
.
size = 40;
d
.
bark();
}
}
DOG
size
breed
name
bark()
making objects
class Dog {
int size;
String breed;
String name;
void bark() {
System.out.println(“Ruff! Ruff!”);
}
}
Making your first object
3OWHATDOESITTAKETOCREATEANDUSEANOBJECT9OUNEEDTWOCLASSES/NE
CLASSFORTHETYPEOFOBJECTYOUWANTTOUSE$OG!LARM#LOCK4ELEVISION
ETCANDANOTHERCLASSTOTESTYOURNEWCLASS4HETESTERCLASSISWHEREYOUPUT
THEMAINMETHODANDINTHATMAINMETHODYOUCREATEANDACCESSOBJECTS
OFYOURNEWCLASSTYPE4HETESTERCLASSHASONLYONEJOBTOTRYOUTTHEMETH
ODSANDVARIABLESOFYOURNEWOBJECTCLASSTYPE
&ROMTHISPOINTFORWARDINTHEBOOKYOULLSEETWOCLASSESINMANYOF
OUREXAMPLES/NEWILLBETHEREALCLASSnTHECLASSWHOSEOBJECTSWE
REALLYWANTTOUSEANDTHEOTHERCLASSWILLBETHETESTERCLASSWHICHWE
CALLWHATEVER9OUR#LASS.AME)STestDrive&OREXAMPLEIFWEMAKEA
Bungee CLASSWELLNEEDABungeeTestDriveCLASSASWELL/NLYTHE
SOME#LASS.AMETestDrive CLASSWILLHAVEAMAINMETHODANDITSSOLE
PURPOSEISTOCREATEOBJECTSOFYOURNEWTYPETHENOTTHETESTERCLASSAND
THENUSETHEDOTOPERATORTOACCESSTHEMETHODSANDVARIABLESOFTHENEW
OBJECTS4HISWILLALLBEMADESTUNNINGLYCLEARBYTHEFOLLOWINGEXAMPLES
1
Write your class
class DogTestDrive {
public static void main (String[] args) {
// Dog test code goes here
}
}
2
Write a tester (TestDrive) class
3
In your tester, make an object and access the object’s variables and methods
instance variables
a method
just a main method
(we’re gonna put code in it in the next step)
make a Dog object
use the dot operator (.) to set the size of the Dog
and to call its bark() method
dot
operator
4HEDOTOPERATORGIVES
YOUACCESSTOANOBJECTS
STATEANDBEHAVIORINSTANCE
VARIABLESANDMETHODS
MAKEANEWOBJECT
$OGDNEW$OG
TELLITTOBARKBYUSINGTHE
DOTOPER
ATORONTHE
VARIABLEDTOCALLBARK
DBARK
SETITSSIZEUSINGTHE
DOTOPER
ATOR
DSIZE
The Dot Operator (.)
If you already have some OO savvy, you’ll know we’re not using encapsulation. We’ll get there in chapter 4.
you are here4
classes and objects
37
Sharpen your pencil
object 1
object 2
object 3
title
genre
rating
title
genre
rating
title
genre
rating
MOVIE
title
genre
rating
playIt()
class Movie {
String title;
String genre;
int rating;
void playIt() {
System.out.println(“Playing the movie”);
}
}
public class MovieTestDrive {
public static void main(String[] args) {
Movie one = new Movie();
one.title = “Gone with the Stock”;
one.genre = “Tragic”;
one.rating = -2;
Movie two = new Movie();
two.title = “Lost in Cubicle Space”;
two.genre = “Comedy”;
two.rating = 5;
two.playIt();
Movie three = new Movie();
three.title = “Byte Club”;
three.genre = “Tragic but ultimately uplifting”;
three.rating = 127;
}
}
Making and testing Movie objects
4HE-OVIE4EST$RIVECLASSCREATESOBJECTSINSTANCESOF
THE-OVIECLASSANDUSESTHEDOTOPERATORTOSETTHE
INSTANCEVARIABLESTOASPECIFICVALUE4HE-OVIE4EST$RIVE
CLASSALSOINVOKESCALLSAMETHODONONEOFTHEOBJECTS
&ILLINTHECHARTTOTHERIGHTWITHTHEVALUESTHETHREE
OBJECTSHAVEATTHEENDOFMAIN
38
chapter 2
GuessGame
p1
p2
p3
startGame()
get the heck out of main
Quick! Get out of main!
!SLONGASYOUREINMAINYOURENOTREALLYIN/BJECTVILLE)TSlNEFORATEST
PROGRAMTORUNWITHINTHEMAINMETHODBUTINATRUE//APPLICATIONYOU
NEEDOBJECTSTALKINGTOOTHEROBJECTSASOPPOSEDTOASTATICMAINMETHOD
CREATINGANDTESTINGOBJECTS
The two uses of main:
Nto test your real class
Nto launch/start your Java application
!REAL*AVAAPPLICATIONISNOTHINGBUTOBJECTSTALKINGTOOTHEROBJECTS)NTHIS
CASETALKINGMEANSOBJECTSCALLINGMETHODSONONEANOTHER/NTHEPREVIOUS
PAGEANDINCHAPTERWELOOKATUSINGAMAINMETHODFROMASEPARATE
4EST$RIVECLASSTOCREATEANDTESTTHEMETHODSANDVARIABLESOFANOTHERCLASS)N
CHAPTERWELOOKATUSINGACLASSWITHAMAINMETHODTOSTARTTHEBALLROLLING
ONAREAL*AVAAPPLICATIONBYMAKINGOBJECTSANDTHENTURNINGTHOSEOBJECTS
LOOSETOINTERACTWITHOTHEROBJECTSETC
!SA@SNEAKPREVIEWTHOUGHOFHOWAREAL*AVAAPPLICATIONMIGHTBEHAVE
HERESALITTLEEXAMPLE"ECAUSEWERESTILLATTHEEARLIESTSTAGESOFLEARNING*AVA
WEREWORKINGWITHASMALLTOOLKITSOYOULLlNDTHISPROGRAMALITTLECLUNKY
ANDINEFlCIENT9OUMIGHTWANTTOTHINKABOUTWHATYOUCOULDDOTOIMPROVE
ITANDINLATERCHAPTERSTHATSEXACTLYWHATWELLDO$ONTWORRYIFSOMEOFTHE
CODEISCONFUSINGTHEKEYPOINTOFTHISEXAMPLEISTHATOBJECTSTALKTOOBJECTS
The Guessing Game
3UMMARY
4HEGUESSINGGAMEINVOLVESA@GAMEOBJECTANDTHREE@PLAYEROBJECTS4HEGAMEGEN
ERATESARANDOMNUMBERBETWEENANDANDTHETHREEPLAYEROBJECTSTRYTOGUESS
IT7EDIDNTSAYITWASAREALLYEXCITINGGAME
#LASSES
GuessGame.class Player.class GameLauncher.class
4HE,OGIC
4HE'AME,AUNCHERCLASSISWHERETHEAPPLICATIONSTARTSITHASTHEMAIN
METHOD
)NTHEMAIN
METHODA'UESS'AMEOBJECTISCREATEDANDITSSTART'AMEMETHOD
ISCALLED
4HE'UESS'AMEOBJECTSSTART'AMEMETHODISWHERETHEENTIREGAMEPLAYSOUT
)TCREATESTHREEPLAYERSTHENhTHINKSvOFARANDOMNUMBERTHETARGETFORTHEPLAYERS
TOGUESS)TTHENASKSEACHPLAYERTOGUESSCHECKSTHERESULTANDEITHERPRINTSOUT
INFORMATIONABOUTTHEWINNINGPLAYERSORASKSTHEMTOGUESSAGAIN
Player
number
guess()
instance variables
forthe three
players
the number
this player
guessed
method for
making a guess
GameLauncher
main(String[] args)
makes a GuessGame
object and
tells it to
startGame
you are here4
classes and objects
39
public class GuessGame
{
Player p1;
Player p2;
Player p3;
public void startGame() {
p1 = new Player();
p2 = new Player();
p3 = new Player();
int guessp1 = 0;
int guessp2 = 0;
int guessp3 = 0;
boolean p1isRight = false;
boolean p2isRight = false;
boolean p3isRight = false;
int targetNumber = (int) (Math.random() * 10);
System.out.println(“I’m thinking of a number between 0 and 9...”);
while(true) {
System.out.println(“Number to guess is “ + targetNumber);
p1.guess();
p2.guess();
p3.guess();
guessp1 = p1.number;
System.out.println(“Player one guessed “ + guessp1);
guessp2 = p2.number;
System.out.println(“Player two guessed “ + guessp2);
guessp3 = p3.number;
System.out.println(“Player three guessed “ + guessp3);
if (guessp1 == targetNumber) {
p1isRight = true;
}
if (guessp2 == targetNumber) {
p2isRight = true;
}
if (guessp3 == targetNumber) {
p3isRight = true;
}
if (p1isRight || p2isRight || p3isRight) {
System.out.println(“We have a winner!”);
System.out.println(“Player one got it right? “ + p1isRight);
System.out.println(“Player two got it right? “ + p2isRight);
System.out.println(“Player three got it right? “ + p3isRight);
System.out.println(“Game is over.”);
break; // game over, so break out of the loop
} else {
// we must keep going because nobody got it right!
System.out.println(“Players will have to try again.”);
} // end if/else
} // end loop
} // end method
} // end class
GuessGame has three instance variables for the three Player objects
create three Player objects and assign them to the three Player instance variables
declare three variables to hold the three guesses the Players make
declare three variables to hold a true or false based on the player’s answer
make a ‘target’ number that the players have to guess
call each player’s guess() method
get each player’s guess (the result of their guess() method running) by accessing the number variable of each player
check each player’s guess to see if it matches the target number. If a player is right, then set that player’s variable to be true (remember, we set it false by default)
if player one OR player two OR player three is right... (the || operator means OR)
otherwise, stay in the loop and ask the players for another guess.
40
chapter 2
File Edit Window Help Explode
%java GameLauncher
I’m thinking of a number between 0 and 9...
Number to guess is 7
I’m guessing 1
I’m guessing 9
I’m guessing 9
Player one guessed 1
Player two guessed 9
Player three guessed 9
Players will have to try again.
Number to guess is 7
I’m guessing 3
I’m guessing 0
I’m guessing 9
Player one guessed 3
Player two guessed 0
Player three guessed 9
Players will have to try again.
Number to guess is 7
I’m guessing 7
I’m guessing 5
I’m guessing 0
Player one guessed 7
Player two guessed 5
Player three guessed 0
We have a winner!
Player one got it right? true
Player two got it right? false
Player three got it right? false
Game is over.
/UTPUTITWILLBEDIFFERENTEACHTIMEYOURUNIT
Runni ng the Guessi ng Game
Guessing Game
public class Player {
int number = 0; // where the guess goes
public void guess() {
number = (int) (Math.random() * 10);
System.out.println(“I’m guessing “ + number);
}
}
p
ublic class GameLauncher {
public static void main (String[] args) {
GuessGame game = new GuessGame();
game.startGame();
}
}
Java takes out the Garbage
%ACHTIMEANOBJECTISCREATED
IN*AVAITGOESINTOANAREAOF
MEMORYKNOWNAS4HE(EAP
!LLOBJECTSNOMATTERWHENWHERE
ORHOWTHEYRECREATEDnLIVEONTHE
HEAP"UTITSNOTJUSTANYOLDMEMORY
HEAPTHE*AVAHEAPISACTUALLYCALLEDTHE
'ARBAGE#OLLECTIBLE(EAP7HENYOU
CREATEANOBJECT*AVAALLOCATESMEMORY
SPACEONTHEHEAPACCORDINGTOHOW
MUCHTHATPARTICULAROBJECTNEEDS!N
OBJECTWITHSAYINSTANCEVARIABLES
WILLPROBABLYNEEDMORESPACETHANAN
OBJECTWITHONLYTWOINSTANCEVARIABLES
"UTWHATHAPPENSWHENYOUNEEDTO
RECLAIMTHATSPACE(OWDOYOUGETAN
OBJECTOUTOFTHEHEAPWHENYOUREDONE
WITHIT*AVAMANAGESTHATMEMORY
FORYOU7HENTHE*6-CAN@SEETHATAN
OBJECTCANNEVERBEUSEDAGAINTHAT
OBJECTBECOMESELIGIBLEFORGARBAGE
COLLECTION!NDIFYOURERUNNINGLOWON
MEMORYTHE'ARBAGE#OLLECTORWILLRUN
THROWOUTTHEUNREACHABLEOBJECTSAND
FREEUPTHESPACESOTHATTHESPACECAN
BEREUSED)NLATERCHAPTERSYOULLLEARN
MOREABOUTHOWTHISWORKS
you are here4
classes and objects
41
BULLET POINTS
ß
Object-oriented programming lets you extend a program without having to touch previously-
tested, working code.
ß
All Java code is defined in a class. ß
A class describes how to make an object of that class type. A class is like a blueprint.
ß
An object can take care of itself; you don’t have to know or care how the object does it.
ß
An object knows things and does things.
ß
Things an object knows about itself are called instance variables. They represent the state of an object.
ß
Things an object does are called methods. They represent the behavior of an object.
ß
When you create a class, you may also want to create a separate test class which you’ll use to create objects of your new class type.
ß
A class can inherit instance variables and methods from a more abstract superclass.
ß
At runtime, a Java program is nothing more than objects ‘talking’ to other objects.
there are no
D
umb Questions
Q: 7HATIF)NEEDGLOBAL
VARIABLESANDMETHODS(OW
DO)DOTHATIFEVERYTHINGHASTO
GOINACLASS
A: 4HEREISNTACONCEPTOF
@GLOBALVARIABLESANDMETHODSIN
A*AVA//PROGRAM)NPRACTICAL
USEHOWEVERTHEREARETIMES
WHENYOUWANTAMETHODOR
ACONSTANTTOBEAVAILABLE
TOANYCODERUNNINGINANY
PARTOFYOURPROGRAM4HINK
OFTHErandom()METHODIN
THE0HRASE/-ATICAPPITSA
METHODTHATSHOULDBECALLABLE
FROMANYWHERE/RWHATABOUT
ACONSTANTLIKEPI9OULLLEARN
INCHAPTERTHATMARKING
AMETHODASpublic AND
static MAKESITBEHAVEMUCH
LIKEA@GLOBAL!NYCODEINANY
CLASSOFYOURAPPLICATIONCAN
ACCESSAPUBLICSTATICMETHOD
!NDIFYOUMARKAVARIABLEAS
publicstaticANDfi nal nYOUHAVEESSENTIALLYMADEA
GLOBALLYAVAILABLECONSTANT
Q: 4HENHOWISTHISOBJECT
ORIENTEDIFYOUCANSTILLMAKE
GLOBALFUNCTIONSANDGLOBAL
DATA
A: &IRSTOFALLEVERYTHING
IN*AVAGOESINACLASS3OTHE
CONSTANTFORPIANDTHEMETHOD
FORrandom()ALTHOUGHBOTH
PUBLICANDSTATICAREDEFINED
WITHINTHEMathCLASS!NDYOU
MUSTKEEPINMINDTHATTHESE
STATICGLOBALLIKETHINGSARETHE
EXCEPTIONRATHERTHANTHERULE
IN*AVA4HEYREPRESENTAVERY
SPECIALCASEWHEREYOUDONT
HAVEMULTIPLEINSTANCESOBJECTS
Q: 7HATISA*AVAPROGRAM
7HATDOYOUACTUALLYDELIVER
A: !*AVAPROGRAMISAPILE
OFCLASSESORATLEASTONECLASS
)NA*AVAAPPLICATIONONEOF
THECLASSESMUSTHAVEAMAIN
METHODUSEDTOSTARTUPTHE
PROGRAM3OASAPROGRAMMER
YOUWRITEONEORMORECLASSES
!NDTHOSECLASSESAREWHATYOU
DELIVER)FTHEENDUSERDOESNT
HAVEA*6-THENYOULLALSO
NEEDTOINCLUDETHATWITH
YOURAPPLICATIONSCLASSES
SOTHATTHEYCANRUNYOUR
PROGRAM4HEREAREANUMBER
OFINSTALLERPROGRAMSTHAT
LETYOUBUNDLEYOURCLASSES
WITHAVARIETYOF*6-SSAYFOR
DIFFERENTPLATFORMSANDPUTITALL
ONA#$2/-4HENTHEENDUSER
CANINSTALLTHECORRECTVERSIONOF
THE*6-ASSUMINGTHEYDONT
ALREADYHAVEITONTHEIRMACHINE
Q: 7HATIF)HAVEAHUNDRED
CLASSES/RATHOUSAND)SNT
THATABIGPAINTODELIVER
ALLTHOSEINDIVIDUALl LES
#AN)BUNDLETHEMINTOONE
!PPLICATION4HING
A: 9ESITWOULDBEABIG
PAINTODELIVERAHUGEBUNCHOF
INDIVIDUALFILESTOYOURENDUSERS
BUTYOUWONTHAVETO9OUCAN
PUTALLOFYOURAPPLICATIONFILES
INTOA*AVA!RCHIVEnAJARFILEn
THATSBASEDONTHEPKZIPFORMAT
)NTHEJARFILEYOUCANINCLUDE
ASIMPLETEXTFILEFORMATTEDAS
SOMETHINGCALLEDAMANIFESTTHAT
DEFINESWHICHCLASSINTHATJAR
HOLDSTHEMAINMETHODTHAT
SHOULDRUN
Make itStick
!CLASSISLIKEARECIPE
/BJECTSARELIKE
COOKIES
42
chapter 2
A
class TapeDeck {
boolean canRecord = false;
void playTape() {
System.out.println(“tape playing”);
}
void recordTape() {
System.out.println(“tape recording”);
}
}
class TapeDeckTestDrive {
public static void main(String [] args) {
t.canRecord = true;
t.playTape();
if (t.canRecord == true) {
t.recordTape();
}
}
}
B
class DVDPlayer {
boolean canRecord = false;
void recordDVD() {
System.out.println(“DVD recording”);
}
}
class DVDPlayerTestDrive {
public static void main(String [] args) {
DVDPlayer d = new DVDPlayer();
d.canRecord = true;
d.playDVD();
if (d.canRecord == true) {
d.recordDVD();
}
}
}
Each of the Java files on this page represents a complete source file. Your job is to play compiler and determine whether each of these files will compile. If they won’t compile, how would you fix them, and if they do compile, what would be their output?
"%THECOMPILER
1dQ^OU_Q
exercise: Be the Compiler
you are here4
classes and objects
43
!*AVAPROGRAMISALLSCRAMBLEDUPON
THEFRIDGE#ANYOURECONSTRUCTTHE
CODESNIPPETSTOMAKEAWORKING*AVA
PROGRAMTHATPRODUCESTHEOUTPUTLISTED
BELOW3OMEOFTHECURLYBRACESFELLON
THEFLOORANDTHEYWERETOOSMALLTOPICK
UPSOFEELFREETOADDASMANYOFTHOSE
ASYOUNEED
boolean topHat = true;
boolean snare = true;
void playSnare() {
System.out.println(“bang bang ba-bang”);
}
if (d.snare == true) {
d.playSnare();
}
d.snare = false;
class DrumKitTestDrive {
d.playTopHat();
public static void main(String [] args) {
File Edit Window Help Dance
% java DrumKitTestDrive
bang bang ba-bang
ding ding da-ding
void playTopHat () {
System.out.println(“ding ding da-ding”);
}
class DrumKit {
DrumKit d = new DrumKit();
Code Magnets
d.playSnare();
1dQ^OU_Q
44
chapter 2
X
X
X
X
X
X
Pool Puzzle
9OURJOBISTOTAKECODESNIPPETSFROM
THEPOOLANDPLACETHEMINTOTHE
BLANKLINESINTHECODE9OUMAY
USETHESAMESNIPPETMORETHAN
ONCEANDYOUWONTNEEDTOUSE
ALLTHESNIPPETS9OURGOALISTO
MAKECLASSESTHATWILLCOMPILEAND
RUNANDPRODUCETHEOUTPUTLISTED
public class EchoTestDrive {
public static void main(String [] args) {
Echo e1 = new Echo();
_________________________
int x = 0;
while ( ___________ ) {
e1.hello();
__________________________
if ( ____________ ) {
e2.count = e2.count + 1;
}
if ( ____________ ) {
e2.count = e2.count + e1.count;
}
x = x + 1;
}
System.out.println(e2.count);
}
}
class ____________ {
int _________ = 0;
void ___________ {
System.out.println(“helloooo... “);
}
}
.OTE%ACHSNIPPET
FROMTHEPOOLCANBE
USEDMORETHANONCE
File Edit Window Help Implode
%java EchoTestDrive
helloooo...
helloooo...
helloooo...
helloooo...
10
/UTPUT
EE
ECOUNT
ECOUNTCOUNT
ECOUNTECOUNT
EE
%CHOE
%CHOEE
%CHOENEW%CHO
X
Y
E
COUNT
%CHO
4ESTER
ECHO
COUNT
HELLO
"ONUS1UESTION
)FTHELASTLINEOFOUTPUTWAS
INSTEADOFHOWWOULD
YOUCOMPLETETHEPUZZLE
puzzle: Pool Puzzle
you are here4
classes and objects
45
Who am I?
I am compiled from a .java file.
My instance variable values can
be different from my buddy’s
values.
I behave like a template.
I lik
e to do stuff.
I can have many methods.
I represent ‘state’.
I have behaviors.
I am located in objects.
I live on the heap.
I am used to create object instances.
My state can change.
I declare methods.
I can change at runtime.
class
!BUNCHOF*AVACOMPONENTSINFULLCOSTUMEAREPLAYINGAPARTY
GAMEh7HOAM)v4HEYGIVEYOUACLUEANDYOUTRYTOGUESSWHO
THEYAREBASEDONWHATTHEYSAY!SSUMETHEYALWAYSTELLTHETRUTH
ABOUTTHEMSELVES)FTHEYHAPPENTOSAYSOMETHINGTHATCOULDBETRUE
FORMORETHANONEOFTHEMCHOOSEALLFORWHOMTHATSENTENCECAN
APPLY&ILLINTHEBLANKSNEXTTOTHESENTENCEWITHTHENAMESOFONEOR
MOREATTENDEES4HEFIRSTONESONUS
4ONIGHTSATTENDEES
#LASS-ETHOD/BJECT)NSTANCEVARIABLE
46
chapter 2
A
B
Code Magnets:
File Edit Window Help Dance
% java DrumKitTestDrive
bang bang ba-bang
ding ding da-ding
class DrumKit {
boolean topHat = true;
boolean snare = true;
void playTopHat() {
System.out.println(“ding ding da-ding”);
}
void playSnare() {
System.out.println(“bang bang ba-bang”);
}
}
class DrumKitTestDrive {
public static void main(String [] args) {
DrumKit d = new DrumKit();
d.playSnare();
d.snare = false;
d.playTopHat();
if (d.snare == true) {
d.playSnare();
}
}
}
class TapeDeck {
boolean canRecord = false;
void playTape() {
System.out.println(“tape playing”);
}
void recordTape() {
System.out.println(“tape recording”);
}
}
class TapeDeckTestDrive {
public static void main(String [] args) {
TapeDeck t = new TapeDeck( );
t.canRecord = true;
t.playTape();
if (t.canRecord == true) {
t.recordTape();
}
} We’ve got the template, now we have
} to make an object !
class DVDPlayer {
boolean canRecord = false;
void recordDVD() {
System.out.println(“DVD recording”);
}
void playDVD ( ) {
System.out.println(“DVD playing”);
}
}
class DVDPlayerTestDrive {
public static void main(String [] args) {
DVDPlayer d = new DVDPlayer();
d.canRecord = true;
d.playDVD();
if (d.canRecord == true) {
d.recordDVD();
}
} The line: d.playDVD( ); wouldn’t
} compile without a method !
%XERCISE3OLUTIONS
1dQ^OU_Q
Be the Compiler:
exercise solutions
you are here4
classes and objects
47
public class EchoTestDrive {
public static void main(String [] args) {
Echo e1 = new Echo();
Echo e2 = new Echo( ); // the correct answer
- or -
Echo e2 = e1; // is the bonus answer!
int x = 0;
while ( x < 4
) {
e1.hello();
e1.count = e1.count + 1;
if ( x == 3
) {
e2.count = e2.count + 1;
}
if ( x > 0
) {
e2.count = e2.count + e1.count;
}
x = x + 1;
}
System.out.println(e2.count);
}
}
class Echo
{
int count
= 0;
void hello( )
{
System.out.println(“helloooo... “);
}
}
File Edit Window Help Assimilate
%java EchoTestDrive
helloooo...
helloooo...
helloooo...
helloooo...
10
I am compiled from a .java file.
My instance variable values can be different from my buddy’s values.
I behave like a template.
I like to do stuff.
I can have many methods.
I represent ‘state’.
I have behaviors.
I am located in objects.
I live on the heap.
I am used to create object instances.
My state can change.
I declare methods.
I can change at runtime.
class
object
class
object, method
class, object
instance variable
object, class
method, instance variable
object
class
object, instance variable
class
object, instance variable
Pool Puzzle
7HOAM)
Note: both classes and objects are said to have state and behavior. They’re defined in the class, but the object is also said to ‘have’ them. Right now, we don’t care where they technically live.
0UZZLE3OLUTIONS
3
primitivesandreferences
KnowYourVariables
Variablescomeintwoflavors:primitiveandreference.
So
far
you've
usedvariablesIn
twoplaces-asobjectstate(instancevariables),andaslocalvariables
(variablesdeclared
withina
method).
Later,we'llusevariablesasarguments(valuessenttoa
methodbythecallingcode),andas
returntypes(valuessentbacktothecallerofthemethod).
You'veseenvariablesdeclaredassimpie
prjmIUveintegervaIues(typein
c).
You'veseen
variablesdeclaredassomethingmore
complexlikeaStringoranarray.Butthere'sgottabe
moretolifethanintegers,Strings,andarrays.WhatIfyouhaveaPetOwnerobjectwithaDog
instancevariable?Ora
Car
withanEngine?Inthischapterwe'llunwrapthemysteriesofJava
typesandlookat
whatyoucan
declare
asavariable,what
you
can
pur
Inavariable,andwhatyou
can
do
withavariable.Andwe'llfinallyseewhatlifeIs
truly
likeonthegarbage-collectibleheap.
thisIsanewchapter49
declaringavariable
Peclarittgavariable
Javacaresabout
type.
It
won'tletyoudo
somethingbizarreanddangerouslikestuffa
Giraffereference
intoaRabbitvariable-what
happenswhensomeonetriestoasktheso-called
Rabbit
tohop()?Anditwon'tletyouputa
floating
pointnumberintoanintegervariable,
unlessyou
lKknowledge
to
thecompiler
thatyou
knowyoumightloseprecision(like,everything
afterthedecimalpoint).
Thecompilercanspotmostproblems:
Rabbithopper
=
newGiraffe();
Don'texpectthattocompile.
Thankfully.
Forall
this
type-safetytowork,youmustdeclare
thetypeofyourvariable.
Is
itaninteger?aDog?
Asinglecharacter?Variables
comeintwoflavors:
primitive
and
object
reference.
Primitiveshold
fundamentalvalues(think:simplebitpatterns)
includingintegers,booleans,
andfloatingpoint
numbers.Objectreferenceshold.well,
references
to
objects
(gee,didn't
that
clearitup.)
We'Ulook
atprimitivesfirstandthenmove
on
to
whatanobjectreferencereallymeans.
Butregardlessofthetype,youmustfoUowtwo
declarationrules:
variablesmusthaveatype
Besidesatype,avariableneedsaname,sothat
youcanusethat
nameincode.
variablesmusthaveaname
int
;?1
type
count;
<,
na.....e
50chapter3
Note:Whenyouseeastatementlike:"anobject
oftypeX",
thinkofl)'Peand
classes
synonyms.
(We'llrefinethatalittle
moreinlaterchapters.)
primitivesandreferences
PrimitiveTypes
Integer
byte
8
bits
-128
to
127
short
16
bits
-32768
to
32767
int
32
bits
-2147483648
to
2147483647
long
64
bits
-hugetohuge
Type
Bit
Depth
Value
Range
booleanandchar
boolean
(JVM..
pedfic)
trueorfalse
char
16
bits
0
to
65535
numeric(allaresigned)
floatingpoint
float
32
bitsvaries
double
64
bitsvaries
char
c
='f'j
lntz
e
x:
booleanIsPunkRock;
isPunkRock
=
false;
booleanpowerOn;
powerOn
=
IsFun;
longbig
=
3456789j
float
f
=
32.5i
.(qatta
"a~t
-that
Nott
tht
~
btU\,<St
ja~a thi"~
..,i-tha
~\.~\oab~
foi"t
I~
'"'ythi,,~
'fI1-tha
\,<St
'~'.
a
ci~\e,
"",\65
'fO'#
Primitivedeclarations
withassignments:
Int
){i
x
=
234;
byte
b
=
89;
booleanisfun
=
true;
doubled
=
3456,98j
grande
double
64
tall
float
32
smallshort
long
64
byteshortint
81632
--'!II"
AndinJava,primitivescomeindifferentsizes,andthosesizes
havenames.
Whenyoudeclareavariable
in
Java,
I
E::a-YoUmustdeclareitwithaspecifictype.The
fourcontainershereareforthefour
integerprimitivesinJava.
fangintshortbyte
cupholdsavalue,soforJavaprimitives,ratherthansaying,"I'dlikea
frenchroast",you
say
tothecompiler,"I'dlikeanintvariablewiththe
ber90please."Exceptforonetinydifference...inJavayoualsohave
to
yourcupa
name.
Soit'sactually,"I'dlikeanintplease,withthevalue
:H86,
andnamethevariable
height."
Eachprimitivevariablehasafixed
berofbits(cupsize).ThesizesforthesixnumericprimitivesinJava
shownbelow:
nyou
thinkofJavavariables,thinkofcups.Coffeecups,teacups,giant
thatholdlotsandlotsofbeer,thosebigcupsthepopcorncomesinat
movies,cupswithcurvy,sexyhandles,andcupswithmetallic
trim
that
learned
can
never,
ever
gointhemicrowave.
wariable
is
just
acup.A
container.
It
holds
something.
asize,
andatype.
In
thischapter,we'regoingtolookfirstatthe
-bles(cups)
thatholdprimitives,thenalittlelaterwe'lllookatcups
hold
references
to
objects.
Staywithushereonthewholecupanalogy-as
pieasitisrightnow,it'llgiveusacommonwaytolookatthingswhen
discussiongetsmorecomplex.Andthat'llhappensoon.
-itivesarelike
thecupstheyhaveatthecoffeehouse.
If
you'vebeentoa
ucks,youknowwhatwe'retalking
abouthere.Theycomeindifferent
andeachhasanamelike'short',
'tall',
and,"I'dlikea
de'mochahalf-eaffwithextrawhippedcream".
mightseethecupsdisplayedon
thecounter,
ucan
orderappropriately:
youarehere
~
51
prlmltlveassignment
You
really
dot1~t
wat1ttospillthat...
Besurethevaluecanfitintothevariable.
You
can't
put
alargevalueintoa
smallcup.
WeU,OK,
you
can,but
you'll
losesome.You'llget,aswe
say,
spillage.
The
compilertries
to
helppreventthisifitcantell
from
yourcodethatsomething's
notgoingtofit
in
thecontainer
(variable/cup)you'reusing.
Forexample,you
can'tpouran
int-fullofstuff
into
abyte-sized
container,
as
follows:
intx
=
24;
byteb
=
x;
//won'twork!!
Why
doesn't
this
work,youask?Afterall,thevalueof
x
is
24,and24isdefinitely
small
enoughto
fit
intoabyte.
You
knowthat,and
we
knowthat,butallthe
compilercaresaboutisthatyou'retryingtoputabigthingintoasmallthing.
andthere'sthe
possibility
ofspilling.
Don't
expectthecompiler
to
know
what
the
valueofxis.even
if
you
happen
to
beable
to
seeitliterallyinyourcode.
You
can
assign
avaluetoavariable
in
oneofseveral
ways
including:
•typealitera/valueafter
theequals
sign
(x=12.isGood=
true,
etc.)
•assignthevalueofonevariabletoanother(x
=
y)
•useanexpressioncombiningthetwo(x
=
y
+
43)
In
theexamplesbelow,theliteralvaluesarein
bold
italics:
Thecompilerwon'tletyouput
avaluefromalargecup
into
asmallone.Butwhatabout
theother
way-pouringa
smallcup
into
a
bigone7
No
problem.
Basedonwhatyouknow
aboutthesizeandtypeofthe
primitiveva
rlables,
seeifyou
canfigureoutwhichofthese
arelegalandwhicharen't,
Wehaven'tcoveredallthe
rules
yet,soonsomeofthese
you'llhavetouseyourbest
judgment.
Tip:
Thecompiler
alwayserrsontheside
of
safety.
Fromthefollowing
list
Circle
thestatementsthatwouldbe
legaliftheselineswerein
a
singlemethod:
1.intx
=
34.5;
2.booleanboox;
3.
int
g
=
17;
4.
inty'"
9;
5.Y
=
Y
+
10;
6.shorts;
intsize
=
32;
booleanisCrazy;
int
y
=
x
+
456;
doubled
=
456.709;
128;
11.
v'"n;
12.bytek
10.shortn'"12;
8.
byte
b
=
3;
7.
s
=
y;
9.
byte
v
=
b;
declareanintnamedsize,assIgnilthevalue32
declareacharnamedinitial,assignitlhevalue
T
declareadoublenamed
d,
assignitthevalue
456.709
declareabooleannamedIsCrazy(noassignment)
assignthevaluetruetothepreviously-declared;sCrazy
declareanintnamedy,assignItlhevaluethat
is
thesum
ofwhatever
x
isnowplus456
true;
isCrazy
charinitial
=
'j';
52chapter3
prlmitJvesandreferences
JackawayfrotHthatkeyword!
lbuknowyouneedanameandatypeforyourvariables.
YOu
alreadyknowtheprimitive
types.
.,what
can
you
we
asnames?
Therulesaresimple.You
an
name
aclass,
method,orvariableaccordingtothe
owing
rules(therealrulesareslightlymoreflexible,
t
thesewillkeepyousafe):
•Itmuststartwithaletter,underscore
U,
or
dollaralgn
($).
Youcan'tatartanamewitha
number.
•Afterthefirstcharacter,youcanu..numbersas
well.Justdon'tatartItwithanumber,
•Itcanbeanythingyou
like,
subject
to
thosetwo
rules,
JU8t80
longasItIsn'tone
of
Java'sreserved
words.
.'ftIfIeS
ote:
b\e
,/'It
primitIve'7"
floatdo
U
.
The
elg
es\"lOft
lotlong.
t/'lem:
\
eaochar
byt
membermg
boOonicforre
,om
nem
And
here
S,
ges
t
urge
S
u\dn'tn
CafefU\~
8ea's
\"10
8e
bertet.
furryOogs
't'llstick
even
out
own,
I
It
yoU
make
up
Y
D
SILF--
B_
c-
B_--
Andtheprimitivetypesarereservedaswell:
voidstaticpublic
fhlstablereserved.
boolean
byte
mardoubleflom
Inl
long
protectedabstract
flnal
nativestoricstrictfpsyndJronlzed
transient
If
else
do
while
swllm
case
delauhfor
break
continueassart
doss
ex1and~
implementsimport
rnstanceofinterface
new
package
super
this
catch
flnol~
try
throwthrows
return
voidcanst
gala
enum
booleancharbyteshortintlongfloa.tdouble
t
therearealotmorewehaven'tdiscussedyet.Even
if
youdon't
ed
to
knowwhat
they
mean,youstillneed
to
knowyoucan't
use
'emyourself.
Do
not-underanycircumstances-try
to
memorize
these
.w.
Tomakeroomfortheseinyourhead,you'dprobablyhave
to
somethingelse.Likewhereyourcarisparked.Don't
worry,
by
theendofthebookyou'llhavemostofthemdowncold.
Java'skeywordsandotherreservedwords(Innousefulorder).Ifyouusethesefornames,thecomplierwillbevery,
vel}'
upset.
youare
here
I
53
objectreferences
Controllingyour
~og
object
Youknowhowtodeclareaprimitivevariableandassign
it
a
value.
Butnowwhataboutnon-primitivevariables?Inother
words,
whataboutobjects?
•ThereIsactuallynosuchthingasan
object
variable.
•There's
onlyanobject
reference
variable.
•An
objectreferencevariableholdsbitsthatrepresenta
way
to
accessanobject.
•
Itdoesn'tholdtheobjectItsetf,butItholdssomething
likeapointer.Oranaddress.Except.,inJavawe
don't
reallyknow
what
IsInsideareferencevariable.Wedo
know
thatwhateverItIs,Itrepresentsoneandonlyone
object.AndtheJVMknows
how
to
usethereference
to
get
to
theobject.
Youcan
'1
stuffanobjectintoavariable.Weoftenthinkof
it
that
way...
wesaythingslike,"IpassedtheStringtothe
System.out.printlnf)
method."Or,"ThemethodreturnsaDog",
or,"I
putanewFooobjectintothevariablenamed
rnyf'oo."
Butthat'snotwhathappens.Therearen'tgiant
expandablecupsthatcangrowtothesizeofany
object.Objectslivein
oneplaceandoneplace
only-thegarbagecollectibleheap!(You'll
learnmoreaboutthatlaterinthischapter)
Althoughaprimitivevariableisfullof
bitsrepresentingtheactual
value
ofthe
variable,anobjectreferencevariable
is
full
ofbits
representing
a
way
to
get
to
the
obJect.
Youusethedotoperator(.)
onareferencevariable
10
say,
"usethething
before
thedotto
getmethething
after
thedot."For
example:
myDog.bark();
means,"usetheobjectreferencedbythevariablemyDogto
invoke
the
barkt)
method."Whenyouusethedotoperatoron
anobject
referencevariable,thinkofitlikepressingabutton
ontheremotecontrolforthatobject.
54
chapter3
Dogd
=
newDog();
d.bark();
\thi.k
ot
this
Thillk
o-f
a
D~
referentevdl'iableal
a
D~
l'en-oteto.\h-ol.
You.
IUC
it
to
~tt -t\l~
objut
to
do
~tthill9
(h'IVolcc
",et.h~).
primitivesandreferences
byteshortint
8
1632
longreference
64
Iblldepthnotrelevant)
The3stepsofobject
declaration,creationand
assignment
12
~3~
DogmyDog
=
newDog();
At1objectreferet1ceisjust
a"othervariablevalue.
O
Declareareference
variable
Dog
Dogobject
Dogobject
DoqmyDoq
=
newDog();
TellstheJVMtoallocatespacefora
referencevariable,andnamesthat
variable
myDog.
Thereferencevariable
Is,forever.oftypeDog
.lnotherwords,
aremotecontrolthathasbuttonsto
control
a
Dog,but
not
aCatoraButton
or
a
Socket.
Dog
DogmyDog
=
newDog();
AssignsthenewDogtothereference
variablemyDog.lnotherwords,
programstheremotecontrol,
e
Linktheobject
andthereference
e
Createanobject
DogmyDog'"
new
Dog();
TellstheJVMtoallocatespacefora
newDogobjectontheheap(we'll
learna
lotmoreaboutthatprocess,
especiallyinchapter
9,)
~\.\.
J~itive
U
vall.4t
byte
Dog
myDog
=
newDoq();
SomethingthatgoesInacup.
Onlythistime,thevalue15aremotecontrol.
PrhldtlveVariable
byte
x
=
7;
the
bitsrepresenting
7
go
tothevariable.
(00000111),
~n
carehowmenyt'sandO'stho,o
are
In
a
(afare~08l1tlriabla lrs
UP10
a&eh
:"a."ld
IhephaseofIhemoon,
you
arehere.
55
objectreferences
D
:the re l ~ o
"
ume
~uest19115
Q:
Howbig
15
areference
variable?
A.
:Voudon'tknow.Unless
you'recozywithsomeoneonthe
JVM'sdevelopmentteam,you
don'tknowhowareferenceis
represented.Therearepointers
intheresomewhere,butyou
can'taccessthem.
Youwon't
needto.
(OK,
Ifyou
I
nsl
st,
you
mightaswellJustimagineIt
tobea54-bitvalue.)Butwhen
you'retalkingaboutmemory
allocationissues,your
Big
Concernshouldbeabouthow
many
objects
(asoppose-dto
object
references)
you'recreating,
andhowbig
they
(the
objects)
reallyare.
Q:
So,does
thatmean
that
allobject
referencesare
the
samesize,
regardless
of
the
size
of
the
actua
Iobjectsto
which
they
refer?
A.:
Yep.Allreferencesfora
givenNMwillbethesame
sizeregardlessof
theobjects
theyreference,buteach
JVM
mighthaveadifferentwayof
representingreferences,so
referencesonone
JVMmaybe
smallerorlargerthanreferences
onanother
JVM.
Q:can
Idoarithmeticona
referencevariable,Increment
It
youknow-Cstuff7
A.:
Nope.SayItwithmeagain,
"Java
IsnotC."
56chapter3
,
.
Java,
£Nposecl
Thisweek'sInterview:
ObjectReference
HeadFirst
So,
tell
us,
what'slifelikeforanobjectreference?
Reference:
Prettysimple,really.I'maremotecontrolandI
can
beprogrammedto
controldifferentobjects.
HeadArst
Doyoumeandifferentobjects
even
whileyou'rerunning?
Like,can
you
refertoaDogandthen
five
minuteslaterreferto
aCar?
Reference:
or
course
not-
Once
I'mdeclared,that's
it.
IfI'm
a
Dogremotecontrol
then
ru
neverbeabletopoint(oops-mybad,we'renotsupposedtosay
poin~
Imean
rifer
toanythingbutaDog.
HeadFirst
Doesthatmeanyou
can
refertoonlyoneDog?
Reference:
No.
I
can
be
referringtooneDog,andthen
five
minuteslaterI
can
referto
some
other
Dog.
As
long
as
it'saDog,
I
can
beredirected(likereprogranuningyourremote
to
a
different
TV)
toit.Unless...nonever
mind.
HeadFirst
No,tellme.Whatwereyou
gonna
say?
Reference:
Idon'tthinkyouwant
to
getintothis
now,
but
I'lljust
giveyouthe
short
version-if
I'm
maned
asfinal,
thenonce
I
am
assigned
aDog,
I
can
never
berepro-
grammedto
anything
elsebut
I1ul1
oneandonlyDog:
In
otherwords,nootherobject
can
be
assigned
tome.
HeadFirst
You're
right,
we
don'twanttotalkaboutthatnow.
OK,sounless
you're
final,
thenyoucanrefertooneDogandthenrefer
to
adifferentDoglater.
Can
youever
refer
to
fIl)tJring
atalP.
Is
itpossibletonotbeprogrammed
to
anything?
Reference:
Yes,butitdisturbsme
to
talkabout
it.
HeadArst
Why
is
that?
Reference:
BecauseitmeansI'm
null,
andthat'supsettingtome.
HeadFirst
Youmean.
because
thenyouhavenovalue?
Reference:
Oh,nullisavalue.I'mstillaremotecontrol,butit'slikeyoubrought
homeanew
universalremotecontrolandyoudon'thaveaTVI'mnotprogrammedto
control
anything.They
can
press
my
buttons
all
daylong,butnothing
good
happens.I
justfeel
so...useless.
A
wasteof
bits.
Granted,notthatmanybits,but
still.
Andthat'snot
theworstpart.
IfI
am
theonlyreferencetoapanicularobject,andthenI'msetto
null
(deprogrammed),itmeansthatnow
rwboqy
can
gettothatobjectIhadbeenreferringto.
HeadFirst
Andthat'sbad
because...
Reference:
Youhaveto
ask?
HereI'vedevelopedarelationshipwiththisobject,an
intimateconnection,andthenthetieissuddenly,
cruelly,severed.AndI
will
neversee
thatobject
again,
becausenowit'seligiblefor[producer,cue.tragic
music)
garbagecollection.
Sniff.Butdoyouthinkprogrammerseverconsider!haP.Snif.
Why,
wIrY
can'tI
be
aprimi-
tive?
Ihatebeing
arefcrcut.
Theresponsibility,
all
thebrokenattachments...
ott
thegarbage..collectibleheap
=
new
Book();
=
new
Book();
etwoBookreference
-les.Create
twonewBook
.AssigntheBookobjectsto
referencevariables.
twoBookobjectsarenowliving
eheap.
Obiects:2
Bookd
=
c;
reanewBookreferencevariable.
rthancreatinganew,
thirdBook
•assignthevalue
ofvariablecto
.ble
d.
Butwhatdoesthismean?
likesaying,"TakethebitsIn
c,
makea
ofthem,andstickthatcopyInto
d."
.....canddrefertothesame
....ect.
The
canddvariableshold
two
dlHerentcopiesofthe
..mevalue.Tworemotes
.....grammedtooneTV.
ferences:
3
Objects:
2
c
=
h;
Assignthevalueofvariable
b
to
variable
c.
By
nowyouknowwhat
ismeans.Thebitsinsidevariable
at
arecopied,andthatnewcopyIs
stuffed
intovariable
c.
Bothbandcrefertothe
sameobject.
References:
3
Objects:2
Book
Book
Book
Book
primitivesandreferences
youare
here
~
57
objectsontheheap
Ufea.,ddeath
0.,
theheap
Bookb
=
newBook();
Bookc
=
newBook()
i
DeclaretwoBookreferencevariables.
Create
twonewBookobjects.Assign
theBookobjectstothereference
variables.
The
twobookobjectsarenowliving
ontheheap.
ActIveReferences:2
ReachableObjects:2
Book
b
=
Ci
Assignthevalueofvariablectovariable
b.
ThebitsInsidevariablecarecopied,and
thatnewcopyisstuffedIntovariable
b.
Bothvariablesholdidenticalvalues.
Bothbandcrefertothe••me
object.Object1I.abandoned
andeligibleforGarbageCollec-
tion(GC).
ActiveReferences:2
ReachableObjects:1
AbandonedObjects:1
Thefirst
objectthat
b
referenced,Object1,
hasnomorereferences.It's
unreachable.
C
=
null;
Assignthevaluenu11tovariablec.
Thismakes
c
a
nullreference,
meaning
Itdoesn'trefertoanything.ButIt'sstill
areferencevariable,andanotherBook
objectcan
stili
beassignedtoIt.
Object2.tlllh••anactive
reference(b),and••long
asItdoes,theobjectI.not
eligibleforGC.
ActIveReferences:1
null
References:1
ReachableObjects:1
AbandonedObjects:1
68
chapter3
Book
primitivesandreferences
An
array
is
likeatrayofcups
o
Declare
anint
array
verinble.An
arrayvariableis
aremotecontroltoanarrayobject.
int[]nums;
Create
a
newintarraywitha
length
of
7
I
and
assign
ittothepreviously-
declared
int
r
J
variable
nums
nums
=
newint[7];
Giveeach
element
in
thearray
an
int
value.
Remember,elementsin
onint
array
arejust
int
variables.
~
.:is
nums[0]
=
6;
.3'
~
nums[l]
=
19;
~
~
nums[2]
=
44:
∙s
nums[3]
=
42:
nums[4]
=
10:
nums[5]
=
20;
nums[6]
='1;
int[]
intarrayobject(int[])
Not it~
that.-tnea'rYa'fihtlt
is
dl'l
objtd:,
evel'l
t.h~h ~e
I
tltMtl'lt.s
art
f\"i",j∙I:.'Ives.
Arraysareobjectstoo
Javastandardlibraryincludes
ofsophisticated
data
structures
udingmaps,trees.andsets
Appendix
B).
butarraysare
t
whenyoujustwantaquick.
red,efficientlist
ofthings.
,"'5
giveyoufastrandom
essbylettingyouuseanindex
itiontoget
to
anyelementin
array.
ry
elementinanarrayisjust
nriable.Inotherwords,oneof
eightprimitivevariabletypes
.k:Large
FurryDog)ora
referencevariable.Anythingyou
would
putina
variable
ofthatrype
can
be
assignedtoan
arrayelement
ofthattype.Soinanarrayoftype
int
(int[]).eachelementcanhold
anint,
In
aDogarray(Dog[])each
elementcanhold...aDog?No.
rememberthatareferencevariable
justholdsareference(aremote
control),nottheobjectitself.So
ina
Dogarray,eachelementcan
holda
remotecontrol
toaDog.Of
course,westillhavetomakethe
Dogobjects...andyou'llseeallthat
onthenextpage.
Be
suretonoticeone
key
thing
inthepictureabove-
the
arm)'
is
anobject,even
thoughit's
anarrayof
primitives.
Arrays
are
always
objects,whether
they're
declaredtobold
primitives
orobjectreferences.Butyoucan
haveanarray
objectthat'sdeclared
to
hold
primitivevalues.Inother
words,thearrayobjectcanhave
elements
whichareprimitives.but
thearrayitselfis
never
aprimi
tive,
Regardlessofwhatthearrayholds,
thearrayitselfisalwaysanobjectl
youarehere.
59
anarrayofobjects
MakeattarrayofPogs
pets
=
newD09[7];
pets[D]
=
newDog();
pets[l]
=
newDog();
A
CreateanewDogarraywith
W
alengthof7,andassignitto
thepreviously-declared
Dog
[J
variable
pets
Dog
array
object(Dog[])
Dog
array
object(Dog[])
DeclareaDogarrayvariable
Dog[]pets;
o
What~
.ttfsShtg1
DogslWehaveanarray
ofDog
rmrence$,
butno
actualDog
obJects
I
A
CreatenewDogobjects,and
V
assignthemtothearray
elements.
Remember,elementsinaDog
array
arejustDogreference
variables.
WestillneedDogs!
_
~n,~~:':~:f
~~~i:/_t
_
-- ~dmake
-neofthe
11objects?
58(..
.r3
Javacaresabouttype.
Onceyou'vedeclaredanarray.you
can'tputanythingan
It
exceptthing-
that
are
of
the
declaredarray
type.
Forexample,
you
can't
put
Q
COtintoaDog
array
(it
wouldbe
pretty
awful
if
someone
thinksthatonlyDogsareintheorrat,so
the.y
askeochoneto
~ark,
and
th~n
totheir
horrordiscovertheresacatlurkmg.)And
you
can'tstick
adouble
into
on
int
orr'atl
(spillage.,
remember?).Youcan,
however.
putQ
byteintoonin
t
arraf,
b~QuSe
a
byte
will
always
fit
into
on
int-SIZ
ed
cup.
ThisisknownasanImplicitwid&ning.We'''
gat
Intothedetailstater.for
now
just
remember
thatthe
compiler
won't
1st
you
put
the
wrM'9
thingInon
orraf,
basedon
the
Gtf'OY's
d&elored
type.
,
Dog
name
barkO
eatO
chaseCalO
primitivesandreferences
Cot1trolyour
~og
(withareferetlcevariable)
Dog
fide
=
newDog();
fido.name
=
~FidoN;
WecreatedaDogobjectand
usedthedotoperatoronthe
referencevariable
fido
toaccess
thenamevariable."
We
canusethe
fido
reference
togetthedogtobarkt)or
eat/)orchaseCatO.
fido.bark()
i
Dog
fido.chaseCat();
Whathappettsifthe
POQ
isItt
a
OOQ
array?
~e
knowwecanaccesstheDog's
Instancevariables
andmethodsusing
thedotoperator,but
emwhat1
WhentheDogisinanarray,wedon't
haveanactualvariablename(like
fido).
Insteadweusearraynotationand
pushtheremotecontrolbutton(dot
~perator)
onanobjectataparticular
Index(position)inthearray:
Dog[]myDogs
=
newDog[3];
myDogs[O]
=
newDog();
myDogs[O].name
=
"Fido";
myDogs[O].bark();
'Yesweknow
we're
notdemonslralin-
tryingtokeep
it
simple.FornowW'1IgdencapsuiatiOn
he_reo
but
we're
.e
0
encapsulation
10
chapter4.
youarehere
~
61
usingreferences
classDog(
Stringname;
publicstaticvoidmain(String()args)
II
makeaDogobjectandaccessit
Dogdogl
=
newDog();
dogl.bark{);
dogl.name
=
"Bart";
APogexatMple
Dog
name
barkO
eatO
chaseCal()
II
nowmakeaDogarray
Dog()myDogs
=
newDog[3);
Output
II
andputsomedogsin
i ~
/1
nowRecesstheDogsusingthearray
II
references
pUblicvoideat(){
pub
licvoidchaseCat()
•Variablescomeintwoflavors:primitiveand
reference.
•Variablesmustalwaysbedeclaredwithaname
and
a
type.
•Aprimitivevariablevalueisthebitsrepresenting
thevalue(5,'a',true,3.1416,etc.).
•A
referencevariablevalueisthebits
representingawaytoget
to
anobjectonthe
heap.
•Areferencevariableislikearemotecontrol.
Usingthedotoperator(.)onareference
variableislikepressingabuttonontheremole
controltoaccessamethodorinstancevariable.
•Areferencevariablehasavalueof
nu11
when
itisnotreferencinganyobject
•An
arrayisalwaysanobject,even
if
the"array
isdeclared
to
holdprimitives"Thereisnosuch
thingasaprimitivearray,onlyanarraythat
holdsprimitives.
"Fred";
"Marge";
newDog();
newDog();
dog!;
myDogs[O)
myDog
s[l)
myDogs[2)
myDogs(O).name
myDogs(l).narne
II
now
100
throughthearr
y
II
andtellalldogstobark
pUblicvoidbark()(
System.out.println(narne
i-"
saysRuff!");
II
Hmmnm...whatismyDogs(2jname?
System.out.print("!astdog'snameis");
System.out.println(myDogs
(2)
.narne);
i
ntx
=
0;
whi1e(x
<
mYDOgs.1ength)~
J
myDogs
[xl
.bark();
a\/aYiab\c
l'~~
x
=
X
+
1;
ay-yii'(S
ha\/C
t."c
l'I~bCl"
t)lat.
~\\/ts
'lOlA
a'J
L'
t,\lc
jlY"Y
I
e\e,.,.tf\'V
11'1
62chapter3
prlmltlvesandreferences
BE
thecornriler
Each
of
theJava
nles
on
this
page
represents
a
cOtIlplete
source
file.
Your
job
is
to
playcompilerand
detel"llline
whether
eachof
thesefiles
will
compile.
If
they
won't
cmqpile,howwould
rOll
fIX
them?
A
B
classBooks{
Stringtitle;
Stringauthor;
classHobbits{
Stringname;
}
publicstaticvoidmain(String
(J
args){
classBooksTestDrive
publicstaticvoidmain(StringIjargs)
Hobbits()h
=
newHobbits[3]i
intz
=
0;
Books()myBooks::newBooks(3);
int
x::
0;
myBooks{Oj.title::"TheGrapesofJava";
myBooks(lj.title
=
~The
JavaGatsby"i
myBooks(2).title::
~The
JavaCookbook";
myBooksIO).author
=
"bob";
myBooksllj.author::"sue";
myBooks(2).author
=
"ian";
wbile(x
<
3){
System.ou
t.print(myBookslxj.title)i
System.out.print("
by
U)i
System.out.println(rnyBooks[xj.author);
x
=
x
+
1;
while(z
<
4){
z
=
z
+
1;
hlz]::newHobbits();
h{z].name
=
"bilbo"i
if
(z
==
I){
hlz].name::"frodo";
}
if(z==2){
h[z).name
=
Usam";
System.out.print(h{z).name
+"
isa
H);
System.out.println(UgoodHobbitname");
}
}
youarehere.63
exercise:
CodeMagnets
Code
Magnets
Aworking
Java
program
Isallscrambledup
on
thefridge.Canyoureconstructthecode
snippetstomakeaworkingJavaprogram
thatproducestheoutputlistedbelow?
Someof
thecurlybracesfellonthefloor
andtheyweretoosmalltopickup,sofeel
freetoaddasmanyof
thoseasyouneed!
int
Y
==
intref;
index(y);
while
(y
<
4){
System.out.print1n(islands{refj)i
index(Ol.,.1;
index(ll'"3;
index
(21
==
0;
index[31.,.2;
~
String(]islands
new
String(4)i
System.out.print(Uisland;
U);
int
[1
index""
yy
+
1;
newint[4Ji
classTestArrays{
publicstaticvoidmain(Strin
N
":J
r
J
args){
64
chapter3
primitivesandreferences
_______.height
(x+
1)
*
2:
_______.leogthx
+
4:
)
{
voidmain(String[]args)
while(
class
Triangle
double
arear
intheight;
iotlength;
publicstatic
poolpuzzle
Your
Job
istotakecodesnippetsfrom
thepoolandplacethem
intothe
blanklinesinthecode.You
may
usethesamesnippetmorethan
once,andyouwon'tneedtouse
all
thesnippets.Your
gOlll
isto
makeaclass
that
will
compileand
runandproducethe
outputlisted.
Output
System.out.print("triangle
"+x+"
I
area"};
System.out.println("
="
+
.area):
}
x
=
27:
Triangle
tS
=
ta[2]:
ta[2J.area
=
343:
System.out.print(uy
=
U
+
y):
System.out.println(",tSarea
=
"+
tS.area};
Bonus
Questlonl
Forextrabonuspoints,usesnippets
fromthepoolto
fill
inthemissing
output(above).
}
voidsetArea(){
(height
*
length)/2;
}
}
Note:
Each
lnlppet
from
the
pool
nnbe
usedmore
than
oncel
youarehere
~
65
puzzle:Heapo'Trouble
AHeap
0'
Trouble
AshortJavaprogramislistedtothe
right.When
'/1
dostuff'isreached,some
objectsandsomereferencevariables
willhavebeencreated.YourtaskIs
todetermine
whichofthereference
variablesrefertowhichobjects.Notall
thereferencevariableswillbeused,and
someobjects
mightbereferredtomore
thanonce.Drawlinesconnectingthe
referencevariables
withtheirmatching
objects.
Tip:Unlessyou'rewaysmarterthanus,
youprobablyneedtodrawdiagrams
liketheonesonpage55and56
ofthis
chapter.Useapencilsoyoucandraw
andthenerasereferencelinks(the
arrowsgoIngfromareferenceremote
controltoanobject).
classHeapQuiz{
intid
==
0;
publicstaticvoidmain(String[]argsl
int
x
=
0;
HeapQuiz(]
hq
=
newHeapQuiz(S]i
while(x
<
3
1(
hq[x)
=
newHeapQuiz();
hq(x]
.id
==
Xi
x
=
X
+
1i
}
hq[3]
==
hq[l]i
hq[4]
hq[l];
hq[3]
=
null;
hq(4)
hq(0];
hq(Ol
==
hq(31i
hq(3]hq[2];
hq[2]
=
hq[0];
II
do
stuff
ReferenceVariables:
HeapQulzObjects:
hq[3]
hq[1]
hq[O]
hq[2]
hq[4]
10
~~
f
til
64
chapter3
primitivesandreferences
Thecaseofthepilferedreferences
It
was
a
clark
and
stormy
night
Tawnystrolledintotheprogrammers'bullpenlikeshe
ownedtheplace.Sheknewthatalltheprogrammerswouldstill
be
hardatwork,andshe
wantedhelp.She
needed
anewmethodaddedtothepivotalclassthatwastobeloadedinto
the
client'snewtop-secretJava-enabledcellphone.Heap
space
in
thecellphone'smemory
was
astightasTawny'stop,
andeveryone
knewitThenormally
raucous
buzz
in
thebullpenfellto
silenceasTawny
eased
herwaytothewhiteboard.She
sketched
aquickoverviewofthenew
method'sfunctionalityandslowlyscanned
the
room.
'Well
boys,it'scnmchtime",she
purred.
'Whoevercreatesthemostmemoryefficientversionofthismethod
is
comingwithmetothe
client'slaunch
party
onMauitomorrow...tohelpme
install
thenewsoftware."
ThenextmorningTawnyglidedintothebullpenwearinghershortAlohadress.
"Gentlemen",shesmiled,"theplaneleavesina
few
hours,showmewhatyou've
got!".Bobwent
first;
ashebegantosketch
his
design
onthewhite
board
Tawny
said,"Let'sget
to
thepointBob,
show
mehowyouhandled
updating
thelistof
con-
tact
objects."
Bob
quicklydrew
a
code
fragmentontheboard:
ContactI)ca
=
newContact[10];
while(
x
<
10){
II
make
10
contactobjects
calx)
newContact()i
x
=
x
+
1;
II
docomplicatedContactlistupdatingstuffwithca
"Tawny
r
knowwe'retightonmemory,butyour
spec
saidthatwe
had
to
be
ableto
access
individualcontactinformationforalltenallowablecontacts,
this
wasthebestschemeIcould
cookup",
saidBob.Kentwasnext,already
imagining
coconut
cocktails
withTawny,"Bob,"
hesaid,
"your
solution'sabitkludgydon'tyouthink?"Kentsmirked,"Take
a
lookat
this
baby":
Contact.refc;
while(x<
10){
II
make10contact.objects
refe
=
newCont.act()i
x=x
+
1;
I
II
docomplicatedContactlistupdatingstuffwith
rete
"I
savedabunchofreferencevariablesworthofmemory,Bob-o-rino,soputawayyour
sunscreen",mockedKent"NotsofastKent!",saidTawny,"you'vesavedalittle
memory,but
Bob'scomingwithme.''.
Why
did
TawnychooseBob'smethodoverKent's,whenKent'sused
Jess
memory?
youarehere
t
67
exercisesolutions
Exercise
Solutions
classBooks{
Stringtitle;
Stringautbor;
)
if(z==2){
b[z].name
=
"sam";
}
System.out.print(hlz).name
+"
isaH);
system.out.println{"good80bbitnameH)j
classHobbits{
Stringname:
publicstaticvoidmain{StringI)args){
Hobbits()h
=
ne_w=--H..:.ob::..:b7i:...:t..:.s~(3:....:)~:~,....,....-,
Int
:z::
-1;
I
Remember:
o.rrcys
start
with
whfle(z(
2)(
element0)
z
=
z
+
1
i------------
h[z]
=
newHobbits{):
B
h[z].name
=
"bilbo';
if
(z
==
1){
b[z].name
=
"frodo"j
classBooksTestDrive(
public
staticvoidmain{StringI)args)
Books
II
myBooks
=
newBooks(3);
intx
=
0:
myBooks[O]::
ntw
9ooksO;
IUrnanber:
We
hGvt
to
myBooks[1]::
ntw
BooksO:
actuclily
InQJc.e
the
BooI<s
myBooks[2]::
new
BooksO:
objects
I
~~----=-
----l
myBooksIO].title
=
uTheGrapesofJava';
myBooksll].title
=
"TheJavaGatsby∙;
myBooks[2].title
=
NTheJavaCookbook';
myBooks[O].author=Nbob';
myBooks[l].author
=
Nsue";
myBooks[2].author
=
"ian";
while(x
<
3){
System.out.print(myBoOks(x).title)i
System.out.print("by")j
system.out.println(myBooks[x).author);
x
e
X
+
1;
A
CodeMagnets:
}
}
classTestArrays
pUblicstaticvoidmain(String()args){
int[)index
=
newint{4]:
index[O)I:
Lndex]1)3:
index[
2)0:
index(3)
2;
String(]islands
=
newString[4]:
islandslO]"Bermuda":
islandsjl]
=
"Fiji";
islands(2]"Azores
H
:
islands{3]"Cozumel";
inty
=
0:
intref;
while
(y
<
4){
ref
=
index(yl;
system.out.print("island
=
H);
System.out.println(islandslref]l;
y
=
y
+
1;
68
chapter3
Puzzle
Solutions
primitivesandreferences
Thecaseofthepilferedreferences
4.0
10.0
19.0
28.0
TawnycouldseethatKent'smethodhadaserious
flaw.It's
truethathe
didn't
useasmanyreference
variablesasBob,butthere
was
no
way
toaccess
any
butthelastoftheContactobjectsthat
his
methodcre-
ated.Witheachtripthroughtheloop,hewasassign-
inganewobjecttotheonereferencevariable,sothe
previouslyreferencedobjectwasabandoned
on
the
heap-
unreachable.
Withoutaccesstonineoftheten
objects
created,Kent'smethod
was
useless.
(The
software
was
8
huge
success
atKl
the
dlent
gave
Tawny
and
Bob
an
extra
week
In
Hawa~.
we'dlike
to
~
you
that
by
finishingthis
book
you
too
wil
get
stuff
likeIhaL)
classTriangle
doublearea;
intheight;
intlength,
publicstatic
void
main(String
[1
argB){
lnt
x
=
0:
Triangle[]tel
=
new
Trlangle[4];
while(x•
4){
tel[x]
=
new
Tr/ClllglcQ;
~x].he19ht ~
(x+1)
*
2;
talx].length
=
x
+
4;
talx).
set.
Arec();
System.out.print(~triangle ~+X+".
area"),
System.ouLprintln(U-
N
+
talx).area);
x=x+1;
}
Int
'I
=x:
x-
27;
TriangletS
~
ta[2J;
ts[2J.area
=
343;
Syatem.out.print(Ny
=
U
+
Y);
System.out.println(",tS
area"
U+
tS.area);
}
void
setArea(){
~
=
(height∙length)
J
2;
~
;,java
Triangle
triangle
0,
area
triangle
1.
area
criangle
2,
area
triangle3,area
'i
=
4,
t5
arca
=
343
ReferenceVariables:
hq[O]
HeapQulzObjects:
youare
here
~
69
4
methodsuseInstancevariables
HowObjectsBehave
Stateaffectsbehavior,behavioraffectsstate.
Weknowthatobjects
have
stateandbehavior,representedby
Instance
variablesandmethods.Butuntilnow,we
haven'tlookedathowstateandbehaviorare
related.
Wealreadyknowthateachinstanceofa
class(eachobject
ofaparticulartype)canhaveitsownuniquevaluesforitsinstancevariables.
Dog
Acanhavea
name
"Fido"anda
weight
of70pounds.DogBIs"Killer"andweighs9pounds.
AndIftheDogclasshasamethodmakeNoiseO,well,
don'tyouthinka70-pounddogbarksa
bitdeeperthanthelittle9-pounder7(Assumingthatannoyingylppysoundcanbeconsidered
a
bark.)
Fortunately,that'sthewholepointofanobject-Ithas
behavior
thatactsonits
state.
In
otherwords,
methods
use
/nstllnnvllt/llb/Iftvalues.
Like,"ifdogIslessthan14pounds,make
ylppysound,else..."or"Increase
weightby
5~
Let'sgochllngesomestat«,
thisIsanewchapter71
objects
have
state
and
behavior
RetMetMber:aclassdescribeswhatan
objectknowsandwhatat1objectdoes
Song
83
.play();
does
kt10ws
I
C-illi~
playO
0l'I
this
iflSta~te
will
t4lASe
"My
W;Y::
to
play.
(blAt
PI~
the
~r.ab-a ~d
Song
title
artist
setTItleO
setArtlstO
playO
lt1stat1ce
variables
(state)
'Methods
(behavior)
Aclass
is
theblueprintforanobject.Whenyou
writeaclass,
you'redescribinghowtheJVM
shouldmakeanobjectofthattype.Youalready
know
thateveryobjectofthattypecanhave
different
instancevariable
values.Butwhatabout
themethods?
}
Songt2
=
newSong();
t2.setArtist("Travis");
Ca"everyobjectofthattypehavedlfferettt
lMethodbehavior?
Well...
sort
cif.*
Everyinstanceofaparticularclasshasthesame
methods,butthemethodscan
behave
differently
basedon
thevalueoftheinstancevariables.
TheSongclasshastwoinstancevariables,
title
and
artist.
TheplayOmethodplaysasong.but
theinstanceyoucallplayOonwillplaythesong
representedbythevalueofthe
title
instance
variableforthatinstance.So,
if
youcalltheplayO
methodononeinstanceyou'llhearthesong
"Politik",whileanotherinstanceplays
"Darkstar",
Themethodcode,however,isthesame.
void
pla.y(){
soundPlayer.playSound(title);
s3.
setTi
tie
("My
Way");
t2.setTitle("Sing");
Songs3
=
newSong();
s3.sstArtist("SexPistols");
∙Yes.
another
stunninglyclearanswerl
72chapter4
methodsuseinstancevariables
System.out.println("Yip!Yip!-);
~:= s s
DogTestDrive{
Dog
size
name
bark()
Dog(
size;
esizeaffectsthe
bark
_:'0bark(){
:.f(size>
60)
System.out.println("Wooof!Wooof!"};
else
if
(size>
14){
System,out.println("RUff!Ruff!");
else(
pub
licstaticvoidmain(String!
J
args){
Dog
one
=
new
Dog();
one.size
=
70;
Dogtwo
=
newDog();
two,size
=
8;
;;:
=':'ngname;
AtlD3cIJ
Dog'sbarkisdifferentfromabigDog'sbark.
ogclasshasaninstancevariable
size,
thatthe
methodusestodecidewhatkindofbarksound
Dogthree
=
new
Dog();
three.size
=
35;
one.bark();
two.bark();
three.bark/);
~
~ j a v a
DogTestDrive
Wooof!Wooof
I
'lip!Yip!
Ruff!Ruff!
youarehere.73
method
parameters
Youcansendthingstoatttethod
Justasyouexpectfrom
any
programminglanguage,you
aU1
pass
valuesinto
yourmethods.Youmight,forexample,wanttotellaDogobjecthowmany
timestobarkbycalling:
d.bark(3);
Dependingonyourprogrammingbackgroundandpersonalpreferences,
you
mightusetheterm
arguments
orperhaps
paramet.ers
forthevaluespassed
in
to
amethod.Althoughthere
em
formalcomputersciencedistinctionsthat
peoplewhowearlabcoatsandwho
will
almostcertainlynotread
this
book.
make.wehave
biggerfishto
fry
inthisbook.So
yuu
can
call
themwhatever
youlike
(arguments,donuts,hairballs,etc.)butwe'redoingitlikethis:
Amethod
~
parameters.Acallerpassesarguments.
Argumentsarethethingsyoupassintothemethods.An
argument
(avalue
like2,
"Faa",
orareferencetoaDog)landsface-downintoa...waitforit..
parameter.
Andaparameter
is
nothingmore
than
alocalvariable.Avariable
withatype
andaname,thatcanbeusedinsidethebodyofthemethod
Buthere'sthe"importantpart:
If
amethodtakesaparameter,you
must
pass
itsomething.Andthatsomethingmust
be
avalueoftheappropriatetype.
O
CallthebarkmethodontheDogrefer-
ence,andpassinthevalue3
(as
the
argumenttothemethod).
Dog
d
=
newDog();
d.bark(3);
~ aY'~~",e~t.
A
Thebitsrepresentingtheint
W
value3aredeliveredintothe
barkmethod.
System.out.println("ruff");
numOfBarks
=
numOfBarks-1;
A
ThebitslandinthenumOfBarks
V
parameter(anint-stzecvariable).
P~,"d_~,"
l:>''\.
~
in
voidbark(intnumOarks)
while(numOfBarks
>
0)
{
{
O
UsethenumOfBarks
parameterasavariablein
themethodcode.
}
}
74
chapter4
methodsuseinstancevariables
Youca.,
getthi.,gs
backfrottt
a
lMethod.
odscanreturnvalues.Everymethod
is
declaredwithareturn
.butuntil
nowwe'vemade
all
ofourmethodswith
avoid
type,
whichmeanstheydon't
giveanythingback.
recan
declare
a
method
to
give
a
specific
type
ofvalue
to
thecaller,suchas:
~
gi
veSecret()
return
42;
declare
a
method
to
return
a
value,
you
must
avalueofthedeclared
rypel
(Oravalue
.(()mpatiblewith
thedeclaredtype.We'llget
atmore
when
wetalkaboutpolymorphism
pter
7
andchapter8.)
ateveryou
say
'II
giveback,you
tter
giveback!
}
t-life.giveSecret();
giveSecet(){
return42-
t,nis
"'~ ~it.
.tJ
illaWl\WI\...
youarehere
~
75
..
multiplearguments
Youcansend",orethanonething
toatMethod
Methodscanhavemultipleparameters.Separatethem
with
commas
whenyoudeclarethem,andseparatethe
argumentswithcommaswhenyou
pass
them.Most
importantly,
if
amethodhasparameters,you
must
pass
arguments
oftherighttypeandorder.
Call1"Qatwo-paralMeterIMethod,altdseltdh,g
IttwoarQuIMe"ts.
void
qo(){
TestStuff
t
=
newT8Ststuff()i
t.takeTwo(12,34);
\\
voidtakeTwo(int
x,
int
y)(
lnt
z
=
x
+
y;
Systam.out.prinUn("Total.is"
+
z);
.
)
Youca"passvariablesh'toaIMethod,aslo"c.1as
the
variabletypeIMatchestheparaIMefertype.
void
qoO(
int
faa
=
7;
intbar
=
3;
t.
takeTwo(foo,bar);
\~
voidtakeTwo(intx,int
y)
int
z...x
+
Yi
System.
out.
println("Totalis
rr
+
z);
76chapter4
methodsuseinstancevariables
Javaispass...by...value.
=
ThattMea"spass"'by"'copy.
-----
intx
=
7;
int
O
Declarean
in~nd
assignit
thevalue'7.Thebitpatternfor
7
goesintothevariablenamedx.
voidgo(intz){
}~
int
A
Declareamethodwithanint
'iii'
parameternamed
z.
ft
CallthegoOmethod,passing
W
thevariablexastheargument.
Thebitsinxarecopied,and
thecopylandsinz.
int
foo.go(x);
int
voidqo(intz){}
lit
dots,,'f.
thci
~........
a.,.d
'J..
d'f't":-\:'
tf
e'Vb\•
f'
11
3
4:'\1..,.
L.
j
,~ ~ d~.~~t~g
><:∙..
∙∙∙∙∙∙∙∙∙∙∙0∙∙∙..∙∙∙∙∙∙∙...
intmt
voidgo(intz){
z
=
0;
}
A
Changethevalueofzinside
V
themethod.Thevalueofx
doesn't
change!Theargument
passedtothezparameterwas
onlyacopyofx.
---
Themethodcan'tchangethe
bitsthatwereinthecalling
variablex.
youarehere.77
argumentsandreturnvalues
Reminder:Java
caresabouttype!
Youcan'treturnaGiraffewhen
thereturntypeIsdeclared
asa
Rabbit.Samethingwith
parameters.Youcan'tpassa
GiraffeIntoamethod
that
takesaRabbit.
•Classesdefine
whatan
objectknowsand
whal
an
objectdoes.
•Thingsanobjectknowsareits
Instance
variables
(state).
•Thingsanobjectdoesare
its
methods(behavior).
•Methodscanuseinstancevariablessothatobjects
ofthesametypecanbehavedifferently.
•Amethodcanhaveparameters,whichmeansyou
canpassoneormorevaluesintothemethod.
•Thenumberandtypeofvaluesyoupassinmust
matchtheorderandtypeoftheparameters
declaredbythemethod.
•
Valuespassedinandoutofmethodscanbe
implicitlypromotedtoalarger
Iype
orexplicitlycast
to
asmallertype.
•Thevalueyoupassasanargumenttoamethod
can
be
aliteralvalue(2,
'c',
etc.)oravariableof
thedeclaredparametertype(forexample,xwhere
x
isanintvariable).(Thereareotherthingsyou
canpassasarguments,butwe'renotthereyet.)
•Amethod
must
declarearetumtype.Avoidretum
typemeansthemethoddoesn'treturnanything.
•Ifa
methoddeclaresanon-voidreturntype,
it
must
returnavaluecompatiblewiththedeclaredreturn
type.
Q..:
DoIhave
to
dosomethingwiththereturn
valueofamethod?
canIJustIgnoreit?
A
:Javadoesn'trequire
you
toacknowledge
a
returnvalue.Youmightwanttocallamethodwith
a
non-voidreturntype,eventhoughyoudon'tcare
aboutthereturnvalue.Inthis
case,you'recalling
themethodfortheworkitdoes
inside
themethod,
ratherthanforwhatthe
methodgives
returns.
In
Java,youdon'thavetoassignorusethereturnvalue.
Q:
WhathappensIftheargument
you
wantto
passIsanobjectInstead
of
II
primitive?
A:
You'lllearnmoreaboutthisInlaterchapters,
butyoualready
know
theanswer.Javapasses
everything
byvalue.EverythIng.But...
value
means
bitsInsidethevcrtable.
Andremember,youdon't
stuffobjectsIntovariables;thevariableIsaremote
control-a
referencetoanobject.
SoIfyoupassa
referenceto
an
objectinto
a
method,you'repassing
a
copyoftheremotecontrol.
Staytuned,though,we'll
havelotsmore
tosayaboutthis.
Q..:
Canamethoddeclaremultiplereturnvalues?
OrIs
theresomewaytoreturnmorethanone
value?
A:
Sortof.
A
methodcandeclareonIyonereturn
value.
BUT...
Ifyouwanttoreturn,say,threeintvalues,
thenthedeclaredreturntypecanbeanInt
orray.
Stuffthoselntsintothearray,andpassItonback.It's
a
littlemoreinvolvedtoreturnmultiplevalueswith
differenttypes;we'llbetalking
aboutthatinalater
chapterwhen
~e
talkaboutArrayLlst.
'Q:
DoIhave
to
returntheexacttype,declared?
A.:
Youcanreturnanythingthatcanbe
implicitly
promotedtothattype.So,
you
canpassabytewhere
anIntIsexpected.Thecaller
won'tcare,becausethe
bytefitsJustfineIntothetnt
thecallerwillusefor
assigningtheresult.Youmustusean
explicit
cast
whenthedeclaredtypeIs
smaller
thanwhatyou're
tryingtoreturn.
78
chapter4
ElectrlcGultar
methodsuseinstancevariables
brand
numOfPickups
rockStarUsesl1
getBrandO
selBrandO
getNumOfPickuPSO
setNumOfPickupsO
getRockStarUsesltO
setRockSlarUsesllO
setRockStaruseslt(booleany&sOrNo){
~tarU8eslt
m
yesOrNoi
-i.DcJ
brand
i
•numOfPiclcups;
.an
rockStarUs8sIt;
:.dsetNumOfPickups(int
num)
numOfPickups
=
num;
.an
g8tRockStarusealt()
=-~rn
rockStarUseslt;
ids8tBrand(String&Brand)(
brand
=
&Brand
i
•getNumOfPickups(){
return
numOfPickups;
"ttgsyoucattdowithparameters
returtttypes
Si:.:-'.-nCJ
qetBrand()
returnbrand;
__.....e'veseenhowparametersandreturntypeswork,it's
themtogooduse:GettersandSetters.
If
you'reinto
rmalaboutit,youmightpreferto
call
them
ACC610TS
.Jw.;ifO;OOIrl.
Butthat'sawasteofperfectlygoodsyllables.
Gcters
andSetters
fits
thejavanamingconvention.so
~,wl:l2 l
we'Ilcallthem.
ndSettersletyou,well,
get
and
sa
things.
Instance
van-
1r:1_JeS.
usually.AGetter'ssolepurposeinlife
is
tosendback,
~az!lnl
value,thevalueofwhateverit
is
thatparticularGetter
".-as.:d
tobeGetting.Andbynow,it'sprobablynosurprise
1&3,~ne r
livesandbreathesforthechance
to
takean
argu-
.~1De
anduseitto
set
thevalueofaninstancevariable.
youarehere.79
realdevelopersencapsulate
Et1capsulaffot1
00Itor
risk
hUlMlliatiot'at'd
ridicule.
Untilthismostimportantmoment,we've
beencommittingoneoftheworst00
fauxpas(andwe'renottalkingminor
violationlikeshowingupwithouttheIB'
inBYOB).No,
we'retalkingFauxPaswith
acapital
'F'.And∙P'.
Ourshamefultransgression?
Exposing
ourdatal
Hereweare.justhummingalongwithout
acareintheworldleaving
ourdataout
therefor
anyoru
toseeandeventouch.
Youmayhavealready
experiencedthat
vaguelyunsettlingfeelingthatcomeswith
leavingyourinstancevariablesexposed.
Exposed
meansreachable
with
thedot
operator,asin:
theCat.height:27;
.Thinkaboutthisideaofusingourremote
controltomakeadirectchangetotheCat
object'ssizeinstancevariable.Inthehands
ofthewrongperson,areferencevariable
(remotecontrol)isquiteadangerous
weapon.Becausewhat'stoprevent:
't.
~\l.ts~
W
t.
eA"
1
theCa
t.
height
=
0;
1e-t
~i5.
"ayYt".
ThiswouldbeaBadThing.Weneedto
buildsetter
methodsfor
all
theinstance
variables,
andfindawaytoforceother
code
to
callthesettersratherthanaccess
thedatadirectly.
80
chapter4
publicvoidsetBeight(intht){
if(ht
>
9){
height:ht;
}
thedata
it
is
thatsimpletogofrom
implementationthat'sjust
.gforbad
data
to
one
protects
your
data
and
ectsyourrighttomodify
implementationlater.
sohowexactlydoyou
thedata?
With
the
lieandprivate
essmodifiers.You're
.
iar
with
public-weuse
rith
everymainmethod.
r
e'sanencapsulation
nileofthumb(allstan-
disclaimers
aboutrules
~
thumbareineffect):mark
instancevariables
privati!
provide
public
getters
settersforaccesscontrol.
youhave
moredesign
codingsavvyinJava,you
bablydothingsalittle
rently,
butfornow.this
I!!!IlP:oach
will
keepyousafe.
arkgettersand
etterspUblic.
∙Sodly.Bill
forgotto
CftCopsulQt~
hisCatclass
and
endedupwltk
Q
flatcat.
H
(overheardatthewater
cooler).
methodsuseInstancevariables
'"
Java'~ed
Thisweek'sInterview:
AnObjectgetscandidaboutencapsulation.
HeadFirst
What'sthebigdealaboutencapsulation?
Object:
OK.,youknowthat
dream
whereyou're
giving
a
talkto
500
peoplewhenyou
suddenly
realize-
you're
TUJkaP.
HeadFirst:
Yeah,we'vehadthatone.It'srightuptherewiththeoneabouttheNates
machineand...no,
we
won'tgothere.OK,soyoufeelnaked.Butother
than
beingalittle
exposed,
is
there
any
danger?
Object
Is
there
any
danger?
Is
thereany
danger?
[St3.I'1S
laughing]
Hey,
did
all
youother
instanceshearthat,
"Is
lhert
aT[!
danger?"
he
asks?
[falls
onthefloorlaughing]
HeadFirst:
What'sfunnyaboutthat?Seems
like
a
reasonablequestion.
Object:
OK,
I'll
explainit.It's
[bW'StS
outlaughingagain,uncontrollably]
HeadFirst:
Can
I
getyouanything?Water?
Object:
Whew!
Oh
boy.
NoI'mfine,really.
I'll
beserious.Deepbreath.OK,goon.
HeadFirst:
Sowhat
does
encapsulationprotectyoufrom?
Object
Encapsulationputsaforce-fieldaround
my
instancevariables,sonobodycanset
themto,let's
say,something
inappropriaJ.e.
HeadFirst
Canyougivemean
example?
Object:
Doesn'ttakea
PhDhere.
Mostinstancevariablevalues
are
codedwithcertain
assumptions
about
theboundariesofthevalues.
Like,
think
ofallthe
things
thatwould
break
if
negativenumberswereallowed.Number
of
bathrooms
in
anoffice.
Velocityof
anairplane.Birthdays.Barbell
weight
Cell
phonenumbers.Microwaveoven
powet
HeadArst:
I
seewhatyoumean.
So
howdoesencapsulationletyou
set
boundaries?
Object
By
forcing
othercodeto
go
through
settermethods.Thatway,thesettermethod
can
validatetheparameteranddecide
if
it'sdo-able.Maybethemethod
will
reject
it
and
donothing,ormaybeit'llthrowanException
(like
if
it'sanull
social
securitynumber
foracreditcardapplication),ormaybethemethod
will
roundthepanlITletersentin
to
thenearestacceptablevalue.Thepointis,you
can
dowhateveryouwant
in
thesetter
method,
whereasyoucan'tdo
aT[!thing
if
your
instance
variables
are
public.
HeadFirst:
ButsometimesI
see
settermethodsthatsimplysetthevaluewithoutcheck-
inganything:
If
youhave
aninstance
variablethatdoesn't
have
aboundary,doesn'tthat
senermethodcreateunnecessaryoverhead?
A
performance
hit?
Object:
Thepointtosetters(andgetters,
too)
is
that
you
canc1umge
your
mind
later,
without
breaking
any1Jo4y
else's
code!
Imagine
if
halfthepeopleinyourcom-
pany
usedyourclasswithpublicinstancevariables,andonedayyousuddenlyrealized,
"Oops-there'ssomethingIdidn'tplanforwiththatvalue,I'mgoing
to
havetoswitchtoa
settermethod."Youbreakeveryone'scode.Thecoolthingaboutencapsulation
is
that
you
get
tocJumgt
)'CUT
mind.
AndnobodygetshurtTheperformance
gain
fromusingvariables
directly
is
sorninisculeandwould
rareIy--if
DJn-
be
worthit
youarehere
~
81
howobjectsbehave
GoodDog
size
gelSize(}
selSize()
bark()
classGoodDog(
privateintsize;
.~.,.t,L
/I
tJ\o¥-t.
.\.)\t.\.
#.,/-
'\,,\l\t.
~
publicintgetSize()
~o~
0
~
)r,turn
,i,e,
t).
~~
al\G
~
publicvoidsetSi"le(ints)(
Ma'¥.t.
t..1.\..~~ ~.
~tt.~
",CV'
size
=
sr
Ettcapsulatittgthe
t}oodPog
class
voidbark()(
if
(size>
60)
System.out.println("wooof!Wooof!");
else
if
(size>
14)(
Syscem.out.princln("Ruff!Ruff!");
else(
System.out.println("Yip!Yip!");
classGoodDogTestDrive
I
+
one.getSize(»;
"+
tWQ.getSize(»;
I.Any
placewherea
particularvaluecan
be
used,a
method
callthatreturnsthat
type
can
beused.
Instead
of:
intx
=
3
+
24;
you
can
say:
intx
=
3
+
one.gdSize();
publicstaticvoidmain(String!)args)(
GoodDog
one
=
newGoodDog();
one.setSize(70);
GoodDogtwo
=
newGoodDog();
two.setSize(8);
System.out.printlnIWDogone:
System.out.printlnl"Dogtwo:
one.bark();
two.bark();
82
chapter4
Howdo
objects
I"a"array
have?
like
any
otherobject.Theonlydifferenceis
.you
get
tothem.Inotherwords,howyouget
remotecontrol.Let's
try
callingmethodson
objectsin
anarray.
DeclareandcreateaDogarray,
tohold
7
Dogreferences.
Doq[]pets;
pets
=
newDoq[7];
Dog[]
CreatetwonewDogobjects.
andassignthemtothefirst
twoarrayelements.
pets[0]
=
newDog();
pets[l]
=
newDog();
Call
methodsonthetwoDog
objects.
pet8[O].setSize(30);
intx
=
pets[O].qetsize();
peta[l).setSize(8);
Dog[]
methodsuseinstancevariables
Dogarrayobject(Dog[])
Dog
array
object(Dog[])
youarehere
~
83
Instancevariables
alwaysgeta
defaultvalue.If
youdon'texplicitly
assignavalue
toaninstance
variable,oryou
don'tcallasetter
method,the
instancevariab'e
stillhasavalue!
integers0
floatingpoints0.0
booleansfalse
Initializinginstancevariables
Peclarfttgandinitializing
ittstatlcevariables
Youalreadyknowthatavariabledeclarationneedsatleastaname
andatype:
intsize;
Stringname;
Andyouknowthatyoucaninitialize(assignavalue)tothe
variableatthe
same
time:
intsize
=
420;
String
name
=
"Donny";
Butwhenyoudon'tinitializeaninstancevariable,whathappens
whenyou
call
agettermethod?Inotherwords,whatisthe
value
of
aninstancevariable
bejoreyou
initialize
it?
t,al'll.t
IIayia\,\e
s
,
classPoorDog(
dtt\a'Ct
t..,o
i~ ~
IIalw.
../}\:l",t.
d()t\'
t.
a~I~1\
private1ntsize;
k'
~
privateStringname;
Whatwill-tnue:
'Cd!.',",??
P)ubliCintgetsize()
(~
returnsize;
If
publicString
getName()(
returnname;
references
null
,Y.-?
y.l\\\
publicclassPoorDogTestDrive{
~\:,~o ~O'"t.~j
,
publicstaticvoidmain(String[]args)(/.
"'1\
t,O"'~
PoorDogone
=
newPoorDog();
'.!.
~\~
e)
System.out.println("Dogsizeis"
+
one.getSize(»);
System.out.println("Dognameis"
+
one.getName(»);
%javaPoorDogTestDrive
Dogsizeis
0
Dognameisnull
84chapter
4
methodsuseinstancevariables
fhedifferet1cebetwee"it1sfat1ce
at1d
localvariables
publiciotadd(){
int
total
=
a
+
b;
returntotal;
o
Instance
variablesaredeclared
insideaclass
butnotwithinamethod.
e
Local
variablesaredeclaredwithinamethod.
classAddThing{
iota;
intb
=
12;
Q:
Whataboutmethodparameters?
Howdo
therulesaboutlocalvariables
apply
tothem?
Localvariablesdo
NOTgetadefault
value!Thecompiler
complainsifyou
trytousealocal
variablebefore
thevariableis
initialized.
15.2;
classHorse(
privatedouble
height
privateString
breed;
II
morecode...
e
Local
variables
~UST
beinitializedbeforeusel
class
Foo{
"I\e"
Yov.
u~
publicvoidgo()(
W()\'l
t
to"'''
't ~ ~
a
'Ja\~,
Ln
t
x;deda
ye
Yo
WI0
b-1
nl.&t.
as
$CO¥\
as
'f~
.
Lrrtz
=
x
+
3;
to
~
it,
~e l.oft<~\
tr
"-------
~~ea~
ol.&-t.
FileEditWindowHe!
'r'lke6
%
javacFoo.java
Foo.java:4:variablexmight
nothavebeeninitialized
intz
=
x
+
3;
1error
A:
Methodparametersarevirtuallythe
sameaslocal
variables-they'redeclared
Inside
themethod(well,technicallythey're
declaredinthe
argumenrltst
ofthemethod
ratherthanwithinthe
body
ofthemethod,
butthey'restilllocalvariablesasopposedto
Instancevariables).Butmethodparameters
willneverbeuninitialized,soyou'llneverget
acompliererrortellingyouthataparameter
variable
mightnothavebeeninitialized.
Butthat'sbecausethecompilerwillgive
youanerrorifyoutrytoinvokeamethod
withoutsendingargumentsthatthemethod
needs.Soparametersare
ALWAYSinitialized,
becausethecompilerguaranteesthat
methodsarealwayscalledwitharguments
thatmatchtheparameters
declaredforthe
method,andtheargumentsareassigned
(automatically)totheparameters.
youare
here.
85
objectequality
Colttpari"Qvariables(primitivesorrefere.,ces)
Sometimesyouwanttoknow
if
two
primitives
arethesame.That'seasy
enough,justusethe
=
operator.Sometimesyouwanttoknow
if
two
referencevariablesrefertoasiogleobject
~>n
theheap.
Easy
aswell,
jusluse
the
==
operator.Butsometimesyouwanttoknow
if
two
objects
areequal.
Andforthat,youneedthe.equals
0
method.Theideaofequalityfor
objects
dependsonthetypeofobject.Forexample,
if
twodifferentString
objectshavethesamecharacters(say."expeditious"),theyaremeaningfully
equivalent,regardless
ofwhethertheyaretwodistinctobjectsontheheap.
ButwhataboutaDog?DoyouwanttotreattwoDogs
as
beingequal
if
they
happentohavethe
same
sizeandweight?Probablynot.
So
whethertwo
differentobjectsshouldbetreated
as
equaldependsonwhatmakessensefor
thatparticularobjecttype.We'llexplorethenotionofobjectequalityagain
in
laterchapters(andappendixB),butfornow,weneedtounderstandthat
the
==
operatorisused
emly
tocomparethebitsintwovariables.
What
those
bits
representdoesn'tmatter.Thebitsareeitherthesame,orthey'renot.
Tocomparetwoprimitives,usethe
==
operator
Use
==
tocompare
twoprimitives,
ortosee
if
two
referencesreferto
thesameobject.
UsetheequalsO
methodtosee
if
two
diHerenf
objectsareequal.
(Suchastwodifferent
Stringobjectsthatboth
representthecharacters
In"Freel")
The
=
operatorcanbeusedtocomparetwovariablesofanykind,andit
simply
comparesthebits.
if
(a
=
b){...
j
looksatthebitsin
a
andbandreturns
true
if
thebitpattern
is
thesame(although
itdoesn't
careaboutthe
size
ofthevariable,
50
all
the
extrazeroesontheleftenddon'tmatter).
~~
0"
)(~\
oV'eu'(
t
in
t
Ii
=
3;
(t.t.t'«(
aye.'"
J
t"e
iYl,
\
rt
~\de L~t
.
.lc.he
tJ(
't.
(.4'(e
6
1l
a--
byteb
=
3;
\,~t.
'Ole
o.~
--
if
(a
==
b){
II
tl:Ue}
t.'ha
t
n('(e),
int
byte
ToseeIftworeferencesarethesame(whichmeansthey
refertothesameobjectontheheap)usethe
==
operator
if
(a
==
b)
{
II
false
}
Foo
a=t.ish"\oI.e
if
(a
--
c)
(
II
true
)
if
(b
c)
(
II
false
)
a=
b
is
.falst
Foo
--
Foa
Remember,the
==
operatorcaresonlyaboutthepatternofbitsinthe
variable.Therulesarethesamewhetherthevariableisareferenceor
primitive.Sothe
==
operatorreturnstrue
if
tworeferencevariablesreferto
thesameobjectlInthatcase,wedon'tknowwhatthebitpatternis(because
it's
dependentontheJVM,andhiddenfromus)butweMknowthatwhatever
itlookslike,
itwiUbe
the
samefortworefmrues
to
asingleobject.
Fooa
=
newFoo();
Foo
b
=
newFoo();
Fooc
=
a;
86
chapter4
methodsuseInstancevariables
Make
,tst,tk
Roses
are
red,
this
poem
ischopPY,
.byvalue
passing
;s
passing
by
copy,
1it.Replaceour
can
do
better?
r'J
8e~ryet.
Oh,
like
yoU
dllne
withyourow'"wn
wOld~
dumbseco
n
Ithingwith
YOUl
0
theY/hoe
replaceforget
it.
a"dyou'll
never
intcalcArea(intheight,intwidth)
returnheight•width;
What'slegal?
Giventhemethodbelow,which
of
themethodcallslistedonthe
rightorelegalt
Putacheckmcrk
nexttothe
onesthatarelegal.(Some
statementsaretheretoassign
valuesused
in
themethodcolis).
KEEP
+-
RIGHT
inta'"calcArea(7,12);
short
c'"
7;
calcArea
(c,15);
int
d'"
calcArea(S7);
calcArea(2,3);
long
t'"
42;
int
f
=
calcArea(t,17);
int9'"calcArea();
calcArea();
byteh
=
calcArea(4,20);
int
j
=
calcArea(2,3,5);
youarehere
~
87
exercise:BetheCompiler
BE
the
oomriler
EachoftheJava
files
on
this
page
represents
a
complete
sourcefile.
Yourjoh
is
to
playcollll'iler
and
determine
whether
each
of
thesefiles
will
compile.
If
they
won't
compile.how
would
you
rIX
them,
and
if
theydo
c011lpile.
what
wouldhe
theiroutput'i'
A
B
classXCopy{
publicstaticvoidmain(Strinq[)arqs){
classClock{
Stringtime;
intorig
=
42;
void
setTime(Stringt)
time
=
tj
Xcopyx
=
new
xCopy();
int
y:
x.go(orig)j
System.out.println(orig
+
UU
+
y);
voidgetTime()
returntime;
}
intgo(intarg)
arg
=
arg
*
2;
classClockTestDrive{
publicstaticvoidmain(String(]args){
returnarg;
}
Clockc
=
newClock();
}
c.setTime(U124S
n
)j
Stringtad
=
c.getTime()i
System.out.println(Utime:
u
+
tod)j
88
chapter4
methodsuseinstancevariables
AbunchofJavacomponents,infullcostume,areplayingaparty
game,∙Whaam
W
Theygilleyouaclue,andyou
try
toguesswho
theyare,basedonwhattheysay.Assumetheyalwaystellthetruth
aboutthemselves.Iftheyhappentosaysomethingthatcouldbetrue
formorethanoneguy,then
writedownallfarwhomthatsentence
applies.FillIntheblanksnexttothesentencewith
thenamesofone
ormoreattendees.
Tonight'sattendees:
Insta
nee
variable,argument,return,getter,setter,
encapsulation,public,private,pass
by
value,method
Aclasscanhaveanynumberofthese.
A
methodcanhaveonlyoneofthese.
Thiscanbe
Implicitlypromoted.
I
prefermyInstancevariablesprivate.
Itreallymeans'makeacopy'.
Onlysettersshouldupdatethese.
Amethodcanhavemany
ofthese.
I
returnsomethingbydefinition.
I
shouldn'tbeusedwithinstancevariables.
Icanhavemanyarguments.
Bydefinition,Itakeone
argument.
Thesehelp
createencapsulation.
Ialways
flysolo.
youarehere.89
puzzle:Mi)(edMessages
Mixed
Messages
AshortJavaprogramIslistedtoyourright.
Twoblocksof
theprogramaremissing.
YourchallengeIsto
match
thecandIdate
blocksof
code(below),withtheoutput
thatyou'dsee
if
theblockswereInserted.
Notall
thelines
of
outputwillbeused,and
someofthelinesofoutputmightbeused
more
thanonce.Drawlinesconnecting
thecandidateblocksofcodewiththeir
matchingcommand-line
output.
publicclassMix4(
intcounter=
OJ
publicstaticvoidmain(String[)args)(
intcount=0;
Mix4[)m4a=new
Mix4[20lj
intx
=
0;
while
(I
I)
m4a[x]
=
newMix4();
m4a(x].counter=m4a(xl.counter
+
1;
count
count
count
+
1;
count
+
m4a[x).maybeNew(x);
CandIdates:
x∙<
9
index
<
5
,!
x
<
20
index
<
5
.~
x
<7
index
<
'1
x
<
19
index
<
1•.
90
chapter4
Possible
output:
x
=
x
+
1;
System.out.println(count
+
~
"
+
m4a[1).counter);
publiciotmaybeNew(intindex)
if
(II')(
Mix4m4
=
newMix4();
m4.counter=m4.counter
+
1;
return1;
return0;
methods
use
Instancevariables
Your
Job
istotakecodesnippetsfromthe
poolandplace
themIntotheblanklines
inthecode.Youmay
not
usethesame
snippetmorethanonce,andyou
won't
needtouseallthesnippets.Your
goal
istomakeaclassthatwillcompileand
runandproducethe
outputlisted.
publicclassPuzzle4{
publicstaticvoidmain(Strinq[]arqs){
int
y
=
I:
int
x
=
0:
intresult
=
0;
while
(x
<
6){
yy
*
10;
}
x
=
6;
while
(x
>
0){
}
result
=
result
+__
}
system.out.println("result"
+
result);
{
_____doStuff(int){
if
(ivar>
100){
int
ivar;
}
class
Output
return_
}
else{
-
return
---------------------
}
}
Note:Eachsnippet
"omthepoolcanbe
usedonlyoncel
}
you
arehere)
91
puzzle:FiveMinuteMystery
FastTImes
in
Stim-Clty
WhenBuchananjammedhistwitch-gunintoJai'sside,
Jai
froze.JaiknewthatBuchanan
wasasstupid
lis
hewasuglyandhedidn'twanttospookthebigguy.BuchananorderedJai
intohis
boss'soffice,butJai'ddonenothingwrong,(lately),sohe
figured
alittlechatwith
Buchanan'sbossLevelercouldn'tbetoobad.
He'dbeenmovinglots
of
neural-stimmersin
thewestsidelately
and
hefiguredLevelerwouldbepleased.Blackmarketstimmersweren't
thebestmoneypumparound,buttheywereprettyharmless.Mostoftheslim-junkieshe'd
seentappedoutafter
a
whileandgotbacktolife,maybejustalittlelessfocused
than
before.
Leveler's'office'
was
askungylookingskimmer,butonceBuchananshoved
him
in,Jai
couldseethat
it'd
beenmodifiedtoprovideaILtheextraspeedandarmorthatalocalbosslike
Levelercouldhopefor.
"Jai
myboy",hissedLeveler,"pleasuretoseeyouagain"."Likewise
I'msure...",saidJai,sensingthemalicebehindLeveler'sgreeting,"Weshouldbesquare
Leveler,have
r
missedsomething?""Ha!You're
making
itlookprettygoodJai,yourvolume
isup,but
I'vebeenexperiencing,shallwesay,
a
little'breach'lately..."saidLeveler.
Jaiwincedinvoluntarily,
he'dbeenatopdrawerjack-hackerinhisday.Anytimesomeone
.figuredouthowtobreak:astreet-jack'ssecurity,unwantedattentionturnedtoward
Jai,
"No
wayit'smeman",saidJai,
"not
worththedownside.I'mretiredfromhacking,[justmove
my
stuffandmindmyownbusiness","Yeah,yeah",laughedLeveler,"I'msureyou're
cleanonthisone,but
I'll
belosingbigmarginsuntilthisnewjack-hackerisshut
out!""Well,best
ofluckLeveler,maybeyoucouldjustdropmehereandI'llgo
moveafewmore
'units'
foryoubefore
I
wrapuptoday",saidJai.
"I'mafraidit'snotthat
easy
Jai,Buchananheretellsmethatwordisyou're
currenton
137NE",
insinuatedLeveler."NeuralEdition?sure
I
playaroundabit,
so
what?".Jairespondedfeelingalittlequeasy."Neuraledition'sbow
I
letthestim-junkies
knowwherethenextdropwillbe",explainedLeveler."Troubleis,some
srim-junkie's
stayed
straightlongenoughto
figure
outhowtohackintomyWareHousingdatabase.""Ineed
a
quickthinkerlikeyourself
Jai,
totakealookatmyStimDrop
137NE
class;methods,instance
variables,thewholeenchilada,andfigureouthowthey'regettingin.
It
should..",
"HEY!",
exclaimedBuchanan,
"I
don'twantnoscumbackerlike
Jai
DOSin'aroundmycode!""Easy
big
guy",
Jaisawhischance,"I'msureyoudidatopratejobwithyouraccessmodi.."Don't
tellme-bittwiddler!",shoutedBuchanan,"1leftallofthose
junkie
levelmethodspublic,
sotheycouldaccessthedropsitedata,but
1
markedallthecriticalWareHousingmethods
private.Nobodyontheoutsidecanaccessthosemethodsbuddy,nobody!"
"I
think
I
canspotyourleakLeveler,whatsaywedropBuchananhereoffatthecomer
andtake
a
cruisearoundtheblock",suggestedJai.Buchananreachedforhistwitch-gunbut
Leveler'sstunnerwasalreadyonBuchanan'sneck,"LetitgoBuchanan",sneeredLeveler,
"Dropthetwitcherandstepoutside,
I
think
Jaiand
I
havesomeplanstomake",
Whatdid
J
aisuspect?
Willbegetout
ofLeveler'sskimmerwithallhisbonesintact?
92
chapter
4
Instance
varl~bles,
getter,utter,method
return
setter
getter.s£'tter,public.private
return
return.argument
encapsulation
passby
value
Instancevariables
o.rgt.llnent
getter
public
method
Note:'Getter'methodshaveareturn
type
by
definition.
}
methodsuseInstancevariables
}
String
getTime()
returntime;
classClock
Stringtime;
void
setTime(~tring
t){
time::t;
}
classClockTestDrive{
publicstaticvoidmain(String
rl
args){
Clockc
=
newClock();
c.setTime(R124S
R
)j
Stringtod
=
c.getTime();
System.out.println(Utime:•
+
tod);
B
XCopy'compilesandrunsas
it
standsIThe
84'.RememberJavaispassby
value,(which
copy),thevariable'orig'
is
nolchangedbythe
dass
canhaveanynumberofthese.
methodcanhaveonlyone
ofthese.
I'
canbeimplicitlypromoted.
prefermyinstancevariablesprivate.
reallymeans'makeacopy'.
settersshouldupdatethese.
methodcanhave
manyofthese.
returnsomethingbydefinition.
shouldn'tbeused
with
instancevariables
canhave
manyarguments.
definition,,takeoneargument.
sehelpcreateencapsulation.
alwaysflysolo.
youarehere.
93
puzzle
answers
PuzzleSolutions
Answertothe5-minutemystery...
pUblicclassPuzzle4(
publicstaticvoidmain(String[]args){
Puzzle4b[]ebs
=
new
Puzzle4b[6J;
int
y-
1;
int
K..
0,
intresult
=
0:
while
(x
<
6)(
obs[x)
=
newPU2zle4b():
obs[x).
ivar
=
y;
y-y..
10;
x=><+1;
Jai
knewthatBuchananwasn'tthesharpest
pencil
in
thebox.When
J
ai
heardBuchanan
talk
abouthiscode,Buchanannevermentioned
hisinstancevariables.
Jai
suspectedthat
whileBuchanan
did
in
fact
handle
his
methods
correctly,hefailedtomarkhisinstancevariables
private.
Thatslipupcouldhaveeasilycost
Levelerthousands.
x
=
6,
while
(x
>
0){
x
=
x-I;
result
=
result
+
obs[x].doStuff(x):
Candidates:
Possibleoutput:
System.out.println("result
u
+
result);
q\
javaPuzzle4
result543345
index
<
1
index
<
5
index
<
7
index
<
5
x
<
19
x
<
9
x
<
7
x
<
20
Output
}
class
Punle4b{
1nt
ivar,
publicint
doStuff(int
factor)
if
(ivar
>
100){
returnivar
*
factor;
else{
returnivor"
(5-
factor);
94
chapter4
5writingaprogram
Extra-StrengthMethods
Let'sputsomemuscleInourmethods.
Wedabbledwithvariables,played
withafewobjects,andwrotealittlecode.Butwewereweak.Weneedmoretools.Like
operators.
Weneedmoreoperatorssowecandosomethingalittlemoreinterestingthan,say,
bark.
And
loops.
Weneedloops,butwhat'swiththewimpy
while
loops?Weneed
10,
loops
jfwe'rereallyserious.
Mightbeusefulto
generaterandomnumbers.
And
turnaString
IntoanInt,
yeah,thatwouldbecool.Betterlearnthattoo.Andwhydon'twelearnItallby
building
somethingreal,toseewhatit'sliketowrite(andtest)aprogramfromscratch.
Maybe
agame,
likeBattleships.That'saheavy-liftingtask,soIt'lltake
two
chapterstofinish.We'llbuild
asimpleversioninthischapter,andthenbuildamorepowerfuldeluxeversioninchapter6.
thisisa
newchapter
95
buildingarealgame
LetlsbuildaJattleship...style
gattte:
"Sitdc
a
Pot
COttt
N
o
123456
'-shr-h
at.
ut"o,
like
Java
d'n'ays
It'syouagainstthecomputer,butunlikethereal
Battleshipgame,inthis
oneyoudon'tplaceanyships
ofyourown.Instead,yourjob
is
tosinkthecomputer's
ships
\0
thefewest
numberof
guesses.
Oh,
andwearen'tsinkingships.We'rekillingDot
Corns.(Thusestablishingbusinessrelevancysoyoucan
expensethecostofthisbook).
Goal:Sinkallofthecomputer'sDotCornsinthefewest
numberofguesses.You'regivenaratingorlevel,based
onhowwellyou
perform.
Setup:Whenthe
game
programislaunched,the
computerplacesthreeDotCornsona
virtual
7x7
grid.
Whenthat'scomplete,thegame
asks
foryour
first
guess.
Howyouplay:Wehaven'tlearnedtobuildaCUIyet,so
thisversionworksat
thecommand-line.Thecomputer
willpromptyoutoenteraguess(acell),thatyou
'U
type
at
thecommand-lineas
~A.3",
"C5",etc.).Inresponse
toyourguess,you'llseearesultatthecommand-
line,either"Hit","Miss",or"YousunkPets.corn"(or
whateverthe
lucky
DotComofthedayis).When
you'vesentallthreeDotCamstothatbig404inthe
sky,thegameends
by
printingoutyourrating.
tat.\-.
'oo~~
"7
)<
"7
~r-id
',s
a
"t.t\\
A
B
C
D
E
F
G
k
E
5
•
~
e
P4
ts.ccm
II
Asi
Me.c
pm
You'regoingtobuildthe
SinkaDotCom
game,with
a
7x7
grid
and
three
DotComs.
Each
DotCom
takesupthreecells.
part
of
agalMe
it1feraetlott
..
%javaOotComBust
Enter
a
guess
A3
miss
Entera
guess
82
miss
Enter
a
guess
C4
miss
Enter
a
guess
02
hit
Enteraguess
03
hit
Enteraguess
04
Ouch!Yousunk
Pets.com
kill
Enter
aguess
B4
miss
Enteraguess
G3
hit
Enter
aguess
G4
hit
Enter
aguess
GS
Ouch!'lousunkAskMe.com
96chapter5
writingaprogram
Firsta
high...
leveldesigtt
A
dial'l\Of\d
yt:f""~l\b
a
dt:t.isiOl\
~O'l\t
hit
remove
DotCom
displayuser
score/rating
Gameset-up
o
Userstartsthegame
Gamefinishes
Givetheuser
a
rating
based
on
the
numberof
guesses.
o
GamecreatesthreeDotComs
o
GameplacesthethreeDot
ColTlSonto
a
virtualgrid
A
Promptuserfor
a
guess
1'\
W
("'2','CO',
etc.).)
(0
Check'heuserguess
oga;nst
allDotComstolookforahit,
miss,orkill.Takeappropri-
ateaction:
if
ahit,deletecell
(A2,D4,etc.).
If
akill,delete
DotCom.
Game
play
begins
Repeatthefollowinguntilthereare
nomoreDot
Coms:
'e
knowwe'llneedclassesandmethods.butwhat
uldtheybe?Toanswerthat,we
needmore
formationaboutwhatthegameshoulddo.
First,
weneedto
figure
outthegeneralflowofthe
zame.
Here'sthe
basic
idea:
~ o w
we
have
an
idea
of
the
kinds
ofthingsthe
rogram
needstodo.
The
next
stepis
figuring
ut
whatkindof
objects
we'llneed
to
do
the
loo∙ork.
Remember,
thinklikeBradratherthan
Larry;
focus
first
on
the
things
in
theprogram
rather
thanthe
jrroredures.
Whoa.Arealflowchait.
youarehere.97
asimplerversionofthegame
6arM
starts,
andcreatesONEDotCom
andgivesitalocationonthree.cellsin
thesinglerowofsevencells.
Insteadof•
A2",
∙C4",and
50
on,the
locationsarejustintegers
(for
example:
1,2,3
arethecelllocationsinthis
picture:
6
5
4
3
2
6ame
'finisheswhenallthreecellshave
beenhit
(thenumOfHitsvariable
vel-
ue
is
3),
andtellstheuserhowmany
guessesittooktosink
theDotCom.
6a1U
play
begins.
Promptuserfor
aguess,thenchecktoseejf
it
hit
anyof
theDotCom'sthreecells.
Ifahit,incrementthenumOfHits
variable.
1
o
o
SlmpleDotCom
Game
~
SlmpleDofCom
voIdmail\
Inl
0
localionCells
Intnum01Hl1s
String
checkYou~If(Stril\g
guess)
voidSetlocallonCellsQntOloe)
three
fhe"SitMplePotCO"'.allte
N
aget1tlerit1troductiot1
It
lookslikewe'regonnaneedatleasttwoclasses,a
Gameclass
andaDotComclass.Butbeforewebuild
the
fuJI
monty
Sinh
a
Dot
Com
game,we'llstartwith
astripped-down.simplifiedversion,
Simple
Dot
Com
Game.
We'llbuildthesimpleversion
in
this
chapter,
followedby
thedeluxeversionthatwebuildinthe
next
chapter.
Everythingissimplerinthisgame,Instead
ofa2-D
grid,we
hidetheDotCominjustasingle
TOW.
And
insteadof
three
DotCorns,weuse
one.
Thegoalisthesame,though,sothegamestillneeds
tomakeaDotCominstance,assignitalocation
somewherein
therow,getuserinput,andwhenall
of
theDotCom'scellshavebeenhit,thegame
is
over,
Thissimplifiedversion
ofthe
gamegivesusabigheadstart
onbuilding
thefullgame.
If
wecangetthissmallone
working,wecanscaleitupto
the
morecomplexonelater.
Inthissimpleversion,
the
gameclasshasnoinstance
variables,
andallthegame
codeisinthemain()method,
Inotherwords,whenthe
programislaunchedand
main()beginstorun,itwill
make
theoneandonlyDotCom
instance,pickalocationforit(
consecutivecellson
thesinglevirtual
seven-cellrow),asktheuserforaguess,check
the
guess,andrepeatuntilallthreecellshavebeenhit.
Keepin
mindthatthevirtualrowis...
virtual:
Inother
words,itdoesn'texistanywhereintheprogram.
As
longasboththegameandtheuserknowthatthe
DotComishiddeninthreeconsecutivecellsoutofa
possib\eseven(startingat
zero),
the
tOW
i.tselfdoesn't
havetoberepresentedincode.Youmightbetempted
tobuildanarrayofsevenintsandthenassignthe
DotComto
threeofthesevenelementsinthearray,
butyoudon'tneedto.Allweneedisanarraythat
holdsjustthethreecellstheDotComoccupies.
98chapter5
Pevelopit1QaClass
_aprogrammer,youprobablyhaveamethodology/
ess/approachtowritingcode.Well.sodowe.Our
sequenceisdesignedtohelpyousee(andlearn)what
're
thinkingasweworkthroughcodingaclass.It
't
necessarilythewaywe(or
you)
writecode
in
the
World.IntheRealWorld,ofcourse,you'llfollow
approachyourpersonalpreferences,project,or
ployerdictate.We,however,candopretty
much
teverwewantAndwhenwecreateaJavaclassasa
rningexperience",weusuallydoitlikethis:
DFigureoutwhattheclassissupposedto
do.
D
List
the
Instancevariablesandmethods.
D
Write
prepcode
forthemethods.(You'llsee
thisinJusta
moment.)
D
Write
testcode
forthemethods.
D
Implement
theclass.
o
Test
themethods.
writingaprogram
fhethreethlt19S
we~1I
wrItefor
eachclass:
ThisbarIsdisplayedonthenextsetofpagestotell
youwhichpartyou'reworkingon.Forexample,ifyou
see
thispictureatthetopofapage.itmeansyou're
workingonprepcodefortheSimpleDotComclass.
~
SlmpleDolComclass
prepcode
Aformofpseudocode.to
help
youfocus
on
the
logic
without
stressing
aboutsyntax.
testcode
A
class
ormethodsthat
will
testtherealcode
andvalidatethatit'sdoing
theright
thing.
o
Debug
and
relmplement
asneeded.
reaIcode
The
actual
implementation
of
the
class.Thisis
o
Expressgratitudethatwedon'thavetotest__----.....alJava
code.
ourso-called
learningexperience
appon
ToDO.:
actuallJveusers.
Flex
thosedendrftes.
HowwouldyoudecidewhIchclassorclasses
to
build
first,
whenyou'rewritIngaprogram?
Assuming
thatallbutthetiniestprograms
needmore
thanoneclass(Ifyou're
following
good00principles
and
not
havingoneclass
do
manydifferentJobs),wheredoyoustart?
s'mp'eDotCOmclaSS
o
writeprepcode
o
writetestcode
o
writefinalJavacode
s,mp'eDotCOmoame
cia••
o
writeprepcode
writetestcode
{nol
o
writefinalJavacode
youarehere.
99
SimpleDotCom
class
SlmpleOolCom
illl
0
IocaIiooCelIs
inlnumOft-lils
StringcheckYourself(stringguess)
void
selLoca~onCells{inlj)
lot)
100
chapter5
You'11gettheideaofhowprepcode(ourversionofpseudocode)worksasyou
readthroughthisexample.It'ssortofhalf-waybetweenrealJavacodeandaplain
Englishdescriptionofthe
class.
Mostprepcodeincludesthreeparts:instance
variabledeclarations,
methoddeclarations,methodlogic.Themostimportant
partofprepcode
is
themethodlogic,because
it
defines
what
hastohappen,
whichwelatertranslateinto
hotu;
whenweactuallywritethemethodcode.
DECLARE
an
intarray
toholdthelocationcells.
Call
it
loeatJonCells.
DECLARE
an
int
to
holdthenumberof
hits.Call
it
numOfHits
and
SET
it
to
O.
DECLARE
a
checkYourset(()
methodthat
takesa
String
fortheuser'sguess("
I","3",
etc),
checks
it.
andretumsaresultrepresentinga"hit","miss",or
"kill",
DECLARE
a
setLocationCeJ/sO
settermethodthattakesan
intarray
(whichhasthethreecell
locations
asints
(1.3/1,
etc.).
METHOD:
StringcheckYourself(StringuserGuess)
GET
theuserguess
as
aString
parameter
CONVERT
theuserguessto
an
int
REPEATwith
eachofthelocationcellsinthe
int
array
II
COMPARf
theuserguess
to
thelocationcell
IF
theuserguessmatches
INCREMENT
thenumberofhits
IIFIND
OUT
if
it
was
the
last
locationcell:
[
IF
numberofhitsis
3,
RETt,JRN
"kill"
as
theresult
ELSE
it
was
nota
kill.so
RETURN"hit"
ENDIF
ELSE
theuserguessdidnotmatch,so
RETURN
"miss"
ENDIF
ENDREPEAT
ENDMETHOD
METHOD:void
setLocotJonCe//$(lnt[]
eel/Locations)
GET
thecelllocations
as
an
in!array
parameter
ASSIGN
thecelllocationsparametertothecelllocationsinstancevariable
ENDMETHOD
writingaprogram
Writingthetttethod
hMpletM8ntations
let'swritethereal
...ethodcode
ttOW,ittd
get
this
puppy
worklttg.
Beforewestartcodingthe
methods,though,let'sback
up
andwritesomecode
to
test
themethods.That'sright,
we'rewriting
the
testcode
1M/ore
there'sanythingtotestl
Theconceptofwriting
thetestcodefirstis
oneof
thepracticesofExtreme
Programming
(XP),
and
itcanmake
it
easier(and
faster)foryoutowriteyour
code.We're
notnecessarily
sayingyou
shoulduseXP,
butwedolikethepartabout
....Tilingtestsfirst.And
XP
just
sounds
cool.
ExtremeProgramming(XP)
ExtremeProgramming(XP)Isanewcomertothesoftware
evelopmentmethodology
world.Conslderedbymany
t
be"thewayprogrammersreallywanttowork
~
XP
eergedInthelate90'sandhasbeenadoptedby
•ompaniesrangingfromthetwo-persongarageshop
theFord
MotorCompany.ThethrustofXPisthatthe
sternergetswhathewants,whenhewantsIt,even
enthespecchangeslateInthegame.
isbasedonaset
ofprovenpracticesthatareall
esignedtoworktogether,althoughmanyfolksdopick
andchoose,andadoptonlya
portionofXP'srules.These
cticesincludethingslike:
kesmall,butfrequent,releases.
velopinIterationcycles.
Don't
putinanythingthat'snotinthespec(nomatter
howtemptedyouaretoputInfunctionality"forthe
future).
Writethetestcode
first.
Nokillerschedules;workregularhours.
Refactor(improvethecode)wheneverandwhereveryou
noticetheopportunity.
Don'treleaseanythinguntilitpassesallthetests.
Setrealisticschedules,basedaroundsmallreleases.
Keepitsimple.
Programinpairs,andmovepeoplearoundsothat
everybodyknows
prettymucheverythingaboutthecode.
youarehere
~
101
SlmpleDotComclass
prepcode
Writh1QtestcodefortheShttp[eUoi'ColMclass
WeneedtowritetestcodethatcanmakeaSimpleDotComobject
andrun
its
methods.FortheSimpleDotComclass.wereally
careaboutonlythe
cMckYourselj()
method,althoughwe
will
have
to
implementthe
sdLocatiun~l1s()
methodinorder
to
getthe
cMckYourself()
methodtoruncorrectly.
Takea
goodlookattheprepcodebelowforthe
checkYourselj()
method(the
setLocaticmCells()
methodisano-brainersettermethod,
sowe'renotworriedaboutit.butina'real'applicationwemight
wan
I
amorerobust'setter'method.whichwe
wouldwant
totest).
Thenaskyourself,"IfthecheckYourselfOmethodwere
implemented.whattestcodecouldIwritethatwouldprovetome
themethodisworkingcorrectly?"
'ased
Ott
thisprepcode:
METHOD
StringcheckYourselffStringuserCuess)
GET
theuserguessasaStringparameter
CONVERT
theuserguesstoan
Int
REPEAT
witheachofthelocationcellsinthe
Int
array
/I
COMPARf
theuserguesstothelocationcell
IF
theuserguessmatches
INCREMENT
thenumberofhits
//FIND
OUT
if
it
wasthe
last
locationcell:
IF
numberofhitsis
3.
RETURN
"Kill"astheresult
ELSE
it
was
not
a
kill,so
RETURN"Hif'
ENDIF
ELSE
theuserguess
did
notmatch,so
RETURN
"Miss"
END
IF
ENDREPEAT
ENDMETHOD
102
chapter5
Here1s
whatweshould
test:
1.Instantiate
a
SlmpleDotComobject.
2,AssignItalocation(anarray
of
3ints,like
{2,3.4}).
3.
Createa
SlJing
torepresent
a
userguess
('2",'0',
etc.).
4.InvokethecheckYourselfOmethodpass-
ingilthefakeuserguess.
5.Printouttheresult
to
seeIfIt'scorrect
("passed"or"failed").
•
writingaprogram
~relare,..{l?
"
DiiJjjo
~uestl9ns
festcodefortheSIIMpiePotCoIMclass
}
~ r.~~,!::~~"
ofp••es
w'
ImplememtheS1mpleDoteomclass,
and
thenlaterwereturntothe
test
class.Lookingatourtestcode
above,
whatelse
shou
Id
be
added
7
Whatarewenottestinginthis
code,
thatweshouldbetestingfor?Writeyourideas(orlines
of
code)below:
publicclassSimpleDotComTestDrive(.
...sta"ba-tl.
a
\~
....y\e'Da\:.e,o...
publicstaticvoidmain(Strinq[]arqs)(
do
~et,
t.
SimpleDotcomdot
=
newSimpleDotCom();
t::"
0'1
~oY
.".a't.-e
0"
"'~t.
il:l
-\:.be
Got.
&e
\ot.WOl'
vb~e
,,,b
------t.o"'"
C,
~'1o\t
1)∙
int[]locations
=
{2
I
3
I
4};
V
O'>t.
J
a
Y°sJ.\
dot.setLocationCells(locations);.
~
'''...oIc
e
tJ..•
.....L
.--..,.,tih
e
~tn-
od
0,.
the
dot.
to....
"",Itt
0
~
ake
StringuserGuess
=
"2
H
;
~
~tv"~~
Stringresult
=
dot.checkYourself(userGuess);
~i""'ok 1:~
StrinqtestResult
=
"failed"
j
_...1.,
e
e
thetJcYoursel.fO
m.ev\od
onille
dot
to...
objttt,a"d
Pdss
if.
ill
if(result.equals("hit"))(
.f<ilr:e
~LAe.11.
e
)
System.out.println(teStResult);~
f"'in1:0Ii01:the
wf.
reslOl
(p-aued
at"
.f<iiledJl)
t
}
Q..:MaybeI'mmissingsome-
here,
buthowexactlydo
runa
testonsomething
..doesn'tyetexistI1
:Youdon't.Weneversaid
startbyrunning
thetest;
startby
writing
thetest.At
.eyou
writethetestcode,
won'thaveanythingtorun
,against.soyou
probablywon't
IetocompileItuntilyou
e'stub'code
thatcancom-
but
thatwillalwayscause
est
tofail(like,returnnull.)
:ThenIstilidon'tseethe
••..,rt.
Why
notwalt
untilthe
Is
written,
andthenwhip
thetestcode?
:Theactofth
I
nkln9
th
rough
writing)thetestcodehelps
....bri"tv
yourthoughtsaboutwhat
methodItselfneedstodo.
soonasyour
implementation
eisdone,youalreadyhave
codeJust
waitingtovalidate
Besides,youknowIfyou
don't
'tnow,
YOU'll
neverdo
It.
e'salwayssomethingmore
estingtodo.
ally,
writea
little
testcode,
writeonlytheImplementa-
codeyouneedinorderto
thattest.Thenwritealittle
etestcodeandwriteonly
new
implementationcode
edtopass
thatnewtest.At
testlteratlon,you
TU
n
all
preViously-writtentests,so
youalwaysprove
thatyour
tcode
additionsdon'tbreak
iously-testedcode.
youarehere
~
103
SimpleDotComclass
ThecheckYourselfOtttethod
Thereisn'taperfectmappingfromprepcodetojavacode;you'llseeafew
adjustments.
Theprepcodegaveusamuchbetterideaof
what
thecodeneedsto
do,andnowwehavetofindtheJavacodethatcandothe
how.
Inthebackofyourmind,bethinkingaboutpartsofthiscodeyoumightwant
(orneed)toimprove.Thenumbers
(18
areforthings(syntaxandlanguage
features)youhaven'tseenyet.They'reexplainedontheoppositepage.
GETtheuser
guess
CONVERT
theuserguessto
an
int
REPEAT
with
eachceilinthe
int
array
IFtheuserguess
matches
INCREMENT
the
nUI1"lber
of
hits
//FINDOUT
if
it.
wasthelasteel!
IFnumberofhits
is
3.
RETURN
"kili"
astheresult
ELSEitwas
nota
kill.
so
RETURN"hit"
ELSE
RETURN
104chapter5
publicStringcheckYourself(StringstringGuess){
I)
to"verith&t'
intguess
=
Integer.parselnt(stringGuess);
L-
L•
1-
er'''9
,---w
al'l
I I'I ~
Stringresult
=
"miss";(-....
a:
e
avar
iable
to
holdthereslAltwe'll
re~lAr"
Plat
II."
..""ss
i"
asthedetalAlt
('.e.weclsslA....
ea......iss")
•
for(intcell:locationCells){
~
9d;
QlAt
o.f
th
I
to
te
t
e
<><>p,
no
"eed
!
I
end
if
s
theother
tells
}II
endfor
if(numOfHits
==
locationcells.length)(
result
=
"kill";
/!
end
if
System.out.println(result);
~
displaythereslAlt.forthelASer
returnresult;
("Miss",
lAl'lless
it
wastha"ged
to
"I-hi;"
or
"Kill")
t"-.
retlAr"thereslAltbade
to
}II
endmethod
the
talli"9....
ethod
ethingswehaven'tseenbefore
on
this
page.StopworryinglThe
ofthedetailsareattheendof
chapter.This
isjustenoughtolet
keepgoing.
Convertinga
StringtoanInt
writingaprogram
The
post-increment
operator
break
statement
(
n ~
++...
taY\1
add
I
to
'WhaWtr'Sth&e(il'l
~
'Wc*d.s,
int__
e",ent
by,).
numOfHits++
roIArllOtl∙hh++
i.s
thesa...
t
(il'l
this
~)
as
sayi,,~
"......
O.f»its::.
""",o.f~hh
+"
e~rt
sli9hUt
...
~~
tHitient
break;
~et.s y~
out
o-f
alOOf∙
l......
ediduly.
Ri~ht
htl'"t.
No
ihl'"atiol'l,no
boolul'I
ust,iwt
o.d
out"ow!
youarehere
~
105
SlmpleDotComclass
prep
code
:therelare~~
"
DUmb
~uesti9115
Q..:WhathappensIn
Integer.parselnt(l
If
thethingyou
pauIsn'tanumber?And
does
It
recognizespelled-outnumbers,
/Ike
Jl
three"?
A:
Integer.parselntOworksonly
onStrings
thatrepresent
the
ascii
valuesfordigits
(0,1,2,3,4,5,6,7,8,9).
If
youtrytoparsesomethinglike
"two"
or
"blurp';
thecodewi
II
blow
upatruntime.
(By
blowup,
we
actuallymean
throwanexception,
but
wedon'ttalkaboutexceptions
untiltheExceptionschapter.Sofor
now,
blowup
iscloseenough.)
publicclass
S~leDotComTestDrive
{
publiCstaticvoidmain
(S~ringl]
args){
SimpleDotCom
dot
~
newSimpleDotCom{};
intI]locations
~
(2,3,4);
dot,setLocationCells(locations);
StringuserGuess
~
"2-;
Stringresult
~
dot.checkYourself(userGuess);
publicclassSimpleDotCom
intI)locationCells;
intnumOfHits
~
0;
pUblicvoidsetLocationCells(intl]locs)(
locationCells
=
locs;
pUblicStringcheckYourself(StringstringGuess)
intguess
~
Integer.parselnt{stringGuess);
Stringresult-"miss";
for(intcell:IocationCells)
if
(guess
~ ~
cell)(
result
=
"hit-;
numOfHits++;
break;
Q..:lnthebeginningofthe
book,therewasanexampie
ofa
for
loopthatwasreallydifferent
fromthis
one-aretheretwo
differentstyles
of
forloops?
A:YeSlFromthefirstversionof
JavatherehasbeenasInglekind
of
(or
loop(explainedlaterInthis
chapter)thatlookslikethis:
for(Int
i
=
0:/
<
10;1++){
//dosomething
10
times
Youcanusethisformatforany
kind
ofloopyouneed.But...
beginnIng
withJava
5.0
(Tiger),
youcanalsousethe
enhanced
for
loop(that'stheofficialdescription)
whenyourloopneedstoiterate
overtheelementsInanarray(or
another
kindofcollection,asyou'll
seeInthe
next
chapter).Youcan
alwaysusetheplainoldforloop
toiterateoveranarray,butthe
enhanced
forloopmakesiteasier.
106
chapter5
)
II
outoftheloop
if
(numOfHits
==
locationCells.length)
result
~
"kill-;
)
System.out.println{result};
returnresult;
)II
closemetho'
II
clo'ecIas
There'salittlebuglurkinghere.Itcompliesend
runs.butsometimes...don't
WOffY
aboulllfornow,
butwe
will
havetoface
it
II
littlelater,
Whatshould
we
see
when
werun
thiscode?
Thetestcodemakesa
SimpleDotComobject
andgivesitalocationat
2,3,4.
Then
it
sendsafake
userguessof
"2"
Intothe
checkYouselfOmethod.
Ifthecodeisworking
correctly,weshouldseethe
resultprintout:
JavaSlmpleDotComTestDrlve
lat
Webuiltthetestclass,andtheSimpleDotComclass.Butwestillhaven't
made
theactuaI
game.
GiventhecodeontheopposItepage,andthespecfor
theactualgame,writeInyourIdeasforprepcodeforthegameclass.We'vegiven
youafewlineshereandthereto
getyoustarted.Theactualgamecodeisonthe
nextpage,so
don't
tumthepageuntilyoudothisexerdsel
Youshouldhavesomewherebetween12and18lines(includingtheoneswewrote,
but
not
includinglinesthathaveonlyacurlybrace).
METHOD
publicstaticvoidmain(String
0
OI'J:S)
DECLARE
anintvariabletoholdthenumberof
user
guesses.namednumOfGuesses
COMPUTE
arandomnumberbetween0and
"I
thatwillbethestartinglocationcellposition
WHILE
thedotcom
IS
~i ll
ahve:
GET
userinput(romthecommandline
writingaprogram
TheSlmpleDotComGame
needstodothis:
1.Makethesingle
SimpleDotComObject.
2.
Makealocationforit(three
consecutivecellsonasingle
rowofsevenvirtualcells).
3.
Asktheuser
for
aguess.
4.
Checktheguess.
5.
Repeatuntilthedotcomis
dead.
6.
Telltheuserhowmany
guessesittook..
you
arehere.
107
SlmpleOotCom
class
PrepcodefortheShMpleUo'fCottttatMeclass
Everythfnghappetts
IttIttal..
n
Therearesomethingsyou'llhavetotakeonfaith.Forexample.wehaveone
lineofprepcodethatsays,
wCET
userinputfromcommand-line".Letmetell
you,that'salittle
morethanwewanttoimplementfromscratchright
now,
But
happily,we'reusing00.Andthatmeansyougettoasksome
otherc1ass/object
todosomethingforyou,withoutworryingabout
how
itdoesit.Whenyouwrite
prepcode,youshouldassumethat
somehoto
you'llbeabletodowhateveryou
needtodo,soyoucanputallyourbrainpowerintoworkingoutthelogic.
public
stadcvoJd
main(String
D
args)
DECLARE
anintvariabletoholdthenumberofuserguesses.named
numO(t;uesses.
set
it
to
O.
MAKE
a
newSimpleDotCominstance
COMPUTE
arandomnumberbetween
0and'\
thatwillbethestartinglocationcellposition
MAKE
an
intarraywith
3
intsusingtherandomly-generatednumber,thatnumberincremented
by
I.
andthatnumberincrementedby2(example:3.4,5)
INVOKE
theretLocOlionCeI!sOmethodontheSimpleDotCominstance
DECLARE
a
boolean
variablerepresentingthestateofthegame.named
isAhve.
SET
it
totrue
nl~ogn.itive
ttl
Don'tworkonepartofthebrainfor
100
longastretchatonetime.
WorkingJusttheleftsideofthebrainformorethan30minules
islikeworkinglust
your
left
arm
for30minutes,Giveeachside
ofyourbrainabreakbyswilchlngsidesat
regular
intervals..
When
you
shifttooneside.theothersidegels
10
restand
recover.Left-brainactJvltiesIncludethingslikestep-by-step
sequences,logicalprob\em-solving,andanalysis.whilethe
right-brainkicksinformetaphors,creativeproblem-solving,
pattern-matching,andVisualizing.
WHILE
thedotcomis
still
alive
(isAlive
==
true):
GET
userinput{romthecommandline
//CHECK
theuserguess
INVOKE
the
checkYourse/fO
methodontheSlmpleDotCominstance
INCREMENT
numO(t;uesses
variable
IICHECK
(ordotcom
death
IF
resultis"kill"
SET
isAlwe
tofalse(whichmeansweWOT'l'!entertheloopagain)
PRINT
theT'lumberofuserguesses
ENDIF
ENDWHILE
ENDMETHOD
108
chapter5
•
--
•YourJavaprogramshouldstartwithahigh∙
leveldesign.
•Typicallyyou'llwritethreethingswhenyou
createanewclass:
prepcode
testcode
real(Java)code
•Prepcodeshoulddescribe
what
todo,not
how
todoit.Implementationcomeslater.
•Usetheprepcodetohelpdesignthetest
code.
•Writetestcodebeforeyouimplementthe
methods.
How
many
hitsdid
you
get
lastmonth?
writingaprogram
•Choose
for
loopsover
while
loopswhenyou
knowhowmanytimesyouwanttorepeatthe
loopcode.
•Usethepre/postincrementoperatortoadd
1
to
avariable(x++;)
•Usethepre/postdecrementtosubtract
1
from
a
variable
(x-;)
•Use
Integer.parseInt()
togettheint
valueofaString.
Integer.parseIn
t()
worksonly
if
the
Stringrepresentsadigit
("0":1',"2",
etc.)
•Usebreak
10
leavealoopearly(i.e.even
if
thebooleantestconditionisstilltrue).
youarehere)
109
SimpleDotComGameclass
JustasyoudidwiththeSimpleDotComclass,bethinkingaboutpartsofthiscode
you
mightwant(orneed)toimprove.Thenumbered
things•
areforstuffwe
wantto
pointout.They'reexplainedontheoppositepage.Oh,
if
you'rewonder-
ingwhyweskippedthetestcodephaseforthisclass,wedon'tneedatestclassfor
the
game.
Ithasonlyonemethod,sowhatwould
you
doin
your
testcode?
Make
a
separate
classthatwould
call
maini]
on
t~is
class?Wedidn'tbother.
boolean
isAli
va'"
true;
publicstaticvoidmain(String[]arqs)(
GameBelperhelper'"newGameBelper();
e-r:
this
is
a1ft/.'Ialt1ass\role
wv~
thdthas
t.he...
dhod
+OY
~d±i,,~ ~
il'lfl<t..
+OY
l\O'<II,
l""Wl'IGit's
part.
~
Java
SimpleDotComt:.heDotCom'"newSimpleDotcomO;
~
.....
lcethe
dot
tOO>l
objet+'
•
intrandomNum
=
(int)(Mat:.h.random()...
5)
;b--lft<1lcearil,wf"",l'I"",beY.toythe
.first
tell,and
lUe
it
to
~ke
theleU
~
lotdtiOt\.!
array
let(]
locations•(randamNum,randOlllNum+l,rand0lllNUm+2);
thaDotCom.IIstLocationCells(locations);.
L1..
dot
tQtI\
ih
lotdtiOtlS
(th,
C1Yril'1)
~ ~,ve
v>e
MAKEan
int
array
WIth
the3
cellloca-
lions,and
DECLARE
3
vari-
able
to
hold
user
guesscount.set
it
to
0
COMPUTE,\
randomnumber
between0and.\
MAKE
aSimplefzot-
Com
object
WHILEthedot
com
1\
stillalive
DECLARE
abool-
eat"sAlive
GETuser'
input
INVOKEseu.oca-
[lonCellson
the
dot
corn
object
IICHE.CK
It
INVOKEcheckro-
ursell()
ondotcom
INCREMENT
nurnOfGuesses
IF
re
ult
is
"kill"
SET
gameAlive
to
false
PRINTthenumber
ofuserguesses
II
close
if
-
II
closewhile
II
closemain
chapter5
writingaprogram
jf...
rothingsthatneedabitmore
,:xplaining.areonthispage,Thisis
.t
aquicklooktokeepyougoing;
redetailson
theGameHelper
areattheendofthischapter.
Makearandom
number
(Math.random()'"5)
t
t
A
tlauthat
tOfllts
A...
rthoci
ok
the
wit.hJava.Mat.hdaS$.
i
Gettinguserinput
using
theGameHelper
class
An
'l"rl,arU
wt
"'<id.t
tdrlieY,
ok
at1ass
that
we
bl/.ilt
to
hell'
wit},
tnt
~
...e.
It'
s
~lItd
qaft't~tlfeY
a"d
'feN
haVbl
t
set"
it
yd
('fov
wilD.
~
Stringguess
=
helper.getUserInput("enteranumber");
l'
A...
ethod
o..f
the
~a
...t!'+e'ft"rtlau
~t
asksthe
w.ser
~ot'
toow.",a"d-
li"e
i"f\lt,
\'"ealb
it
in
.»u.-
-the
1ISe'r
hits
R~Tl).RN,
ahli
~'Ives
batk
theytsl/.I-c
clS
a
Sh-i,,~.
youarehere)
111
GameHelperclass(Ready-bake)
Onelastclass:G-attteHelper
importjava.io.*;
publicclassGameBelper
publicStringgetOserlnput(Stringprompt)
StringinputLine
=
null;
System.out.print(prompt
+"");
try{
Bu£feredReaderis
=
newBufferedReader(
new
InputStre~ader(SY8tem.in);
inputLine
=
is.readLine();
if
(inputLine.length()
==
0)
returnnull;
}catch
(IOExceptione)(
System.out.println("IOException:"
+
e);
Wemadethe
dot
CQtn
class.
We
madethe
game
class.
All
that'sleft
is
the
helperclass-
theonewiththe
getUserInputOmethod.Thecodetogetcommand-
lineinputismorethanwewanttoexplainrightnow.
It
opensupwaytoomanytopicsbestleftforlater.
(Later,asin
chapter14.)
Justcopy*thecodebelowandcompileitinto
aclassnamedGameHelper.Drop
all
three
classes(SimpleDotCom,SimpleDotComGame,
GameHelper)intothesamedirectory.andmake
it
yourworkingdirectory.
"Ready-IMke
Wheneveryouseethe
Bell
de
logo,you'resee-
ingcodethatyouhavetotypeas-isandtakeonfaith.
Trust
it,
You'Illeamhowthatcodeworks
later.
returninputLine;
)
"Weknowhowmuchyouenjoytyping.bul
for
thoeerare
momentsWhenyou'd
mlherdo
some\hlngelse,
we'vilmad
II
11111Ready-bakeCodeavallable
on
wlckedlyamart.com.
112
chapter
5
lefs
play
Here'swhathappenswhenwe
run
itandenterthenumbers
1,2,3,4,5,6.Leckin'good.
A
coltlplete
gatMll
lltteractlolt
(yourmileagemayvary)
%java
SimpleDotComGame
enter
a
number
1
miss
enter
a
number
2
miss
enteranumber
3
miss
enteranumber
4
hit
enteranumber
5
hit
enter
anumber
6
kill
Youtook6guesses
writingaprogram
What'sthis?A
bug?
Gaspl
Here'swhathappenswhenwe
enter
1.1,1.
Adlfferettf
gaIMe
h,teractlotl
(ylkes)
%javaSimpleDotComGame
enteranumber
1
hit
enter
anumber
1
hit
enteranumber
1
kill
'lou
took3guesses
It'sacliff-hangerl
Will
we
find
thebug?
Will
we
flxthe
bug?
Staytuned
r
thenextchapter,whereweanswer
these
quest!ns
andmore...
And
Inthemeantime,see
If
youcancomeupwith
Ideasforwhatwentwrong
and
howto
fixIt.
youare
here.
113
for
loops
Moreaboutforloops
We'vecovered
all
thegamecodefor
this
chapter(butwe'llpickitupagain
tofinishthedeluxeversion
ofthegameinthenextchapter).Wedidn't
wanttointerruptyourwork
with
someofthedetailsandbackgroundinfo,
sowe
put
it
backhere.We'Ustart
with
thedetailsofforloops,andifyou're
a
Ct+
programmer,youcanjustskimtheselastfewpages...
legularbto"-e.,ha"ced]forloops
WhatItmeansInplainEnglish:
~Repeat
100times."
Howthecompliersees
It:
•createavariableIandsetIttoO.
-;.repeatwhileIIsiessthan100.
•attheendofeach
loopIteratIon,add1toI
Part
One:
Initialization
UsethisparttodeclareandInitializeavariabletousewithintheloopbody.
You'llmostoftenusethisvariableasacounter.Youcanactuallyinitializemore
thanonevariablehere,
butwe'llgettothatlaterInthebook.
PartTwo:
booleantest
ThisIswheretheconditional
test
goes.Whatever'sInthere,It
must
resolvetoa
booleanvalue(youknow,
tru«
or
flllu).
Youcanhaveatest"like(x
>=
4),oryou
canevenInvokeamethodthatreturnsaboolean.
PartThree:
IteratIonexpression
Inthispart,putoneormorethingsyouwanttohappenwitheachtripthrough
theloop.KeepIn
mindthatthisstoffhappensatthe
end
ofeachloop.
114
chapter5
repeatfor
100
reps:
writingaprogram
enter
loop
body
intz
c
x++;
I-
I
int
x'"
0;
X
=
X
produces:)(IsI,zIs1
But
puttingthe
++
after
thexgiveyouadifferentresuIt:
PreandPostIncrement/DecrementOperator
++
Theshortcutfor
adding
orsubtracting
1
fromavariable.
X++;
Isthesameas:
X
=
X
+
1;
Theybothmeanthesamethinginthiscontext:
"add
1
tothecurrentvalueof
x"
or
∙'ncrement
x
by
1∙
And:
Ofcoursethat's
never
thewholestory.Theplacementofthe
operator(eitherbeforeorafterthevariable)canaffectthere-
sult.Puttingtheoperator
before
thevariable(forexample,
++x),
means:'!irst,incrementxby1,and
then
usethisnewvalueofx."
Thisonlymatterswhenthe
++x
Ispartofsomelargerexpres-
sionratherthanjustinasinglestatement.
intx
=
0;
intz
=
++x;
X--;
Isthesameas:
output:
printthe
value
of;
int
i
=
0;
i
<
8;
i++)
tem.out.println(i);
Increment
(theiteration
expression)
sthroughaloop
~
..0
~
'lJehelv..
1
d
I
11:lt
1.
=;
"lII,<---~,jllitia/i~
ih
et.
ire
dl'ld
while
(i
<
8)
e
lOlAl'\k
System.out.println(i);
i++;
~
,
J..;t
have
to
illl
Ule
lOlA;,k
I'"e"'e,.,f
phasonlythebooleantest;Itdoesn'thave
I _!I!!I ~ -in
initializationorIterationexpression.A
while
goodwhenyoudon'tknowhowmanytimesto
justwanttokeepgoingwhilesomecondl-
ue.ButIfyouknowhowmanytlmesto
loop
•elengthofanarray,7times,etc.),aforloopIs
t,
Here'stheloopaboverewrittenusing
while:
produces:)(IsI,butz
Is
01zgetsthevalueofxand
then
xis
Incremented.
youarehere'115
..
enhanced
for
Theetthattcedforloop
Beginning
with
Java5.0(Tiger),theJavalanguagehasasecondkindof
Jor
loop
called
the
enhanced
jM,
thatmakesiteasiertoiterateover
all
theelementsinan
array
orotherkindsofcollections(you'lllearnabout
other
collectionsinthenext
chapter).That'sreally
all
thattheenhancedforgivesyou-asimpler
way
towalk
through
all
theelementsinthecollection,butsinceit'sthemostcommonuseofa
for
loop,it
was
worthaddingittothelanguage.We'llrevisitthe
enhancedfor
lMp
in
thenextchapter,whenwe
talk
aboutcollectionsthat
aren't
arrays.
WhatItmeansInplainEnglish:
"ForeachelementinnameArray,assignthe
elementtothe'narne'varlable,andrunthebodyoftheloop."
How
the
complier
seesIt:
...CreateaStringvarIablecalled
name
andsetIttonull.
...AssignthefirstvalueIn
nameArray
toname.
...Runthebodyoftheloop(thecodeblockboundedbycurlybraces).
...AssignthenextvalueIn
nameArray
toname.
...Repeatwhile
therearestilielementsInthearray.
PartOne:
Iterationvariabledeclaration
UsethisparttodeclareandInitializeavariabletousewithintheloopbody,Witheach
Iterationoftheloop.thisvariablewillholdadifferentelementfromthecollection.The
typeofthisvariablemustbecompatible
withtheelementsinthearraylForexample,
youcan'tdeclarean
lnt
Iterationvariabletousewitha
StrlngU
array.
PartTwo:
theactualcollection
Thismustbeareferencetoanarrayorothercollection.Again,don'tworryaboutthe
other
non-arraykindsofcollectionsyet-you'llseetheminthenextchapter.
116
chapter5
writJngaprogram
butyoumight
losesomething
long
~
short
canbecastto
Inchapter3wetalkedaboutthesizesofthevariousprimitives.andhowyou
can'tshoveabIgthIngdlrecUyIntoasmallthing:
10n9Y
=
42;
intx
=
y;
II
won't
compile
A
long
Isbiggerthanan
int
andthecompliercan'tbesurewherethat
long
has
been.Itmighthavebeenoutdrinkingwiththeotherlongs,andtakingonreally
bigvalues.ToforcethecompliertoJamthevalueofabiggerprimitivevariable
intoasmallerone,youcanusethecasloperator.IIlookslikethis:
long
y
==
42;
II
sofarso
good
int
x
=
(int)
y;
II
x
=
42
oool!
PuttlngInthe
~
tellsthecompliertotakethevalueofy,chopItdownto
iot
size,andsat)(equaltowhatever
Is
left.Ifthevalueofywasbiggerthenthe
maximumvalueofx,thenwhat'sleftwillbeaweird(butcalculable')number:
long
y
==
40002;
II
40002exceedsthe16-bitlimdtofashort
Casthtg
prhttftives
float
f..
3.14£;
int
x
==
(int)
f;
II
x
will
equal
3
Anddon'teven
think
aboutcastinganything
\0
abooleanorviceversa-just
walkaway.
'It
involvessignblls,bInary,
'two's
complement'andothergeekery,allofwhich
arediscussedai/hebeginning
of
appendixB.
shortx
c
(short)
y;
II
xnow
equ~s
-25534!
Stili,Ihepointisthatthecomplierletsyoudo
It.
Andlet'ssayyouhaveanoal-
Ingpointnumber,andyoujustwanttogetatthewholenumber(in/)partof
it
Sotogetaroundthewholeapplesand
oranges
thing,wehavetomakethe
String
'2"intothe
int
2.
BuiltIntothe
Java
class
braryisaclasscalledInteger(that's
right
a
Integer
class,
nottheint
primitive),
andoneof
its
Jobs
is
totakeStringsthat
represen:
numbersandconvertthemInto
actual
numbers.
takes
d
~b-i,,~
t
teger.parseInt("3")
I
operator
==
cannotbeappliedto
int,java.lang.String
if
(x
==
nurn){}
,.,
d...
etJ,odinthe
I"u~et"
das.s
thatknowshow
io
"pa~J)
a
Sb-in~
i"io
the
il'.t:
it
l"epl"C!seni.s.
.(x
=
num)
II
horribleexplosionl
ryingto
compilethatmakesthecomplier
laughandmockyou:
convertingaStringtoanint
.tx"
2;
iDequess
=
Int8qer.parseInt(strinqGuess);
Theusertypeshisguessatthecommand-
line,whenthegamepromptshim.That
guesscomesInasaString
(M2;"0~
etc.),
andthe
gamepassesthatStringintothe
checkYourselfOmethod.
But
thecelllocationsaresimplylntsIn
an
array,andyoucan'tcompareanInttoa
String.
Forexample,
thiswon'twork:
youarehere_
117
exercise:BetheJVM
BEtheJVM
The
Javafile
on
this
page
representsacompletesource
rue.
Yourjob
is
to
play
JVM
and
detel"llline
what
wouldbe
the
outpltt
whenthe
programruns?
classOutput{
pUblicstaticvoidmain(String
[J
args){
Output
0
=
newOutput();
o.go();
-or-
}
void
go(){
int
y
=
7;
for(intx
=
I:
x<
8:
x++){
y++;
if
(x
>
4){
System.out.print(++y
+•-):
if
(y
>
14){
Systern.out.println(Ux
=
u
+
x);
break;
}
}
}
}
118
chapter5
-or-
writingaprogram
Code
Magnets
Aworking
Java
programIsallscrambleduponthefridge.Canyou
reconstruct
thecodesnippetstomake
a
working
Java
programthat
producestheoutputlistedbelow?Someofthecurlybracesfellonthe
floorandtheyweretoosmallto
pickup,
sofeelfreetoaddasmanyof
thoseasyouneed!
1){
System.out.println(x
+
~
M
+
y):
for(int
Y
4;Y
>
2;
y--){
for(int
:l(
0;
x
<
4;
x++)(
youarehere
~
119
puzzle:
JavaCross
JavaOr~ss
Howdoesacrosswordpuzzle
help
youleamJava?Well,all
of
thewords
are
Javarelated.
Inaddition,thecluesprovide
metaphors,
puns.
and
the
like.
Thesemental
twists
and
turns
bum
alternateroutes
to
Java
knowledge,
right
intoyour
bralnl
Across
1.
Fancycomputerword
forbuild
4.
Multi-part
loop
6.
Test
first
7.32bits
10.Method'sanswer
,1.Prepcode-esque
13.
Change
15.Thebigtoolkit
17.An
array
unit
,8.
Instanceor
10C41
20.Automatictoolkit
22.Lookslikea
primltfve.
buL
25.
Un-castable
26.Mathmethod
28.
Converter
method
29.
Leaveearly
Down
2.
Incrementtype
3.Classsworkhorse
5.
Pre
Isa
type
of__
6.For'sIteration__
7.Establish
first
value
8.
WhileorFor
9.UpdateanInstance
variable
12
Towardsblastoff
14.Acycle
16.Talkative
package
19.Methodmessenger
(a
bb
rev)
21.
As
if
23.
Addafter
24.PI
house
26.
Compile
it
and__
27.
++
quantity
writingaprogram
AshortJavaprogramislistedbelow.Oneblockoftheprogram
ismissing.YourchallengeIsto
matchthecandidateblockof
code
(ontheleft),
withtheoutput
thatyou'd
see
Iftheblock
wereinserted.Notallthelinesof
outputwillbeused,andsome
ofthelinesof
outputmightbeusedmorethanonce.Drawlines
connectingthecandidateblocksofcode
withtheirmatching
command-lineoutput.
classMixForS(
publicstaticvoidmain(String[)args)
intx
=
0;
int
y
=
30;
for(intouter
=
0;outer
<
3iouter++)(
for(intinner
=
4;inner>liinner--){
y
=
y-
2;
if
(x
==
6)
break;
x
=
x
+
3;
}
y
=
y-2;
}
System.out.println(x
+""
+
y};
+
O~
Candidates:
Possibleoutput:
X
+
3~
45
6
~-\:t.'"'
tat"
t.a~i6at.t'fI~
x
+
6~
6
Qt\t~t.ht
yo"\b\t
~~h
x
+
2~
6
10
6
youarehere
~
121
•
exercise
solutions
BetheJVM:
classOutput{
publicstatic
voidmain(String
[
)
args)
{
Output
0
=
newOutput();
o.go();
}
voidgo{)
{
inty
=
7;
for(int
x
=:
i.
x<
B'
x++)
{
I
I
y++;
if
(x
>
4){
System.out.print(++y+•
h);
}
if
(y
>
14){
system.out.println(Ux
=
h
+
x);
break;
}
}
}Did
youremembertofactor
In
the
breakstatement?How
didthat
affecttheoutput?
122
chapter
5
CodeMagnets:
classHultiFor{
publicstaticvoidmain(String[]args){
for(int
x
0;
x
<
4;
X++){
for(inty
=
4;Y
>
2;y--){
system.out.println(x
+
UU.;.
y);
}
if
(x
=:=
1){
Whatwouldhappen
x++;
Ifthis
code
blockcame
beforethe
'y'
forloop?
}
}
writingaprogram
Candidates:
x•x
+
3;
x•x
+
6;
x•x+
2;
x++;
x--;
x-x
+
0,
Possibleoutput
youarehere•
123
6
gettoknowtheJavaAPI
UsingtheJavaLibrary
Javashipswithhundredsofpre-builtclasses.
Youdon'thaveto
reinventthewheelIfyouknowhowto
f1
ndwhatyouneedIntheJavaIIbra
ry,
knownas
the
Java
API.
You'vegotbetterthingstodo.
Ifyo
u're
goingtowritecode,youmightaswell
write
only
thepartsthat
are
trulycustomforyourapplication.Youknowthoseprogrammers
whowalk
outthedooreachnightat
5PM?
Theoneswhodon'tevenshow
up
until
lOAM?
TheyusetheJavaAPI.
And
abouteightpagesfromnow,sowillyou.ThecoreJavalibrary
IsagiantpileofclassesJust
waitingforyoutouselikebuildingblocks,toassembleyourown
program
outoflargelypre-bulltcode.TheReady-bakeJavaweuseinthisbookIscodeyou
don'thavetocreatefromscratch,
but
youstilihavetotype
It.
TheJava
API
isfullofcodeyou
don'tevenhaveto
type.
All
youneedtodoislearntouseit.
thisIs
a
newchapter125
•
westilihaveabug
Itt
ourlastchapter,weleftyou
withthecliff...ha.,ger.A
bug.
Howifssupposedtolook
Here'swhathappenswhenwe
run
it
andenterthenumbers
1,2,3.4,5,6.Lookin'good.
A
co~plete
galMeI.,teractlon
(yourmileagemayvary)
126chapter6
Howthe
bug
looks
Here'swhathappenswhenwe
enter
2,2,2.
AdifferentgaltleInteract/o.,
(yikes)
Fllo
Ed~
WindowHeFelnl
~ j a v a
SimpleDotComGame
enter
anumber
2
hit
enteranumber
2
hit
enter
anumber
2
kill
Youtook
3
guesses
hithe
CUffltlt
verslotl.
otlce
you
get
a
hit,
youcatl
shttplv
repeatthathittwotMore
tllllesforthekill!
get
to
know
theJava
API
Sowhathappetted?
publicStringcheckYourself(StringstringGuess)(
intguess'"Int:8ger.pa.rselnt{stringGue8S);(--
fon\l~
the
Sh-ill~
1;Q
alllilt.
Strinq
reBUlt'"''miss'';(-
A1ake
cl
va~jable
t.D
holdthereswi:'II
rttwhl
p.,.e
II"
we
('....iss
i\'\
asthedetault
I.
e.
lIIe
as.s""'e
8
u...
iss''),
for
(int
cell
Here'swhereIt
goeswrong.We
countedahitevery
~
timetheuser
guessedacell
location.even
If
thatlocationhad
alreadybeenhit!
loeationCells)
Weneedawayto
knowthatwhen
ausermakes
ahit,hehasn't
previouslyhitthat
cell.Ifhehas,then
wedon'twantto
countItasahit.
II
endfoz:
if
(numOfHits
=
locationCells.length)
result:::"kill";
II
end
if
System.out.println(result)
j
~
Di1fla'f
the
res"l!
k()lr
the
lI.1Cr
(.....
i~",
",,1e1S
it
waJ
i.hcl,,~ed
to
"hit"
CW'
"1cill
U
).
returnresult;
r-,
R~
the"mitbaLk
to
II
endmethod
the
talli~
"'«hod.
youarehere.127
fixingthebug
Howdowefix
it?
Weneedawaytoknowwhether
Q
cellhasalreadybeenhit.Let'srun
throughsomepossibilities,
butfirst,we'lllookatwhatweknowsofor...
Wehaveavirtualrow
of
7
celts,andaDotComwilloccupythree
consecutivecellssomewhereinthat
row.
Thisvirtualrowshowsa
DotComplaced
ateel/locations
4,5
and
6.
TheDotComhasaninstancevariable-anintarray-thatholdsthat
DotComobject'scelllocations.
locatlonCells
(instancevariable
of
theDotCom)
•OptlO"
o"e
Wecouldmakeasecondarray,andeachtimetheusermakesahit,we
storethathitinthesecondarray.andthencheckthatarrayeachtime
we
getahit.toseeifthatcel/hasbeenhitbefore.
kltCells
arra~
(thiswouldbe
0
newbooleanarray
instancevariable
of
theDotCom)
128
chapter6
gettoknowtheJavaAPI
Optiononeistooclunky
Optiononeseemslikemoreworkthanyou'dexpect.
It
meansthateach
time
theusermakesahit,youhavetochangethestateofthe
second
array(the'hitCells'array),oh
-~
butfirstyouhavetoCHECKthe'hitCeJls'
arraytosee
jf
thatcellhasalreadybeenhitanyway.Itwouldwork,but
there'sgottobesomethingbetter...
•OpfloHtwo
Wecouldjustkeeptheoneoriginalarray,butchangethevalueofanyhit
cellsto
-1.
Thatway,weonlyhaveONEarraytocheckandmanipulate
locQtlonCells
(instancevariableof
theDotCom)
Option
twoisalittle
better,but
stillprettyclu"ky
Optiontwoisalittlelessclunkythanoptionone,butit'snotveryefficient.You'd
stillhavetoloopthroughall
threeslots(indexpositions)inthearray,even
jf
oneormorearealready
invalidbecausethey'vebeen'hit'(andhavea-1value).
Therehastobesomethingbetter...
youarehere
I
129
prepcode
prepcode
locatlonCells
array
BEFOREanycells
have
be.en
hit
Optlo.,three
Wedeleteeachcelllocationasitgetshit,andthenmodifythearrayto
be
smaller.Exceptarrayscan'tchangetheirsize,sowehavetomakea
new
arrayandcopytheremainingcellsfromtheoldarrayintothenew
smallerarray.
locatlonCellsarray
AFTERcell'5',which
was
atinde.x1inthe.
array,hasbeenhit
Optlo.,threewouldbe'MuchbetterIfthearraycouldshrlttlc,sothatwewould.,'thave
to",akea.,ew''Mallerarray,copythere",altt'"(1values
ht,
attdreasslQ"thereferettce.
fheorlal"81prepcodeforpartofthe
checkYourselfU'Method:
Lifewouldbegood
'f
otdywecould
chattaeItto:
ELSEuserguess
did
notmatch,soRETURN"miss"
ENDIF
ENDREPEAT
REPEATwitheachofthelocationcellsintheintarray..
~
-REPEAT
with
eachofthe
remaining
locationcells
1/COMPARE
theuserguesstothelocationcell
/1COMPARE
theuserguesstothelocationcell
IFtheuserguessmatchesIFtheuserguessmatches
INCREMENTthenumberofhits
~
REMOVEthiscellfromthe
array
/1FINDOUT
if
itwasthelastlocationcell:1/FINDOUTif
it
wasthelastlocationcell:
IFnumberofhitsis
3.
RETURN"kill"
~
'IFthe
array
isnowempty,RETURN"kill"
ELSE
it
wasnotakill,soRETURN"hit"ELSE
it
was
notakill.soRETURN"hit"
ENDIFENDIF
ELSEuserguess
did
notmatch,
50
RETURN
"miss"
ENDIF
ENDREPEAT
130
chapter
6
get
to
knowtheJavaAPI
when
arrays
aren'tenough
Wakeupat1d
stMellthe
library
As
if
bymagic,therereallyIssuchathing.
Butit'snotanarray,it'sanArrayLisf.
AclassinthecoreJavalibrary(theAPI).
ThejavaStandardEdition(which
is
whatyouhaveunlessyou'rework-
ingontheMicroEditionforsmalldevicesandbelieveme,
you'd
know)
ships
with
hundredsofpre-builtclasses.JustlikeourReady-Bakecode
exceptthatthesebuilt-inclassesarealreadycompiled.
That
means
no
typing.
ArrayUS
t
dd{Ob}ede\en")
aram
eter
tothe\\st.
a
AddstheobjectP
eUntIndex)
h\nde)(paralTl
eter.
ren"o"
heobjectatt
e
Removest
{Ob}edelel1\)
t'
'I'
theAnayLlst).
rel1\o"e
thIsobject(If
I
s
RelTl
oves
)
arameter
.{Objecte\en"
hfortheobjectP
,o"ta,n
s,
'Ifthere'S
a
mate
ReturnstrUe
II
\em
entS
\sEI1\PtV..
Ifthelisthas
no
e
RetUrns
true,
,)eter,or'
\"dellOf{Obiec~ ~:~de)(
oftheobjectparalTl
RetUrns
elthe
currentlyInthelist
s\zell
hnumberofelements
RetUrnste
aram
eter
tt\nt
Indell)
entlyat
the.l.n.de.'Il.p.
ge
theobleeteur
r
Returns
Justuse'em.
Ont.
of
a5az..illiol\t1asst.$
in
t.ht.
Ja~a
libvavy.
Yo...tan
lASt.
it
itl
'fOlJ.V
cede
as
i+
yOlJ.
IIIrOU
if
'f0...
~I.f.
(NoU;
tht
add(ObjttA:.
ele...)...
tthod
att..ally
look.s
a
li-i:.Besh-a"1&
~a
..
-tht
OY\e
..,e'
~t
shOWtl
h,~e
.....,,'11
~tt
to
-the
..tal
Qrlelai&
i..
tht
book.
FOfr""'''',
jlA1t
think
of
it
asa..aodO...
tihod
that
take.!
theobjett
yo<.
",ant
to
addJ
132
chapter6
get
to
knowtheJavaAPI
Putsomethinginit
Eggs
=
newEgg()
i
myList.add(s)i
•
Somethhtgsyouca.,
do
with
~rrayLisr
~
a~\e-h--6t.ket ~"jI,
D
'~wt:IrT'f a~
this
",ew':
-.T.
,l
o.f
c,
ol:!'
eth"∙
'"'
.~.
t
I\S
U....akt
IS
a
\In.
"j~ ~
•Makeone
?....
i~~t
"ow;
I
jW
Mea_.
ArrayList<Egg>myList
=
newArrayList<Egg>();
~-a'1l,ist objet~
\'We
/'I
~
(\P
tnt
\leaf'
\~
5,
tvea~ci,~
...w,
\)eLi~
no'
CW'Y"I
•Putanotherthinginit
Eggb
=
newEgg();
myList.add(b);
•Findouthowmanythingsarein
it
inttheSize
=
myList.size();
Findout
if
itcontainssomething
The
A'rt"a'1L.i.st.
Dol:S
tC/tItail'l
the
~~
t
ltd
,
I/"....,.__
I.e!
ku
'5',
so
tC/tItail\SO
retWY\S
~
booleanis10
=
myList.contains(s)i
~ ~~.~~ ~1
"D
0(...
eal\S
~irtt.;Yllie~
is
0)
Findoutwheresomething
is
(l.e.
itsindex)
~
Atta'1
Ust
15
~
Last,._.
0D'f
'0'
..,os
the
d
'."te
the
Objet..
vt-tc;·~t
I
int
idx
=
myList.indexOf(bl
i
01'1
51l"'
l.\.
\.--1.
i\'lO~'W
....
eboVl\S_
sUO\'IO..
hl"~
lY\
'We
In"
Findout
if
it's
empty
it's
deo.fil'li+.tly
NOT
bftpty,
so
isE"'rtyO
booleanempty
=
myList.
isEmpty();
C-
r~PIS
£ili.e
•Removesomethingfromit
myList.remove(s);
youarehere.133
whenarraysaren'tenough
~
your
penCil
FillIntherestofthetablebelow
by
lookingattheArrayListcode
ontheleftand
puttinginwhatyouthinkthecodemightbe
if
it
wereusingaregulararrayInstead.Wedon'texpectyoutogetall
ofthemexactlyright,soJustmakeyourbestguess.
ArrayList
regulararray
hrrayList<String>myList
=
new
~h-i"9
0
"'yList::..
"ew
Sh-il'l~ClJj
hrrayList<String>();
Stringa
=
new
String("whoohoo
H
);
Sb-il'l'l
a
=-
~ Sb-i~("whoohool)j
myList.add(a);
Stringb
=
newString("Frog
H
);
~iri,,~
\>::."""
~ir;I'I~C'n-~»)j
myList.add(b);
inttheSize
=
myList.sizeO:
Object
0
=
myList.get(l);
myList.remove(l);
booleanisIn
=
myList.contains(b);
134chapter
6
R..,:
SoArl1lyListIscool,but
howwouldIknow
It
exists?
!A.:Thequestionisreally,
-HowdoI
know
what'sInthe
API?"
andthat'sthekeytoyour
successasaJavaprogrammer.
Nottomention
yourkeyto
beingaslazyaspossiblewhile
still
managingtobuildsoftware.
You
might
be
amazedathow
muchtimeyoucansavewhen
somebodyelsehasalreadydone
mostoftheheavylifting,and
allyouhavetodoisstepinand
createthefunpart.
Butwedigress...theshort
answerIsthat
you
spendsome
timelearningwhat'sInthecore
API.
Thelonganswerisatthe
end
ofthischapter,whereyou'll
learn
how
todo
that.
R:
Butthat's
aprettybig
Issue.Not
onlydoIneedto
know
thatthe
Javalibrary
comeswith
ArrayLlst,
but
more
ImportantlyIhavetoknow
that
ArrayListIsthe
thingthat
candowhatIwantlSohow
110Igo
from
aneed-to-do-
somethingtoa-way-to-do-It
using
theAPI?
!A..:
Nowyou'rereallyatthe
heart
ofIt.Bythetimeyou've
finishedthisbook,you'llhave
agoodgrasp
ofthelanguage,
and
therestofyourlearning
curvereallyIsaboutknowlnq
nowtogetfromaproblemto
asolution,
with
you
writingthe
leastamount
ofcode.Ifyoucan
be
patientforafewmorepages,
westarttalkingaboutitatthe
!ndofthischapter.
gettoknowtheJavaAPI
;\.
Java'&pos~
This
week'sInterview:
ArrayList.onarrays
HeadFirst
So,ArrayListsarelikearrays,right?
ArrayLlst
In
theirdreams!
I
aman
objec:
thankyouverymuch.
HeadFirst
If
I'mnotmistaken,arraysareobjectstoo.
They
liveontheheapright
therewithallthe
otherobjects.
ArrayList
Surearrays
go
ontheheap,
duh,
butanarrayis
still
awanna-be
ArrayList.Aposer.Objectshavestate
and
behavior,right?We'reclearonthat.But
haveyouactuallytriedcallingamethodonanarray?
HeadFirst
Nowthatyoumention
it,
can'tsayIhave.ButwhatmethodwouldI
call,anyway?Ionly
careaboutcallingmethodsonthestuffIput
in
thearray,not
thearrayitself.AndIcanusearray
syntax
whenIwanttoput
things
in
andtake
things
outofthearray.
ArrayUst
Is
thatso?Youmeantotellmeyouactually
remooed
somethingfroman
array?(Sheesh,wheredo
they
train.
youguys?Mljava's?)
HeadFirst
Of
&OlITSe
Itakesomethingoutofthearray.IsayDogd
=
dogArray[l)
and
J
gettheDogobjectatindexloutofthearray.
ArrayList
Allright,I'llttytospeakslowlysoyoucanfollowalong.
You
were
1UJ1,
Irepeat
TUI~
removingthatDogfromthearray.Allyoudidwasmakeacopyofthe
rifmnce
to
tht
Dog
andassignittoanotherDogvariable.
HeadFirst
Oh,Iseewhatyou'resaying.NoIdidn'tactuallyremovetheDog
objectfromthearray.It'sstillthere.ButIcanjustsetitsreferencetonull,Iguess.
ArrayLlst:
ButI'mafirst-classobject,soIhavemethodsandIcanactually,you
know,
M
things
likeremovetheDog'sreferencefrommyself,notjustsetittonull.
AndIcanchangemysize,
dynami£al£y
(lookitup).Just
tty
togetan
ami)'
todothat!
HeadArst
Gee,hate
to
bring
this
up,buttherumor
is
thatyou'renothingmore
thanaglorifiedbutless-efficientarray.That
in
factyou'rejustawrapperforan
array,
addingextramethodsfor
things
likeresizingthatIwouldhavehadtowrite
myself.
Andwhilewe'reat
it,J'OU
can'teven
haM
primiJiDes!
Isn'tthatabiglimitation?
ArrayList
Ican't
believe
youbuyinto
that
urbanlegend.No,Iam
not
justaless-
efficientarray.I
will
admitthatthereareafew
extmne{y
raresituationswherean
arraymightbejustatad,Irepeat,
tad
bitfasterforcertain
things.
But
is
it
worththe
miniscule
performance
gain
to
giveupall
this
poWa'.
Still,lookatall
tlllsflexihiliry.
And
asfortheprimitives,of
'dum
youcanputaprirntive
in
anArrayList,aslongasit's
wrappedinaprimitivewrapper
class
(you'llseealotmoreonthatinchapter10).
AndasofJava5.0,thatwrapping(andunwrappingwhenyou
take
theprimitiveout
again)happensautomatically.Andallright,I'll
Q£krwwledge
that
yes,
if
you'reusingan
ArrayList
of
primitives,
it
probably
is
faster
with
anarray,becauseofallthewrapping
andunwrapping,butstill...whoreallyusesprimitives
Uu.se
days?
Oh,lookatthe
rime!
I'm
llJujor
Pilaus:
We'llhavetodo
this
again
sometime.
youarehere
~
135
differencebetween
ArrayList
and
array
CotMparhtgArrayListtoaregulararray
ArrayList
regulararray
ArrayList<String>myList
=
newString
[]
myList
=
newString[2J;
ArrayList<String>();
Stringa
=
newString("whoohoo");
Stringa
=
new
String("whoohoo");
myList.add(a);
myList[O)
=
a;
Stringb
=
new
String("Frog");
Stringb
=
newString("Frog");
myList.add(b);myList{l)
=
b;
int
theSize
=
myList.size();
int
theSize
=
myList.length;
~
,
\
\\eY~
s..,'ncYt
Object
0
=
myList.get(l);
String
0
=
myList(l];
rl;s
tp
\oo\t.
\
~a\\'t d'~~eYO\t...:
t
myList.remove(lj;
myList(l]
=
null;
..,..
boolean
isIn
=
myList.contains(b);
boolean
isIn
=
false;
for
(Stringitem
:
myList)
(
if
(b.equals(item))
{
isIn
=
true;
break;
)
I
NoticehowwithArrayList,you'reworking
withanobjectoftypeArrayList,so
you'rejust
invokingregularoldmethodsonaregularold
object,usingtheregularolddotoperator.
136
chapter6
Withan
arra)',
youuse
specialarray
syntax
(like
myList[O]
=
foo)
thatyouwon'tuseanywhere
elseexceptwitharrays.Even
thoughan
array
is
anobject,
it
livesin
its
own
special
world
andyoucan'tinvokeanymethodson
it,
although
you
canaccessitsoneandonly
instancevariable,
length.
gettoknowtheJavaAPI
CotMparit1gArrayListtoaregulararray
•
•
•
Aplainoldarrayhastoknowits
sizeatthetimeit'screated.
Butfor
Arrayl.ist,
youjustmakeanobjectof
type
Arrayl.ist,
Everytime.
It
neverneedsto
know
howbigitshouldbe,becauseitgrows
andshrinksasobjectsareaddedorremoved.
~
newString[2]
Needs0siu∙
newArrayList<String>()
No
siu\"e,"'i\"eo
(olthOl,\~h
YOl,\tan
~ive
it
0
siu
i~
yo",wont
to).
Toputanobjectinaregulararray,
youmustassignittoaspecific
location.
(Anindexfrom0toonelessthanthelengthof
thearray.)
myList[l]
=
b;
~
NeedsoYl
il'lde~.
If
thatindexisoutsidetheboundariesofthe
array(like,thearraywasdeclaredwithasizeof
2,andnowyou'retryingtoassignsomething
toindex3),itblowsupatruntime.
WithArrayIist,youcanspecifyanindexus-
ingthe
add(anlnt,anObject)
method,oryou
canjustkeepsaying
add(anObject)
andthe
ArrayListwillkeepgrowingtomakeroomfor
thenewthing.
myList.add(b);
-,
No
il'ldex.
Arraysusearraysyntaxthat'snot
usedanywhereelseinJava.
ButArrayListsareplainoldJavaobjects,so
theyhave
nospecialsyntax.
myList[l]
~
.\
L
otkets[
J
o\"esfet,o
Theott0'l
o\"
s'll'lta~
l,ISed
01'1\'1
kO't'
attd'ls.
ArrayListsinJava5.0are
parameterized.
Wejustsaidthatunlikearrays,Arrayl.ists
have
nospecialsyntax.Butthey
do
use
somethingspecialthatwasaddedtoJava5.0
Tiger-paramet:erizedtypes.
ArrayList<String>
'"
The
<St\"il'l~>
in
ol'l~le
b\"otlcetsis0"-t'ife
fo\"offtete\"".A\"\"oyList<St\"il'lg>ffteal'lSSifftf1y
"0
list
~
Stril'lgs",oSoffosed
to
AttoyList<Dog>
whith""eons,"
0
list
~
Dogs".
PriortoJava5.0,therewasnowaytodeclare
the
type
ofthingsthatwouldgointhe
ArrayList,sotothecompiler,allArrayIists
weresimply
heterogenouscollectionsof
objects.Butnow,usingthe<typeGoesHere>
syntax,we
candeclareandcreatean
ArrayIistthatknows(andrestricts)the
typesofobjectsitcanhold.We'lllookatthe
detailsofparameterizedtypesinArrayLists
in
theCollectionschapter,sofornow,don't
thinktoomuchabouttheanglebracket<>
syntaxyousee
whenweuseArrayl.ists,Just
knowthatit'sawaytoforcethecompilerto
allowonlyaspecifictype
ofobject
(thetypein
anglebrackets)
intheArrayList.
"_"........_L.....
the
buggy
DotComcode
Letlfixthe
t'otCOItt
code.
int(]locationCells;
intnurnOfHits
=
OJ
publicvoidsetLocationCells(int[]locs)(
locationCells
=
locs;
publicStringcheckYourself(StringstringGuess)
intguess
=
Integer.parselnt(stringGuess);
Stringresult"miss";
for(intcelllocationCells)
break;
}
II
outof:theloop
if(numOfHits
==
locationCells.length)
result.
=
"kill";
System.out.println(result);
returnresult;
//closeme
t
hod
II
closeclass
138
chapterS
gettoknowtheJavaAPI
prep
code
ID~~
New
and
hMprovedPotCOtM
class
import
publicclassDocComI
p
rLva
t
e
ArrayList<Strinq>
locationCells;
//privateincnurnOf<Jit
~ ~-a
L.irt.
that.
ho\ds
Shin~S -
//don'
t
needt.hacnow
C
Lhe
Shin
l1
a"r.,.a~
to
an
f\n
~
ha"ljl",.(;)
publicvoidsetLocationCells
(ArrayList<String>
Loc)
!
l'll
"al'l'l-
locationCells
=
loc;_
.,.-o'ItO
a'(~l>J"t
~t'tI
a"d""r-
/'""t
\I.SC'f"~!>S
is
i"
t.he
publicStringcheckYourself(String
userInputl(
find
out,
tne-
~orr
ib
inde~
~
An-a~L.-'st...b~ l~skll~1)
t.hen
i,..oe-d)tO
I
r",l.'s
_A
l
'"
",I'll
1St.
String
result
=
"miss";
~
'".-'"
y~'n\S
a
-l-
intindex
=
locationCells.indexOf(userlnput):
if(index
>=
0){
if(locationCells.isEmpty(»
result"kill";
else
I
result
c:
"hit";
II
close
if
II
close
ou
er
if
return
result;
)II
closemethod
II
closeclass
you
arehere.
-139
makingtheOotComBust
Let's
build
theREALgaltte:
HSi"k
aPot
COItt
M
7
)<.
7
~
__id
o
123456
\start.s
at
ZbO,
likeJava
ar'ra'f~
We'vebeenworkingonthe'simple'version,butnow
let'sbuildthereal
one.Insteadofasinglerow,we'll
useagrid.
AndinsteadofoneDotCOID,we'lluse
three.
Goal:Sink
all
ofthecomputer'sDotCorns
in
the
fewest
numberofguesses.You'regivenaratinglevel
basedonhowwellyou
perform.
Setup:Whenthegameprogramislaunched,the
computerplacesthreeDot
Corns,
randomly.onthe
virtual.
7:x.7grid.
Whenthat'scomplete,thegame
asksfor
yourfirst
guess.
Howyou
play:
Wehaven'tlearnedtobuild
a
GUI
yet,sothisversionworksatthecommand-line.The
computer
will
promptyou
to
entera
guess(a
cell),
whichyou'lltypeat
thecommand-line(as
"A3n,
WCS\
etc.),
Inresponsetoyourguess,you'llsee
a
result
at
thecommand-line,either
"hit",
"miss",
or"Yousunk
Pets.com"(orwhatevertheluckyDotComoftheday
is).
Whenyou'vesent
all
threeDotCornstothatbig
404
inthesky,thegameendsbyprintingoutyour
rating.
You'regoingtobuildthe
SinkaDotComgame,with
a
7
x
7
gridandthree
DotCams.EachDotCom
takesupthreecells.
partofagattteI.,teractlo.,
'tjava
DotComBust
Enter
aguess
A3
miss
Enter
aguess
82
miss
Enter
aguess
C4
miss
Enteraguess
02
hit
Enter
aguess
D3
hit
Enter
aguess
04
Ouch!
You
sunkPets.com
kill
Enter
aguess
B4
miss
Enteraguess
G3
hit
Enteraguess
G4
hit
Enteraguess
G5
Ouch!YousunkAskMe.com
k
V
E
q
N
i
....p
L;~
I∙
.~
.,.~ ~,~c
f~ ~~ ~
rMe~c
~m
RS.I
I.
'.
E
F
A
(
o
B
G
140
chapter
6
What
tteeds
tochattge?
Wehavethreeclassesthatneedtochange:the
DotComclass(which
is
nowcalledDotCominsteadof
SimpleDotCom),thegame
class
(DotComBust)andthe
gamehelperclass(whichwewon'tworryaboutnow).
o
DotComclass
o
Addanamevariable
toholdthenameoftheDotCom
("Pets.com",
uGo2.com~,
etc.)soeachDot-
Comcan
print
its
namewhenit'skilled(see
theoutputscreenontheoppositepage).
o
DotComBustclass(thegame)
o
Create
three
DotComsinsteadofone.
o
Give
eachofthe
three
DotComs
a
name.
Calla
settermethodoneachDotCom
instance,sothattheDotComcanassignthe
name
to
its
name
instancevariable.
get
to
knowtheJavaAPI
DotComBustclasscontinued.••
o
PuttheDotComsona
grid
rather
than
justasinglerow,anddo
it
for
all
three
DotComs.
Thisstepisnow
way
more
complexthan
before,ifwe'regoingtoplacetheDotComs
randomly.Since
we'renotheretomess
with
themath,weputthealgorithmfor
givingtheDotComsalocationintothe
GameHelper(Ready-bake)
class.
@
Checkeachuserguess
with
all
three
DotComs,
instead
ofjustone.
@
Keepplaying
thegame(i.eaccepting
userguesses
and
checkingthemwiththe
remainingDotComs)
until
there
areno
nwre
liveDotComs.
o
Getoutof
main.
Wekeptthesimpleonein
mainjustto...keepitsimple.Butthat'snot
whatwewantforthe
real
game.
3
Classes:
DotcomBlItt
DotCom
Gam.Helper
5Objects:
Thegameclass.
Makes
DolComs,
gelsuserInput,
playsuntilall001∙
Cornsaredead
DotComBust
Theactual
DotComobjects.
DolComs
knowtheir
name.
location,
and
how10checkauser
gu6SSfora
match.
Thehelperclass
(Ready-Bake).
It
knowshow
to
acceptusercom-
mand-llneinput,
and
malle
DOICom
locations.
GameHelper
Plus4
ArrayLists:1for
theDotComBust
and1foreach
of
the
3
DotCom
objects.
youarehere
~
141
detailedstructureofthegame
Whodoes
what
it'
thePofColMJustgatMe
(at'd
whetd
o
DotCom8u"
Thegame
class.
instantiates
DotComBust
object
The
mainOmethod
inthe
DotComBust
class
instantiatesthe
DotComBustobjectthat
does
all
thegamestuff.
142chapter6
DotComBust
object
ArrayList
object(to
holdDotCom
objects)
The
DotComBust(game)
objectinstantiatesan
instance
ofGameHelper.
theobjectthat
will
help
the
game
doits
work
The
DotComBust
object
instantiates
an
ArrayList
that
will
holdthe
3
DotCom
objects.
gettoknowtheJavaAPI
e
ArrayListobjectto
holdDotComobjects
DotCom
objects
TheDotComBustobject
createsthreeDotCom
objects(andputsthemin
theArrayList)
TheDotComBust
objectasksthe
he/perobject
for
alocationfora
DotCom(does
this3times,onefor
eachDotCom)
TheDotComBustobjectasksthehelper
objectforauserguess(thehelper
prompts
theuserandgetsinputfrom
thecommand-line)
Andso
thegamecontinues...get-
tinguserinput.askingeachDotCom
tocheck
foramatch,andcontinuing
until
011DotComsaredead
TheDotComBust
objectgiveseachoftheDot-
Comobjectsalocation(whichtheDotComBust
gotfromthehelperobject)like-
A2
u
•
-B2-.
etc.EachDotComobjectputshisownthree
locationcellsinanArrayList
ArrayList
object
(toholdDotCom
celllocations)
Ar
ray
List
object
ArrayList
object
TheDotComBustobjectloopsthroughthelist
ofDotComs.and
askseachonetochecktheuser
guess
foramatch.TheDotComchecksitslocations
ArrayListand
returnsaresult("hW."miss",erc.)
ArrayList
object
(toholdDotCom
celllccctioas)
ArrayList
1If:Jl~91 o b j e c t
ArrayList
object
youarehere
~
143
theOotComBustclass(thegame)
prepcode
DalComBUJt
GameHelperhelper
ArrayUsldolComsLlsl
Inlnurn
OfGUB.'lS6S
selUpGameO
slarIPlayingO
checkUserGuessO
fin~GameO
Variable
Declarations
Method
Declarations
Method
Implementations
Prep
code
forthereal
PotCOIM'ust
class
-
TheDotComBustclasshasthreemainjobs:setupthegame,playthegame
untiltheDotComsaredead,andendthegame.Althoughwecouldmap
thosethreejobsdirectlyintothreemethods,wesplitthemiddlejob(playthe
game)into
two
methods,tokeepthegranularitysmaller.Smallermethods
(meaningsmallerchunksoffunctionality)helpustest,
debug.
andmodify
the
codemoreeasily.
DECLARE
andinstantiatethe
GomeHelper
instancevariable,named
helper.
DECLARE
andinstantiate
an
ArrayUst
toholdthelistofDotComs(initiallythree)Call
it
dotComsLJst
DECLARE
anintvariable
to
holdthenumberofuserguesses
(so
thatwe
can
givetheuser
a
scoreattheendofthegame).Name
it
numOfGuesses
andsetitto
O.
DECLARE
a
setUpGameO
methodtocreateandinitializetheDotComobjectswith
names
andlocations.Displaybriefinstructionstotheuser.
DECLARE
a
5tortPlayingO
methodthat
asks
theplayerforguessesandcallsthe
checkUserGuessOmethodunt
ilalltheDotComobjectsareremovedfromplay.
DECLARE
a
ched<UserGuessO
methodthatloopsthroughallremainingDotCom
objectsand
calls
eachDotComobject'scheckYourselfOmethod.
DECLARE
a
~nlshGomeO
methodthatprints
a
messageabouttheuser'sperformance,based
onhowmanyguesses
it
tooktosinkalloftheDotComobjects.
METHOD:
voId
JetUpGGmeO
II
make
three
DotCom
objectsandnome
them
CREATE
threeDotComobjects.
SET
a
nameforeachDotCom,
ADD
theDotComstothe
dotComsLJst(
the
ArrayList).
REPEAT
witheachoftheDotComobjectsinthe
dotComsUst
array
CALL
the
placeDotComO
methodonthehelperobject,to
get
arandomly-selected
locationforthis
DotCom(threecells,verticallyorhorizontallyaligned,ona
7X7
grid).
SET
thelocationforeachDotCombasedontheresultof
the
placeDotComO
call,
END
REPEAT
END
METHOD
142
methods,Andwhichmethoddoyoutest
andwritefirst?SeeIfyoucanworkoutsome
prepcodeforasetoftests.Prepcodeor
evenbulletpointsaregoodenoughforthis
exercise,
butIfyouwanttotrytowritethe
rea/test
code(InJava),knockyourselfout,
get
to
know
theJava
API
Method
httpleltt8MtatioMSCOMttMUad:
METHOD:
void
startPlaylng()
REPEAT
whileanyDotComsexist
GET
userinputbycallingthehelpergetUserinputQmethod
EVALUATE
theuser'sguessbycheckUreI'GuessOmethod
END
REPEAT
ENDMETHOD
METHOD:
void
checkUserGuess(SCrlnguserGuess)
/I
find
out
if
there's
a
hit(andkill)onanyDotCom
INCREMENT
thenumberofuserguessesinthenumOfGuessesvariable
SET
thelocalresul!variable(aString)to"miss",assumingthattheuser'sguess
will
beamiss.
REPEAT
with
eachoftheDotObjeC1SinthedotComsUst
array
EVALUATE
theuser'sguessbycallingtheDotComobject'scheckYourseJf()method
SETtheresult
variableto
"hit"
or
"kill"
if
appropriate
IFthe
result
is
"kill",REMOVE
theDotComfromthedotComsUst
END
REPEAT
DISPLAY
theresul!valuetotheuser
END
METHOD
METHOD:
void
fJnlshGameO
DISPLAY
ageneric"gameover"message,then:
IF
numberofuserguessesissmall,
DISPLAY
a
congratulationsmessage
ELSE
DISPLAY
an
insultingone
END
IF
ENDMETHOD
rpen
yoor
penCil------------------,
Howshouldwegofromprepcodetothe
finalcode?Firstwestartwithtestcode.and
thentestandbuildupourmethods
bitby
bit.Wewon'tkeepshowingyoutestcode
InthIsbook,sonowIt'suptoyoutothink
aboutwhatyou'dneedtoknowto
test
these
youarehere.
145
theDotComBustcode(thegame)
inthefewestnumber
of
guesses"):
You'll
u_each
annotationJustonce,
and
you'lln.....11
of
the.nnotatlon•.
Annotat.
thecode
yourself.
Matchthe
annotations
8t
the
bottomofeach...
withthenumbe...
Inthecode.
Writ.
thenumberInthe
slot
In
front
of
the
eorr..pondlns
annoldon.
threedotcorns.");
Go2.com");
•
System.out.println("Yourgoalistosink
System.out,println("Pets.com,eToys.com,
System.out,println("Trytosinkthemall
importjava.util.*;
publicclass
DotComBust
f
PrivateGameHelperhelpernewGameHelper();
~
privateArrayList<DotCom>dotComsList
=
newAIrayList<DotCom>();
privateintnumOfGuesses
=
0;
privatevoid
setUpGame()(
II
firstmakesomedotcornsandgivethemlocations
DotComone
=
newDotCom();
one.setName(-Pets.com");
DotComtwo
=
newDotCom();
two.setName("eToys.com
H
);
DotComthree
=
newDotCom();
three.setName{"Go2.com");
dotComsList,add{one);
dotComsList,add(two);
dotComsList.add(three);
for(DotComdotComToSet:dotComsList)(•
ArrayList<String>newLocation
=
helper.placeDotCom(3);
~
dotComToSet.setLocationcellS(neWLocatiOn);...
I
II
closeforloop
II
close
secUpGame
method
pr
i
vatevoid
startPlayinq()(
while(!dotComsList,isEmpty()(•
StringuserGuess
=
helper.getUserInput("Enter
a
guess");
~
checkUserGuess(userGuess);•
I
II
close
while
linishGame();•
II
closestarcPlayingmethod
146
chapter6
gettoknowtheJavaAPI
privatevoid
checkUserGuess
(StringuserGuess){
numOfGuesses++;
4ID
Stringresult
=
"miss";
~
Whateveryoudo,
DON'Tturnthe
pagel
Notuntilyou've
finishedthis
exercise.
Ourversionison
thenextpage.
~
•
)
if(result.equals("kill"»
dotComsList.remove(dotComToTest);
break;
for(DotComdotComToTest:dotComsList){
~
result
=
dotComToTest.checkYourself(userGuess);
~
if(result.equals("hit"»{
break;•
)II
closefor
System.out.println(result);•
II
closemethod
privatevoid
finishGame()
System.out.println("AllDotCornsaredead!Yourstockisnowworthless.");
if(numOfGuesses
<=
18){
System.out.println("Itonlytookyou"+numOfGuesses+"guesses.");
System.out.println("Yougotoutbeforeyouroptionssank.");
else{
System.out.println("Tookyoulongenough."+numOfGuesses+"guesses.");
System.out.println("Fisharedancingwithyouroptions.");
}
II
closemethod
publicstaticvoid
DUlin
(String[]args){
DotComBustgame
=
newDotCOmBust();.
game.setUpGame();•
game.startPlaying();•
II
closemethod
_Pt'il'l'tthe
~es~lt
to\'"
the
~et'
_ull
the
~a",e
objett
to
set
~f
the
~a
...e
youarehere
~
147
theDotComBustcode(thegame)
importjava.util.*;
pubLi,cclass
DotComBust
Pyi\'lt
b\-ie~
~
i r.s t,n..l tions
.foor
\O.KY.
threedotcoms.");
Go2.com");
inthefewestnumberofguesses");
GameHelperhelper"'newGameHelper();
~,~
ArrayList<DotCom>dotComsList
=
newArrayLlst<DotCom>();
Ma\((a"An-att
atn
intnurnOfGuesses
=
0;
DotCo'"
~jC:L
.L'"
'II
h~d
lis
a
l,st.
Vla~
"'"
ONL.~
Dot:COf'I
~jctb,
'w{:
as
pot£.or..()
...,oJd
J
~
a"
ok
DotcOfl"
",tdll..
II/
o\>jtt.W.
System,out.println("¥ourgoalistosink
System.out.println("Pets.com,eToys.com,
System.out.println("Trytosinkthemall
private
private
private
privatevoid
setUpGame()(
/1fustmakesomedotcornsandgivethemlocations
DotComone
=
newDotCom():
one.setName("Pets.com");
DotComtwo
=
newDotCom();
two
.setName("eToys.com");
DotComthree
~
newDotCom();
three.setName("Go2.com");
dotComsList.add(one);
dotComsList.add(two);
dotComsList.add(three);
for(DotComdotComToSet:dotComsList){
~Reytdt
'WoIith
tdth
DO'l:.COftI
i"
t~t
list.
Ask
t},c
helt'e\'
t....
a
ArrayList<String>newLocation
=
helper.placeDotCom(3);
~ D~
loUBOY\
~a:.~
~a'1Lisi
.J
Sh,,,,..∙..
dotComToSet.setLocationCells(newLocation):(-
C<111
ih
D
e
~~t""'~
.1,.
otCA...to.
't
0"UlIJ
I//
cl.oseforloop
j~ ~ot.(t"o1'V~j
the
10t4i:io
h
y04J.
I
I
closesetUpqame,method
~
helpa-.
privatevoid
startPlayinq()
while(!dotComsLi9t.is~mpty())
StringuserGuess
=
helper.getUserlnput("E:ntera
guess");
k""'
~et
\O.KY
i\'lflo+"
checkUserGuess(userGuess);~
C<111
~
OWJI
lhtl~1A
L.
set'qlotU
"'et.hod
II
closewhile.
finishGame();
~
C<111
010""0"""
+i"ish~a"'e
...
tihod.
I
J
closesC3rtPlayil1gmethod
148
chapter6
gettoknowthe
JavaAPI
privatevoid
checkUserGuess
(StringuserGuess){
numOfGuesses++;
if(result.equals(\\hit"»(
break;
~
,ei
~~
o.f
theloopea\"ly,
1'10
poil'lt
<;
11'1
USt;II'I~
theothers
)
if(result.equals("kill"»(
Stringresult\\miss";
t--asslA",eit's
a
'",iss',IAl'liesstoldoth«wise
for(DotComdotComToTestdotComsList){
~
\"eyeatwithallDotCO\'I'ISil'lthelist
result
=
dotComToTest.checkYourself(userGuess);
~
asktheDotCO\'I'Itothet.ktheWie\"
~IAeSS,lookil'l~ ~O\"
a
hit
(0\"
kill)
dotComsList.remove(dotComToTest);
break;
II
closefor
PY'il'lt
a
l'IIessa~e tellil'l~
the
lASe....howhedidil'lthe
~l'IIe
f
System.out.println(result);
~
PY'il'ltthereslAlt
+0\"
theWi«
II
closemethod
privatevoid
finishGame()
System.out.println(\\AllDotCornsaredead!Yourstockisnowworthless.");
if(numOfGuesses
<=
18)(
System.out.println(\\Itonlytookyou\\+numOfGuesses
+\\
guesses.");
System.out.println(\\Yougotoutbeforeyouroptionssank.");
else(
System.out.println(\\Tookyoulongenough.\\+numOfGuesses
+\\
guesses.");
System.out.println(\\Fisharedancingwithyouroptions");
)
II
closemethod
publicstaticvoid
main
DotComBustgame
=
new
game.setUpGame();
game.startPlaying();
II
closemethod
youarehere•
149
theDotComcode
Thefinal
version
of
the
PotCOtlt
class
importjava.util.*;
publicclassDotCom
privateArrayList<String>locationcells;'S
privateStringname;)
DotCOM'
5
iWlStaWlte"iav-ia'oles:
_ahArra'fl-ist
cJ
tellloeatiOWlS
_theDotCOM'
5
~Me
publicvoidsetLocationCells(ArrayList<String>loc){
locationCells=loc;
publicvoidsetName(Stringn)
~
'lOll-V-
basitseHe\"Method
name=n;
pUblicStringcheckYourself(Stringuserlnput){
Stringresult=
~miss";
intindex=locationCells.indexOf(userlnput);
result=
~kill";
if(index>=0)(
L._'()
il
L_.J
I
L_
L
1___
(,(Sih~
(lrrayl-ist
5
\"eMo"ie
Me~od
1R
aee1;C:anen,,\,,'!,
l ocationCells.remove(index);~
if
(locationCells.isEmpty()){
(-----~'-..(,(sin~
the
iS~Mft'l(
)Method
to
see
i~
all
cJ
theloeatoWlSha"iebeen
~~sed
System.out.println(~Ouch!
Yousunk
~
+name+
~
(
~);
else{
result=
~hit";
}II
close
if
II
close
if
returnresult;
}II
closemethod
II
closeclass
150
chapter6
<,
Tellthe
lASe\"
w
'
h
Lr»
nen
a
Vo"U.,
hb
OM
as
ten
51Ahk.
O_i.......(.,
1\1:1;-
n,
-...5S.....
'h'i',
.....'"or
kill'.
SuperPowerful'oolea"[xpressio"s
Sofar,whenwe'veusedbooleanexpressionsforourloopsor
if
tests,they'vebeenprettysimple.Wewillbeusingmore
powerfulbooleanexpressionsinsomeoftheReady-Bakecode
you'reabouttosee,andeventhoughweknowyouwouldn't
peek,wethoughtthiswouldbeagoodtimetodiscusshowto
energizeyourexpressions.
'And'and'Or'Operators
(&&,
II)
Let'ssayyou'rewritingachooseCamera()method,withlotsofrules
aboutwhichcameratoselect.Maybe
you
canchoosecameras
rangingfrom$50to$1000,butinsomecasesyouwanttolimitthe
pricerangemoreprecisely.Youwanttosaysomethinglike:
'Iftheprice
range
isbetween$300
and
$400thenchoose
x:
if(price
>=
300&&price
<
400){
camera
=
"X"i
}
Let'ssaythatofthetencamerabrandsavailable,youhavesome
logicthatappliestoonlya
few
ofthelist:
if(brand.equals("A")
II
brand.equals("B")){
II
dostufffor
only
brandA
or
brandB
}
Booleanexpressionscangetreallybigandcomplicated:
if«zoomType.equals("optical")&&
(zoomDegree
>=
3&&zoomDegree
<=
8»
II
(zoomType.equals("digital")&&
(zoomDegree
>=
5&&zoomDegree
<=
12»){
II
doappropriatezoomstuff
}
Ifyouwanttoget
really
technical,youmightwonderaboutthe
precedence
oftheseoperators.Insteadofbecominganexpert
inthearcaneworldofprecedence,werecommendthatyou
use
parentheses
tomakeyourcodeclear.
gettoknowtheJavaAPI
Notequals
(!=
and
!)
Let'ssaythat
you
havealogiclike,"ofthetenavailable
cameramodels,acertainthingis
trueforallbutone,"
if(model
1=
2000){
II
donon-model2000stuff
}
orforcomparingobjectslikestrings...
if(lbrand.equals("X"»{
II
donon-brandXstuff
}
ShortCircuitOperators
(&&,
II)
Theoperatorswe'velookedatsofar,
&&
and
II,
are
knownas
shortcircuit
operators.Inthecaseof
&&,
theexpressionwillbetrueonlyif
both
sidesofthe
&&
aretrue.SojftheJVMseesthattheleftsideofa
&&
expressionisfalse,itstopsrightthere!Doesn'teven
bothertolookattherightside.
Similarly,with
II,
theexpressionwillbetrueif
either
sideis
true,soiftheJVMseesthattheleftsideistrue,itdeclares
theentirestatementtobetrueanddoesn'tbotherto
checktherightside.
Whyisthisgreat?Let'ssaythatyouhaveareference
variableandyou'renotsurewhether
it's
beenassigned
toanobject.Ifyoutrytocallamethodusingthisnull
referencevariable
(l.e,
noobjecthasbeenassigned),you'll
geta
NullPointerException.So,trythis:
if(refVar
1=
null&&
refVar.isvalidType()){
II
do'gotavalidtype'stuff
}
NonShortCircuitOperators
(&,
I)
Whenusedinbooleanexpressions,the
&
and
I
operators
actliketheir
&&
and
II
counterparts,exceptthat
they
forcetheJVMto
always
check
both
sidesofthe
expression.Typically,&and
I
areusedinanothercontext,
formanipulatingbits.
youarehere
~
151
Ready-bake:GameHelper
importjava.io.*i
importjava.util.∙:
pUblicclassGamaBelper
Thisisthehelperclassforthegame.Besidesthe.userinputmethod
(thatpromptstheuserandreadsinputfromthecommend-line),the
helper'sBigServiceistocreatethe
cell
locationsfortheDotComs.
Ifwewereyou,we'djustbackawayslowlyfromthiscode,except
totypeitinandcompileit.
We
triedtokeepitfairlysmalltoyou
wouldn'thove
totypesomuch,butthatmeansitisn'tthemost
readablecode.Andremember,youwon',beabletocompilethe
DotComBustgameclassuntilyouhave
this
class.
privatestaticfinalStringalphabet"abcdefg";
privateintgridLength
=
7:
privateintgridSize
=
49;
privateint()
grid
=
newint[gridSize);
privateintcomCount
=
0;
publicStringgetUserlnput(Stringprompt)
StringinputLine
=
null;
System.out.print(prompt
+"
")i
try(
Bu
fferedReaderis
=
newBufferedReader(
newInputStreamReader(System.in»);
inputLine
=
is.readLine();
if(inputLine.length()
==
0)
returnnull;
catch(IOExceptione)(
System.out.println("IOException:"
+
eli
I
returninputLine.toLowerCase();
NoU:
F~
elttta,,,e,M,
'101#
",\~h-l:
b-)'
'1<rI-'o......
c:"ti,,~'
tht
S)'lu....
Ollt.fri..
HI,,)'s
i..
t.he
fl.lteDoiCo...()...
dhod,
j\l.1t.
to
w<iUh
it
work!
These
?,"i"t
1~te-e"u
willId
Y0l#
"',heai
u
by
~ivi,,~
'f.....
tilelold∙tioll
o-f
the
Dot.ColN,
bl#t
it.willhell'
'fOIl
ust
it..
publicArrayList<Stxing>placeDotCom(intcomSize)(
ArrayList<String>alphaCells
=
newArrayList<String>();
String
[1
a1phacoords
=
newString(comSizel:
II
holds'f6'typecoords
Stringtemp
=
null;
II
temporaryStringforconcat
int
II
coords
=
newintlcomSize);
II
currentcandidatecoords
intattempts
=
0;
II
currentattemptscounter
booleansuccess
=
false;
II
flag
=
foundagoodlocation?
intlocation
=
0;
II
currentstartinglocation
comCount++;
intincr
=
1;
if
«cornCount
%
2)
==
1)(
incx
=
gridLength;
while(
!
success
&
attempts++
<
200)(
location
=
(int)(Math.random()..gridSize);
I/System.ouc.print("
try"
+
location);
intx
==Oi
success
=
true;
while(success&&x
<
comSizel
if
(grid(locacion)
=-=
0){
152chapter6
II
nthdotcomtoplace
II
sethorizontalincrement
II
ifodddotcom(placevertically)
II
setverticalincrement
II
mainsearchloop
(32)
II
getrandomstartingpoint
II
nthpositionindotcomtoplace
II
assumesuccess
II
lookforadjacentunusedspots
II
ifnotalreadyused
gettoknowthe
Java
API
tallteHelperclasscodecot1tlt1ued...
coords[x++]=location;
location+=incr;
if(location>=gridSize){
success=false;
}
if(x>O
&&
(location
%
gridLength
success=false;
II
savelocation
II
try'next'adjacent
II
outofbounds-'bottom'
II
failure
0»{
II
outofbounds-rightedge
II
failure
}
else(
II
foundalreadyusedlocation
II
System.out.print("used"
+
location);
success=false;
II
failure
II
endwhile
intx=0;
introw=0;
intcolumn=0;
II
System.out.println("\n");
while(x
<
comSize){
grid[coords[x]]=1;
row=(int)(coords[x]
I
gridLength);
column=coords[x]
%
gridLength;
temp=String.valueOf(alphabet.charAt(column);
II
turnlocationintoalphacoords
II
markmastergridpts.as'used'
II
getrowvalue
II
getnumericcolumnvalue
II
converttoalpha
alphaCells.add(temp.concat(Integer.toString(row»);
tt
nat
x++;
n'
is
tnC
state
VOlC
"tnC
II
System.out.print(ncoord"+x+"
=
n
+
alphaCells.get(x-l));<;-,,1
~s
olJ.c"14t.H'i'f/nCVOC
te
s'f.
\-'at
CO
.
1)otC
OVOI
IS""
I
ISystem.out.println
r"
\n");
returnalphaCells;
youarehere
~
153
API
packages
UsittgtheLibrary
(theJava
API)
Youmadeit
all
thewaythroughtheDotComBustgame,
thanksto
thehelpofArrayList.
And
now,aspromised,
it'stimeto
learnhowtofoolaroundintheJavalibrary.
In
the.Java
API.
classes
aregroupedintopackages.
TouseaclassintheAPI.you
havetoknowwhichpackage
theclassIsin.
Every
class
intheJavalibrarybelongsto
a
package.
Thepackagehasaname,like
javax.swlng
(a
package
thatholdssomeoftheSwing
CUI
classes
you'll
learnaboutsoon).ArrayListisinthepackage
called
java.utll,
whichsurprisesurprise,holdsa
pile
of
utility
classes.
You'lllearnalotmoreabout
packagesinchapter
16,
includinghowtoputyour
own
classesintoyour
own
packages.Fornowthough,
we'rejustlookingto
use
someoftheclassesthatcome
withJava.
Usingaclassfromthe
API,
inyour
own
code,
is
simple.
You
justtreatthe
class
asthoughyouwrote
ityourself...
as
thoughyoucompiledit,andthereit
sits.waiting
foryoutouseit.
With
one
big
difference:
somewhereinyourcodeyouhavetoindicatethe
full
nameofthelibraryclassyouwanttouse,andthat
meanspackagename
+
class
name.
Evenifyoudidn'tknowit,
you'vealreadybeen
using
cJassesfrom
a
ptu:kage.
System(System.out.println),
String,
andMath(Math.random
0),
allbelong
to
the
java.lang
package.
154
chapter6
gettoknowtheJavaAPI
:tberet&rH?
Dumo
~uest19ns
Q.:
Whydoestherehaveto
beafullname?Is
thattheonly
purposeofapackage?
A:
Packagesareimportant
forthreemainreasons.First,they
helptheoverallorganizationofa
projectorlibrary.Ratherthan
just
havingonehorrendouslylarge
pile
ofclasses,they'reallgrouped
intopackagesforspecifickinds
offunctionality(likeGUI,ordata
structures,ordatabasestuff,etc.)
Second,packagesgiveyouaname-
scoping,tohelppreventcollisions
ifyouand12otherprogrammers
inyourcompanyalldecideto
makeaclass
withthesamename.
IfyouhaveaclassnamedSetand
someoneelse(includingtheJava
API)hasaclassnamedSet,you
needsomewaytotelltheJVM
which
Setclassyou'retryingtouse.
Third,packagesprovidealevelof
security,becauseyoucanrestrict
thecodeyouwriteso
thatonly
otherclassesinthesamepackage
canaccessit.You'lllearnall
about
thatinchapter16.
IMPORT
Putanimportstatementatthetopofyoursourcecodefile:
importjava.util.ArrayList;
publicclassMyClass{...}
OR
Youhavetoknowthefullname*
-
oftheclassyouwanttousein
yourcode.
ArrayListisnotthe
full
nameofArrayList,justas'Kathy'
isn'tafullname(unlessit'slikeMadonnaorCher,butwe
won'tgothere).ThefullnameofArrayListisactually:
java.util.ArrayList
~~
/
'\
patka~e
l'lc11l1ee.\a
ss
~"'c
YouhavetotellJavawhichArrayListyou
wantto
use.
Youhavetwooptions:
o
TYPE
Typethefullnameeverywhereinyourcode.Eachtime
youuseit.
Anywhere
youuseit.
n.
~:
OK,backtothename
.
..collisionthing.Howdoesafull
Whenyoudeclareand/or
instantlate
It:
namereallyhelp?What'sto
java.util.ArrayList<Doq>list
=
newjava.util.ArrayList<Dog>0;
prevent
two
peoplefromgivinga
class
thesamepackagename?
Whenyouuseitasanargumenttype:
publicvoidgo(java.util.Arraytist<Dog>list){}
Whenyouuseitasareturntype:
publicjava.util.Arraytist<Doq>fooO{...}
A:Javahasanamingconvention
thatusuallypreventsthisfrom
happening,aslongasdevelopers
adhereto
it.
We'llgetintothatin
moredetailinchapter16.
"Unlesstheclassisinthejava.langpackage.
youarehere.155
•
•
•ToremovesomethingfromanArrayUstuse
r&moveD∙
•Tofindoutwheresomethingis(andIf
it
is)inan
ArrayUst,useindexOfO.
•Tofindout
if
anArrayUstisempty,use
IsEmpfyQ.
•Togetthe
size
(numberofelements)inan
ArrayUst.usethe
sizeD
method.
•Toget!he
length
(numberofelements)ina
regularoldarray.remember,youusethelength
variable.
•An
Arraylist
res1z&s
dynamicallytowhat-
eversizeis
needed.
It
growswhenobjects
are
added,and
it
shrinks
whenobjectsare
removed.
•Youdeclarethe
type
ofthearrayusinga
type
parameter,
which
isatypenameinangle
brackets.
Example:
ArrayList<8utton>means
theArrayUstwill
be
abletoholdonlyobjectsof
type
Button(orsubclassesofButtonasyou'll
learnin!henextcoupleofchapters).
•
AlthoughanArrayUstholdsobjectsandnot
primitives,thecompilerwillautomatically
"wrap.
(and∙unwrap∙whenyoutakeItout)
a
primI-
tiveinto
an
Object,
andplacethatobjectInthe
ArrayUstInsteadoftheprimitive.(Moreonthis
featurelaterinthe
book..)
•Classesaregrouped
into
packages.
•A
classhasafullname,whichisacombina-
tionofthepackage
name
andtheclassname.
ClassArrayListisreally
java.utiIArrayUst.
•Touseaclassinapackageotherthanjava.
lang,youmusttellJavathefullnameofthe
class.
•YouuseeitheranImportstatementatthetopof
yoursourcecode,oryoucan
type
thefullname
everyplaceyouusetheclassinyourcode.
.-----_BUUD
POINIS-
ArrayList
isaclassintheJavaAPI.
ToputsomethingintoanArrayUst.useaddD,
Where'dthat
'x'
comefrom?
(or,whatdoesitmeanwhen
apackagestartswithJavax?)
InthefirstandsecondversionsofJava(1.02
and
1.1),
allclassesthatshIppedwithJava(In
otherwords,
thestandardlibrary)wereInpackages
thatbeganwlthJava.Therewas
alwaysjllva.lang,
ofcourse
-
theoneyoudon'thavetoimport.Andtherewas
jlllla.net
l
jOl/a,/o,java.util
(althoughtherewasnosuchthingasArrayList
waybackthen),andafewothers,Includingthe
ja
va.aWl
packagethatheldGUI-relatedclasses.
Loomingonthehorizon,though,wereotherpackagesnot
Includedin
thestandardlibrary.Theseclasseswereknownas
extensions,
andcame
in
twomaInflavors:
standard,
and
not
standard.StandardextensionswerethosethatSunconsidered
official,asopposedtoexperimental,earlyaccess,orbeta
packagesthatmightormIghtnoteversee
thelightofday.
StandardextensIons,byconvention,allbeganwithan
'x'
appendedtotheregular
java
packagestarter.Themotherofall
standardextensionswastheSwinglibrary.ItIncludedseveral
packages,allofwhichbeganwith
jallax.swlng.
Butstandardextensionscangetpromotedtofirst-class,shlps-
wIth-Java,standard-out-of-the-boxlibrarypackages.Andthat's
whathappenedtoSwing,beginningwithversion
1.2
(which
eventuallybecamethefirstversiondubbed'Java
2').
MCool:everyonethought(Including
us).~Now
everyonewhohas
Java
willhavetheSwIngclasses,andwewon'thavetofigure
outhowtogetthoseclassesInstalledwithour
end-users:
Troublewaslurkingbeneaththesurface,however,because
whenpackagesgetpromoted,well
of
COURSEtheyhaveto
startwlthjalla,
notjavax.EveryoneKNOWSthatpackagesIn
thestandardlibrarydon'thavethat
"lC:
andthatonly
extensions
havethe
"x~
So,Just(andwemeanJust)beforeversion
1.2
wentfinal,Sunchangedthepackagenamesanddeletedthe
"x∙(amongotherchanges).BookswereprintedandInstores
featurIng
SWingcodewiththenewnames.NamingconventIons
wereintact.
AllwasrightwiththeJavaworld.
Exceptthe20,000orsoscreamingdeveloperswhorealized
thatwiththatsimplenamechangecamedlsasterl
Alloftheir
Swing-usingcodehadtobechangedlThe
horrorl
ThInkofall
thoseImportstatementsthatstartedwlthjavCDf...
AndIntheflnalhour,desperate,astheirhopesgrewthin,the
developersconvIncedSunto"screwtheconvention,saveour
code"
TherestIshistory.SowhenyouseeapackageInthe
librarythatbeglnswith
Javax,
youknowItstartedlife
as
an
extension,andthengotapromotion.
whenarraysaren'tenough
156
chapter6
Q.:
D06S
import
makemy
class
bigger?DoesItactually
compile
theimportedclassor
packageInto
my
code7
A:
Perhapsyou'reaCpro-
grammer?An
import
isnotthe
sameasan
include.
Sothe
answerisnoandno.Repeatafter
rne.ranimport
statementsaves
you
fromtyping:That'sreallyIt.
Youdon'thaveto
worryabout
yourcodebecomingbloated,or
slower,
fromtoomanyImports.
An
import
issimplythewayyou
giveJavathe
fullnameofaclass.
Q:
OK,
how
come
I
never
had
toimporttheStringclass?Or
System?
A:
Remember,yougetthe
java.langpackagesort
of∙pre-
Imported"forfree.Because
theclassesIn[ava.lanqareso
fundamental,you
don'thaveto
usethefullname.ThereIsonly
onejava.lang.Strlngclass,andone
[ava.tanq.System
class,andJava
darnwellknowswheretofind
them.
Q:
DoIhavetoputmyown
classesIntopackages?HowdoI
do
that?
Can
Idothat?
A..:
Intherealworld(which
youshould
trytoavoid),yes,you
wl/l
wanttoputyourclassesInto
packages.We'llgetintothatin
detailInchapter16.Fornow,we
won't
putourcodeexamplesIna
package.
gettoknowtheJavaAPI
N/ale~
if.
oS
tit.1e
Rosesarered
applesareri;e.
if
youdon't
im;on
You'lljusthave
t
c
otYpe
Youmust
tell
Java
youuse,
unle
thefull
nameofev
packag
A
s.sthatclass
isin
til'
ery
class
e.n
lmport
Sf
e
Java.lang
or
packageatthe
to
f
atementfortheclass
easyway.OtherWise
~~ ~our
sourceCodeisthe
name
oftheclass,
e:e~h
ave
to
type
thefUll
.ereyouuseit!
Onemoretime,intheunlikely
eventthatyoudon'talready
havethisdown:
youarehere.157
getting
to
knowtheAPI
"Goodtoknow
there's
anArrayListin
the
java.utilpackage.Butbymyself,
how
would
1
havefiguredthatout?"
-Julia,31,handmodel
Howto
play
withtheAPI
o
WhatclassesareInthelibrary?
e
UsetheHTMLAPIdocs
o..n-wo....z
PIal....
51:
l.O1
I"...0.
e..
+
~ ~t/Jlot &-Il.A (OMI Il'ftl.',O/_ IJ ~1
O ~· ~ Q.·'-
-
.......1_...
~,
E'IlIiIIlIPocuooC.,UU
JJlN
~
nIn
tlAlD
J"""'~
_USJl
.........
..-.
.........
~U Hi
&G!.~
Jav,,'"
2
P1IItlormStaodardEdlllon51)
......
-¥ ~,.,;,,:i
APISpedtblloD
.
.-
IoAClM_
'Nt-...Is'"
API__
(00""
b...,
Pbtl.....
S<a\.ooI
rod•..,
1,0
--
-
1-
-
Ila<dIIJIoIl
Nnlr!cI".!ffIU
N"1!rW1">"9'T"1
J8va2P18t1ormhcbgcs
P'Jl.wtdca
IIlc
d...
~ 1lC'CD""'~ l nc
...
~
.....
ANeJIChQ"""",
C9ntr.i
IIu.I.oPI<l
c~u.~tan
.,COl['IIamCC
"lib
b
~
","""l.
--
CmWMaD
at
Iht
daun
larClQlilt
DID~
arid
b
6CID:!lraCr=
/IW..nJ
...-.JnliIIct
1lOI1m>;n.
iIIlIIICUI
......u.ab:
_.et......
f«coInf___•
.
f'roo'Io tic"~ ~ d:l Ul:f for ttll:).ran.'.im t:w:r- tcII ~
~.
.
..
~ lnll>I",
JAVA
Onceyoufindaclass,howdo
youknowwhatItcando?
INANUTSHELL
Ii
CX:sJdopQuick
RI!jlf'l:llce
Twothingsyouwanttoknow:
o
BrowseaBook
e
O'REillY'
158
chapter
6
get
to
knowtheJavaAPI
I
JAVA
''?''!!!@I'
}twa
,utU,ClUnmcy
R,/JUJUId
Bj~ IN.ltU1lleeImalFaT1lat#lCun8lctO.IM,te:l1-~malf~o.mncyO.
J-.l8ItN~eum:lley(I.O:JtnlllCY'~
Date
This
d:I5:l
represents
dates
andlimes
2nd
leu
you...
∙ork
with
themin
~ ~em-ind~pen­
den!way,You
C:1n
createa
D8l&
by
specityina
thenumberofm1Diseconds(romthe
epoch(audf\is/11GMT.
J:>nw<y
181.
1970)
orWe
year.
month,date,and,oplional1)',the
hour.
m1nUle,
llrld
second.
Yo,..
are
5p<'cilied
asthe
number
of
fC"'lS
since1900,
If
you
calltheDaleconstruClorwilhno
"'BWDCfIlS.
theOIIe
ts
iniriJn:z...d
10
thecurrenttime
J11d
dJ'e.ThtInsuncerunhodsoftheclass
.110""
you
10
get
:lOdsetthe
\':l( i O ll ~
UJI"
andlimefields,
(0
compare
mid
"nd
umes,and
'0
convertdates
to
2nd
from
SIring
n:prcscnulio""
11:>
of
J'V>
1.1,
=)'
or
the
dalemetho<bbave
been
deprecated
in
fa\'Or
of
themethods
ofth
e
calendar
cl.....
PiUc
dass
Oila
iIIpltments
ctonUblt.
Coml*;tblt;SedllriilleI
II
Mil;
~strucl:lrs
IUbllc
Dm():
~leD~r.ct.l l e ):
,iiiIl1t
o.tt(SlJire
I);
,
lIUbIlcD
m..
lIllye
.v,ln
lmonlft,IIIlct.lf!):
,PliIIlclllWCiI1ltw,lnlllll:'l,liIldlle.lnlhn,inlt*l;
,pUllIlcDItIl(lr>Iye¥,lnl
/llMlII,lnlttaDl.lnllirs.
Int
mil,
tnt
sec):
II
Piijiiifj~S{l(
1rIer1t4df
(tj
~- J
~It
Itr(
e-t1llMl):
IdiIlt
will
MtTIIM(Ion&1tIIe):
7/JljibJ;
IiiSfiiiij
MilIiOili
public
boomn
aftal\lmJJ1lLIl8:t.,):
.II\iIllc
booIelI\
hhlr-aM.UliLDiIl'-);
1.1
publicIntc-..N1To11m.uDI.DJI'
~Irllat,}:
ll lIiI1JDiif~~~
1.1putIIlc
In!
_PANTo(ObjtCl0):
II
JIlIbIi:
j,jeth6ill
~0l;Id
1.1
pulIIlc
0lijtcI
doN(
I:
puliIic
b09Iear!.q.II(OijIlc:l
«II:
IdiIlcIIIl••1Ie.c1e():
PliIII~Sllitl(toStrlDiO;
.
II
~W
Pubic
lIe~
,llWIlC
irt
1I!tI!at1():
,
~ic
Int
,.0.,0:
,puliIicIII
ptHoan/):
,puliIlc
IntptMlllCIttI():
,
~~lnt ~ d();
,pWlc
Int,.S
aMI(J:
,pUblic
rt
1itI'IMIo..otfiit(1:
'~ltlnt"""l():
•
liibIlclll~clq,.lM(S1(IrcJ);
,pJlllc'/Old
utDat-r1fll
dlIIlI):
,
lIulill~
iOId
iittIilIrI('llllllOurl);
,
lQlillcvoIdMtMl~nlllllilwl8s):
,
~lc'lOliI ~ntllDllII);
youarehere)
159
usingtheJavaAPIdocumentation
e
UsetheHTMLAPIdocs
Javacomeswithafabuloussetofonline
docs
called,strangely,theJavaAPI.They'repartof
alargersetcalledtheJava
5
StandardEdition
Documentation(which,depending
on
what
dayoftheweekyoulook,Sunmayberefer-
ringtoas"Java
2
StandardEdition
5.0"),
and
youhavetodownloadthedocsseparately;
theydon'tcomeshrink-wrappedwiththeJava
5
download.Ifyouhave
a
high-speedinternet
connection,ortonsofpatience,youcanalso
browse
them
at
java.sun.com,Trustus.you
probablywanttheseonyourharddrive.
TheAPIdocsarethebestreferenceforget-
tingmoredetailsabouta
class
anditsmethods.
Let'ssayyouwerebrowsingthroughtherefer-
encebookandfounda
class
calledCalendar,
in
java.util,
Thebooktellsyoualittleaboutit,
enoughtoknowthatthisisindeedwhatyou
wanttouse,butyoustillneedtoknowmore
aboutthemethods.
Thereferencebook,forexample,tellsyou
whatthemethodstake,asarguments,andwhat
theyreturn.Look
at
ArrayList,forexample.
Inthereferencebook.you'llfindthemethod
index
Of'(},thatweused
in
theDotCom
class,
But
if
allyouknewisthatthereisamethod
calledindexOf()thattakesanobjectandre-
turnstheindex
(anint)
ofthat
object,
youstill
needtoknowonecrucialthing:whathappens
if
theobjectisnotintheArrayList?Looking
atthemethodsignaturealonewon'ttellyou
howthatworks,ButtheAPIdocs
will
(mostof
thetime,anyway).TheAPIdocstellyouthat
theindexOff)methodreturnsa-1iftheobject
parameterisnotintheArrayList.That'show
weknewwecould
use
itbothasawaytocheck
if
anobject
is
even
in
the
ArrayList,andtoget
itsindexatthesametime,
if
theobjectwas
there.ButwithouttheAPIdocs,
we
mighthave
thoughtthattheindexOf()methodwould
blowup
if
theobjectwasn'tintheArrayList.
boolNA.tdlM1.1(rp))eCt(PDcr.n...o.d..
c:'
e)
Appilrod'
>IJ
of
lbo
C~1S
In
the
<pcci1kd
Collccrlon
10
do:
<lid
0(
1IIlJ
!lSI.
In
lIlc
Older
dill.
dley
lite
teI1lmCd
by
lIlc
spcd{1ed
CollccOOt>',ItcralQT.
tloOoQl.u
.I44I.llf
hot.
.1..1:I4••
1
Co))lOt
iQa<)
Qt._tlds
P(III
1Jumj
allr>i
lIlc
d<ma!1J
in
!be
<pcd/ltd
Collcctloo!n1O
Ihi>
hst,
stuIing
4I1llC
<nccif1n1
nndrinn
160
chapter6
get
to
knowtheJavaAPI
publicstaticvoidprintAL(ArrayList<String>
al)(
pri.ntAL(a);
if(a
.Contains
("brO"
&.ad
d
("2.2");
»(
)
a.add(O"
I
zero").
a..
add(1",
,one"),.
a.remove(2);
CodeMagnets
Canyoureconstructthecodesnippetstomakea
working
Javaprogramthatproducestheoutput
listedbelow7
NOTE:
Todothisexercise,
you
need
a_.....
-oz-I
one
NEW
pieceofinfo-IfyoulookintheAPIfor
ArrayList,you'llfinda
second
addmethodthattakes
twoarguments:
.';;;~.jiI:"-
lIdd(lntIndex.Object
0)
Itletsyouspecifytothe
Arrayl.lst
where
toputtheobjectyou'readding.
publicstaticvoidmain(String[]
System.out.print(eleme.nt
+"");
)
Syst.em.out.println("");
(a.contains("three"»
a.add("fourn)i
importjava.
util.*;
printAL(a);
publicclassArrayListMagnet
for(Stringe1............-
~t:
dd(
3
"three")
i
a.a
J
printAL(a);
if(a.indaxOf("four")
!=
a.add(4,"4.2");
ArrayList<String>a
=
newArrayL
you
arehere.161
puzzle:
crossword
JavaOr~ss
t.
O
Howdoesthiscrosswordpuzzlehelpyoulearn
Java
7
Well,allof
the
words
are
Javarelated
(exceptoneredherring).
HInt:
WhenIndoubt,rememberArrayUst.
Aaoss
1.I
can'tbehave
6.Or,In
thecourtroom
7.
Where
It's
atbaby
9.Afork'sorigin
12.
Grow
anArrayUst
13.Wholly
massive
14.Valuecopy
16.Notanobject
17.
An
arrayonsteroids
19,Extent
21.19'scounterpart
22,
Spanishgeeksnacks(Note:This
has
nothingtodowithJava)
23.
For
lazy
fingers
24.Wherepackagesroam
MoreHints:
Down
2.WheretheJavaactionIs.
3.
Addressableunit
4.
2ndsmallest
5.
Fractionaldefault
8.
Ubrary'sgrandest
10.Must
be
lowdensity
11.
He'sInthere
somewhere
15.
As
if
16.dearthmethod
18.
What
shoppingandarrayshaveIncommon
20,
Ubraryacronym
21.Whatgoesaround
--1l6UI~IlWS.ill-l ·81
lSn,(IlJJv
l(U!ll..L'91
ilhll!W!!d'01
~
'to'
lSn.<eJJyl(U!ll..L
'E
lillqllP!JJahOS,lllllM'Z
uMO(J
162
chapter6
sJ~ladde
4SIUIldS'
1!hIl(
l/1oqeION
'U
IUillXd
s•
.(IlJJV'IZ
~w!Jd
UOWWO)'91
ISn'<WY'lUI'lJ.
'L
5a!liljJRh8'I
stoJ:lV
gettoknowtheJavaAPI
importjava.uti!.
*
i
I
publicclassArrayListMagnet
(II
I
publicstaticvoidmain
(Strinq[]arqs)
(I
I
ArrayList<Strinq>
a
=
newArrayList<String>()i
l
a.add(O,HzerOn)i
a.add(l,"one")i
a.add(2,"twO")i
a.add(3,"three")i
printAL(a)
i
if(a.contains("three"»
(
a.add("four")j
)
a.remove(2)
i
Ie
printAL(a)
i..
..
if(a.indexO£("four")
!=
4)
(
a.add(4,
"'4.2")i
}
printAL(a);..
if(a.contains("two"»
{
a.add("2.2")i
}
printAL(a);..
[
II'
r
I
publicstaticvoidprintAL(ArrayList<String>a1)
{r
for
(Strinqelement
:
al)
(
System.out.print(element
+"
")
;
)
ofll
System.out.println("
\\}
;
}
-
youarehere
~
163
puzzJe
answers
JavaOrctSS
answers
~
your
re::,~e
you.
OWN
setofclueslLookateach
word,
and
"y
to
writeyourownclues.
Try
makingthemeasier,orharder,or
Aaoss
moretechnicalthantheoneswehave.
I.
6.
Down
7.2
9.3.
12.
4.
13.
5.
14.8.
16.10.
17.
II.
19.
15.
21.
16.
2218.
23.
20.
24.
21.
164
chapter6
7
inheritanceand
polymorphism
BetterLivingin
Objectville
Wewereunderpaid,
overworkedcoders
'fill
we
triedthePolymorphismPlan.But
thanks
tothe
Plan,ourfutureis
bright.Yourscan
be
tool
Planyourprogramswiththefutureinmind.
Iftherewereawaytowrite
Javacodesuchthatyoucouldtakemorevacations,howmuchwouldItbe
worthtoyou?What
ifyoucouldwritecodethatsomeone
else
could
extend,
easily?
Andifyoucouldwritecode
thatwasflexible,
for
thosepeskylast-minutespecchanges,wouldthatbesomethingyou're
interestedIn?Thenthisisyourluckyday.ForJustthreeeasypaymentsof
60
minutestime,you
canhaveallthis.WhenyougetonthePolymorphismPlan,you'lllearnthe
5
stepstobetter
class
design,the
3
trickstopolymorphism,the
8
waystomakeflexiblecode,andifyouactnow-a
bonuslessononthe
4
tipsforexploitinginheritance.Don'tdelay,an
offer
thisgoodwillgive
youthedesignfreedomandprogrammingflexlbllltyyoudeserve.It'squick.it's
easy,andit's
availablenow.Starttoday,andwe'll
throwinanextralevelofabstractionl
this
isanewchapter
16i
thepowerofinheritance
ChairWars
(evisited...
Remember
way
back
in
chapter
2,
when
Larry
(procedural
guy)
andBrad
(00
guy)
were
vyingfor
the
Aeron
chair?
Let's
look
at
(J
few
pieces
of
that
story
to
review
the
basics
of~.
LARRY:You'vegotduplicatedcodelTherotateprocedure
is
inall
fourShapethings.It'sastupiddesign.Youhave
[0
maintainfourdifferentrotate"methods".Howcanthat
everbegood?
BRAD:Oh,I
guessyou
didn't
seethe
final
design.
Let
me
showyouhow
00inheritanceworks,
Larry.
Square
rotateQ
playSoundO
rotateO
playSoundQ
Amoeba
rotate()
playSoundO
o
Ilookedatwhatallfour
classeshaveI"
OOIMIIIO".
~
rhev're
Shapes,
and
they
allrotate
and
plavSound.SoIabstraGtedoutthe
COIMIMonfeaturesandput
thelllinto
a
ttewclasscalledShape.-:;,
shape
rotateQ
playSound()
superclass
Shape
rotale()
playSoondO
Youcanreadthisas,
uS
quareInheritsfromShape".
"CircleInheritsfrom
Shape",andsoon.Iremoved
(olale()andplaySound()fromtheothershapes,so
now
~here's
onlyonecopytomaintain.
Th&.~hape
classIscalledtheluperciasloftheotherfour
classes.TheotherfourarethelubelauesofShape.The
SUbclassesInheritthemethodsofthesuperclass.Inother
words.
If
theShapeclasshasthe(unci/anality,thenthe
subclassesautomaticallygatfhatsamefunctionality.
166
chapter
7
Square
Circle
Triangle
inheritanceand
polymorphism
WhatabouttheAIMoebarotate()?
o
Shape
rotateQ
playSoundO
superolau
"MOreautract)
~
LARRY:Wasn'tthatthewholeproblemhere-thattheamoebashape
hadacompletelydifferentrotateandplaySoundprocedure?
How
can
amoebadosomethingdifferent
if
it
inherits
irs
functionalityfromtheShape
class?
BRAD:
That'sthelaststep.
TheAmoebaclass
overrides
the
methodsoftheShapeclass.Thenatruntime,the
JVM
knows
exactlywhich
rota/eO
methodtorunwhensomeonetellsthe
Amoeba
to
rotate.
Square
lubclasses
"MOre
speolflol
\
Circle
Tilangle
Amoeba
rotateO
/I
amoeba-specific
/I
rotatecode
playSoundO
II
amoeba-speclfic
II
soundcode
'"
!<"
OverrldlnQlMethods
Howwouldyourepresentahousecatandatiger.Inan
inheritancestructure.Isadomesticcataspecialized
version
ofa
tiger?
Whichwouldbethesubclassand
whichwouldbethesuperclass?Orarethey
both
subclassestosomeotherclass?
HowwouldyoudesignanInheritancestructure?What
methods
wouldbeoverridden?
ThInk
aboutIt.
Before
youturnthepage.
you
arehere
~
167
I
way
inheritance
works
Ut1derstat1dit1QInheritance
Whenyoudesignwithinheritance,youputcommoncodein
aclass
andthentellothermorespecificclassesthatthe
common(moreabstract)classistheirsuperclass.Whenone
classinheritsfromanother,
thesubclass
inherits
frOID
the
superclass.
InJava,wesaythatthe
subclass
extends
thesuperclass.
An
inheritancerelationshipmeansthatthesubclassinherits
the
lDelDbers
ofthesuperclass,Whenwesay"membersof
aclass"
we
meantheinstancevariablesandmethods.
Forexample,
ifPantherMan
is
asubclassof
SuperHero,
the
PantherManclassautomaticallyinheritstheinstancevariables
andmethodscommontoallsuperheroesincluding
sui
t,
tights,specialPower,useSpecialPower()
and
soon.ButthePantherMan
subclasscanaddnew
:methodsandinstancevariables
ofitsown,andit
can
overridethe:methodsitinheritsfro:mthesuperc1ass
SuperHero.
OverrldfttQ
!Methods
~
I"sta"cevarIables
(state.attributed
lMethods
(behavIor)
PantherMan
useSpeclalPowerij
putOnSultO
SuperHero
sul1
lights
spec/alPower
useSpecialPower()
putOnSull()
/~
FriadEggMan
superclasa
(tHoreabstract)
~
FriedEggMandoesn'tneedanybehaviorthat'sunique,
sohedoesn'toverride
anymethods.Themethodsand
instancevariablesinSuperHeroaresufficient.
PanthenMan,though,hasspecificrequirementsforhissuit
andspecialpowers,so
useSpecialPower()and
putOnSui
t()
arebothoverriddeninthePantherMan
class.
Instancevariablesarenotoverridden
becausethey
don'tneedtobe.Theydon'tdefine
any
specialbehavior,soa
subclasscangivean
inheritedinstancevariableanyvalueit
chooses.
PantherMancanset
his
inherited
tights
(0
purple,whileFriedEw\1ansetshistowhite.
subclasses
(tHorespeolfle)
~
if
.lJ,v4'
:;.t"
t(
~
chapter7
inheritanceand
polymorphism
publicclassDoctor{
booleanworksAtHospita1i
voidtreatPatient()[
II
performacheckup
publicclassFamilyOoctorextendsDoctor{
booleanmakesHouseCallsi
voidgiveAdvice(}{
II
givehomespunadvice
publicclassSurgeonextendsDoctor(
voidtreatPatient()(
II
performsurgery
voidmakeIncision()(
II
makeincision(yikes!)
superclass
your
pencU
makesHouseCal1s
FamllyDoctor
glveAdvlce
0
CaneFamllyDoctordolreatPatient()?__
CanaFamllyDoctordornakelneisloru)?__
Howmanyinstancevariablesdoes
Surgeonhave7__
HowmanyInslancevariablesdoes
FamiryDoctorhave7__
HowmanymethodsdoesDoctorhave?__
HowmanymethodsdoesSurgeonhave?_
HowmanymethodsdoesFamilyDoctor
have7__
Addsonenew
Instancevariable
Addsonenewmethod
OMe
'"stattcevariable
ottetMethod
Doctor
treatPatient
0
worksAlHosptlal
Surgeon
subclasses
OvenidestheInherited
lrealPaUenlQmethodlreatPatlenl()
AddsonenewmethodmakelnclslonO
youarehere
~
169
Let"sdesig"theit1heritattcetree
for
att
Atti~al
sitltulatiot1
progralM
Imagineyou'reaskedtodesignasimulationprogramthat
letstheuserthrowabunchofdifferentanimalsintoan
environmenttoseewhathappens.Wedon'thavetocodethe
thingnow,we'remostlyinterestedinthedesign.
We've
beengivenalistof
some
oftheanimalsthat
will
be
intheprogram,
butnotall.Weknowthateachanimalwill
be
representedbyanobject,andthattheobjects
will
move
aroundintheenvironment,doingwhatever
it
isthateach
particulartypeisprogrammedtodo.
And
we
want
otherprogrammers
to
be
able
to
add
new
kinds
ofanimals
to
the
programatanytime.
Firstwehavetofigureoutthecommon,abstract
characteristicsthat
all
animalshave,andbuildthose
characteristics
intoaclassthatallanimalclassescanextend.
170
chapter7
o
Lookforobjectsthathavecommon
attributesandbehaviors.
WhatdothesesixtypeshaveIn
common?Thishelpsyoutoabstract
outbehaviors.(step2)
Howare
the~
typesrelated?This
helpsyoutodefine
theInheritance
treerelationships(step4-5)
Usi.,gi.,herita.,cetoavoid
duplicatit1Qcodeit1subclasses
Wehavefive
instancevariables:
pidure-
thefilenamerepresentingtheJPEGofthisanimal
food-
thetypeoffoodthisanimaleats,Rightnow,there
canbeonly
1:\'10
values:
meat
or
grass.
hunger-
an
intrepresentingthehungerleveloftheanimal.
It
changesdependingonwhen(andhowmuch)the
animaleats.
boundaries-
valuesrepresentingtheheightandwidthof
the'space'(forexample,640
x
480)thattheanimals
will
roamaroundin.
location>
theXandYcoordinatesforwheretheanimalis
in
thespace.
Wehavefour
methods:
makeNoUe
0-
behaviorforwhentheanimalissupposedto
makenoise.
eatO-
behaviorforwhentheanimalencountersits
preferredfoodSOUTee,
meat
or
grass.
skepO-
behaviorforwhentheanimalisconsideredasleep.
roam()-
behaviorforwhentheanimalisnoteatingor
sleeping(probablyjustwanderingaroundwaitingtobump
intoafoodsourceoraboundary).
LIon
HIppo
Inheritanceand
polymorphism
Designaclassthatrepresents
thecommonstateandbehavior.
The~
objectsareallanimals,so
we'll
makeacommonsuper-class
calledAnimal.
We'll
put
Inmethodsandinstance
variablesthatallanimalsmight
need.
Animal
picture
food
hunger
boundaries
location
makeNoiseO
eatO
sleept)
roamt)
Wolf
Dog
youarehere
~
171
designingforinheritance
Poallat1httalseat
the
saIMe
way?
Assumethatwe
all
agreeononething:theinstance
variables
will
workforaUAnimaltypes.Alionwill
havehis
own
valueforpicture,food(we'rethinking
meat),
hunger,boundaries,andlocation.Ahippo
will
havedifferent
values
forhisinstancevariables,
buthe'llstillhavethesamevariablesthattheother
Animaltypeshave.Samewithdog,tiger,andsoon.
Butwhatabout~h~~
Decide
if
asubclass
needsbehaviors(method
implementations)
thatarespecific
to
thatparticularsubclasstype.
Animal
Which'Methodsshouldwe
override?
lookingatth£Animalclass,
w£
decidethateatQand
makeNolseOshouldbeoverridden
by
theIndividualsubclasses.
Inthedog
community,barkingisan
important
part
ofour
cultural
identity.
We
haveauniquesound,
andwewant
thatdiversityto
berecognizedandrespected.
sleepf)
roamO
picture
food
hunger
boundaries
location
Doesalion
makethesamenoiseasadog?Does
a
cat
eatlike
ahippo?MaybeinyouTversion,but
inours,eatingandmakingnoiseareAnimal-type-
specific.We
can'tfigureouthowtocodethose
methods
in
sucha
way
thatthey'dworkfor
any
animal.
OK,
that'snottrue.Wecouldwritethe
rnakeNoise()method,forexample,sothatall
it
does
isplayasound
file
definedinaninstancevariable
for
thattype,butthat'snotveryspecialized.Some
animalsmightmakedifferentnoises
fordifferentsituations(like
one
foreating,andanotherwhen
bumpingintoanenemy,etc.)
So
justaswiththeAmoeba
overridingtheShapeclassrotateO
method,
to
getmoreamoeba-specific
(in
otherwords,
unique)
behavior,we'llhave
todo
thesameforourAnimalsubclasses.
172
chapter7
Inheritanceand
polymorphism
Looklt1Qformoreit1heritat1ce
opportut1itles
e
Theclasshierarchyisstartingtoshapeup.We
have
eachsubclassoverridethe
makeNoise()
and
eat()
methods,sothatthere'snomistakingaDog
barkfromaCatmeow(quiteinsultingto
both
parties).And
a
Hippowon'teatlikeaLion.
But
perhapsthere'smorewecando.Wehaveto
look
atthesubclassesofAnimal,andsee
if
CWo
ormorecanbegroupedtogether
in
someway,
andgivencodethat'scommontoonly
that
new
group.Wolf
andDoghavesimilarities.Sodo
Lion,Tiger,
andCat.
Lookformoreopportunitiestouse
abstraction,byfindingtwoormore
subclasses
thatmightneedcommon
behavior.
Welookatourclassesandsee
thatWolfandDogmighthavesome
behaviorIn
common,andthesamegoes
for
Lion,Tiger,
andCat.
Animal
picture
food
hunger
boundaries
location
Wolf
Dog
mekeNolseO
eatO
· ~ IIIII!IIl"'_ rl ma k e N o l se O
eatO
Hippo
makeNoiseO
eatO
Lion
youarehere)173
designing
forinheritance
mamO
Animal
sleept)
picture
food
hunger
boundaries
location
makeNolseO
6810
Cat
makeNolseO
eatO
mem()
Finishtheclasshierarchy
Sinceanimalsalreadyhaveanorganizational
hierarchy
(thewholekingdom,genus,phylum
thing),wecanuse
thelevelthatmakesthemost
sense
forclassdesign.We'llusethebiological
"families"toorganize
theanimalsbymakinga
Feline
class
and
a
Canineclass.
WedecidethatCaninescoulduseacommon
roomOmethod.because
theytendtomoveIn
packs.Wealso
seethatFelinescouldusea
commonraamOmethod,becausethertendto
avoidothersoftheirownkind.We'lletHippo
continue
touseItsInheritedroamOmethod-
thegenericoneIt
gds
fromAnimal.
Sowe'redonewiththe:deSign
fornow:
come
backtoItlaterInthechapter.
TIger
makeNolseO
eat()
makeNolseO
e.atO
Wolf
makeNolse()
eatO
makeNolseO
eatO
174chapter
7
inheritanceand
polymorphism
WhichtttethodIscalled?
TheWolfclasshasfourmethods.One
inheritedfromAnimal,oneinheritedfrom
Canine(whichisactually
an
overridden
versionofamethodinclassAnimal),and
twooverriddenintheWolfclass.When
youcreateaWolfobjectandassign
it
to
avariable,you
canusethedotoperator
onthatreferencevariabletoinvokeall
fourmethods.Butwhich
version
ofthose
methodsgetscalled?
Whenyoucallamethodonanobject
reference,you'recallingthemostspecific
version
ofthemethodforthatobjecttype.
In
otherwords,
thelowest
one
wins!
"Lowest"meaninglowestonthe
inheritancetree.Canineislowerthan
Animal,andWolfislowerthanCanine,
soinvokingamethodonareference
toaWolfobjectmeansthe
JVM
starts
lookingfirst
in
theWolfclass.
If
the
JVM
doesn'tfindaversionofthemethodin
theWolfclass,itstartswalkingbackup
theinheritancehierarchyuntil
it
findsa
match.
Canine
Anima'
Wolf
makeNolseO
eatO
sleepO
roarnr)
roamO
newWolf();
w.
sleep();
w.eat();
w
.makeNoise();
w.
roam()
i
Wolf
w
=
talls
t.he
v~ion
inWol.f
tails
t.he
versioninWol.f
talls-theversion
inAni...al
youarehere
~
175
practicedesigninganinheritancetree
suparclass
hMore
abstract)
~
~
L..:::..J
subelaases
I
~
(lttoretpeolflol'\.
~
Box,,"
~
InheritanceCIUlIDiagram
Sharpen
your
pencil
InherftanceTable
Class
Superclasses
Subclasses
Clothing
--
Boxers,Shirt
BoxersClothing
ShirtClothing
PeslgttiMQaMInherltaMcefree
'-..:I
l
~~
Drawan
inheritance
diagramhere.
Findtherelationshipsthatmakesense.Fill
In
thelast
two
columns
Chus
SuperclassesSubclasses
Musician
RockStar
Fan
Bass
Player
ConcertPianist
Hint:noteverythIngcanbeconnectedtosomethingelse.
Hint:you'reallowedto
add
toorchangethe
cl8SSes
listed.
therejltrer\l?
DUmb
~uesti9n.8
Q.:
YousaidthattheJVM
starts
walkingup
the
Inheritancetree,
starting
at
the
classtypeyouInvoked
themethod
on(like
the
Wolf
example
on
theprevious
pagel.
Butwhat
happensIftheJVMdoesn'teverfind
ill
match?
A.:
GoodquestionlButyoudon't
havetoworryaboutthat.Thecompiler
guarantees
thataparticularmethod
Iscallableforaspecificreference
type,
butItdoesn'tsay(orcare)fromwhich
class
thatmethodactuallycomesfrom
atruntime.WiththeWolfexample,the
compilerchecksforasleepf)
method,
butdoesn'tcarethatsleepOIsactually
definedIn(andInheritedfrom)class
Animal.Remember
thatIfaclass
Inherits
amethod,It
has
themethod.
Where
theinheritedmethodIsdefined
(In
otherwords,Inwhichsuperclass
It
Is
defined)makesnodifference
to
thecomplier.ButatruntIme,theJVM
will
alwayspick
therightone.And
the
rightonemeans,
the
most
specific
version
forthatparticularobject.
176
chapter7
Inheritanceand
polymorphism
UsittQIS...AattdHAS-A
What
if
wereverseittoBathroom
extendsTUb?Thatstilldoesn'twork.,
BathroomIS-ATubdoesn'twork.
TubandBathroom
are
related,but
notthroughinheritance.Tuband
BathroomarejoinedbyaHAS-A
relationship.Doesit
makesenseto
say
"BathroomHAS-ATUb"?
If
yes,
thenitmeansthatBathroomhasa
Tubinstancevariable.
In
otherwords,
Bathroomhasa
reference
toaTub,but
Bathroomdoesnot
extend1\lb
and
vice-versa.
Rememberthatwhenoneclass
inheritsfrom
another,wesaythatthe
subclassextendsthesuperclass.When
youwanttoknow
if
onethingshould
extendanother,applytheIS-A
test,
TriangleIS-AShape,yeah,thatworks.
CatIS-AFeline,
thatworkstoo.
SurgeonIS-ADoctor,stillgood.
Tub
extendsBathroom,sounds
reasonable.
UntilyO'uapply1MIS-A
test.
Toknow
if
you'vedesignedyourtypes
correctly,ask,"Does
it
makesenseto
saytype
X
IS-Atype
Y?"
If
itdoesn't,
youknowthere'ssomethingwrong
with
thedesign,soifweapplythe
IS-A
test,TubIS-ABathroomisdefinitely
false.
Doesitmakesenseto
say
aTubIS-ABathroom?Ora
Bathroom
IS-ATub?Wellitdoesn'tto
me.TherelationshipbetweenmyTub
andmyBathroomisHAS-A.Bathroom
HAS-ATub.That
meansBathroom
has
Q
Tubinstancevariable.
Bubbles
inlradius:
Inl
oolorAm~
Tub
Inl
size:
Bubblesb:
Bathroom
Tubbathtub;
SinklheSink;
BathroomHAS-ATubandTubHAS-ABubbles.
BulnobodyInheritsfrom(extends)anybodyelse.
youarehere
~
177
exploitingthepower
of
objects
Jutwait!There"s'More!
TheIS-Atestworks
anywhere
intheinheritancetree.
If
your
inheritancetreeiswell-designed,the
IS-A
testshouldmake
sensewhenyouask
any
subclass
if
itIS-A
any
of
i
IS
supertypes.
IfclassBextendsclassA,classBIS-AclassA.
Thisistrueanywhereintheinheritancetree.If
class
C
extendsclass
B,
class
C
passestheIS-A
testforbothBandA.
178
chapter7
CanineextendsAnimal
WolfextendsCanine
WolfextendsAnimal
CanineIS-AAnimal
WolfIS-ACanIne
WolfIS-AAnimal
Animal
makeNolseO
eatO
sleepO
roamO
Canine
roarnt)
Wolf
makeNolseO
eal()
Withaninheritancetreelikethe
oneshownhere,you're
always
allowedtosay"Wolfextends
Animal"or"Wolf
IS-A
Animal".
It
makesnodifference
if
Animal
isthesuperc1assofthesuperclass
ofWolf.Infact,aslongasAnimal
issomewhere
in
theinheritance
hierarchyaboveWolf,Wolf
IS-A
Animal
will
always
betrue.
The
structureoftheAnimal
inheritancetree
says
totheworld:
"Wolf
IS-A
Canine.soWolfcando
anythingaCaninecando.And
WolfIS-AAnimal,soWolfcando
anythinganAnimalcando."
It
makesnodifference
if
Wolf
overrides
someofthemethods
inAnimalorCanine.
As
faras
theworld(ofothercode)is
concerned,aWolfcandothose
fourmethods.
H(JlJ)
hedoesthem,
or
inwhichclass
they
1'e
overridden
makesnodifference.AWolfcan
makeNoise
O.
ea
to,
sleep(),and
roamObecauseaWolfextends
fromclassAnimal.
Howdoyouk"owifyotfvegot
yourhtherita"ceright?
There'sobviouslymoretoitthanwhatwe've
coveredsofar,
butwe'lllookatalotmore
00
issuesinthenextchapter(whereweeventually
refineandimproveonsomeofthedesignwork
we
didin
this
chapter).
Fornow.though,agoodguideline
is
tousethe
IS-A
test,
U
"XIS-A
Y"
makessense,bothclasses
(X
and
Y)
shouldprobablyliveinthesame
inheritancehierarchy.Chancesare,
they
have
thesameoroverlappingbehaviors.
Keepinmindthatthe
inheritanceIS-Arelationship
worksinonlyonedirectionl
Triangle
IS-A
Shapemakessense,soyoucan
haveTriangleextendShape.
But
thereverse-Shape
IS-A
Triangle-does
notmakesense,soShapeshouldnotextend
Triangle.Rememberthatthe
IS∙A
relationship
impliesthat
if
XIS-A
y.
then
Xcan
doanything
a
Y
cando(andpossiblymore).
Inheritance
andpolymorphism
Ilets
are
blUe..
't
true.
Roses
are
red,
v
0
thereverse
lsn
""ais-aShape,
SqU-d
r
d
laletS
are
ell.
beer.
Roses
are
re
I
v
t
01/
drinks
are
Ink
butnoe-
Beer
is-a
Dr,'"
t
shOWStheon
'f
MKeonet"a.Remember.\
QI(,
your
turr\e~S_A relatiOnshlP~ense,
way.nesSof
~
'S.A'(mustmaKe
'/..extend_s_'(I_------"..........
--~"..
......-
Sharpen
your
pencil------,
Putachecknexttotherelationshipsthat
makesense.
o
OvenextendsKItchen
o
GuitarextendsInstrument
o
PersonextendsEmployee
o
FerrariextendsEngIne
o
FriedEggextendsFood
o
BeagleextendsPet
o
ContainerextendsJar
o
MetalextendsTitanium
o
GratefulDeadextendsBand
o
BlondeextendsSmart
o
BeverageextendsMartini
HintapplytheIS-Atest
youarehere
~
179
whoinheritswhat
therelllreAl~
Dum
D
"<.,uesD9ns
Q:
SO
weseehowasubclassgets
to
In
herlt
asuperclass
method,but
whatIfthesuperclasswantstouse
thesubclassversionofthemethod1
A.:
A
superclasswon'tnecessarily
know
aboutanyofitssubclasses.
Youmightwriteaclassandmuch
latersomeoneelsecomesalongand
extends
it.
ButevenIfthesuperclass
creatordoesknowabout(andwants
touse)asubclassversionofamethod,
there'snosortof
reverse
or
backwards
inheritance.Thinkaboutit,children
Inheritfromparents,nottheotherway
around.
Q:
In
a
subclass,whatif
I
wantto
use
BOTHthe
superclassversionand
myoverridingsubclassversionofa
method?Inotherwords,
I
don'twant
tocompletely
rep/Dee
thesuperclass
version,
I
Justwanttoaddmorestuff
toIt.
A:voucandothis!AndIt'san
importantdesignfeature.Thinkof
the
word
"extends"
asmeaning,"1want
to
extend
thefunctionalityofthe
su
perclass"
publicvoidroamC)
super.roamC);
//my
own
roam
Youcandesignyoursuperclass
methodsinsuchawaythatthey
containmethodimplementations
that
willworkforanysubclass,even
thoughthesubclassesmaystillneed
to'append'morecode.Inyoursubclass
overridingmethod,youcancallthe
superclassversionusingthekeyword
super.
It's
likesaying,"firstgorunthe
superclassversion.thencomebackand
finishwith
my
owncode..,"
WhogetsthePorsche,whogetsthe
porcelah,?
(howtokt'owwhatasubclasscat'
Itt"erlt
frolM
ItssuperelassJ
Asubclassinheritsmembersofthe
superclass.
Membersincludeinstance
variables
andmethods,
although
laterin
thisbook
we'Dlookatotherinheritedmembers.A
superclass
can
choosewhether
or
not
it
wantsa
subclassto
inherit
aparticularmember
by
thelevelof
accesstheparticularmember
is
given.
Therearefouraccesslevelsthat
we'D
cover
in
thisbook.
Movingfrom
most
restrictivetoleast,the
fouraccess
levels
are:
privatedefaultprotectedpublic
180chapter7
Accesslevels
control
whoseeswhat,
andare
crucial
to
havingwell-designed,robustJavacode.Fornowwe'll
focusjustonpublic
andprivate.Therulesare
simple
for
those
two:
publicmembers
are
Inherited
--
private
membersare
~
Inherited
Whenasubclassinheritsamember,
it
is
as
if
the
subclassdefined
the
-memberitself.
IntheShape
example,Square
inherited
the
rotate()
and
playSound()
methods
and
totheoutside
world
(other
code)
the
Squareclasssimply
has
a
rotate()
and
playSound()
method.
The
members
ofa
classincludethe
variables
and
methodsdefinedintheclass
plusanything
inherited
fromasuperclass.
No-«:
get..
O\"C
ddails
aboutdc+alAltand
fl"ot.et.ud
in
'h4y-W-
I
b
(dcrl0't"cnVand.li'fcNli'J<
B.
Whendesigningwithinheritance,
areyou
usit1g
or
abusi"g?
Althoughsomeofthereasonsbehindtheseruleswon'tbe
revealed
untillaterin
this
book,fornow,simply
knowing
a
fewruleswill
helpyoubuildabetterinheritancedesign.
DO
useinheritancewhenoneclassisamorespecifictype
ofasuperclass.Example:WIllow
is
a
morespecifictypeof
Tree,
so
Willow
extends
Treemakessense.
DO
considerinheritancewhenyouhavebehavior
(implementedcode)thatshouldbesharedamong
multipleclassesofthesamegeneraltype.Example:
Square,Circle,andTriangle
all
needtorotateandplay
sound,soputtingthatfunctionality
in
asuperclassShape
mightmakesense,andmakesforeasiermaintenanceand
extensibility.Beaware,however,thatwhileinheritanceis
oneofthekeyfeaturesofobject-orientedprogramming,
it'snotnecessarilythebestwaytoachievebehaviorreuse.
It'll
getyoustarted,andoftenit'stherightdesignchoice,
butdesignpanerns
will
helpyouseeothermoresubtle
andflexibleoptions.!fyoudon'tknowaboutdesign
patterns,a
goodfollow-ontothisbookwouldbe
HeadFirst
DesignPatterns.
DONOT
useinheritancejustsothatyoucanreuse
codefromanotherclass,
if
therelationshipbetweenthe
superclassandsubclassviolateeitheroftheabovetwo
rules.Forexample,
imagineyouwrotespecialprinting
codeintheAlarmclassandnowyouneedprintingcode
inthePianoclass,soyouhavePianoextendAlarmsothat
Pianoinheritstheprintingcode.Thatmakesnosense!A
Pianois
rwt
amorespecifictypeofAlarm.
(So
theprinting
codeshouldbeinaPrinterclass,that
all
printableobjects
cantakeadvantage
ofviaaHAS-Arelationship.)
DONOT
useinheritance
if
thesubclassandsuperclass
donotpasstheIS-Atest,Alwaysaskyourself
if
thesubclass
IS-A
morespecifictypeofthesuperclass.Example:TeaIS-
ABeveragemakessense.BeverageIS-ATea
does
not.
Inheritanceand
polymorphism
•Asubclass
extends
asuperclass.
•AsubclassInheritsall
public
Instance
variablesandmethodsofthesuperclass,but
doesnotInheritthe
private
Instancevariables
andmethodsofthesuperdass,
•Inheritedmethods
can
beoverridden;instance
vartables
cannot
be
overridden(althoughthey
can
be
redefined
inthesubclass,butthat's
notthesamething,andthere'salmostnevera
needtodoit)
•
UsetheIS-A
test
to
verifythaiyour
inheritancehierarchyisvalid.IfX
extends
Y,
thenX
IS-A
Ymustmakesense.
•TherS-ArelationshipworksInonlyone
direction.A
Hippois
an
Animal.butnotall
Animals
areHippos.
•
Whenamethodisoverriddeninasubclass,
andthatmethodisInvokedonaninstanceof
thesubclass,theoverriddenversionofthe
method
is
called.
(Thelowestonewins.)
•IfclassBextendsA,andCextendsB,class
BIS-Aclass
A,
andclassCIS-Aclass
e,
and
classCalsoIS-AclassA.
youarehere)
181
exploitingthepowerofobjects
Sowhatdoesallthis
h1herita"cereallybuyyou?
Yougetalotof00mileagebydesigning
with
inheritance.Youcangetridofduplicate
codebyabstractingoutthebehaviorcommon
toagroupofclasses,andstickingthatcode
inasuperclass.That
way,
whenyouneedto
modifyit,
youhaveonlyoneplacetoupdate,
andthechange
ismagically
reflectedinallthe
classesthatinheritthatbehavior.Well,there's
nomagicinvolved,butitisprettysimple:
make
the
changeandcompiletheclass
again.
That'sit.Youdon'thavetotouchthe
subclasses
I
Jmtdeliverthenewly-ehangedsuperclass,and
all
classesthatextendit
will
automaticallyuse
thenewversion.
AJava
programisnothingbutapile
of
classes,
sothesubclassesdon'thavetoberecompiled
inordertousethenewversionofthe
superclass,Aslongasthesuperclassdoesn't
break
anythingforthesubclass,everything's
fine.(We'lldiscusswhattheword
'break'
meansinthiscontext,laterinthebook.For
now,thinkofitasmodifyingsomethingin
thesuperclass
thatthesubclassisdepending
on,likeaparticularmethod'sargumentsor
returntype,ormethodname,etc.)
182chapter7
(i)
Youavoidduplicate
code.
Putcommoncodeinoneplace,andlet
thesubclassesinheritthatcodefroma
superclass.Whenyouwanttochange
that
behavior,youhavetomodifyitinonly
oneplace,andeverybodyelse
(i.e,
allthe
subclasses)seethechange.
•Youdefineacommon
protocolforagroupof
classes.
lt1heritat1celetsyouguarat1teethat
allclassesgroupedut1deracertaht
supertypehavealltheIttethodsthat
thesupertypehas:
I.,other
words.you
defl"~
aoOttUMO"
protocolfor
a
setofclassesrelatedthroughI"herita"ce,
Whenyoudefinemethodsinasuperclass,thatcan
be
inheritedbysubclasses,you'reannouncingakindof
protocoltoothercodethat
says,
"All
my
subtypes
(i.e,
subclasses)candothesethings,
with
thesemethods
thatlooklikethis.;"
Inotherwords,youestablisha
contract:
ClassAnimalestablishesacommonprotocolforall
Animalsubtypes:
Anlm.1
makeNolse()
eatO
sleepO
roamO
Andremember,whenwe
say
any
AlIima~
wemean
Animal
andanyclassthatextends
from
Animal
Which
againmeans,
anyclass
tha:
hasAnimal
SO"TTIeWhere
aboueit
intheinheritance
hierarchy,
Butwe'renotevenatthereallycoolpartyet,because
wesavedthe
best--polymarphism--for
last
Whenyoudefineasupertypeforagroupofclasses,
anysubclass
0/
thatsupmypecanbesubstitutedwhere
the
supertype
is
expected.
Say,what?
Don'tworry.we'renowhere
neardoneexplainingit
Twopagesfromnow,you'llbeanexpert
"Whenwesay"allthemethods'
we
mean"alilhe
Inheritable
methods',which
fornowactuallymeans,"allthe
public
methods',althoughlaterwe'llrefinethat
defini\Jonabitmore.
Inheritanceandpolymorphism
AndIcarebecause•••
Becauseyougettotakeadvantageof
polymorphism.
Whichmatterstome
because•••
Becauseyougettorefertoasubclass
objectusingareferencedeclaredasthe
supertype.
Andthatmeanstome•••
Yougettowritereallyflexiblecode.
Codethat'scleaner(moreefficient,
simpler).Codethat's
notjusteasierto
develop,
butalsomuch,mucheasierto
extend,
inwaysyouneverimaginedat
thetimeyouoriginallywroteyourcode.
Thatmeans
youcantakethattropical
vacation
whileyourco-workersupdate
theprogram,andyourco-workersmight
notevenneedyoursourcecode.
You'llsee
howitworksonthenextpage,
We
don'tknowaboutyou,but
personally,wefindthewhole
tropicalvacationthing
particuIarlymotivating.
youarehere.
183
the
way
polymorphismworks
Toseehowpolymorphism
works,wehavetostepback
andlookatthewaywe
normallydeclareareference
andcreateanobject...
The3stepsofobject
declarationandassignment
12
~3~
DogmyDog
=
newDog();
O
Declareareference
variable
Dog
myDoq
=
newDog();
TellstheJVMtoallocatespacefora
referencevariable.Thereferencevariable
Is,
forever,oftypeDog.
In
otherwords,
aremotecontrolthathasbuttonsto
control
a
Dog,butnotaCator
a
Button
or
a
Socket.
Dog
G
Createanobject
DogmyDoq
=
newDog();
Tellsthe
JVM
toallocatespacefor
anewDogobjectonthegarbage
collectibleheap.
Dogobject
~
Linktheobject
~
andthereference
DogmyDog
=
new
Dog();
AssignsthenewDogtothe
refer-
encevariablemyDog.lnotherwords,
programtheremotecontrol.
Dogobject
184chapter7
Dog
inheritanceand
polymorphism
Theimportantpointisthatthe
referencetypeANDtheobject
typeare
the
same.
Inthisexample,bothareDog.
Butwithpolymorphism,the
referenceandtheobjectcan
bedifferent.
Animal
myDog-
new
~
();
~/'
nest:
two
.i~e
NOT
the
sd",e
t)'Pe.
ne
re-ftyel'luI/ariable
t)'Ptisdetlarta
as
APli...aI,
b~t
thtobjtt+'is
tytaud
asPltw
D~O.
youarehere
~
185
polymorphismInaction
Withpolymorphism,thereference
typecanbeasuperclassofthe
actualobjecttype.
Whenyoudeclareareferencevariable,
any
objectthatpassestheIS-Atestforthe
declaredtype
ofthereferencevariable
canbeassignedtothatreference.In
otherwords,anythingthat
extends
the
declaredreferencevariabletypecan
be
assigned
tothereference
variable.
Thislets
you
do
thing!
likemake
polyrruwphic
arrays.
animals
[0]
=
newDog();
animals
[1]
=
new
cat0;
Blot.
look
",hdt.
'fOU
~d.
to
do...
~O"
Un
fvl:.
A
NY
animals
[2)
=
newWolf();
<-
s"bclass
of
A"i...al
i..
tnt
A..
i1'fl41
a.......a'f!
animals
[3)
=
newHippo();
186
chapter7
Butwait!There'smore!
Youcanhavepolymorphic
argumentsandretu!!,types.
If
youcandeclareareferencevariable
ofasuperrype,say,Animal,
andassigna
subclassobjectto
it,
say,
Dog,thinkofhow
thatmightworkwhenthereferenceisan
argumenttoamethod...
class
Vet{
Inheritanceandpolymorphism
publicvoidqiveShot(Animala)
II
do
horriblethings
to
theAnimalat
//theotherendofthe'a'parameter
a.ma.keNoise();
}
}
class
Petowner
publicvoidstart()
Vetv
=
newVetO;
Dog
d
=
new
Dog()i
~
Hippo
h
=
new
Hippo();
~
v.
giveShot(d);
~
D'1's
"",ktNoiUO--1Ai\S
)
)
v.
giveShot(h);
(
Itippo'sOr\dkeNoiseO
l"1AN;
you
arehere)187
exploitingthepowerof
polymorphism
NOWIgetitlIfIwrite
mycodeusingpolymorphicarguments,
where.
r
declarethemethodparameterasa
super-classtype,
r
CM
passinanysubclassobject
at
runtime.Cool.Becausethatalsomeans
r
canwritemy
code,goonvacation,andsomeoneelsecanaddnew
subclasstypesto
theprogramandmymethodswill
still
work...(theonlydownsideisrmjustmaking
life
easierforthatidiotJim).
WIthpolytttorphlSttt,youcaMwritecodethatdoutt't
have
tochattgewhe..
you
'tttroduce..
ew
subclass
typesI..to
the
progratlt.
RememberthatVetclass?
If
youwritethatVetclassusing
argumentsdeclaredastype
Animal;
yourcodecanhandleany
Animal
subclass.
Thatmeans
if
otherswanttotakeadvantageof
yourVetclass.
all
theyhavetodo
is
makesure
their
newAnimal
types
extendclassAnimal.TheVetmethodswillstillwork,even
thoughtheVetclasswaswrittenwithoutanyknowledgeofthe
newAnimalsubtypestheVetwillbeworkingon.
Whyispolymorphismguaranteedtoworkthisway?WhyIs
it
alwayssafetoassumethatany
subclass
type
will
havethe
methodsyouthinkyou'recallingonthe
suoerclass
type(the
superclassreferencetypeyou'reusing
thedotoperatoron)?
18a
chapter
7
:the
re
l
ar
H?
0
Diimo
~uesti9n8
Q:
Arethereanypracticallimits
on
thelevelsofsubclassing?How
deepcanyougo?
A.:
IfyoulookintheJavaAPI,
you'llsee
thatmostinheritance
hierarchiesarewide
butnotdeep.
Mostarenomorethanoneor
two
levelsdeep,althoughthereare
exceptions(especiallyintheGUI
classes).You'llcometorealizethat
it
usuallymakesmoresensetokeep
yourinheritancetreesshallow,but
thereisn'tahardlimit(well,notone
thatyou'deverruninto).
Q:
Hey,Ijustthoughtof
something...ifyou
don'thave
Kcesstothesourcecodeforaclass,
but
youwanttochangethewaya
methodofthatclassworks,could
JOuusesubclassingtodo
that?To
extendthe"bad"classandoverride
the
methodwithyourownbetter
code?
A.:
Yep.That'sonecoolfeature
of
00,andsometimesitsavesyou
fromhavingtorewritetheclass
fromscratch,ortrack
downthe
programmerwhohidthesourcecode.
Q:
Canyouextend
any
class?Or
isitlikeclassmemberswhereif
the
classisprivateyoucan'tinheritit...
A.:
There'snosuchthingasa
privateclass,exceptinaveryspecial
casecalledan
inner
class,thatwe
haven'tlookedatyet.Butthere
are
threethingsthatcanpreventaclass
frombeingsubclassed.
Thefirstisaccesscontrol.Even
though
aclass
can't
bemarkedprivate,a
class
can
benon-public(whatyou
get
ifyoudon'tdeclaretheclassas
p
ublic).Anon-publicclasscanbe
subclassedonlyby
classesinthe
samepackageastheclass.
Classesin
adifferentpackage
won'tbeableto
subclass(oreven
use,
forthatmatter)
thenon-publicclass.
Thesecond
thingthatstopsaclass
frombeingsubclassedisthekeyword
modifier
final.Afinalclassmeans
thatit'stheendoftheinheritance
line.Nobody,ever,canextendafinal
class.
Thethirdissueis
thatifaclasshas
onlypri
va
te
constructors(we'll
lookatconstructorsinchapter9),it
can'tbesubclassed.
inheritanceandpolymorphism
Q:
Whywouldyoueverwantto
makeafinalclass?What
advantage
wouldtherebeinpreventingaclass
frombeingsubclassed?
A:
Typically,youwon'tmakeyour
classesfinal.Butifyouneedsecurity
-thesecurity
ofknowingthatthe
methodswillalways
worktheway
thatyouwrotethem(becausethey
can'tbeoverridden),afinalclass
willgiveyouthat.A
lotofclassesin
theJavaAPIarefinalfor
thatreason.
TheStringclass,forexample,isfinal
because,well,imaginethehavoc
if
somebodycamealongandchanged
thewayStringsbehave!
Q:
Canyoumakea
method
final,
withoutmaking
thewhole
class
final?
A.:
Ifyouwanttoprotectaspecific
methodfrombeingoverridden,mark
the
method
withthefinalmodifier.
Markthewhole
class
asfinalifyou
wanttoguaranteethat
none
ofthe
methodsin
thatclasswilleverbe
overridden.
youareherer189
Keepl.,gtheco"tract:rulesforoverriding
Appliance
booleanbJmOnO
booleanbJmOffO
Toaster
boolean
tumOn(~lleveD
I
Argumentsmustbethesame,andreturn
typesmustbecompatible.
WhenyouoverrideamethodfromasupercIass,you'reagreeingto
fulfill
thecontract.Thecontractthatsays.forexample,
~I
takeno
argumentsandIreturnaboolean."Inotherwords,thearguments
andreturntypesofyouroverridingmethodmustlook
to
theoutside
world
exactly
liketheoverriddenmethodinthesuperclass.
Themethods
are
thecontract.
If
polymorphismisgoing
to
work.theToaster'sversionofthe
overriddenmethodfromAppliancehastoworkatruntime.
Remember.thecompilerlooksatthereferencetypetodecide
whetheryoucan
call
aparticularmethodonthatreference.Wilh
anAppliance
referencetoaToaster,thecompilercaresonly
if
class
Appliance
hasthemethodyou'reinvokingonanAppliancereference.
Butatruntime,
thejVMlooksnotatthe
reference
type(Appliance)but
attheactual
Toaster
objectontheheap.So
if
thecompilerhasalready
~
approved
themethodcall,theonly
way
itcanworkis
if
theoverriding
"This
\~
1'./01
6"
methodhasthesameargumentsandreturntypes.Otherwise.
'1t:Y""'\dt~
someone
with
anAppliancereferencewillcallturnOn
0
asano-
o.
h6e\)Ie
argmethod,eventhoughthere'saversioninToasterthattakesan
ta"\:.
t.
b~"
61\
int.Whichoneiscalledatruntime?TheoneinAppliance.Inother
~\WI'.~~
....
e-t.n06..
words,
the
turnOn{int
level)
m.etJwd
in
Toaster
is
notan
override.'
O~~I
ThIs
j!
.t,i:.ua/ly
.a
Je5d1
overLOADb∙
i
.L
olle"rRIDE.
I""l;
"()l:.
an
Thecontractofsuperclassdefineshowothercodecanuseamethod.
Whateverthesuperclasstakesasanargument.thesubclassover-
ridingthemethodmustusethatsameargument.Andwhateverthe
superclassdeclaresasaretumtype.theoverridingmethodmustde-
clareeitherthesametype.orasubclasstype.Remember,asubclass
objectisguaranteedtobeabletodoanything
itssuperclassdeclares.
soiI'ssafetoretumasubclasswherethesuperclassIsexpected.
•Themethodcan'tbelessaccessible.
Thatmeanstheaccesslevelmustbethesame,orfriendlier.That
meansyoucan't,forexample,overrideapublicmethodandmake
It
private.Whatashockthatwouldbetothecodeinvokingwhat
It
thinks
(atcompiletime)isapublicmethod.Ifsuddenlyatruntime
theJVMslammedthedoorshutbecausetheoverridingversion
calledatruntimeIsprlvatel
Sofarwe'veleamedabouttwo
accesslevels:privateandpublic.
TheothertwoareInthedeploymentchapter(ReleaseyourCode)
andappendixB.There'salsoanotherruleaboutoverridingrelated
toexceptionhandling,butwe'llwaltuntilthechapteronexceptions
(RiskyBehavior)
to
coverthaI.
Appliance
pUblicbooleantumOnO
publicbooleantumOnO
Toaster
privatabooleanbJmOnO
\
190
chapter7
Overloadingatttethod
~
Methodoverloadingisnothingmorethanhaving
two
methodswiththesamenamebutdifferent
argumentlists.Period.There'snopolymorphism
involvedwithoverloadedmethods!
Overloadingletsyoumakemultipleversions
ofamethod,withdifferentargumentlists,for
conveniencetothecallers.Forexample,ifyou
havea
methodthattakesonlyanint,thecalling
codehastoconvert,say,adoubleintoanint
beforecallingyourmethod.Butifyouoverloaded
themethodwithanotherversionthattakesa
double,thenyou'vemadethingseasierforthe
caller.You'llseemoreofthiswhenwelookinto
constructorsintheobjectlifecyc1echapter.
Sincean
overloadingmethodisn'ttryingto
fulfill
thepolymorphismcontractdefinedbyits
superc1ass,
overloadedmethodshavemuchmore
flexibility.
•Thereturntypescanbe
different.
You'refreetochangethereturntypesin
overloadedmethods,aslongastheargumentlists
aredifferent.
•Youcan'tchangeONLYthe
returntype.
Ifonlythereturntypeisdifferent,it'snota
valid
overload-the
compilerwillassume
you'retryingto
override
themethod.Andeven
that
won'tbelegalunlessthereturntypeis
asubtypeofthereturntypedeclaredinthe
superclass.Tooverloadamethod,youMUST
changetheargumentlist,althoughyou
can
changethereturntypetoanything.
•Youcanvarytheaccess
levelsinanydirection.
You'refreetooverloadamethodwithamethod
that'smorerestrictive.Itdoesn'tmatter,sincethe
newmethodisn'tobligatedtofulfillthecontractof
theoverloadedmethod.
inheritanceandpolymorphism
Anoverloadedmethod
is
just
adii±erentmethodthat
happenstohavethesane
methodname,Ithas
nothing
todowithinheritanceand
pol)'Illorphism.Anoverloaded
method
is
NoT
thesaneas
an
overriddenmethod.
Legalexamplesofmethod
overloading:
publicclassOverloads
StringuniqueID;
publicintaddNums(inta,intb)(
returna
+
b;
publicdoubleaddNums(doublea,doubleb)(
returna
+
b;
publicvoidsetUniqueID(StringtheID)(
II
lotsofvalidationcode,andthen:
uniqueID
=
theID;
publicvoidsetUniqueID(intssNumber)
StringnumString
=""
+
ssNumber;
setUniqueID{numString);
youarehere
~
191
exercise:MixedMessages
theprograttt:
Mix~d
MessagES
a
~ 6i~56
b
~
Si11
a
~
5i65
A
shortJavaprogramislistedbelow.Oneblockof
theprogramismissing!Yourchallengeistomatch
thecandidateblockofcode(ontheleft),withthe
outputthat
YOU'd
see
iftheblockwereInserted.
Notall
thelinesofoutputwIllbeused,andsomeof
thelines
of
outputmightbeusedmorethanonce.
Drawlinesconnecting
the
candidate
blocksof
codewiththeirmatchingcommand-lineoutput.
class
A{
int
ivar;;
7;
voidml()(
System.out.print("A'S
mIt");
class
C
extends
B{
void
m3(){
system.out.print(UC's
nU,
"+(ivar
+
6»;
[I
args){
cattdldatecode
I
~
goeshere
(threeIIttes)
'----------
public
classMixed2{
publicstaticvoidmain(String
A
a""
new
A();
Bb;;
new
B();
C
c
=
new
e();
Aa2
=
newC();
}
void
m3()(
System.out.print("A's
m3,
U);
}
void
m2(){
System.out.print("A'S
m2,");
classBextendsA{
voidml(I(
System.out.print(UB'Sml,
U);
}
}
}
code
b.ml();
}
output:
candidates:
c.m2();
a.m3();
A's
ml,
A's
m2,
C's
m3,6
c.ml();
B's
ml,
A's
m2,
A's
m3,
}
c.m2();
A's
ml,
B's
rn2,
A's
m3,
c.m3();
B's
ml,
A's
m2,
C's
m3,
13
a.ml()i
}
B's
ml,
m2
t
m3,
b.rn2();
C'sA's
c.m3();
B's
m1,
A's
rn2,
C's
m3,
6
a2.ml();}
A's
m1,
A's
rn2,
C's
mJ,
13
a2.m2()
i
a2.m3();
192
chapter7
inheritanceandpolymorphism
BE
the
Ct»mril
er
"Which
of
the
A-B
pai.rS
ofmethodslistedon
the
right,
if
inserted
into
the
classesontheleft.wouldcompile
and
produce
the
output
shown?
(TheA
ltIethod
inSerted
into
class
Monster,
the
B
JIlethodinsertedintoclass
VlUtlpil'e.)
publicclassMonsterTestDrive{
publicstaticvoidmaio(String
(I
args){
Monster(Jrna
=
newMonster(3J:
ma[OInewVampire();
marl)newDragon():
ma[2JnewMonster():
for(iot
x
=
0:
x
<
3;
X++){
ma[xJ.frighten(x);
1
e
booleanfrighten(intd){
System.out.println("arrrgh
U);
returntrue;
}
booleanfrighten(intx)
System.out.println("&bite?");
returnfalse;
}
}
}
}
2
e
booleanfrighten(int
x){
System.out.println(Uarrrgh");
returntrue;
classMonster{
}
iotfrighten(intf){
4)
System.out.println(Uabite?");
return
1:
}
}
classVampireextendsMonster(
3
e
booleanfrighten(int
x){
System.out.println("arrrgh"):
returnfalse;
}
classDragonextendsMonster{
booleanfrighten(intdegree)
System.out.println("breathfire");
}
booleanscare(int
x){
System.out.println("abite?"):
returntrue;
}
booleanfrighten(byte
b){
o
System.out.println("abite?H);
returntrue;
returntrue;
}
4
e
booleanfrighten(int
z){
System.out.println("arrrgh")i
returntrue;
}
youarehere
~
193
puzzle:PoolPuzzle
Your
Job
istotakecodesnippetsfromthepoolandplacetheminto
theblanklinesInthecode.Youmayusethesamesnippetmore
thanonce,andyoumight
notneedtouseallthesnippets.Your
goal
Istomakeasetofclassesthat
will
compileandruntogether
asaprogram.Don'tbefooled-thisone'sharderthanItlooks.
PoolPuzzle
publicclass
Rowboat{
publicrowTheBoat(){
Syatem.out.print(nstrokenatashaW)i
publicclassTestBoats{
_________main(String(
I
args){
______bI
=
new
Boat();
Rowboat_
}
publicclass
privateint_
____void__
length::len;
}
publicintgetLength(){
)
{
Sailboatb2
=
new();
newRowboat();
b2.setLength(32);
bl.()
i
b3.
()i
___.move();
}
}
publicmove(){
publicclassBoat{
public(){
System.out.print(
u");
System.ou
t.
print("
H);
}
}
}
}
OUTPUT:
driftdrifthoistsail
194
chapter
7
code
catldldates:
inheritanceandpolymorphism
Set1willwork.
Set2willnotcompilebecauseofVampire'sretum
type
(Int).
TheVampire'sfrightenOmethod
(B)
isnotalegal
overrideOR
overload
of
Monster'sfrightenOmethod.
ChangingONLYtheretum
type
Is
notenough
tomakeavalidoverload,andsinceanintisnot
compatiblewitha
boolean.themethodisnotavalid
override.
(Remember,IfyouchangeONLYtheretum
type,
it
must
be
to
aretumtypethatIscompatible
withthesuperclassversion'sretum
type,
andthen
ifs
anoverride.
Sets
3
and
4will
compile,
but
produce:
arrrqh
breathfire
arrrgh
Remember,classVampiredidnotoverrideclass
Monster's
frightenOmethod.(ThefrightenOmethod
in
Vampire'sset4takesabyte,
not
an
lnr.)
Mixed
MessagES
B'sml,
B'sml,
A'8ml,
A's
m2,
C's
m3,
6
A's
mz,
A'9m3,
B'B
m2,
A's
m3,
A's
mz,
C'snU,
13
C's
m2,
A's
m3,
A's
11\2,
C's
m3,
6
A'S
m2,
e's
m3,
13
youarehere
~
195
puzzle
answers
•
pUblicclassRowboatextendsBoat
publicvoidrowTheBoat(){
System.out.print("strokenatasha")1
publicclassBoat{
privateintlength
publicvoidsetLength(intlen){
length
=
lenl
publicintgetLength()
returnlength1
pub.l.Lcvoidmove()
System.out.print("drift")1
publicclassTestBoats{
public
staticvoidmain(String[largs){
Boatbl
=
newBoat()l
Sailboatb2
=
newSailboat()1
Rowboatb3
=
newRowboat()1
b2.setLength(32)1
bl.mOVe()1
b3.mOVe()1
b2.move()1
pubLi.cclassSailboatextendsBoat{
publicvoid
mover
i{
System.out.print("hoistsail••)1
196
chapter7
OUTPUT:
driftdrifthoistsail
this is a new chapter
197
8 interfaces and abstract classes
Inheritance is just the beginning. 4OEXPLOITPOLYMORPHISMWENEEDINTERFACES
ANDNOTTHE'5)KIND7ENEEDTOGOBEYONDSIMPLEINHERITANCETOALEVELOFFLEXIBILITYAND
EXTENSIBILITYYOUCANGETONLYBYDESIGNINGANDCODINGTOINTERFACESPECIFICATIONS3OMEOFTHE
COOLESTPARTSOF*AVAWOULDNTEVENBEPOSSIBLEWITHOUTINTERFACESSOEVENIFYOUDONTDESIGN
WITHTHEMYOURSELFYOUSTILLHAVETOUSETHEM"UTYOULLWANTTODESIGNWITHTHEM9OULLNEED
TODESIGNWITHTHEM9OULLW
ONDERHOWYOUEVERLIVEDWITHOUTTHEM7HATSANINTERFACE)TS
AABSTRACTCLASS7HATSANABSTRACTCLASS)TSACLASSTHATCANTBEINSTANTIATED7HATSTHAT
GOODFOR9OULLSEEINJUSTAFEWMOMENTS"UTIFYOUTHINKABOUTTHEENDOFTHELASTCHAPTER
ANDHOWWEUSEDPOLYMORPHICARGUMENTSSOTHATASINGLE6ETMETHODCOULDTAKE!NIMAL
SUBCLASSESOFALLTYPESWELLTHATWASJUSTSCRATCHINGTHESURFACE)NTERFACESARETHEPOLYIN
POLYMORPHISM4HEA
BINABSTRACT4HECAFFEINEIN*AVA
Serious Polymorphism
198
chapter 8
Animal
Feline
roam()
Canine
size
picture
food
prey
Lion
size
picture
food
prey
Tiger
size
picture
food
prey
Cat
size
picture
food
prey
Wolf
size
picture
food
prey
Dog
size
picture
food
prey
Hippo
makeNoise()
eat()
roam()
makeNoise()
eat()
makeNoise()
eat()
makeNoise()
eat()
makeNoise()
eat()
makeNoise()
eat()
picture
food
hunger
boundaries
location
makeNoise()
eat()
sleep()
roam()
designing with inheritance Did we forget about something when we designed this?
4HECLASSSTRUCTUREISNTTOOBAD7EVEDESIGNED
ITSOTHATDUPLICATECODEISKEPTTOAMINIMUM
ANDWEVEOVERRIDDENTHEMETHODSTHATWETHINK
SHOULDHAVESUBCLASSSPECIlCIMPLEMENTATIONS
7EVEMADEITNICEANDmEXIBLEFROMA
POLYMORPHICPERSPECTIVEBECAUSEWECANDESIGN
!NIMALUSINGPROGRAMSWITH!NIMALARGUMENTS
ANDARRAYDECLARATIONSSOTHATANY!NIMAL
SUBTYPEINCLUDINGTHOSEWENEVERIMAGINEDATTHE
TIMEWEWROTEOURCODECANBEPASSEDINANDUSED
ATRUNTIME7EVEPUTTHECOMMONPROTOCOLFOR
ALL!NIMALSTHEFOURMETHODSTHATWEWANTTHE
WORLDTOKNOWALL!NIMALSHAVEINTHE!NIMAL
SUPERCLASSANDWEREREADYTOSTARTMAKINGNEW
,IONSAND4IGERSAND(IPPOS
interfaces and polymorphism
you are here4
199
Wolf aWolf = new Wolf();
We know we can say:
A Wolf reference to a Wolf object.
Wolf
aWolf
W
o
l
f
o
b
j
e
c
t
These two are the same type. Animal aHippo = new Hippo();
And we know we can say:
Animal reference to a Hippo object.
Animal
aHippo
H
i
p
p
o
o
b
j
e
c
t
These two are NOT the same type. Animal anim = new Animal();
But here’s where it gets weird:
Animal reference to an Animal object.
Animal
anim
A
n
i
m
a
l
o
b
j
e
c
t
These two are the same type, but...
what the heck does an Animal object look like?
?
200
chapter 8
scary objects What does a new Animal()
object look like?
when objects go bad )TMAKESSENSETOCREATEA7OLFOBJECTORA(IPPO
OBJECTORA4IGEROBJECTBUTWHATEXACTLYISAN
!NIMALOBJECT7HATSHAPEISIT7HATCOLORSIZE
NUMBEROFLEGS
4RYINGTOCREATEANOBJECTOFTYPE!NIMALISLIKEA
NIGHTMARE3TAR4REK©TRANSPORTERACCIDENT4HE
ONEWHERESOMEWHEREINTHEBEAMMEUPPROCESS
SOMETHINGBADHAPPENEDTOTHEBUFFER
"UTHOWDOWEDEALWITHTHIS7ENEEDAN!NIMAL
CLASSFORINHERITANCEANDPOLYMORPHISM"UTWE
WANTPROGRAMMERSTOINSTANTIATEONLYTHELESS
ABSTRACTSUBCLASSESOFCLASS!NIMALNOT!NIMALITSELF
7EWANT4IGEROBJECTSAND,IONOBJECTSNOT!NIMAL
OBJECTS
&ORTUNATELYTHERESASIMPLEWAYTOPREVENTACLASS
FROMEVERBEINGINSTANTIATED)NOTHERWORDSTOSTOP
ANYONEFROMSAYINGhnewvONTHATTYPE"YMARKING
THECLASSASabstractTHECOMPILERWILLSTOPANY
CODEANYWHEREFROMEVERCREATINGANINSTANCEOF
THATTYPE
9OUCANSTILLUSETHATABSTRACTTYPEASAREFERENCETYPE
)NFACTTHATSABIGPARTOFWHYYOUHAVETHATABSTRACT
CLASSINTHElRSTPLACETOUSEITASAPOLYMORPHIC
ARGUMENTORRETURNTYPEORTOMAKEAPOLYMORPHIC
ARRAY
7HENYOUREDESIGNINGYOURCLASSINHERITANCE
STRUCTUREYOUHAVETODECIDEWHICHCLASSESARE
ABSTRACTANDWHICHARECONCRETE#ONCRETECLASSESARE
THOSETHATARESPECIlCENOUGHTOBEINSTANTIATED!
CONCRETECLASSJUSTMEANSTHATITS/+TOMAKEOBJECTS
OFTHATTYPE
-AKINGACLASSABSTRACTISEASYPUTTHEKEYWORD
abstractBEFORETHECLASSDECLARATION
abstract class Canine extends Animal {
public void roam() { }
}
What are the instance variable values?
Some classes just should
not
be instantiated! interfaces and polymorphism
you are here4
201
The compiler won’t let you instantiate an abstract class
!NABSTRACTCLASSMEANSTHATNOBODYCANEVERMAKEANEW
INSTANCEOFTHATCLASS9OUCANSTILLUSETHATABSTRACTCLASSASA
DECLAREDREFERENCETYPEFORTHEPURPOSEOFPOLYMORPHISMBUT
YOUDONTHAVETOWORRYABOUTSOMEBODYMAKINGOBJECTSOFTHAT
TYPE4HECOMPILERGUARANTEESIT
abstract public class Canine extends Animal {
public void roam() { }
}
public class MakeCanine {
public void go() {
Canine c; c = new Dog();
c = new Canine(); c.roam();
}
}
File Edit Window Help BeamMeUp
% javac MakeCanine.java
MakeCanine.java:5: Canine is abstract; cannot be instantiated
c = new Canine();
^
1 error
class Canine is marked abstract,
so the compiler will NOT let you do this.
An abstract class has virtually* no use, no value, no purpose in life, unless it is extended.
With an abstract class, the guys doing the work at runtime are instances of a subclass of your abstract class.
This is OK, because you can always assign a subclass object to a superclass reference, even if the superclass is abstract.
*There is an exception to this—an abstract class can have static members (see chapter 10).
202
chapter 8
Abstract vs. Concrete
!CLASSTHATSNOTABSTRACTISCALLED
ACONCRETECLASS)NTHE!NIMAL
INHERITANCETREEIFWEMAKE
!NIMAL#ANINEAND&ELINE
ABSTRACTTHATLEAVES(IPPO7OLF
$OG4IGER,IONAND#ATASTHE
CONCRETESUBCLASSES
&LIPTHROUGHTHE*AVA!0)AND
YOULLlNDALOTOFABSTRACTCLASSES
ESPECIALLYINTHE'5)LIBRARY7HAT
DOESA'5)#OMPONENTLOOK
LIKE4HE#OMPONENTCLASSISTHE
SUPERCLASSOF'5)RELATEDCLASSES
FORTHINGSLIKEBUTTONSTEXTAREAS
SCROLLBARSDIALOGBOXESYOUNAME
IT9OUDONTMAKEANINSTANCEOF
AGENERIC#OMPONENTANDPUTITON
THESCREENYOUMAKEA*"UTTON)N
OTHERWORDSYOUINSTANTIATEONLYA
CONCRETESUBCLASSOF#OMPONENTBUT
NEVER#OMPONENTITSELF
Tiger
Animal
Canine
abstract
abstract
abstract
Hippo
concrete
Dog
Wolf
concrete
Cat
Lion
concrete
Hmmmm... do I feel like red or white tonight?
Hmmmm... the Camelot Vineyards 1997 Pinot Noir was a pretty decent year...
(OWDOYOUKNOWWHENACLASSSHOULDBE
ABSTRACT7INEISPROBABLYABSTRACT"UTWHAT
ABOUT2EDAND7HITE!GAINPROBABLYABSTRACT
FORSOMEOFUSANYWAY"UTATWHATPOINTINTHE
HIERARCHYDOTHINGSBECOMECONCRETE
$OYOUMAKE0INOT.OIRCONCRETEORISITABSTRACT
TOO)TLOOKSLIKETHE#AMELOT6INEYARDS
0INOT.OIRISPROBABLYCONCRETENOMATTERWHAT
"UTHOWDOYOUKNOWFORSURE
,OOKATTHE!NIMALINHERITANCETREEABOVE$OTHE
CHOICESWEVEMADEFORWHICHCLASSESAREABSTRACT
ANDWHICHARECONCRETESEEMAPPROPRIATE
7OULDYOUCHANGEANYTHINGABOUTTHE!NIMAL
INHERITANCETREEOTHERTHANADDINGMORE!NIMALS
OFCOURSE
abstract or concrete?
concrete
concrete
abstract and concrete classes
Feline
concrete
YiX`e
gfn\i
interfaces and polymorphism
you are here4
203
Abstract methods
"ESIDESCLASSESYOUCANMARKMETHODSABSTRACTTOO!NABSTRACT
CLASSMEANSTHECLASSMUSTBEEXTENDEDANABSTRACTMETHODMEANS
THEMETHODMUSTBEOVERRIDDEN9OUMIGHTDECIDETHATSOMEORALL
BEHAVIORSINANABSTRACTCLASSDONTMAKEANYSENSEUNLESSTHEYRE
IMPLEMENTEDBYAMORESPECIlCSUBCLASS)NOTHERWORDSYOUCANT
THINKOFANYGENERICMETHODIMPLEMENTATIONTHATCOULDPOSSIBLYBE
USEFULFORSUBCLASSES7HATWOULDAGENERICEATMETHODLOOKLIKE
An abstract method has no body!
"ECAUSEYOUVEALREADYDECIDEDTHEREISNTANYCODETHATWOULDMAKE
SENSEINTHEABSTRACTMETHODYOUWONTPUTINAMETHODBODY3ONO
CURLYBRACESJUSTENDTHEDECLARATIONWITHASEMICOLON
public abstract void eat();
No method body! End it with a semicolon.
If you declare an abstract method, you MUST mark the class abstract as well. You can’t have an abstract method in a non-abstract class.
)FYOUPUTEVENASINGLEABSTRACTMETHODINACLASSYOUHAVETO
MAKETHECLASSABSTRACT"UTYOUCANMIXBOTHABSTRACTANDNON
ABSTRACTMETHODSINTHEABSTRACTCLASS
Q: 7HATISTHEPOINTOFANABSTRACTMETHOD)THOUGHT
THEWHOLEPOINTOFANABSTRACTCLASSWASTOHAVECOMMON
CODETHATCOULDBEINHERITEDBYSUBCLASSES
A: )NHERITABLEMETHODIMPLEMENTATIONSINOTHERWORDS
METHODSWITHACTUALBODIESARE!'OOD4HINGTOPUTINA
SUPERCLASS7HENITMAKESSENSE!NDINANABSTRACTCLASSIT
OFTENDOESNTMAKESENSEBECAUSEYOUCANTCOMEUPWITH
ANYGENERICCODETHATSUBCLASSESWOULDFINDUSEFUL4HE
POINTOFANABSTRACTMETHODISTHATEVENTHOUGHYOUHAVENT
PUTINANYACTUALMETHODCODEYOUVESTILLDEFINEDPARTOF
THEPROTOCOLFORAGROUPOFSUBTYPESSUBCLASSES
Q: 7HICHISGOODBECAUSE
A: 0OLYMORPHISM2EMEMBERWHATYOUWANTISTHE
ABILITYTOUSEASUPERCLASSTYPEOFTENABSTRACTASAMETHOD
ARGUMENTRETURNTYPEORARRAYTYPE4HATWAYYOUGETTO
ADDNEWSUBTYPESLIKEANEW!NIMALSUBCLASSTOYOUR
PROGRAMWITHOUTHAVINGTOREWRITEORADDNEWMETHODS
TODEALWITHTHOSENEWTYPES)MAGINEHOWYOUDHAVETO
CHANGETHE6ETCLASSIFITDIDNTUSE!NIMALASITSARGUMENT
TYPEFORMETHODS9OUDHAVETOHAVEASEPARATEMETHOD
FOREVERYSINGLE!NIMALSUBCLASS/NETHATTAKESA,IONONE
THATTAKESA7OLFONETHATTAKESAYOUGETTHEIDEA3OWITH
ANABSTRACTMETHODYOURESAYINGh!LLSUBTYPESOFTHISTYPE
HAVE4()3METHODvFORTHEBENEFITOFPOLYMORPHISM
there are no
D
umb Questions
It really sucks to be an abstract method. You don’t have a body.
204
chapter 8
you must implement abstract methods
You MUST implement all abstract methods !BSTRACTMETHODSDONTHAVEABODYTHEYEXISTSOLELYFORPOLYMORPHISM4HAT
MEANSTHElRSTCONCRETECLASSINTHEINHERITANCETREEMUSTIMPLEMENTALLABSTRACT
METHODS
9OUCANHOWEVERPASSTHEBUCKBYBEINGABSTRACTYOURSELF)FBOTH!NIMALAND
#ANINEAREABSTRACTFOREXAMPLEANDBOTHHAVEABSTRACTMETHODSCLASS#ANINE
DOESNOTHAVETOIMPLEMENTTHEABSTRACTMETHODSFROM!NIMAL"UTASSOONASWE
GETTOTHElRSTCONCRETESUBCLASSLIKE$OGTHATSUBCLASSMUSTIMPLEMENTALLOFTHE
ABSTRACTMETHODSFROMBOTH!NIMALAND#ANINE
"UTREMEMBERTHATANABSTRACTCLASSCANHAVEBOTHABSTRACTANDNONABSTRACT
METHODSSO#ANINEFOREXAMPLECOULDIMPLEMENTANABSTRACTMETHODFROM
!NIMALSOTHAT$OGDIDNTHAVETO"UTIF#ANINESAYSNOTHINGABOUTTHEABSTRACT
METHODSFROM!NIMAL$OGHASTOIMPLEMENTALLOF!NIMALSABSTRACTMETHODS
Implementing an abstract method is just like overriding a method.
7HENWESAYhYOUMUSTIMPLEMENTTHEABSTRACTMETHODvTHATMEANSYOUMUST
PROVIDEABODY4HATMEANSYOUMUSTCREATEANONABSTRACTMETHODINYOURCLASS
WITHTHESAMEMETHODSIGNATURENAMEANDARGUMENTSANDARETURNTYPETHATIS
COMPATIBLEWITHTHEDECLAREDRETURNTYPEOFTHEABSTRACTMETHOD7HATYOUPUTIN
THATMETHODISUPTOYOU!LL*AVACARESABOUTISTHATTHEMETHODISTHEREINYOUR
CONCRETESUBCLASS
I have wonderful news, mother. Joe finally implemented all his abstract methods! Now everything is working just the way we planned...
interfaces and polymorphism
you are here4
205
Sharpen your pencil
,ETSPUTALLTHISABSTRACTRHETORICINTOSOMECONCRETEUSE)NTHEMIDDLE
COLUMNWEVELISTEDSOMECLASSES9OURJOBISTOIMAGINEAPPLICATIONS
WHERETHELISTEDCLASSMIGHTBECONCRETEANDAPPLICATIONSWHERETHELISTED
CLASSMIGHTBEABSTRACT7ETOOKASHOTATTHElRSTFEWTOGETYOUGOING
&OREXAMPLECLASS4REEWOULDBEABSTRACTINATREENURSERYPROGRAMWHERE
DIFFERENCESBETWEENAN/AKANDAN!SPENMATTER"UTINAGOLFSIMULATION
PROGRAM4REEMIGHTBEACONCRETECLASSPERHAPSASUBCLASSOF/BSTACLE
BECAUSETHEPROGRAMDOESNTCAREABOUTORDISTINGUISHBETWEENDIFFERENT
TYPESOFTREES4HERESNOONERIGHTANSWERITDEPENDSONYOURDESIGN
#ONCRETE
3AMPLECLASS
!BSTRACT
golf course simulation 4REE tree nursery application
???????????????????? (OUSE architect application
satellite photo application 4OWN ?????????????????????
???????????????????? &OOTBALL0LAYER coaching application
???????????????????? #HAIR ?????????????????????
???????????????????? #USTOMER ?????????????????????
???????????????????? 3ALES/RDER ?????????????????????
???????????????????? "OOK ?????????????????????
???????????????????? 3TORE ?????????????????????
???????????????????? 3UPPLIER?????????????????????
???????????????????? 'OLF#LUB ?????????????????????
???????????????????? #ARBURETOR ?????????????????????
???????????????????? /VEN ?????????????????????
!BSTRACTVS#ONCRETE#LASSES
206
chapter 8
polymorphism examples
Polymorphism in action
,ETSSAYTHATWEWANTTOWRITEOUROWNKINDOFLISTCLASSONETHATWILLHOLD
$OGOBJECTSBUTPRETENDFORAMOMENTTHATWEDONTKNOWABOUTTHE
!RRAY,ISTCLASS&ORTHElRSTPASSWELLGIVEITJUSTANADDMETHOD7ELLUSE
ASIMPLE$OGARRAY$OG;=TOKEEPTHEADDED$OGOBJECTSANDGIVEITA
LENGTHOF7HENWEREACHTHELIMITOF$OGOBJECTSYOUCANSTILLCALLTHE
ADDMETHODBUTITWONTDOANYTHING)FWERENOTATTHELIMITTHEADD
METHODPUTSTHE$OGINTHEARRAYATTHENEXTAVAILABLEINDEXPOSITIONTHEN
INCREMENTSTHATNEXTAVAILABLEINDEXNEXT)NDEX
public class MyDogList
{
private Dog [] dogs = new Dog[5];
private int nextIndex = 0;
public void add(Dog d) {
if (nextIndex < dogs.length) {
dogs[nextIndex] = d;
System.out.println(“Dog added at “ + nextIndex);
nextIndex++; }
}
}
MyDogList
Dog[] dogs
int nextIndex
add(Dog d)
Use a plain old Dog array behind the scenes.
We’ll increment this each time a new Dog is added.
If we’re not already at the limit of the dogs array, add the Dog and print a message.
increment, to give us the next index to use
Building our own Dog-specifi c list (Perhaps the world’s worst attempt at making our own ArrayList kind of class, from scratch.)
V
E
R
S
I
O
N
1
interfaces and polymorphism
you are here4
207
public class MyAnimalList {
private Animal[] animals = new Animal[5];
private int nextIndex = 0;
public void add(Animal a) {
if (nextIndex < animals.length) {
animals[nextIndex] = a;
System.out.println(“Animal added at “ + nextIndex);
nextIndex++;
}
}
}
MyAnimalList
Animal[] animals
int nextIndex
add(Animal a)
Building our own Animal-specifi c list V
E
R
S
I
O
N
2
Uh-oh, now we need to keep Cats, too.
7EHAVEAFEWOPTIONSHERE
-AKEASEPARATECLASS-Y#AT,ISTTOHOLD#ATOBJECTS0RETTYCLUNKY
-AKEASINGLECLASS$OG!ND#AT,ISTTHATKEEPSTWODIFFERENTARRAYSASINSTANCE
VARIABLESANDHASTWODIFFERENTADDMETHODSADD#AT#ATCANDADD$OG$OG
D!NOTHERCLUNKYSOLUTION
-AKEHETEROGENEOUS!NIMAL,ISTCLASSTHATTAKESANYKINDOF!NIMALSUBCLASS
SINCEWEKNOWTHATIFTHESPECCHANGEDTOADD#ATSSOONERORLATERWELLHAVE
SOMEOTHERKINDOFANIMALADDEDASWELL7ELIKETHISOPTIONBESTSOLETSCHANGE
OURCLASSTOMAKEITMOREGENERICTOTAKE!NIMALSINSTEADOFJUST$OGS7EVE
HIGHLIGHTEDTHEKEYCHANGESTHELOGICISTHESAMEOFCOURSEBUTTHETYPEHAS
CHANGEDFROM$OGTO!NIMALEVER
YWHEREINTHECODE
public class AnimalTestDrive{
public static void main (String[] args) {
MyAnimalList list = new MyAnimalList();
Dog a = new Dog();
Cat c = new Cat();
list.add(a);
list.add(c);
}
}
File Edit Window Help Harm
% java AnimalTestDrive
Animal added at 0
Animal added at 1
Don’t panic. We’re not making a new Animal object; we’re making a new array object, of type Animal. (Remember, you cannot make a new instance of an abstract type, but you CAN make an array object declared to HOLD that type.)
208
chapter 8
9OUKNOWWHERETHISISHEADING7EWANTTOCHANGETHE
TYPEOFTHEARRAYALONGWITHTHEADDMETHODARGUMENTTO
SOMETHINGABOVE!NIMAL3OMETHINGEVENMOREGENERICMORE
ABSTRACTTHAN!NIMAL"UTHOWCANWEDOIT7EDONTHAVEA
SUPERCLASSFOR!NIMAL
4HENAGAINMAYBEWEDO
2EMEMBERTHOSEMETHODSOF!RRAY,IST
,OOKHOWTHEREMOVECONTAINSAND
INDEX/FMETHODALLUSEANOBJECTOFTYPE
/BJECT
Every class in Java extends class Object. #LASS/BJECTISTHEMOTHEROFALLCLASSESITS
THESUPERCLASSOFEVERYTHING
V
E
R
S
I
O
N
3
What about non-Animals? Why not make a class generic enough to take anything?
Many of the ArrayList methods use the ultimate polymorphic type, Object. Since every class in Java is a subclass of Object, these ArrayList methods can take anything!
(Note: as of Java 5.0, the get() and add() methods actually look a little different than the ones shown here, but for now this is the way to think about it. We’ll get into the full story a little later.)
the ultimate superclass: Object
!RRAY,IST
(These are just a few of the methods in ArrayList...there are many more.) %VENIFYOUTAKEADVANTAGEOFPOLYMORPHISM
YOUSTILLHAVETOCREATEACLASSWITHMETHODS
THATTAKEANDRETURNYOURPOLYMORPHICTYPE
7ITHOUTACOMMONSUPERCLASSFOREVERYTHING
IN*AVATHEREDBENOWAYFORTHEDEVELOPERS
OF*AVATOCREATECLASSESWITHMETHODSTHAT
COULDTAKEYOURCUSTOMTYPESTYPESTHEYNEVER
KNEWABOUTWHENTHEYWROTETHE!RRAY,ISTCLASS
3OYOUWEREMAKINGSUBCLASSESOFCLASS/BJECT
FROMTHEVERYBEGINNINGANDYOUDIDNTEVEN
KNOWIT%VERYCLASSYOUWRITEEXTENDS/BJECT
WITHOUTYOUREVERHAVINGTOSAYIT"UTYOUCAN
THINKOFITASTHOUGHACLASSYOUWRITELOOKSLIKE
THIS
public class Dog extends Object { }
"UTWAITAMINUTE$OGALREADYEXTENDSSOMETHING#ANINE
4HAT
S/+4HECOMPILERWILLMAKE#ANINEEXTEND/BJECT
INSTEAD%XCEPT#ANINEEXTENDS!NIMAL.OPROBLEMTHENTHE
COMPILERWILLJUSTMAKE!NIMALEXTEND/BJECT
Any class that doesn’t explicitly extend another class, implicitly extends Object.
3OSINCE$OGEXTENDS#ANINEITDOESNTDIR
ECTLYEXTEND/BJECT
ALTHOUGHITDOESEXTENDITINDIRECTLYANDTHESAMEISTRUE
FOR#ANINEBUT!NIMALDOESDIRECTLYEXTEND/BJECT
2EMOVESTHEOBJECTATTHEINDEXPARAMETER2ETURNS
@TRUEIFTHEELEMENTWASINTHELIST
2ETURNS@TRUEIFTHERESAMATCHFORTHEOBJECTPARAMETER
2ETURNS@TRUEIFTHELISTHASNOELEMENTS
2ETURNSEITHERTHEINDEXOFTHEOBJECTPARAMETEROR
2ETURNSTHEELEMENTATTHISPOSITIONINTHELIST
!DDSTHEELEMENTTOTHELISTRETURNS@TRUE
BOOLEANREMOVE/BJECTELEM
BOOLEANCONTAINS/BJECTELEM
BOOLEANIS%MPTY
INTINDEX/F/BJECTELEM
/BJECTGETINTINDEX
BOOLEANADD/BJECTELEM
MORE
interfaces and polymorphism
you are here4
209
So what’s in this ultra-super-megaclass Object?
Object
boolean equals()
Class getClass()
int hashCode()
String toString()
)FYOUWERE*AVAWHATBEHAVIORWOULDYOUWANTEVERY
OBJECTTOHAVE(MMMMLETSSEEHOWABOUTA
METHODTHATLETSYOUlNDOUTIFONEOBJECTISEQUAL
TOANOTHEROBJECT7HATABOUTAMETHODTHATCAN
TELLYOUTHEACTUALCLASSTYPEOFTHATOBJECT-AYBEA
METHODTHATGIVESYOUAHASHCODEFORTHEOBJECTSO
YOUCANUSETHEOBJECTINHASHTABLESWELLTALKABOUT
*AVASHASHTABLESINCHAPTERANDAPPENDIX"
/HHERESAGOODONEAMETHODTHATPRINTSOUTA
3TRINGMESSAGEFORTHATOBJECT
!NDWHATDOYOUKNOW!SIFBYMAGICCLASS/BJECT
DOESINDEEDHAVEMETHODSFORTHOSEFOURTHINGS
4HATSNOTALLTHOUGHBUTTHESEARETHEONESWE
REALLYCAREABOUT
Just SOME of the methods of class Object. Dog a = new Dog();
Cat c = new Cat();
if (a.equals(c)) {
System.out.println(“true”);
} else {
System.out.println(“false”);
}
equals(Object o)
1
Cat c = new Cat();
System.out.println(c.getClass());
getClass()
2
File Edit Window Help Stop
% java TestObject
false
File Edit Window Help Faint
% java TestObject
class Cat
Cat c = new Cat();
System.out.println(c.hashCode());
hashCode()
3
File Edit Window Help Drop
% java TestObject
8202111
Cat c = new Cat();
System.out.println(c.toString());
toString()
4
File Edit Window Help LapseIntoComa
% java TestObject
Cat@7d277f
Prints out a hashcode for the object (for now, think of it as a unique ID).
Tells you if two objects are considered ‘equal’ (we’ll talk about what ‘equal’ really means in appendix B).
Gives you back the class that object was instantiated from.
Prints out a String message with the name of the class and some other number we rarely care about.
YourClassHere
Every class you write inherits all the methods of class Object. The classes you’ve written inherited methods you didn’t even know you had.
210
chapter 8
there are no
D
umb Questions
Q: )SCLASS/BJECTABSTRACT
A:
.O7ELLNOTINTHEFORMAL
*AVASENSEANYWAY/BJECTISA
NONABSTRACTCLASSBECAUSEITS
GOTMETHODIMPLEMENTATION
CODETHATALLCLASSESCANINHERIT
ANDUSEOUTOFTHEBOXWITHOUT
HAVINGTOOVERRIDETHEMETHODS
Q: 4HENCANYOUOVERRIDE
THEMETHODSIN/BJECT
A:
3OMEOFTHEM"UTSOMEOF
THEMAREMARKEDfinalWHICH
MEANSYOUCANTOVERRIDETHEM
9OUREENCOURAGEDSTRONGLYTO
OVERRIDEHASH#ODEEQUALS
ANDTO3TRINGINYOUROWN
CLASSESANDYOULLLEARNHOWTO
DOTHATALITTLELATERINTHEBOOK
"UTSOMEOFTHEMETHODSLIKE
GET#LASSDOTHINGSTHATMUST
WORKINASPECIFICGUARANTEED
WAY
Q: )F!RRAY,ISTMETHODSARE
GENERICENOUGHTOUSE/BJECT
THENWHATDOESITMEANTOSAY
!RRAY,IST$OT#OM)THOUGHT
)WASRESTRICTINGTHE!RRAY,ISTTO
HOLDONLY$OT#OMOBJECTS
A:
9OUWERERESTRICTINGIT
0RIORTO*AVA!RRAY,ISTS
COULDNTBERESTRICTED4HEY
WEREALLESSENTIALLYWHATYOU
GETIN*AVATODAYIFYOUWRITE
!RRAY,IST/BJECT)NOTHER
WORDSAN!RRAY,ISTRESTRICTED
TOANYTHINGTHATSAN/BJECT
WHICHMEANSANYOBJECTIN*AVA
INSTANTIATEDFROMANYCLASSTYPE
7ELLCOVERTHEDETAILSOFTHISNEW
TYPESYNTAXLATERINTHEBOOK
Q:
/+BACKTOCLASS/BJECT
BEINGNONABSTRACTSO)GUESS
THATMEANSITSCONCRETE(/7
CANYOULETSOMEBODYMAKEAN
/BJECTOBJECT)SNTTHATJUST
ASWEIRDASMAKINGAN!NIMAL
OBJECT
A:
'OODQUESTION7HYIS
ITACCEPTABLETOMAKEANEW
/BJECTINSTANCE"ECAUSE
SOMETIMESYOUJUSTWANTA
GENERICOBJECTTOUSEASWELLAS
ANOBJECT!LIGHTWEIGHTOBJECT
"YFARTHEMOSTCOMMONUSEOF
ANINSTANCEOFTYPE/BJECTISFOR
THREADSYNCHRONIZATIONWHICH
YOULLLEARNABOUTINCHAPTER
&ORNOWJUSTSTICKTHATONTHE
BACKBURNERANDASSUMETHAT
YOUWILLRARELYMAKEOBJECTSOF
TYPE/BJECTEVENTHOUGHYOU
CAN
Q:
3OISITFAIRTOSAYTHATTHE
MAINPURPOSEFORTYPE/BJECT
ISSOTHATYOUCANUSEITFORA
POLYMORPHICARGUMENTAND
RETURNTYPE,IKEIN!RRAY,IST
A:
4HE/BJECTCLASSSERVES
TWOMAINPURPOSESTOACTASA
POLYMORPHICTYPEFORMETHODS
THATNEEDTOWORKONANYCLASS
THATYOUORANYONEELSEMAKES
ANDTOPROVIDEREALMETHODCODE
THATALLOBJECTSIN*AVANEEDAT
RUNTIMEANDPUTTINGTHEMIN
CLASS/BJECTMEANSALLOTHER
CLASSESINHERITTHEM3OMEOF
THEMOSTIMPORTANTMETHODSIN
/BJECTARERELATEDTOTHREADS
ANDWELLSEETHOSELATERINTHE
BOOK
Q:
)FITSSOGOODTOUSE
POLYMORPHICTYPESWHY
DONTYOUJUSTMAKE!,,YOUR
METHODSTAKEANDRETURNTYPE
/BJECT
A:
!HHHHTHINKABOUTWHAT
WOULDHAPPEN&ORONETHING
YOUWOULDDEFEATTHEWHOLE
POINTOF@TYPESAFETYONE
OF*AVASGREATESTPROTECTION
MECHANISMSFORYOURCODE7ITH
TYPESAFETY*AVAGUARANTEESTHAT
YOUWONTASKTHEWRONGOBJECT
TODOSOMETHINGYOUMEANTTO
ASKOFANOTHEROBJECTTYPE,IKE
ASKA&ERRARIWHICHYOUTHINKISA
4OASTERTOCOOKITSELF
"UTTHETRUTHISYOUDONTHAVE
TOWORRYABOUTTHATFIERY&ERRARI
SCENARIOEVENIFYOUDOUSE
/BJECTREFERENCESFOREVERYTHING
"ECAUSEWHENOBJECTSARE
REFERREDTOBYAN/BJECT
REFERENCETYPE*AVATHINKSITS
REFERRINGTOANINSTANCEOFTYPE
/BJECT!NDTHATMEANSTHE
ONLYMETHODSYOUREALLOWEDTO
CALLONTHATOBJECTARETHEONES
DECLAREDINCLASS/BJECT3OIF
YOUWERETOSAY
Object o = new Ferrari();
o.goFast(); //Not legal!
9OUWOULDNTEVENMAKEITPAST
THECOMPILER
"ECAUSE*AVAISASTRONGLYTYPED
LANGUAGETHECOMPILERCHECKS
TOMAKESURETHATYOURECALLING
AMETHODONANOBJECTTHATS
ACTUALLYCAPABLEOFRESPONDING
)NOTHERWORDSYOUCANCALLA
METHODONANOBJECTREFERENCE
ONLYIFTHECLASSOFTHEREFERENCE
TYPEACTUALLYHASTHEMETHOD
7ELLCOVERTHISINMUCHGREATER
DETAILALITTLELATERSODONTWORRY
IFTHEPICTUREISNTCRYSTALCLEAR
Object and abstract classes
interfaces and polymorphism
you are here4
211
"EFOREYOURUNOFFANDSTARTUSINGTYPE/BJECTFORALLYOURULTRAmEXIBLEARGUMENTANDRETURN
TYPESYOUNEEDTOCONSIDERALITTLEISSUEOFUSINGTYPE/BJECTASAREFERENCE!NDKEEPINMIND
THATWERENOTTALKINGABOUTMAKINGINSTANCESOFTYPE/BJECTWERETALKINGABOUTMAKING
INSTANCESOFSOMEOTHERTYPEBUTUSINGAREFERENCEOFTYPE/BJECT
7HENYOUPUTANOBJECTINTOAN!RRAY,IST$OGITGOESINASA$OGANDCOMESOUTASA$OG
ArrayList<Dog> myDogArrayList = new ArrayList<Dog>();
Dog aDog = new Dog();
myDogArrayList.add(aDog);
Dog d = myDogArrayList.get(0);
"UTWHATHAPPENSWHENYOUDECLAREITAS!RRAY,IST/BJECT)FYOUWANTTOMAKEAN!RRAY,IST
THATWILLLITERALLYTAKEANYKINDOF/BJECTYOUDECLAREITLIKETHIS
A
rrayList
<Object>
myDogArrayList = new ArrayList
<Object>
();
Dog aDog = new Dog();
myDogArrayList.add(aDog);
"UTWHATHAPPENSWHENYOUTRYTOGETTHE$OGOBJECTANDASSIGNITTOA$OGREFERENCE
Dog d = myDogArrayList.get(0);
%VERYTHINGCOMESOUTOFAN!RRAY,IST/BJECTASAREFERENCEOFTYPE
/BJECT
REGARDLESSOFWHATTHE
ACTUALOBJECTISORWHATTHEREFERENCETYPEWASWHENYOUADDEDTHEOBJECTTOTHELIST
Using polymorphic references of type Object has a price...
Objects come out of an ArrayList<Object> acting like they’re generic instances of class Object. The Compiler cannot assume the object that comes out is of any type other than Object.
ArrayList<Object>
The objects go IN as SoccerBall, Fish, Guitar, and Car.
Object
Object
Object
Object
Make an ArrayList declared to hold Dog objects.
Make a Dog.
Add the Dog to the list.
Assign the Dog from the list to a new Dog reference variable. (Think of it as though the get() method declares a Dog return type because you used ArrayList<Dog>.)
Make an ArrayList declared to hold any type of Object.
Make a Dog.
Add the Dog to the list.
(These two steps are the same.)
NO!! Won’t compile!! When you use ArrayList<Object>, the get() method returns type Object. The Compiler knows only that the object inherits from Object (somewhere in its inheritance tree) but it doesn’t know it’s a Dog!!
d =
m
d = myD
= m
But they come OUT as though they were of type Object.
212
chapter 8
public void go() {
Dog aDog = new Dog();
Object sameDog = getObject(aDog);
}
public Object getObject(Object o) {
return o;
}
public void go() {
Dog aDog = new Dog();
Dog sameDog = getObject(aDog);
}
public Object getObject(Object o) {
return o;
}
4HEPROBLEMWITHHAVINGEVERYTHINGTREATED
POLYMORPHICALLYASAN/BJECTISTHATTHEOBJECTS
APPEARTOLOSEBUTNOTPERMANENTLYTHEIR
TRUEESSENCE4HE$OGAPPEARSTOLOSEITSDOGNESS
,ETSSEEWHATHAPPENSWHENWEPASSA$OGTO
AMETHODTHATRETURNSAREFERENCETOTHESAME
$OGOBJECTBUTDECLARESTHERETURNTYPEASTYPE
/BJECTRATHERTHAN$OG
When a Dog won’t act like a Dog
This line won’t work! Even though the method returned a reference to the very same Dog the argument referred to, the return type Object means the compiler won’t let you assign the returned reference to anything but Object.
File Edit Window Help Remember
DogPolyTest.java:10: incompatible types
found : java.lang.Object
required: Dog
Dog sameDog = takeObjects(aDog);
1 error ^
The compiler doesn’t know that the thing returned from the method is actually a Dog, so it won’t let you assign it to a Dog reference. (You’ll see why on the next page.)
BAD
This works (although it may not be very useful, as you’ll see in a moment) because you can assign ANYTHING to a reference of type Object, since every class passes the IS-A test for Object. Every object in Java is an instance of type Object, because every class in Java has Object at the top of its inheritance tree.
GOOD
L
J
I don’t know what you’re talking about. Sit? Stay? bark? Hmmmm... I don’t recall knowing those.
When a Dog loses its Dogness
= = g = g
= g
We’re returning a reference to the same Dog, but as a return type of Object. This part is perfectly legal. Note: this is similar to how the get() method works when you have an ArrayList<Object> rather than an ArrayList<Dog>.
interfaces and polymorphism
you are here4
213
3ONOWWEKNOWTHATWHENANOBJECTIS
REFERENCEDBYAVARIABLEDECLAREDASTYPE
/BJECTITCANTBEASSIGNEDTOAVARIABLE
DECLAREDWITHTHEACTUALOBJECTSTYPE
!NDWEKNOWTHATTHISCANHAPPENWHEN
ARETURNTYPEORARGUMENTISDECLARED
ASTYPE/BJECTASWOULDBETHECASE
FOREXAMPLEWHENTHEOBJECTISPUT
INTOAN!RRAY,ISTOFTYPE/BJECTUSING
!RRAY,IST/BJECT"UTWHATARETHE
IMPLICATIONSOFTHIS)SITAPROBLEMTO
HAVETOUSEAN/BJECTREFERENCEVARIABLE
TOREFERTOA$OGOBJECT,ETSTRYTOCALL
$OGMETHODSONOUR$OG4HAT#OMPILER
4HINKS)S!N/BJECT
Objects don’t bark.
Object o = al.get(index);
int i = o.hashCode();
o.bark(); This is fine. Class Object has a hashCode() method, so you can call that method on ANY object in Java.
Can’t do this!! The Object class has no idea what it means to bark(). Even though YOU know it’s really a Dog at that index, the compiler doesn’t..
Object
o
D
o
g
o
b
j
e
c
t
When you get an object reference from an ArrayList<Object> (or any method that declares Object as the return type), it comes back as a polymorphic reference type of Object. So you have an Object reference to (in this case) a Dog instance. Won’t compile!
The compiler decides whether you can call a method based on the reference type, not the actual object type.
%VENIFYOUKNOWTHEOBJECTISCAPABLE
hBUTITREALLYISA$OGHONESTvTHE
COMPILERSEESITONLYASAGENERIC/BJECT
&ORALLTHECOMPILERKNOWSYOUPUTA
"UTTONOBJECTOUTTHERE/RA-ICROWAVE
OBJECT/RSOMEOTHERTHINGTHATREALLY
DOESN
TKNOWHOWTOBARK
4HECOMPILERCHECKSTHECLASSOFTHE
REFERENCETYPENOTTHEOBJECTTYPETO
SEEIFYOUCANCALLAMETHODUSINGTHAT
REFERENCE
Object
o
D
o
g
o
b
j
e
c
t
Object
equals()
getClass()
hashCode()
toString()
The method you’re calling on a reference MUST be in the class of that reference type. Doesn’t matter what the actual object is.
o.hashCode();
The “o” reference was declared as type Object, so you can call methods only if those methods are in class Object..
o.
b
o.ba
o.b
hashCode()
214
chapter 8
!NOBJECTCONTAINSEVERYTHINGITINHERITSFROMEACHOFITS
SUPERCLASSES4HATMEANSEVERYOBJECTREGARDLESSOFITS
ACTUALCLASSTYPEISALSOANINSTANCEOFCLASS/BJECT4HAT
MEANSANYOBJECTIN*AVACANBETREATEDNOTJUSTASA$OG
"UTTONOR3NOWBOARDBUTALSOASAN/BJECT7HENYOU
SAYnew Snowboard()YOUGETASINGLEOBJECTONTHE
HEAPA3NOWBOARDOBJECTBUTTHAT3NOWBOARDWRAPS
ITSELFAROUNDANINNERCOREREPRESENTINGTHE/BJECT
CAPITALh/vPORTIONOFITSELF
Get in touch with your inner Object.
There is only ONE object on the heap here. A Snowboard object. But it contains both the Snowboard class parts of itself and the Object class parts of itself. objects are Objects
Object
equals()
getClass()
hashCode()
toString()
Snowboard
equals()
getClass()
hashCode()
toString()
turn()
shred()
getAir()
loseControl()
Snowboard inherits methods from superclass Object, and adds four more.
t
o
S
t
r
i
n
g
(
)
h
a
s
h
C
o
d
e
(
)
g
e
t
A
i
r
(
)
t
u
r
n
(
)
s
h
r
e
d
(
)
e
q
u
a
l
s
(
)
g
e
t
C
l
a
s
s
(
)
l
o
s
e
C
o
n
t
r
o
l
(
)
Object
Snowboard
S
n
o
w
b
o
a
r
d
o
b
j
e
c
t
He treats me like an Object. But I can do so much more...if only he’d see me for what I really am.
A single object on the heap.
interfaces and polymorphism
you are here4
215
Snowboard s
= new Snowboard();
Object o
= s;
t
o
S
t
r
i
n
g
(
)
h
a
s
h
C
o
d
e
(
)
g
e
t
A
i
r
(
)
t
u
r
n
(
)
s
h
r
e
d
(
)
e
q
u
a
l
s
(
)
g
e
t
C
l
a
s
s
(
)
l
o
s
e
C
o
n
t
r
o
l
(
)
Object
Snowboard
The Object reference can see only the Object parts of the Snowboard object. It can access only the methods of class Object. It has fewer buttons than the Snowboard remote control.
o
s
The Snowboard remote control (reference) has more buttons than an Object remote control. The Snowboard remote can see the full Snowboardness of the Snowboard object. It can access all the methods in Snowboard, including both the inherited Object methods and the methods from class Snowboard.
S
n
o
w
b
o
a
r
d
o
b
j
e
c
t
)FAREFERENCEISLIKEAREMOTECONTROLTHE
REMOTECONTROLTAKESONMOREANDMOREBUTTONS
ASYOUMOVEDOWNTHEINHERITANCETREE!
REMOTECONTROLREFERENCEOFTYPE/BJECTHAS
ONLYAFEWBUTTONSTHEBUTTONSFORTHEEXPOSED
METHODSOFCLASS/BJECT"UTAREMOTECONTROL
OFTYPE3NOWBOARDINCLUDESALLTHEBUTTONSFROM
CLASS/BJECTPLUSANYNEWBUTTONSFORNEW
METHODSOFCLASS3NOWBOARD4HEMORESPECIlC
THECLASSTHEMOREBUTTONSITMAYHAVE
/FCOURSETHATSNOTALWAYSTRUEASUBCLASSMIGHT
NOTADDANYNEWMETHODSBUTSIMPLYOVERRIDE
THEMETHODSOFITSSUPERCLASS4HEKEYPOINTIS
THATEVENIFTHEOBJECTISOFTYPE3NOWBOARDAN
/BJECTREFERENCETOTHE3NOWBOARDOBJECTCANTSEE
THE3NOWBOARDSPECIlCMETHODS
‘Polymorphism’ means ‘many forms’. You can treat a Snowboard as a Snowboard or as an Object.
When you put an object in an ArrayList<Object>, you can treat it only as an Object, regardless of the type it was when you put it in.
When you get a reference from an ArrayList<Object>, the reference is always of type Object. That means you get an Object remote control.
fewer methods here...
216
chapter 8
Wait a minute... what good is a Dog if it comes out of an ArrayList<Object> and it can’t do any Dog things? There’s gotta be a way to get the Dog back to a state of Dogness...
I hope it doesn’t hurt. And what’s so wrong with staying an Object? OK, I can’t fetch, sure, but I can give you a real nice hashcode.
casting objects
Casting an object reference back to its real type.
Object
o
)TSREALLYSTILLA$OGOBJECTBUTIFYOUWANTTOCALL
$OGSPECIlCMETHODSYOUNEEDAREFERENCEDECLARED
ASTYPE$OG)FYOURESURE
THEOBJECTISREALLYA
$OGYOUCANMAKEANEW$OGREFERENCETOITBY
COPYINGTHE/BJECTREFERENCEANDFORCINGTHAT
COPYTOGOINTOA$OGREFERENCEVARIABLEUSINGA
CAST$OG9OUCANUSETHENEW$OGREFERENCETO
CALL$OGMETHODS
Object o = al.get(index);
Dog d = (Dog) o;
d.roam();
Object
o
D
o
g
o
b
j
e
c
t
Dog
d
)FYOURENOTSUREITSA$OGYOUCANUSETHE
instanceofOPERATORTOCHECK"ECAUSEIF
YOUREWRONGWHENYOUDOTHECASTYOULLGETA
#LASS#AST%XCEPTIONATRUNTIMEANDCOMETOA
GRINDINGHALT
if (o instanceof Dog) {
Dog d = (Dog) o;
}
D
o
g
o
b
j
e
c
t
cast the Object back to a Dog we know is there.
Cast the so-called ‘Object’ (but we know he’s actually a Dog) to type Dog, so that you can treat him like the Dog he really is.
interfaces and polymorphism
you are here4
217
7HENYOUWRITEACLASSYOUALMOSTALWAYSEXPOSESOME
OFTHEMETHODSTOCODEOUTSIDETHECLASS4OEXPOSEA
METHODMEANSYOUMAKEAMETHODACCESSIBLEUSUALLYBY
MARKINGITPUBLIC
)MAGINETHISSCENARIOYOUREWRITINGCODEFORASMALL
BUSINESSACCOUNTINGPROGRAM!CUSTOMAPPLICATION
FORh3IMONS3URF3HOPv4HEGOODRE
USERTHATYOUAREYOUFOUNDAN!CCOUNT
CLASSTHATAPPEARSTOMEETYOURNEEDS
PERFECTLYACCORDINGTOITSDOCUMENTATION
ANYWAY%ACHACCOUNTINSTANCEREPRESENTS
ANINDIVIDUALCUSTOMERSACCOUNTWITHTHE
STORE3OTHEREYOUAREMINDINGYOUROWN
BUSINESSINVOKINGTHECREDITANDDEBIT
METHODSONANACCOUNTOBJECTWHENYOUREALIZEYOU
NEEDTOGETABALANCEONANACCOUNT.OPROBLEM
THERESAGET"ALANCEMETHODTHATSHOULDDONICELY
%XCEPTWHENYOUINVOKETHEGET"ALANCEMETHOD
THEWHOLETHINGBLOWSUPATRUNTIME&ORGETTHE
DOCUMENTATIONTHECLASSDOESNOTHAVETHATMETHOD
9IKES
"UTTHATWONTHAPPENTOYOUBECAUSEEVERYTIMEYOU
USETHEDOTOPERATORONAREFERENCEADO3TUFFTHE
COMPILERLOOKSATTHEREFERENCETYPETHETYPE@AWAS
DECLAREDTOBEANDCHECKSTHATCLASSTOGUARANTEETHE
CLASSHASTHEMETHODANDTHATTHEMETHODDOESINDEED
TAKETHEARGUMENTYOUREPASSINGANDRETURNTHEKINDOF
VALUEYOUREEXPECTINGTOGETBACK
*USTREMEMBERTHATTHECOMPILERCHECKSTHECLASSOFTHE
REFERENCEVARIABLENOTTHECLASSOFTHEACTUALOBJECTATTHE
OTHERENDOFTHEREFERENCE
Think of the public methods in your class as your contract, your promise to the outside world about the things you can do.
Account
debit(double amt)
credit(double amt)
double getBalance()
So now you’ve seen how much Java cares about the methods in the class of the reference variable.
You can call a method on an object only if the class of the reference variable has that method.
218
chapter 8
/+PRETENDYOUREA$OG9OUR$OGCLASS
ISNTTHEONLYCONTRACTTHATDElNESWHOYOU
ARE2EMEMBERYOUINHERITACCESSIBLEWHICH
USUALLYMEANSPUBLICMETHODSFROMALLOF
YOURSUPERCLASSES
4RUEYOUR$OGCLASSDElNESACONTRACT
"UTNOTALLOFYOURCONTRACT
%VER
YTHINGINCLASS#ANINEISPARTOFYOUR
CONTRACT
%VERYTHINGINCLASS!NIMALISPARTOFYOUR
CONTRACT
%VERYTHINGINCLASS/BJECTISPARTOFYOUR
CONTRACT
!CCORDINGTOTHE)3!TESTYOUAREEACHOF
THOSETHINGS#ANINE!NIMALAND/BJECT
"UTWHATIFTHEPERSONWHODESIGNEDYOUR
CLASSHADINMINDTHE!NIMALSIMULATION
PROGRAMANDNOWHEWANTSTOUSEYOUCLASS
$OGFORA3CIENCE&AIR4
UTORIALON!NIMAL
OBJECTS
4HATS/+YOUREPROBABLYREUSABLEFORTHAT
"UTWHATIFLATERHEWANTSTOUSEYOUFORA
0ET3HOPPROGRAM9OUDONTHAVEANY0ET
BEHAVIORS!0ETNEEDSMETHODSLIKEBE&RIENDLY
ANDPLAY
/+NOWPRETENDYOURETHE$OGCLASS
PROGRAMMER
.OPROBLEMRIGHT*USTADD
SOMEMOREMETHODSTOTHE$OGCLASS9OU
WONTBEBREAKINGANYONEELSESCODEBY
ADDINGMETHODSSINCEYOUARENTTOUCHING
THEEXISTINGMETHODSTHATSOMEONEELSESCODE
MIGHTBECALLINGON$OGOBJECTS
#ANYOUSEEANYDRAWBACKSTOTHATAPPROACH
ADDING0ETMETHODSTOTHE$OGCLASS
What if you need to change the contract?
Think about what YOU would do if YOU were the Dog class programmer and needed to modify the Dog so that it could do Pet things, too. We know that simply adding new Pet be-
haviors (methods) to the Dog class will work, and won’t break anyone else’s code.
But... this is a PetShop program. It has more than just Dogs! And what if someone wants to use your Dog class for a program that has wild Dogs? What do you think your options might be, and without worrying about how Java handles things, just try to imagine how you’d like to solve the problem of modifying some of your Animal classes to include Pet behaviors.
Stop right now and think about it, before you look at the next page where we begin to reveal everything.
(thus rendering the whole exercise completely useless, robbing you of your One Big Chance to burn some brain calories) modifying a class tree
YiX`e
gfn\i
interfaces and polymorphism
you are here4
219
/NTHENEXTFEWPAGESWEREGOINGTOWALKTHROUGH
SOMEPOSSIBILITIES7ERENOTYETWORRIEDABOUT
WHETHER*AVACANACTUALLYDOWHATWECOMEUPWITH
7ELLCROSSTHATBRIDGEONCEWEHAVEAGOODIDEAOF
SOMEOFTHETRADEOFFS
Let’s explore some design options for reusing some of our existing classes in a PetShop program.
We take the easy path, and put pet methods in class Animal. 1
Option one
All the Animals will instantly inherit the pet behaviors. We won’t have to touch the existing Animal subclasses at all, and any Animal subclasses created in the future will also get to take advantage of inheriting those methods. That way, class Animal can be used as the polymorphic type in any program that wants to treat the Animals as pets
Pros:
So... when was the last time you saw a Hippo at a pet shop? Lion? Wolf? Could be dangerous to give non-pets pet methods. Also, we almost certainly WILL have to touch the pet classes like Dog and Cat, because (in our house, anyway) Dogs and Cats tend to imple-
ment pet behaviors VERY differently.
Cons:
Tiger
Animal
Canine
Hippo
Dog
Wolf
Cat
Lion
Feline
put all the pet method code up here for inheritance.
220
chapter 8
We start with Option One, putting the pet methods in class Animal, but we make the methods abstract, forcing the Animal subclasses to override them.
2
Option two
That would give us all the benefi ts of Option One, but with-
out the drawback of having non-pet Animals running around with pet methods (like beFriendly()). All Animal classes would have the method (because it’s in class Animal), but because it’s abstract the non-pet Animal classes won’t inherit any functionality. All classes MUST override the methods, but they can make the methods “do-nothings”.
Pros:
Because the pet methods in the Animal class are all abstract, the concrete Animal subclasses are forced to implement all of them. (Remember, all abstract methods MUST be implemented by the fi rst concrete subclass down the inheritance tree.) What a waste of time! You have to sit there and type in each and every pet method into each and every concrete non-
pet class, and all future subclasses as well. And while this does solve the problem of non-pets actually DOING pet things (as they would if they inherited pet functionality from class Animal), the contract is bad. Every non-pet class would be announcing to the world that it, too, has those pet methods, even though the methods wouldn’t actually DO anything when called.
This approach doesn’t look good at all. It just seems wrong to stuff everything into class Animal that more than one Animal type might need, UNLESS it applies to ALL Animal subclasses.
Cons:
Tiger
Animal
Canine
Hippo
Dog
Wolf
Cat
Lion
Feline
put all the pet methods up here, but with no implementations. Make all pet methods abstract.
Ask me to be friendly. No, seriously... ask me. I have the method.
modifying existing classes
interfaces and polymorphism
you are here4
221
Put the pet methods ONLY in the classes where they belong.
3
Option three
No more worries about Hippos greeting you at the door or licking your face. The methods are where they belong, and ONLY where they belong. Dogs can implement the methods and Cats can implement the methods, but nobody else has to know about them.
Pros:
Two Big Problems with this approach. First off, you’d have to agree to a protocol, and all programmers of pet Animal classes now and in the future would have to KNOW about the protocol. By protocol, we mean the exact methods that we’ve decided all pets should have. The pet contract without anything to back it up. But what if one of the programmers gets it just a tiny bit wrong? Like, a method takes a String when it was supposed to take an int? Or they named it doFriendly() instead of beFriendly()? Since it isn’t in a contract, the compiler has no way to check you to see if you’ve implemented the methods correctly. Someone could easily come along to use the pet Animal classes and fi nd that not all of them work quite right.
And second, you don’t get to use polymorphism for the pet methods. Every class that needs to use pet behaviors would have to know about each and every class! In other words, you can’t use Animal as the polymorphic type now, because the compiler won’t let you call a Pet method on an Animal reference (even if it’s really a Dog object) because class Animal doesn’t have the method.
Cons:
Put the pet methods ONLY in the Animal classes that can be pets, instead of in Animal.
Tiger
Animal
Canine
Hippo
Dog
Wolf
Cat
Lion
Feline
222
chapter 8
So what we REALLY need is:
Æ
A way to have pet behavior in just the pet classes
Æ
A way to guarantee that all pet classes have all of the same methods defined (same name, same arguments, same return types, no missing methods, etc.), without having to cross your fingers and hope all the programmers get it right.
Æ
A way to take advantage of polymorphism so that all pets can have their pet methods called, without having to use arguments, return types, and arrays for each and every pet class.
Tiger
Animal
Canine
Hippo
Dog
Wolf
Cat
Lion
Feline
Pet
It looks like we need TWO superclasses at the top
We make a new abstract superclass called Pet, and give it all the pet methods.
Cat now extends from both Animal AND Pet, so it gets the methods of both.
Dog extends both Pet and Animal
The non-pet Animals don’t have any inherited Pet stuff.
multiple inheritance?
interfaces and polymorphism
you are here4
223
It’s called “multiple inheritance” and it can be a Really Bad Thing.
That is, if it were possible to do in Java. But it isn’t, because multiple inheritance has a problem known as The Deadly Diamond of Death.
There’s just one problem with the “two superclasses” approach...
CDBurner
burn()
DVDBurner
DigitalRecorder
int i
burn()
burn()
ComboDrive
CDBurner and DVDBurner both inherit from DigitalRecorder, and both override the burn() method. Both inherit the “i” instance variable.
Deadly Diamond of Death
Problem with multiple inheritance. Which burn() method runs when you call burn() on the ComboDrive? Imagine that the “i” instance variable is used by both CDBurner and DVDBurner, with different values. What happens if ComboDrive needs to use both values of “i”?
!LANGUAGETHATALLOWSTHE$EADLY$IAMONDOF$EATHCANLEADTO
SOMEUGLYCOMPLEXITIESBECAUSEYOUHAVETOHAVESPECIALRULESTO
DEALWITHTHEPOTENTIALAMBIGUITIES!NDEXTRARULESMEANSEXTRA
WORKFORYOUBOTHINLEARNINGTHOSERULESANDWATCHINGOUTFOR
THOSEhSPECIALCASESv*AVAISSUPPOSEDTOBESIMPLEWITHCONSISTENT
RULESTHATDONTBLOWUPUNDERSOMESCENARIOS3O*AVAUNLIKE
#PROTECTSYOUFROMHAVINGTOTHINKABOUTTHE$EADLY$IA
MONDOF$EATH"UTTHATBRINGSUSBACKTOTHEORIGINALPROBLEM
(OWDOWEHANDLETHE!NIMAL0ETTHING
224
chapter 8
Interface to the rescue!
Pet
abstract void beFriendly();
abstract void play();
A Java interface is like a 100% pure abstract class.
All methods in an interface are abstract, so any class that IS-A Pet MUST implement (i.e. override) the methods of Pet. *AVAGIVESYOUASOLUTION!NINTERFACE.OTA'5)INTERFACENOTTHEGENERIC
USEOFTHEWORDINTERFACEASINh4HATSTHEPUBLICINTERFACEFORTHE"UTTON
CLASS!0)vBUTTHE*AVAKEYWORDinterface
!*AVAINTERFACESOLVESYOURMULTIPLEINHERITANCEPROBLEMBYGIVINGYOU
MUCHOFTHEPOLYMORPHICBENElTSOFMULTIPLEINHERITANCEWITHOUTTHEPAIN
ANDSUFFERINGFROMTHE$EADLY$IAMONDOF$EATH$$$
4HEWAYINWHICHINTERFACESSIDESTEPTHE$$$ISSURPRISINGLYSIMPLEMAKE
ALLTHEMETHODSABSTRACT4HATWAYTHESUBCLASSMUSTIMPLEMENTTHEMETHODS
REMEMBERABSTRACTMETHODSMUSTBEIMPLEMENTEDBYTHElRSTCONCRETE
SUBCLASSSOATRUNTIMETHE*6-ISNTCONFUSEDABOUTWHICHOFTHETWO
INHERITEDVERSIONSITSSUPPOSEDTOCALL
To DEFINE an interface:
To IMPLEMENT an interface:
public interface Pet {...}
public class Dog extends Canine implements Pet {...}
Use the keyword “interface” instead of “class”
Use the keyword “implements” followed by the interface name. Note that when you implement an interface you still get to extend a class interfaces interfaces and polymorphism
you are here4
225
Making and Implementing the Pet interface public interface Pet {
public abstract void beFriendly();
public abstract void play();
}
public class Dog extends Canine implements Pet {
public void beFriendly() {...}
public void play() {..}
public void roam() {...}
public void eat() {...}
}
All interface methods are abstract, so they MUST end in semicolons. Remember, they have no body!
You say ‘interface’ instead of ‘class’ here
You say ‘implements’ followed by the name of the interface.
You SAID you are a Pet, so you MUST implement the Pet methods. It’s your contract. Notice the curly braces instead of semicolons.
Dog IS-A Animal and Dog IS-A Pet
These are just normal overriding methods. there are no
D
umb Questions
Q:
7AITAMINUTEINTERFACESDONT
REALLYGIVEYOUMULTIPLEINHERITANCE
BECAUSEYOUCANTPUTANY
IMPLEMENTATIONCODEINTHEM)FALL
THEMETHODSAREABSTRACTWHATDOES
ANINTERFACEREALLYBUYYOU
A:
0OLYMORPHISMPOLYMORPHISM
POLYMORPHISM)NTERFACESARETHE
ULTIMATEINFLEXIBILITYBECAUSEIFYOU
USEINTERFACESINSTEADOFCONCRETE
SUBCLASSESOREVENABSTRACTSUPERCLASS
TYPESASARGUMENTSANDRETURN
TYPESYOUCANPASSANYTHINGTHAT
IMPLEMENTSTHATINTERFACE!NDTHINK
ABOUTITWITHANINTERFACEACLASS
DOESNTHAVETOCOMEFROMJUSTONE
INHERITANCETREE!CLASSCANEXTEND
ONECLASSANDIMPLEMENTANINTERFACE
"UTANOTHERCLASSMIGHTIMPLEMENT
THESAMEINTERFACEYETCOMEFROMA
COMPLETELYDIFFERENTINHERITANCETREE
3OYOUGETTOTREATANOBJECTBYTHE
ROLEITPLAYSRATHERTHANBYTHECLASS
TYPEFROMWHICHITWASINSTANTIATED
)NFACTIFYOUWROTEYOURCODETOUSE
INTERFACESYOUWOULDNTEVENHAVETO
GIVEANYONEASUPERCLASSTHATTHEYHAD
TOEXTEND9OUCOULDJUSTGIVETHEM
THEINTERFACEANDSAYh(ERE)DONT
CAREWHATKINDOFCLASSINHERITANCE
STRUCTUREYOUCOMEFROMJUST
IMPLEMENTTHISINTERFACEANDYOULLBE
GOODTOGOv
4HEFACTTHATYOUCANTPUTIN
IMPLEMENTATIONCODETURNSOUTNOTTO
BEAPROBLEMFORMOSTGOODDESIGNS
BECAUSEMOSTINTERFACEMETHODS
WOULDNTMAKESENSEIFIMPLEMENTED
INAGENERICWAY)NOTHERWORDSMOST
INTERFACEMETHODSWOULDNEEDTO
BEOVERRIDDENEVENIFTHEMETHODS
WERENTFORCEDTOBEABSTRACT
interface methods are implicitly public and abstract, so typing in ‘public’ and ‘abstract’ is optional (in fact, it’s not considered ‘good style’ to type the words in, but we did here just to reinforce it, and because we’ve never been slaves to fashion...)
226
chapter 8
Classes from different inheritance trees can implement the same interface.
Tiger
Animal
Canine
Hippo
Dog
Wolf
Cat
Lion
Feline
Pet
RoboDog
Robot
Agent
Class RoboDog doesn’t come from the Animal inheritance tree, but it still gets to be a Pet! 7HENYOUUSEACLASSASAPOLYMORPHICTYPELIKEAN
ARRAYOFTYPE!NIMALORAMETHODTHATTAKESA#ANINE
ARGUMENTTHEOBJECTSYOUCANSTICKINTHATTYPE
MUSTBEFROMTHESAMEINHERITANCETREE"UTNOTJUST
ANYWHEREINTHEINHERITANCETREETHEOBJECTSMUSTBE
FROMACLASSTHATISASUBCLASSOFTHEPOLYMORPHICTYPE
!NARGUMENTOFTYPE#ANINECANACCEPTA7OLFANDA
$OGBUTNOTA#ATORA(IPPO
"UTWHENYOUUSEANINTERFACEASAPOLYMORPHIC
TYPELIKEANARRAYOF0ETSTHEOBJECTSCANBE
FROMANYWHEREINTHEINHERITANCETREE4HEONLY
REQUIREMENTISTHATTHEOBJECTSAREFROMACLASSTHAT
IMPLEMENTSTHEINTERFACE!LLOWINGCLASSESINDIFFERENT
INHERITANCETREESTOIMPLEMENTACOMMONINTERFACE
ISCRUCIALINTHE*AVA!0)$OYOUWANTANOBJECT
TOBEABLETOSAVEITSSTATETOAlLE)MPLEMENTTHE
3ERIALIZABLEINTERFACE$OYOUNEEDOBJECTSTORUN
THEIRMETHODSINASEPARATETHREADOFEXECUTION
)MPLEMENT2UNNABLE9
OUGETTHEIDEA9OULL
LEARNMOREABOUT3ERIALIZABLEAND2UNNABLEINLATER
CHAPTERSBUTFORNOWREMEMBERTHATCLASSESFROM
ANYPLACEINTHEINHERITANCETREEMIGHTNEEDTO
IMPLEMENTTHOSEINTERFACES.EARLYANYCLASSMIGHT
WANTTOBESAVEABLEORRUNNABLE
Better still, a class can implement multiple interfaces!
!$OGOBJECT)3!#ANINEAND)3!!NIMALAND
)3!/BJECTALLTHROUGHINHERITANCE"UTA$OG)3!
0ETTHROUGHINTERFACEIMPLEMENTATIONANDTHE$OG
MIGHTIMPLEMENTOTHERINTERFACESASWELL9OUCOULD
SAY
public class Dog extends Animal implements Pet, Saveable, Paintable { ... }
interface polymorphism
interfaces and polymorphism
you are here4
227
MakeitStick
2OSESAREREDVIOLETSAREBLUE
%XTENDONLYONEBUTIMPLEMENTTWO
*AVAWEIGHSINONFAMILYVALUES
3INGLE0ARENTS/NLY!*AVACLASSCANHAVE
ONLYONEPARENTSUPERCLASSANDTHATPARENT
CLASSDEFINESWHOYOUARE"UTYOUCANIMPLE
MENTMULTIPLEINTERFACESANDTHOSEINTERFACES
DEFINEROLESYOUCANPLAY
How do you know whether to make a class, a subclass, an abstract class, or an interface?
Make a class that doesn’t extend anything (other than Object) when your new class doesn’t pass the IS-A test for any other type.
Make a subclass (in other words, extend a class) only when you need to make a more specifi c version of a class and need to override or add new behaviors.
Use an abstract class when you want to defi ne a template for a group of subclasses, and you have at least some implementation code that all subclasses could use. Make the class abstract when you want to guarantee that nobody can make objects of that type.
Use an interface when you want to defi ne a role that other classes can play, regardless of where those classes are in the inheritance tree. 228
chapter 8
class BuzzwordsReport extends Report {
void runReport() {
super.runReport(); buzzwordCompliance();
printReport();
}
void buzzwordCompliance() {...}
}
using super
Q: 7HATIFYOUMAKEACONCRETESUBCLASS
ANDYOUNEEDTOOVERRIDEAMETHODBUTYOU
WANTTHEBEHAVIORINTHESUPERCLASSVERSIONOF
THEMETHOD)NOTHERWORDSWHATIFYOUDONT
NEEDTOREPLACETHEMETHODWITHANOVERRIDE
BUTYOUJUSTWANTTOADDTOITWITHSOME
ADDITIONALSPECIlCCODE
A:
!HHHTHINKABOUTTHEMEANINGOFTHE
WORD@EXTENDS/NEAREAOFGOOD//DESIGNLOOKS
ATHOWTODESIGNCONCRETECODETHATSMEANTTO
BEOVERRIDDEN)NOTHERWORDSYOUWRITEMETHOD
CODEINSAYANABSTRACTCLASSTHATDOESWORK
THATSGENERICENOUGHTOSUPPORTTYPICALCONCRETE
IMPLEMENTATIONS"UTTHECONCRETECODEISNT
ENOUGHTOHANDLEALLOFTHESUBCLASSSPECIFIC
WORK3OTHESUBCLASSOVERRIDESTHEMETHOD
ANDEXTENDSITBYADDINGTHERESTOFTHECODE
4HEKEYWORDSUPERLETSYOUINVOKEASUPERCLASS
VERSIONOFANOVERRIDDENMETHODFROMWITHINTHE
SUBCLASS
Invoking the superclass version of a method
super.runReport();
BuzzwordReport
subclass method (overrides the superclass version)
super.runReport();
The super keyword is really a reference to the superclass portion of an object. When subclass code uses super, as in super.runReport(), the superclass version of the method will run. abstract class Report {
void runReport() {
// set-up report }
void printReport() {
// generic printing
}
}
Report
runReport()
printReport()
runReport()
buzzwordCompliance()
superclass methods (including the overridden runReport()
A reference to the subclass object (BuzzwordReport) will always call the subclass version of an overridden method. That’s polymorphism. But the subclass code can call super.runReport() to invoke the superclass version.
If method code inside a BuzzwordReport subclass says:
the runReport() method inside the superclass Report will run
superclass version of the method does important stuff that subclasses could use
call superclass version, then come back and do some subclass-
specific stuff
interfaces and polymorphism
you are here4
229
BULLET POINTS
When you don’t want a class to be instantiated (in other words, you don’t want anyone to make a new object of that class type) mark the class with the abstract keyword.
An abstract class can have both abstract and non-abstract methods.
If a class has even one abstract method, the class must be marked abstract.
An abstract method has no body, and the declaration ends with a semicolon (no curly braces).
All abstract methods must be implemented in the first concrete subclass in the inheritance tree.
Every class in Java is either a direct or indirect subclass of class Object (java.lang.
Object).
Methods can be declared with Object arguments and/or return types. You can call methods on an object only if the methods are in the class (or interface) used as the reference variable type, regardless of the actual object type. So, a reference variable of type Object can be used only to call methods defined in class Object, regardless of the type of the object to which the reference refers.
A reference variable of type Object can’t be assigned to any other reference type without a cast. A cast can be used to assign a reference variable of one type to a reference variable of a subtype, but at runtime the cast will fail if the object on the heap is NOT of a type compatible with the cast. Example: Dog d = (Dog)
x.getObject(aDog);
All objects come out of an ArrayList<Object> as type Object (meaning, they can be referenced only by an Object reference variable, unless you use a cast).
Multiple inheritance is not allowed in Java, because of the problems associated with the “Deadly Diamond of Death”. That means you can extend only one class (i.e. you can have only one immediate superclass).
An interface is like a 100% pure abstract class. It defines only abstract methods.
Create an interface using the interface keyword instead of the word class.
Implement an interface using the keyword implements Example: Dog implements Pet
Your class can implement multiple interfaces.
A class that implements an interface must implement all the methods of the interface, since all interface methods are implicitly public and abstract.
To invoke the superclass version of a method from a subclass that’s overridden the method, use the super keyword. Example: super
.runReport();
Q:
4HERESSTILLSOMETHING
STRANGEHEREYOUNEVER
EXPLAINEDHOWITISTHAT
!RRAY,IST$OGGIVESBACK$OG
REFERENCESTHATDONTNEEDTOBE
CASTYETTHE!RRAY,ISTCLASSUSES
/BJECTINITSMETHODSNOT$OG
OR$OT#OMORANYTHINGELSE
7HATSTHESPECIALTRICKGOINGON
WHENYOUSAY!RRAY,IST$OG
A: 9OURERIGHTFORCALLINGITA
SPECIALTRICK)NFACTITISASPECIAL
TRICKTHAT!RRAY,IST$OGGIVES
BACK$OGSWITHOUTYOUHAVING
TODOANYCASTSINCEITLOOKSLIKE
!RRAY,ISTMETHODSDONTKNOW
ANYTHINGABOUT$OGSORANYTYPE
BESIDES/BJECT
4HESHORTANSWERISTHATTHE
COMPILERPUTSINTHECASTFORYOU
7HENYOUSAY!RRAY,IST$OG
THEREISNOSPECIALCLASSTHATHAS
METHODSTOTAKEANDRETURN$OG
OBJECTSBUTINSTEADTHE$OG
ISASIGNALTOTHECOMPILERTHAT
YOUWANTTHECOMPILERTOLET
YOUPUT/.,9$OGOBJECTSIN
ANDTOSTOPYOUIFYOUTRYTOADD
ANYOTHERTYPETOTHELIST!ND
SINCETHECOMPILERSTOPSYOU
FROMADDINGANYTHINGBUT$OGS
TOTHE!RRAY,ISTTHECOMPILER
ALSOKNOWSTHATITSSAFETOCAST
ANYTHINGTHATCOMESOUTOFTHAT
!RRAY,ISTDOA$OGREFERENCE)N
OTHERWORDSUSING!RRAY,IST$OG
SAVESYOUFROMHAVINGTOCAST
THE$OGYOUGETBACK"UTITS
MUCHMOREIMPORTANTTHANTHAT
BECAUSEREMEMBERACASTCAN
FAILATRUNTIMEANDWOULDNTYOU
RATHERHAVEYOURERRORSHAPPEN
ATCOMPILETIMERATHERTHANSAY
WHENYOURCUSTOMERISUSINGITFOR
SOMETHINGCRITICAL
"UTTHERESALOTMORETOTHISSTORY
ANDWELLGETINTOALLTHEDETAILSIN
THE#OLLECTIONSCHAPTER
230
chapter 8
1) 2) 3)
4)
5)
Gi ven:
public interface Foo { }
public class Bar implements Foo { }
public interface Vinn { }
public abstract class Vout implements Vinn { }
public abstract class Muffie implements Whuffie { }
public class Fluffie extends Muffie { }
public interface Whuffie { }
public class Zoop { }
public class Boop extends Zoop { }
public class Goop extends Boop { }
public class Gamma extends Delta implements Epsilon { }
public interface Epsilon { }
public interface Beta { }
public class Alpha extends Gamma implements Beta { }
public class Delta { }
What’s the Picture ?
(interface)
Foo
Bar
1)
2)
3)
4)
5)
(ERESYOURCHANCETODEMONSTRATEYOURARTISTICABILITIES/NTHELEFTYOULL
lNDSETSOFCLASSANDINTERFACEDECLARATIONS9OURJOBISTODRAWTHEASSOCIATED
CLASSDIAGRAMSONTHERIGHT7EDIDTHElRSTONEFORYOU5SEADASHEDLINEFOR
hIMPLEMENTSvANDASOLIDLINEFORhEXTENDSv
1dQ^OU_Q
exercise: What’s the Picture?
interfaces and polymorphism
you are here4
231
Click
Top
Fee
Clack
Tip
Fi
Foo
Bar
Baz
Zeta
Beta
Alpha
Delta
1
2
3
4
5
Gi ven:
What’s the Declaration ?
1)
2)
3)
4)
5)
public class Click { }
public class Clack extends Click { }
/NTHELEFTYOULLlNDSETSOFCLASSDIAGRAMS9OURJOBISTOTURN
THESEINTOVALID*AVADECLARATIONS7EDIDNUMBERFORYOU
ANDITWASATOUGHONE
Clack
Clack
Clack
EXTENDS
IMPLEMENTS
CLASS
IN
TERFACE
ABSTRACTCLASS
KEY 1dQ^OU_Q
232
chapter 8
PUBLICINTI-ETHOD
PUBLICINTI-ETHOD[]
PUBLICINTI-ETHOD[
PUBLICINTI-ETHOD[]
CLASS
EXTENDS
INTERFACE
IMPLEMENTS
9OURJOBISTOTAKECODESNIPPETSFROMTHEPOOLAND
PLACETHEMINTOTHEBLANKLINESINTHECODEANDOUT
P
UT9OUMAYUSETHESAMESNIPPETMORETHANONCE
ANDYOUWONTNEEDTOUSEALLTHESNIPPETS9OUR
GOALISTOMAKEASETOFCLASSESTHATWILLCOMPILE
ANDRUNANDPRODUCETHEOUTPUTLISTED
.OTE%ACHSNIPPET
FROMTHEPOOLCANBE
USEDMORETHANONCE
File Edit Window Help BeAfraid
%java ______________
5 class Acts
7 class Clowns
________Of76
/UTPUT
____________ Nose {
________________________
}
abstract class Picasso implements ______{ _________________________
return 7;
}
}
class _________ ________ __________ { }
class _________ ________ __________ {
___________________________
return 5;
}
}
public ___________ ________ extends Clowns {
public static void main(String [] args) {
____________________________
i[0] = new __________
i[1] = new __________
i[2] = new __________
for(int x = 0; x < 3; x++) {
System.out.println(__________________ + “ “ + _______.getClass( ) );
}
}
}
!CTS
.OSE
/F
#LOWNS
0ICASSO
!CTS
.OSE
/F
#LOWNS
0ICASSO
I
I
IX
I;X=
II-ETHODX
IXI-ETHOD;=
I;X=I-ETHOD
I;X=I-ETHOD;=
/F;=INEW.OSE;=
/F;=I
.OSE;=INEW.OSE
.OSE;=INEW.OSE;=
CLASS
CLASS
CLASS
PUBLICCLASS
Pool Puzzle
puzzle: Pool Puzzle
interfaces and polymorphism
you are here4
233
(interface)
Vinn
public abstract class Top { }
public class Tip extends Top { }
What’s the Declaration ?
What’s the Picture ?
2)
3)
4)
5)
Fluffie
(interface)
Epsilon
(interface)
Beta
(interface)
Whuffie
Vout
Muffie
Boop
Goop
Alpha
Zoop
Delta
Gamma
public abstract class Fee { }
public abstract class Fi extends Fee { }
public interface Foo { }
public class Bar implements Foo { }
public class Baz extends Bar { }
public interface Zeta { }
public class Alpha implements Zeta { }
public interface Beta { }
public class Delta extends Alpha implements Beta { }
2)
3)
4)
5)
%XERCISE3OLUTIONS
234
chapter 8
public class Of76
extends Clowns {
public static void main(String [] args) {
Nose [ ] i = new Nose [3] ;
i[0] = new Acts( ) ;
i[1] = new Clowns( ) ;
i[2] = new Of76( ) ;
for(int x = 0; x < 3; x++) {
System.out.println( i [x] . iMethod( )
+ “ “ + i [x]
.getClass( ) );
}
}
}
File Edit Window Help KillTheMime
%java Of76
5 class Acts
7 class Clowns
7 class Of76
/UTPUT
interface
Nose {
public int iMethod( ) ;
}
abstract class Picasso implements Nose { public int iMethod( ) {
return 7;
}
}
class Clowns extends Picasso
{ }
class Acts extends Picasso
{
public int iMethod( ) {
return 5;
}
}
puzzle solution
9
constructorsand
garbagecollection
...thenhesaid,
~I
can'tfeel
my
legs!"
and
I
said"Joel
Stay
withmeJoel
H
Butitwas...toolate.Thegarbage
...
-~ ~
collectorcameand...hewasgone.
-";<"'~_"\.
BestobjectIeverhad.
LifeandDeath
ofanObject
Objectsarebornandobjectsdie.
You'reinchargeofanobject'sIIfecycie.
Youdecidewhenand
howto
construct
It.Youdecidewhento
destroy
It.Exceptyoudon't
actually
destroy
theobjectyourself,yousimply
abandon
it.
Butonceit'sabandoned,the
heartless
GarbageCollector{gel
canvaporizeit,reclaimingthememorythatobjectwas
using.Ifyou'regonnawriteJava,you'regonnacreateobjects.Soonerorlater,you'regonna
havetoletsome
ofthemgo,orriskrunningoutofRAM.Inthischapterwelookathowobjects
arecreated,wheretheylivewhilethey'realive,and
howtokeeporabandonthemefficiently.
Thatmeanswe'lltalkabouttheheap,thestack,scope,constructors,superconstructors,null
references,andmore.Warning:thischaptercontainsmaterial
aboutobjectdeaththatsome
mayflnddisturbing.Best
nottogettooattached.
thisisanewchapter
235
thestackandtheheap
fheStackat1dtheHeap:wherethit1gslive
}
Beforewecanunderstandwhatreallyhappenswhen
youcreateanobject,wehavetostepbackabit,We
needtolearnmoreaboutwhereeverythinglives
(andforhowlong)inJava.Thatmeansweneed
to
learnmoreabouttheStackandtheHeap.Injava,we
(programmers)careabouttwoareasofmemory-the
onewhereobjectslive(theheap),andtheone
wheremethodinvocationsandlocalvariableslive
(thestack).
WhenaJVMstartsup.itgetsachunkof
memoryfromtheunderlying
as,
andusesittorun
yourJavaprogram.How
mucl,
memory.andwhether
ornotyoucantweakit,isdependentonwhich
versionof
theJVM(andonwhichplatform)you're
fheStack
WheremethodInvocations
andlocalvariableslive
I
nstance
Variables
Instance
variablesaredeclared
Inside
a
claSJ
but
not
Insideamethod.Theyrepresentthe"fields"thateach
Individualobjecthas(whichcanbefilled
withdifferent
valuesforeachInstance
oftheclass).Instancevariables
liveInsIdetheobjecttheybelongto.
public
int
}
236
chapter
9
running.Butusuallyyou
WO?I',
haveanythingto
S2.y
about
it,
Andwithgoodprogramming.youprobably
won'tcare
(moreonthatalittlelater).
Weknow
thatall
objects
liveonthegarbage-collectible
heap.
butwehaven'tyetlookedatwhere
variables
live.Andwhereavariablelivesdependsonwhat
kind
ofvariableitis.And
by
"kind",wedon'tmean
type
(i.e.primitiveorobjectreference).Thetwo
kinds
of
variableswhoseliveswecareaboutnoware
instance
variablesand
local
variables.Localvariablesarealso
knownas
slack
variables,whichisabigclueforwhere
theylive.
fheHeap
Where
ALL
objectslive
LocalVariables
LocalvariablesaredeclaredInsidea
method,
Including
methodparameters,They'retemporary,andliveonlyas
longasthemethodisonthestack(in
otherwords,aslongas
themethodhas
notreachedtheclosingcurlybrace).
constructorsandgc
Methodsarestacked
Acallstackwithtwomethods
,UtI'-
~y~ ~,- i!!~~ ~
?l.........
boitor..
of
-the
statk
Themethodonthetopofthe
stackisalwaysthecurrently-
executingmethod.
Whenyoucallamethod,themethodlandson
thetopofacallstack.Thatnewthingthat's
actuallypushedontothestack
is
thestack
frame,
anditholdsthestateofthemethod
includingwhichlineofcodeisexecuting,and
thevaluesofall
local
variables.
Themethodatthe
top
of
theslackis
always
thecurrently-runningmethodforthatstack
(fornow,assumethere'sonlyonestack.butin
chapter
14
we'lladdrnore.)
A
methodstayson
thestackuntilthemethod
hits
itsclosingcurly
brace(whichmeansthe
method's
done).If
method
foo()
callsmethod
bar(),
method
bast)
is
stackedontop
of
methodfoot).
publicvoiddoStuff(){
booleanb
=
true;
go(4);
publicvoidgo(intx)
intz
=
x
+
24;
crazy();
//imaginemorecodahere
Astackscenario
Thecodeontheleftisasnippet(wedon'tcarewhattherestofthe
class
lookslike)
with
threemethods.Thefirstmethod
(drot-u.ff(»
calls
thesecondmethod
(go(),
andthesecondmethodcallsthethird
(craz)'()).
Eachmethoddeclaresonelocalvariablewithinthebody
ofthemethod,andmethod
goO
alsodeclaresaparametervariable
(which
means
goO
hastwolocalvariables).
publicvoidcrazy()
charc
=
'a';
•Codefromanother
classcallsdoStuffO,
and
doStuffOgoes
intoa
stackframe
atthetopofthe
stack.Theboolean
variablenamed'b'
goeson
thedoStuffO
stackframe.
@
doStuffOcalls
goO,
goOis
pushed
on
topof
thestack.
Variables'x'and
'z'
areinthe
goO
stack
frame.
@goOcellscrozyO,
crozyQisnowon
the
topofthestack,
withvariable'e'in
theframe.
@crazy()completes,
anditsstackframeis
popped
offthestack.
Executiongoesback
to
thegoOmethod.
andpicksup
atthe
linefollowingthecaU
tocrazy().
you
arehere.
237
publicvoidbarf(){
Duckd'"
Dew
Duck(24);
publicclassStackRef
publicvoidfoof()
barf();
objectreferencesonthe
stack
Whataboutlocalvariablesthatareobjects?
Remember,anon-primitivevariableholdsa
reference
toan
object,
nottheobjectitself.Youalreadyknowwhereobjects
live--ontheheap.Itdoesn'tmatterwherethey'redeclaredor
created.
If
thelocal
variable
is
a
reference
to
anobject,
only
the
variable
(the
reference/remotecontrol)goeson
the
stack.
.,.t.....
The
objectitselfstillgoesin
the
heap.
0
t\a'C'es
a~ t'"t.a~ ~ si~t.
\t:
s
'oa~O
elJay∙'i"o\t.
rt
sa
\ot.i\
t""IlIL~
,"to
~
tv"
t.,.tl.
e
",e\:.h0
0
I
v
1.
,.s\ot.
.\)I
~t\L.
ot.i\ayt.
o
'
ov.
()YI
-\:.'M
...."o\e
6,,0
~
'l4ayl..
~
Q:
Onl!!moretime,WHYarewelearningthe
wholestack/heapthing?Howdoesthishelpme?
DoI
reallyneedtolearnaboutIt?
A.:
KnowlngthefundamentaIsoftheJava
StackandHea
piscrucialIfyouwanttounderstand
variablescope,objectcreationIssues,memory
management,threads,andexceptionhandling.
WecoverthreadsandexceptionhandlingInlater
chapters
buttheothersyou'llleamInthisone.You
do
notneedtoknowanythingabout
how
theStack
andHeapareImplementedinanyparticularJVM
and/orplatform.Everythingyouneedtoknow
abouttheStackandHeapIsonthispageandthe
previousone.Ifyounailthesepages,alltheother
topics
thatdependonyourknowingthisstuffwill
gomuch,much,mucheasier.Onceagain,someday
you
willSOthankusforshovingStacksandHeaps
downyourthroat.
238chapter9
~
Javahastwoareasofmemorywecareabout
theStackandtheHeap.
~
Instancevariablesarevariablesdeclared
insIdeaclassbutoutsideanymethod.
~
Localvariablesarevariablesdeclaredinsidea
methodormethodparameter.
~
Alllocalvariablesliveonthestack,Inthe
framecorrespondingtothemethodwherethe
variablesaredeclared.
~
Objectreferencevariableswork.justlikeprimi-
tivevariables-ifthereferenceisdeclaredasa
localvariable,
it
goesonthestack.
..AllobjectsliveIntheheap,regardlessof
whetherthereferenceisalocalorInstance
variable.
IflocalvariablesliveOttthe
staek.
wheredoI"stattcevariableslive?
..
WhenyousaynewCellf'hone(),Javahastomake
spaceontheHeapforthatCellPhone.Buthow
much
space?Enoughfortheobject,whichmeansenoughto
house
all
oftheobject'Sinstancevariables.That'sright,
instancevariablesliveonthe
Heap,insidetheobject
they
belongto.
Rememberthatthe
values
ofanobject'sinstance
variablesliveinside
theobject.litheinstancevariables
areallprimitives,Javamakesspacefortheinstance
variablesbasedon
theprimitivetype.An
int
needs
32
bits,
a
long
64
bits,
etc.java
doesn'tcareaboutthe
valueinsideprimitivevariables;thebit-sizeofanint
variable
is
thesame
(32
bits)whetherthevalueofthe
intis
32,000,000
or32.
Butwhatif
theinstancevariablesare
objects?
What
if
CeliPhoneHAS-AAntenna?Inotherwords,CellPhone
hasa
referencevariableoftypeAntenna.
Whenthenewobjecthasinstancevariablesthatare
objectreferencesratherthanprimitives,thereal
questionis:doestheobjectneedspaceforaUof
theobjectsitholdsreferencesto?Theansweris,
not
exQ.{;tly.
Nomatterwhat,Javahastomakespaceforthe
instancevariable
values.
Butrememberthatareference
variablevalueisnotthewhole
object,
butmerelya
remote
control
to
theobject.So
if
CellPhonehasaninstance
variable
declaredasthenon-primitivetypeAntenna,
Javamakesspacewithinthe
CellPhoneobjectonlyfor
theAntenna's
remotecontrol
(i.e.referencevariable)but
nottheAntenna
object.
WellthenwhendoestheAntenna
object
getspaceon
theHeap?Firstwehave
to
findout
whim
theAntenna
objectitselfiscreated.Thatdependsontheinstance
variabledeclaration.
litheinstancevariableisdeclared
butnoobjectisassignedto
it,
thenonlythespacefor
thereferencevariable(theremotecontrol)iscreated.
privateAntennaant;
NoactualAntennaobject
is
madeontheheapunless
oruntilthereferencevariableisassignedanew
Antennaobject.
privateAntennaant::newAntenna();
constructorsandgc
Objettwit.htwop-ri...itiveiJ\St..l"te\/al'"iablcs.
SpdU
+~
theval'"iableslives
i"
the
~jed:,
Objtttwit.h
l»\t
)lOtl-rv-i...itiveir.st..lrlttlIariable-
a
I'"ttt
r-
tlIte
to
d"
A"b,."a
objett.,blot.
"0
olthadl
A"un'nd
objtd~
Thisis\oIhat.
yO'J.
~d,
it
YO4/.
detlal"'tt.helIariable
b...
t.dOtl'i,initialiuitwith
a"
ad:lodlAnta.naobjett.
publicclassCellPhone
private
Antenna
ant;
Objett.with
Ol'le
"or.-p-ri....i-lilleiJ\Stal">ttlIariable,
andtht
A"~,,a
IIdr-iableis
as.si~"ed
a
l\tw
A"u",."a
objet+"
publicclassCellPhone(
privateAntennaant
=
new
Antenna
(l;
youarehere
~
239
objectcreation
fhetttiracleofobjectcreatlott
Nowthatyouknowwherevariablesandobjectslive,wecandiveinto
themysteriousworldofobjectcreation.Rememberthethreesteps
ofobjectdeclarationandassignment:declareareferencevariable,
createanobject,
andassigntheobjecttothereference.
Butuntilnow,steptwo--whereamiracleoccurs
andthenewobject
is
"boron-hasremaineda
Big
Mystery.Preparetolearnthefactsof
objectlife.
Hope
you're
notsqueamish.
Reviewthe3stepsofobject
declaration,creationandassignment:
O
Declareareference
variable
DuckmyDuck
=
newDuck():
e
Createanobject
.
~t.\t.~
DuckmyDuck
=
new
Duck();
~
yV\\V'
gI
e
ot.t.v.V'~
"tv'.
e
Linktheobjectand
thereference
DuckmyDuck@)newDuck();
_--rWL
Duckreference
240chapter9
ArewecallingamethodnamedDuckO?
Because
it
surelookslike
it.
DuckmyDuck
=
No.
We'recallingtheDuck
constructor.
constructorsandgc
Aconstructor
does
lookandfeelalotlikeamethod,butit'snot
amethod.It'sgotthecodethatrunswhenyousaynew.
In
other
words,
the
code
that
runs
when
you
instantiateanobject.
Theonlywaytoinvokeaconstructor
is
withthekeywordnew
followedbytheclassname,ThejVMfindsthatclassandinvokes
theconstructorinthatclass.(OK,technicallythisisn'tthe
only
waytoinvokeaconstructor,Butit'stheonlywaytodoitfrom
outside
aconstructor.You
ca'n
callaconstructorfromwithin
anotherconstructor,withrestrictions,butwe'llgetinto
all
that
laterinthechapter.)
ButwhereIstheconstructor?
Ifwedidn'twriteIt,whodid?
Youcanwriteaconstructorforyourclass(we'reabouttodo
that),but
if
youdon't,
the
compilerwrites
one
foryou!
Here'swhatthecompiler'sdefaultconstructorlookslike:
public
Duck(){
}
Noticesomethingmissing?HowIs
this
~
differentfromamethod?
1.
e
'IS
~t
sa",t
as
1t~'-I
Iv
I'd'"
T\\at
s
,..a"da\,Pl,.
~
t.\ass
y,d",t∙
~Duck()
(
~trejs
theretllm
t//
constructorcodegoeshere
I
thisWtre
a
1,
ype?)
j
rheOlod
you
d
heed
d
'ret
t
j
betweehl'PlI.b/',,"
m
yPe
llDlAlkO",
It.
arid
youarehere.
241
constructinganewDuck
Theconstructorgives
youachancetostepinto
themiddleof
new.
publicDuck(){
System.out.println("Quack~)
;
publicclassDuck{
Thekeyfeatureofaconstructor
is
thatitruns
before
theobjectcanbeassignedtoareference.
Thatmeansyougetachance
to
stepinand
dothingstogetmeobjectreadyforuse.
In
otherwords,beforeanyonecanusetheremote
contra]foranobject,theobjecthasachanceto
helpconstructitselfInourDuckconstructor,
we'renotdoinganythinguseful,butitstill
demonstratesthesequenceofevents.
CottStructaPuck
}
publicclassUseADuck{
publicstaticvoidmain(String[]args){
Duckd
=
newDuck();
f--
!h;s
~lJs
in
D
(.orutr-lAl!or.
t:
lI.lk
~
%
javaUseADuck
Quack
AconstructorletsyouJumpIntothemiddle
oftheobjectcreation
step-intothemiddle
of
new.
Can
you
imagineconditionswhere
thatwouldbeuseful?Whichofthesemight
beusefulinaCarclassconstructor,
if
theCar
ispartofaRacingGame?Check
offtheones
thatyoucameupwithascenariofor.
o
Incrementacountertotrackhowmanyobjectsofthisclasstype
havebeenmade.
o
Assignruntime-specificstate(dataaboutwhat'shappeningNOW).
o
Assignvaluestotheobject'simportantinstancevariables.
o
Getandsaveareference
10
Ihe
objectthat's
creating
thenewobject.
o
AddtheobjecttoanArrayList.
o
CreateHAS-Aobjects.
o
(yourideahere)
242chapter9
}
InitializingthestateofanewPuck
Mostpeopleuseconstructorstoinitializethestateofanobject.
Inotherwords,tomakeandassignvaluestotheobject's
instancevariables.
publicDuck(){
size
=
34;
}
That'sallwellandgoodwhentheDuckclass
developer
knows
howbig
theDuckobjectshouldbe.Butwhat
if
wewantthe
programmerwhoisusingDucktodecidehowbigaparticular
Duckshouldbe?
ImaginetheDuckhasasizeinstancevariable,andyouwantthe
programmerusingyourDuckclasstosetthesizeofthenew
Duck.
Howcouldyoudo
it?
Well,youcouldaddasetSize()settermethodtotheclass.But
thatleavestheDucktemporarilywithoutasize*,andforcesthe
Duckusertowrite
two
statements-onetocreatetheDuck,and
onetocallthesetSize()method.Thecodebelowusesasetter
methodtosettheinitialsizeofthenewDuck.
publicclassDuck{
intsize;
'f--
iY\Sta\'lt..e
~aYiah\e
publicDuck(){
System.out.println("Quack");
'f--
t.oY\ShvLto'r
}
publicvoidsetSize(intnewSize){
~
set..t,eY",et.'nod
size
=
newSize;
}
}
publicclassUseADuck{
publicstaticvoidmain(String[]args){
Duckd
=
newDuck();
T
t--...
i
~~r~'~
abad
thih
h
d.setSize(42);
A
h~
i
PO
/
ht
;1'1
ih~ l~ ~b~'iThe
DlAtk
is
aI'
1'1
hel'l
"OlA'
I~'
lA
witht
/V~
ai
to
KNOW
~hatD~
yihS
01'1
ih~
D:t
a
Si~!*,
protess:
Ol'le
i
lAtk
lr~atioh
is
k-fAS~r
to
tall
th~
Stt
1
~all ih~
tohSirlAtkiwo-pari
Ul-.
ahd
Oh~
*Instancevariablesdohaveadefaultvalue.0or
0.0fornumericprimitives,falseforbooleans,and
nullforreferences.
constructorsandgc
there]lU'H?
Dumo
~uest19ns
Q.:
Whydoyouneedtowrite
aconstructorif
thecompiler
writesoneforyou?
A:
Ifyouneedcodetohelp
initializeyour
objectandget
itreadyforuse,you'llhaveto
writeyourownconstructor.You
might,
forexample,bedepen-
dentoninputfromtheuser
beforeyoucanfinishmaking
the
objectready.There'sanother
reasonyou
mighthavetowrite
aconstructor,even
ifyoudon't
needanyconstructorcode
yourself.Ithastodo
withyour
superclassconstructor,andwe'll
talk
aboutthatinafewminutes.
Q.:
Howcanyoutellacon-
structorfromamethod?Can
youalsohaveamethodthat's
thesamenameastheclass?
A:
Javaletsyoudeclarea
method
withthesamenameas
yourclass.Thatdoesn'tmakeit
aconstructor,
though.Thething
thatseparatesamethodfroma
constructoristhereturntype.
Methodsmusthave
areturn
type,
butconstructorscannot
haveareturntype.
0:
Areconstructorsinher-
it~(h
Ifyoudon'tprovidea
constructor
butyoursuperclass
does,doyou
getthesuperclass
constructorinsteadof
the
default?
A.:
Nope.Constructorsare
notinherited.We'lllookatthatin
justafewpages.
youarehere),243
initializingobject
state
o
LettheusermakeanewDuck
and
settheDuck'ssizeallin
onecall.Thecall
tonew.
Thecall
totheDuck
constructor.
size
=
duckSize;
\:.0
~t
\,,~ ~a'<3""~t'!
publicclassDuck{
fl\4~
0....
1cc~Jv:i'f'
intsize;
~\)uL~!,o~
publicDuck(intduckSize)(
System.out.println("Quack");
L
lw:
-to
~
l,(~
the
ar~Uft\~~
va
~
thesiz.ei"s!:.a"tevariable.
Ushtgthe
eenstruetor
toit1itialize
itMportat1tPock
state"
If
anobjectshouldn'tbeuseduntiloneor
morepartsofitsstate(instancevariables)have
beeninitialized,don
't
letanyonegetaholdof
aDuckobjectuntilyou'refinishedinitializing!
It'susuallywaytooriskytolet
someonemake-
andgetareferenceto-anewDuckobjectthat
isn
't
quitereadyforuseuntilthatsomeonerums
aroundandcallsthe
setSize()
method.Howwill
theDuck-usereven
know
thathe'srequiredto
call
thesettermethodaftermakingthenewDuck?
Thebestplacetoputinitializationcodeisinthe
constructor.Andallyouneedtodoismakea
constructorwitharguments.
System.out.println("sizeis"
+
size);
}
publicclassUseADuck{
"NOIIOImplythainotallDuckstateIsnolunlmportanL
244chapter9
Make
it
easyto",akeaPucle
Jesureyouhaveatlo..argcOtldructor
Whathappens
if
theDuckconstructortakesanargument?
Thinkaboutit.Onthepreviouspage,there'sonlyoneDuck
constructor-andittakesan
int
argumentforthe
size
ofthe
Duck.Thatmightnotbeabigproblem,but
it
doesmakeit
harderforaprogrammertocreateanewDuckobject,especially
if
theprogrammerdoesn't
knot»
whatthesizeofaDuckshould
be.Wouldn'titbehelpfultohaveadefaultsizeforaDuck,so
that
if
theuserdoesn'tknowanappropriatesize,hecanstill
makeaDuckthatworks?
ImaginethatyouwantDuckuserstohave
TWO
optlons
formaking
a
Duck-onewheretheysupplytheDuck
size(astheconstructorargument)
andonewherethey
don'tspecify
a
sizeandthusgetyourdefaultDucksize.
•
Youcan'tdothiscleanlywithjustasingleconstructor.
Remember.
if
amethod(orconstructor-s-samerules)has
aparameter,you
must
passanappropriateargumentwhen
youinvokethat
methodorconstructor.Youcan'tjustsay,
"If
someonedoesn'tpassanythingtotheconstructor,thenuse
thedefaultsize",becausetheywon'tevenbeabletocompile
without
sendinganintargumenttotheconstructor
call.
You
could
dosomethingc1unklylikethis:
'publicclassDuck
intsize;
ButthatmeanstheprogrammermakinganewDuckobjecthas
to
knou:
thatpassinga"0"istheprotocolforgettingthedefault
Ducksize.Prettyugly.What
if
theotherprogrammerdoesn't
knowthat?Orwhat
if
hereally
does
wantazero-sizeDuck?
(Assumingazero-sizedDuckisallowed.
lfyoudon'twant
zero-sizedDuckobjects,
putvalidationcodeintheconstructor
toprevent
it.)
Thepoint
is,
it
mightnotalwaysbepossible
todistinguishbetweena
genuine"Iwantzeroforthesize"
constructor
argumentanda"I'msendingzerosoyou'llgive
me
thedefaultsize,whateverthatis"constructorargument.
constructorsandgc
YoureallywantTWOwaysto
makeanewDuck:
publicclassDuck2
int
size;
public
Duck.2()(
II
supplydefaultsize
size;;
27;
public
Duck2
(int
dUckSize)(
//
uaeduckSiz8parameter
size'"
duckSize;
TomakeaDuckwhenyouknowthesIze:
Duak2
d;;
new
Duck2(15):
TomakeaDuckwhenyoudonotknow
thesize:
Duck.2
d2""
new
Duck2();
Sothistwo-optlons-to-make-a-DuckIdea
needstwo
constructors.
One
thattakes
anIntandone
that
doesn't.Ifyouhaw
mor«thanoneconstructor
In
adau,
It
means
you
have
overloaded
constructors.
youarehere
~
245
overloadedanddefault
constructors
Poes""tthe
cotMpiler
always
",akea
"o-arg
eonstrueter
foryou?
~I,
Youmightthinkthat
if
youwrite
only
aconstructor
with
arguments,the
compilerwillseethatyoudon'thavea
no-arg
constructor,andstickoneinfor
you.Butthat's
nothowitworks.The
compilergetsinvolvedwithconstructor-
making
only
if
you
don't
sayanything
atall
aboutconstructors.
Ifyouwriteaconstructorthat
takesarguments,andyou
stili
wantano-argconstructor,
you'llhavetobuildtheno-arg
constructoryourself!
As
soonasyouprovideaconstructor,
ANY
kindofconstructor,thecompiler
backsoffandsays,"OKBuddy,lookslike
you
'reinchargeofconstructors
now,"
Ifyouhavemorethanone
constructorInaclass,the
constructorsMUSThave
differentargumentlists.
Theargumentlistincludestheorder
andtypesofthearguments.
As
longas
they'redifferent,youcanhavemore
thanoneconstructor.Youcandothis
with
methodsaswell,butwe'llgettothat
inanotherchapter.
246
chapter9
constructorsandgc
Overloadedconstructorsmeansyouhave
morethanoneconstructorinyourclass.
Tocompile,eachconstructormusthavea
dlffersnt
argumentIIstl
Theclassbelowislegalbecauseallfourconstructorshave
differentargumentlists.lfyouhadtwoconstructors
that
took
onlyanint,forexample,theclasswouldn'tcompile.Whatyou
nametheparametervariabledoesn'tcount.It'sthevariable
type
(int,Dog,etc.)and
order
thatmatters.You
can
havetwo
constructorsthathaveidenticaltypes,
as
long
astheorder
is
different.
AconstructorthattakesaStringfollowed
by
anint,
is
not
thesameasonethattakesanintfollowed
by
aString.
kr..o
w
th~
S'IU,
Dlo-t
~Q\i.
pub
licclassMushroom{.
whc"
'jo'J.
.r.
L',.,.al:lit
~
dOWl'
-tkF>Ow
i-t
'n.
s;)
publicMushroom
(int
size){}
u-\.\....
~
~
htJI
'fC)U.
dor-.'t.kno-.l
6Y11""'"
public
Mushroom(){.
W
k
i-t
it's
,.,.a~It.
(Jr
Y\O-I:.
~
wMl\
'1~t
k
t\l~
siu
public:
Mushroom
(booleanisMaqic)(.D\,I.-t
dOWl
nOW
f
publ1C:
Mushroom
(booleanisMaqic,intsize)}
~~ ~
its
:~it.,
AND
'f$
\{,.O'<l
public
Mushroom
(int
size,booleanisMaqic)•
thC
siu.
as
well
~
Instancevariableslivewithintheobjecttheybelongto,on
~
Ifyouwantano-arg
consructor
andyou'vealreadyput
theHeap.inaconstructorwitharguments,you'llhavetobuildthe
~
Iftheinstancevariableisareferencetoanobject,both
no-argconstructoryourself.
thereferenceandtheobject
it
refers
to
areontheHeap.
~
Alwaysprovideano-argconstructor
if
youcan,
to
makeIt
~
Aconstructoristhecodethatrunswhenyousay
new
on
easyforprogrammerstomakeaworkingobjectSupply
aclass
type.
defaultvalues.
~
Aconstructormusthavethesamenameastheclass,and
~
Overloadedconstructorsmeansyouhavemorethanone
must
not
haveareturntype.
constructorinyourclass.
~
YoucanuseaconstructortoInitializethe
state
(Le.the
..
Overloadedconstructorsmusthavedifferentargument
instancevariables)oftheobjectbeingconstructed.
lists.
~
If
you
don'tputaconstructorinyourclass,thecompiler
~
Youcannothave
two
constructorswiththesame
willputInadefaultconsnuctor.
argumentlists.AIlargumentlistIncludestheorderand/or
typeofarguments.
~
Thedefaultconstructorisalwaysano-argconstructor.
Instancevariablesareassignedadefaultvalue,even
Ifyouputa
constructor~ny
conslructor-inyourclass,
~
~
whenyoudon'texplicitlyassignone.Thedefaultvalues
thecompilerwillnotbuildthedefaultconstructor.
are
DID.Olfalse
forprimitives,andnullforreferences.
youarehere
~
247
..
overloadedconstructors
d[O]=newDuck():
classDuck{
publicstaticvoidmain(String[]args)(
publicDuck(boolean
fly){
canFly
=
fly;
System.out.printin("type2duck"):
public
Duck(Stringn,long[]
~)
(
name
=
n:
feathers=
f;
Syst&m.out.printin("type3duck"):
publicDuck()(
System.out.printin("type
1
duck");
intpounds
=
6;
floatfloatabili
ty
=
2.IF;
Stringname="Generic";
long[]feathers
=
{l,2,3,4,S,6,7};
booleancanFly
=
true:
int
maxSpeed
=
25;
publicclassTestDuck{
Matchthe
new
Duck()
callwiththeconstructor
thatrunswhenthatDuckisinstantiated.
We
did
theeasyone
to
getyoustarted.
intweight
=
8;
floatdensity=2.3F;
Stringn8I118="Donald";
lonq[)feathers={l,2,3,4,5,6}:
booleancanFly
=
true:
intairspeed
=
22:
Duck[]d=new
d[l]newDuck(density,weight);
d[2]
=
newDuck(name,feathers):
d[3]
=
newDuck(canFly);
d[4]newDuck(3.3F,airspeed):
d[S]
=
newDuck(false);
d[6]
=
newDuck(airspeed,density);
publicDuck(intw,floatf)
pounds
=w;
floatability
=
f;
SysteJn.out.println("type4duck"):
publicDuck(floatdensity,int
IIIAX){
floatability
=
density:
maxSpeed
=
max;
SysteJn.out.println("type5duck");
Q.:
EarlieryousaidthatIt'sgoodtohaveano-argu-
mentconstructor
50
that
if
peoplecalltheno-argcon-
structor,we
cansupplydefaultvaluesforthe"mlsslng
n
arguments.Butaren'ttheretimeswhenIt'sImpossibleto
comeupwithdefaults?Aretheretimeswhenyoushould
nothaveano-argconstructorInyourclass?
.A..:
You'reright.Therearetimeswhenano-argconstruc-
tordoesn'tmakesense.You'llseethisintheJavaAPI-some
classesdon'thaveano-argconstructor.TheColorclass,for
example,representsa...color.Colorobjectsareusedto,for
example,setorchange
thecolorofascreenfontor
GUI
button.WhenyoumakeaColorInstance,thatinstanceIs
ofa
particularcolor(youknow,Death-by-ChocolateBrown,
Blue-Screen-of-DeathBlue,ScandalousRed,
etc.),
Ifyou
make
a
Colorobjectyoumustspecifythecolor
In
someway.
Color
c;
newColor(3,45,200);
(We'reusingthreeIntsforRGBvalueshere.We'llgetinto
usingColorlater,intheSwingchapters.)Otherwise,what
wouldyouget?TheJavaAPIprogrammers
could
havede-
cided
thatifyoucallano-argColorconstructoryou'llgeta
lovelyshade
ofmauve.Butgood
taste
prevailed.
Ifyou
try
tomakeaColorwithoutsupplyinganargument:
Color
c;
newColor();
Thecompilerfreaksoutbecause
It
can'tfindamatching
00-
arg
constructor
intheColorclass.
248
chapter9
Nattoreview:four
thittQs
to
relHelHberabouteonstrueters
DoIngalltheBrainBarbellshasbeenshown10oreducea42%increasein
neuronsize.Andyouknowwhattheysay,"8lgneurons..'-
•
•
•
•
A
constructoristhecodethatrunswhen
somebodysrrys
new
onaclasstype
Duckd
=
newDuck();
Aconstructormusthavethesamenome
as
theclass,andnoreturntype
publicDuck(int
size){}
Ifyoudon'tputaconstructorinyourclass,
thecompilerputsinadefaultconstructor.
The
defaultconstructorisalwrrysano-arg
constructor.
publicDuck(){}
Youcanhavemorethanoneconstructorinyourclass,
aslongas
theargumentlistsaredifferent.Having
morethanone
constructorinaclassmeansyouhave
overloaded
constructors.
publi
c
Duck(){
publicDuck(int
size){}
publicDuck(Stringname)
publicDuck(Stringname,intsize){}
constructors
and
gc
Whatabout5uperclasses?
WhenyoumakeaDog,
should
theCanine
construdorruntoo?
If
thesuperclassisabstract,.
shoulditeven
have
a
construdor?
We'lllookatthisonthenext
few
pages,sostopnowand
thinkabouttheimplicationsof
constructorsand
superclasses.
dfim~~esti9ns
Q.:
Doconstructorshavetobe
public?
A:
No.
Constructorscanbe
public,
private,
ordefault
(whichmeansnoaccess
modifieratall).We'lllook
moreat
default
accessinchapter16andappendixB.
Q.:
Howcouldaprivateconstructor
everbeuseful?NobodycouldevercallIt,
so
nobodycouldevermakeanewobjectl
A..:
Butthat'snotexactlyright.Marking
somethingprivatedoesn'tmean
nobody
canaccessIt,itJustmeansthat
nobody
outside
the
class
canaccess
it.
Betyou're
thinking"Catch22':Only
codefromthe
same
classastheclass-witb-private-con-
structorcanmakeanewobjectfromthat
class,butwithoutfirstmakinganobject,
howdoyouevergettoruncodefromthat
classinthefirstplace7Howdoyoueverget
toanythinginthatclass?
Patiencegrasshop-
per.
We'llgetthereinthenextchapter.
youarehere
~
249
spaceforanobject'ssuperclassparts
Waifa
tMI"ute...we"everUIPtalkabout
superclassesandhtherita"ceandhowthatall
fitsI"withconstructors.
Here'swhereitgets
fun.
Rememberfromthelastchapter,thepartwherewelookedat
theSnowboardobjectwrappingaroundaninnercorerepresentingtheObjectportion
of
theSnowboardclass?TheBigPointthere
was
thateveryobjectholdsnotjust
its
oum
declaredinstancevariables,but
also
roerythingjromits
superclasses
(which,ataminimum,
meansclassObject,since
every
classextendsObject).
So
whenanobject
is
created(becausesomebodysaidnew;thereis
noother
way
tocreate
anobjectotherthansomeone,somewheresayingnewontheclasstype),theobject
getsspacefor
all
theinstancevariables.from
all
the
way
uptheinheritancetree.Think
about
it
foramoment...asuperclassmighthavesettermethodsencapsulatingaprivate
variable.
Butthatvariable
has
tolive
somewhere.
Whenanobject
is
created,it'salmostas
though
multiple
objectsmaterialize-theobjectbeingnew'dandoneobjectpereach
superclass.Conceptually,though,it's
muchbettertothinkof
it
likethepicturebelow,
wheretheobject
beingcreatedhas
layers
ofitselfrepresentingeach
superclass,
A
si~le
objet+'
Oft
the
heay
ObjetthasIPlStar.tt
varidbl~
trlUpslAlclUdbyatuss
",ethods.
no~
il'lStal'lU
Vc1\"'ic1bl~
c1ye
t\"'e..1~d
whenany5lAbt.lass
is
iPlStantiaUd.
(nest
a.,.t;n'tf.ht
REAL
Objttt
va\"'idbl~,
butwe
donIt
ta.,.e
what
tht'f
dl"'tsil'lU
they'reeY>tc1ps-Jaud)
Sroowboardalso
has
ir-sidntt
variables
0+
its
0WJ\j
so
1:.0...
ake
a
Snowboardobjettwt""eed
5yc1tt
.for
theinstantevariables
0+
both
classes.
-
Object
Foo
8;
Intb:
Inlc;
&qualsO
gelClassO
hashCodeo
IoStringQ
T
Snowboard
Foox
Fooy
Inlz
lumO
shradO
geWrQ
loseConlrolO
Thertisonly
ON~
objett
0""
the
he.ly
htye.
A
Snowboardobjett.Bt..t
it
t.ontail'lS
both
the
Sl"oowboardfdrt.s
of
ihtl.fandthe.Q!.iet.tYc1rt.s
o.f
itself
1\11
il'lStar.tevc1l"'iables
~YOtll
bothdasstshave
to
be
nC\"e.
250
chapter
9
fheroleofsuperclassecastrueters
ittattobJecfslife.
All
the
constructors
inan
object's
inheritance
treemustrun
when
you
make
a
new
object.
Letthatsinkin.
Thatmeanseverysuperclasshasaconstructor
(becauseevery
class
has
a
constructor),andeach
constructorupthehierarchyrunsatthetimean
objectofasubclassiscreated.
SayingnewisaBigDeal.Itstartsthe
wholeconstructorchainreaction.Andyes,
even
abstract
classes
haveconstructors.
Althoughyoucanneversaynewon
an
abstract
class,an
abstract
class
is
still
a
superclass,
soitsconstructorruns
whensomeonemakesaninstanceofa
concrete
subclass.
Thesuperconstructors
run
tobuild
outthesuperclasspartsoftheobject.
Remember,
a
subclassmightinherit
methodsthatdependonsuperclassstate
(in
otherwords,thevalueofinstancevariables
in
thesuperdass).Foranobjecttobe
fully-
formed,allthe
superclass
partsofitselfmustbe
fully-formed,
andthat'swhythesuperconstructor
must
run.Allinstancevariablesfromeveryclass
in
theinheritancetreehavetobedeclaredand
initialized.EvenifAnimalhasinstancevariables
thatHippodoesn'tinherit(ifthevariablesare
private,forexample),theHippostilldependson
theAnimalmethodsthat
use
thosevariables.
When
a
constructorruns,it
immediatelycalls
its
superclassconstructor,all
the
way
lipthechain
untilyougettothe
class
Object
constructor,
Onthenextfewpages,you'lllearnhowsuperclass
constructorsarecalled,andhowyoucancall
themyourself.You'Ualsolearnwhattodoifyour
superclassconstructorhasarguments!
constructorsandgc
Oblect
I"
AnImal
-~f
HIDDO
AnewHippoobjectalsoIS-AAnimal
and
IS-AObject.If
youwanttomakea
Hippo,youmustalsomaketheAnimal
and
Object
parts
of
theHippo.
ThisallhappensInaprocesscalled
ConstructorChaining.
youare
here.251
objectconstruction
Maklt1Qa
Hippo
ttteat1s
tMakit1Q
the
At1hMal
at1dObject
parts
too...
What'stherealoutput?Giventhe
codeontheleft,whatprints
out
whenyourunTestHippo?
A
or
87
(theanswerIsatthebottomofthepage)
publicclassAnimal{
publicAnimAl()(
System.out.p1:'intln("Maldllgan
Animal");
publicclassHippo
axtands
Animal(
public
Hippo(){
System.out.printin("Making
a
BippoH);
publicclassT8StBippo{
public
staticvoidmain(String[]args)
System.
out.println("Starting...");
Hippoh..
new
Hippo();
A
B
~
%
java
TestHippo
Starting...
Making
an
Animal
Makinga
Hippo
~
%
java
TestHippo
Starting...
Making
a
Hippo
MakinganAnimal
•Codefromanother
class
says
new
Hippo()
andthe
HlppoQ
constructor
goesinto
a
stack
frameatthetopof
thestack.
...
Hlp~
invokes
thesuperclass
constructorwhich
pushes
the
AnlrnalO
constructor
ontothe
topofthestock.
•AnlmolOinvokes
thesuperclass
constructorwhich
pushes
theObject()
constructoronto
thetopofthestock.
since
Objectisthe
superclossofAnimal.
@
ObjectOcompletes,
andits
stackframe
is
popped
offthe
stock.Executiongoes
backto
the
AnlmolO
constructor,and
picksup
attheline
followingAnimal's
calltoitssupercloss
constructor
252chapter9
lSJy
s94SlUij
19~1
JOPnJlsuCl:llewlUV'91.11
S.l1
lnq
'I S J ~ pe~O!IU!
&1
JOlOfIJlSUOO
Oodd!H
e41
'd
'eue
ISJ~
9lU
How
doyoulnvekeasuperclasscOMstructot1
Youmightthinkthatsomewherein,
say,
aDuckconstructor,
if
Duckextends
Animal
you'dcall
Anirnalj).
Butthat'snot
how
it
works:
publicclassDuckexttmdsAnimal{
intsize;
publicDuck(intnewSize){
1(,~t>~
--4-
Animal()
i
~
NOI
ti:.
size
=
newSize;.
hl~
's
lIot
IeII
}
~.
}
Theonlywaytocallasuperconstructorisbycalling
superi),
That'sright-super()callsthe
super
consIn.tctor.
Whatarethe
odds?
publicclassDuckextendsAnimal{
intsize;
publicDuck(intnewSize){
constructors
and
gc
Andhowisitthatwe've
gottenawaywithout
doingit?
Youprobablyfiguredthatout,
Ourgoodfriendthecompiler
putsinacallto
super()
Ifyou
don't.
Sothecompliergetsinvolvedin
constructor-makingintwoways:
<D
Ifyou
don't
provideaconstructor
Thecomplierputsoneinthatlookslike:
publicClassName()
super();
super();
~(-~
size
=
newSize;
®
I'you
do
provideaconstructor
butyoudo
not
putinthecallto
superl)
A
callto
suPer()
inyourconstructorputsthe
superclass
constructoronthetopoftheStack,Andwhatdoyou
thinkthatsuperclassconstructordoes?
Calls
its
superclass
constructor.
AndsoitgoesuntiltheObjectconstructoris
onthetopoftheStack,Once
Object()
finishes,it'spopped
offtheStackandthenextthingdowntheStack(the
subclassconstructorthatcalled
Objul(»)
isnowontop.
That
constructorfinishesandsoitgoesuntiltheoriginal
constructorisonthetopoftheStack,where
it
cannow
finish,
Thecompilerwillputacalltosupert)in
eachofyouroverloadedconstructors."
Thecomplier-suppliedcalllookslike:
super();
Italwayslookslikethat.Thecompiler-
Inserted(allto
supert)
Isalwaysano-arg
call.If
thesuperclasshasoverloaded
constructors,
onlytheno-argoneiscalled.
'Unlesstheconslructorcallsanotheroverloaded
constructor(you'llseethaiinafew
pages).
youarehere
~
253
objectlifecycle
Cattthechildexistbefore
theparents?
If
youthinkofasuperclassastheparenttothesubclasschild,
youcanfigure
outwhichhastoexist
first,
The
superdass
parts
ofanobjecthave
to
beJUUy-jormed(completely
built)
btfore
the
subclass
parts
can
beconstructed.
Remember,
thesubclassobjectmightdependonthingsit
inheritsfromthesuperclass,soit's
important
thatthoseinheritedthingsbefinished.No
way
aroundit.Thesuperc1assconstructor
mustfinishbeforeitssubclassconstructor,
LookattheStackseriesonpage
248
again,
andyoucanseethatwhiletheHippo
constructoristhe
first
tobeinvoked(it's
thefirstthingontheStack),it'sthe
last
one
tocomplete
I
Eachsubclassconstructor
immediatelyinvokesitsownsuperclass
constructor,until
theObjectconstructor
isonthetop
of
the
Stack,
ThenObject's
constructorcompletesandwebounce
backdowntheStacktoAnimal's
constructor.OnlyafterAnimal's
constructorcompletes
dowefinallycomebackdowntofinishtherestoftheHippo
constructor.For
that
reason:
ThecalltosuperOmustbethefirststatement
Ineacheenetrueterr'
Possible
constructorsfor
classBoop
o
public
Boop(){
super();
0'
publicBoop
(int
i)(
sup&r();
size
=
i;
}
"There'sanexceptiontothisrule:you'lileamItonpage252.
254
chapter9
o
publicBoap()(
I
0'
publicBoop
(int
i)
size'"
i;
f-~--
o
publicBoop(int
i)(
BAD!!
Thi5'
/'
VOlt
'f.
'4'otl
t
lOll,l>'j
size
=
i;
.1,
t-ill
txp/∙(;'.l'
[It.
U1~ ~II
to
I
'T.Jy
pc-I:
super();
ClllythiM
I
lIoP~)
belo'o.l
.J
e5e.
Superclass
eoastrueters
with
argUtMettfs
What
if
thesuperclassconstructorhasarguments?Canyoupasssomethinginto
the
super()
call?Ofcourse.
If
youcouldn't.you'dnever
be
abletoextendaclass
thatdidn'thaveano-argconstructor,Imaginethisscenario:allanimalshavea
name.There'sa
gelName()
methodinclassAnimalthatreturnsthevalueofthe
name
instancevariable.Theinstancevariableismarkedprivate,butthesubclass
(inthiscase,
Hippo)inheritsthe
getName()
method.Sohere'stheproblem:
Hippohasa
getName()
method(throughinheritance),butdoesnothavethe
name
instancevariable.HippohastodependontheAnimalpartofhimselftokeepthe
nameinstancevariable,andreturnitwhensomeonecalls
geLNa1T/~()
onaHippo
object.But...howdoestheAnimalpartgetthename?TheonlyreferenceHippo
hastotheAnimalpartofhimselfisthrough
supert),
sothat'stheplacewhere
HipposendstheHippo'snameuptotheAnimalpanofhimself,sothatthe
Animalpartcanstoreitintheprivate
n~me
instancevariable.
publicabstractclassAnimal{
privateStringname;
~
All
al'li",al
s
(i"dwii,,~
slobdas.ses)
hall'a
"a",e
publicStringgetName()
(~~ 9~k"'rl::~od
returnname;
Ill
ppo
i
llherib
ihai
constructorsandgc
Animal
privateStringname
Animal(StTingn)
StringgetNameO
T
Hippo
Hlppo(Stringn)
[otherHippo-spe-
cificmethods]
publicclassRippoextends
Animal(
publicAnimal(String
name
=
theName;
publicclassMakeHippo(
publicstaticvoidmain(StJ:ing[]args)(
NJak
e
d
Ili
Hippoh
=
new
Bippo("Buffy");
~
Il<lrnt
"BI.I(ly~:
f:
SS
;"9
t~e
to~i.,.
f..ot.
theIll
ppo
System.out.println(h.getName());
Hip
I
~
•
The,.
tall
f.h
C"_
po
5
'hht:r j~d
Lvt
e
\~
g
e
l:./¥a'fte
()
~
%javaMakeHippo
Buffy
youarehere.
255
callingoverloadedconstructors
lt1vokh,gOt1eoverloaded
cot1structor
fro",
at10ther
-
constructor.
1\.
constructorcan\\avea
catttosUfel'O
ott
thisO,
llutnevel'\loth!
Tl,e
caUtothis\)
canbeused
onl
y
ina
condl'uet
o
1',
andmust
he
thetirs
t
statementina
Usethis\)tocatta
-
constructortromanother
o-vertoad
ed
constructorin
tl,esautectas
s.
What
if
youhaveoverloadedconstructorsthat,with
theexceptionofhandlingdifferenta.Tg1l!l1enttypes,
all
dothesamething?Youknowthatyoudon't
want
duplicate
codesitting
in
eachoftheconstructors(pain
tomaintain,etc.),soyou'dliketoputthebulkofthe
constructorcode(includingthecalltosuper())inonly
om
oftheoverloadedconstructors.Youwantwhichever
constructorisfirstinvokedtocallTheRealConstructor
andletTheRealConstructorfinishthejobof
construction.It'ssimple:justsay
this().
Or
this(aString).
Or
this(27,x).
Inotherwords.justimaginethatthe
keyword
this
isareferencetothecurrentobject
Youcansay
thist)
onlywithinaconstructor.anditmust
bethefirststatementintheconstructor!
Butthat'saproblem.isn'tit?Earlierwesaidthat
super()mustbethefirststatementintheconstructor.
Well,thatmeansyougetachoice.
Everyconstructorcanhaveacalltosuper()
orthlsO,butneverbothl
classMini
extends
Car(
Colorcolor;
n,
YIO-ay~
t.o\'\Stvl>Lttx
d
liesa
d'~
il",lt.ColO'/"
d"
publicMini(){
~s
tnt
ol/CY'\oadtd
Real
this
(Color.
Red);{----'"
Col\3.~-\:.O'I"(~t
OJIt
that
)taIls
SIIYcY(»'
publicMini(Colorc)
8uper("Mini");
l-(----..
color
=
c;
JJ
moreini
tialization
public
Mini(int
size)(
thi5(COIor.Re~);~
super
(size);
~
WOl'l'i
'4IO\"'k.!!
eall'i
have
r
slJ.r
cy
()
a"d
thisO
;1'1
thesa...
e
lOl'l5tn.tt:or,
bel41/.U
theycad
....lUt
bethe
+il"'St
stau....
ent.
256chapter9
•
~
YOIJr
pencil
SomeoftheconstructorsIntheSonOOooclasswillnot
compile.See
if
you
can
recognlzewhichconstructorsare
notlegal.MatchthecompilererrorswiththeSonOfBoo
constructors
thatcausedthem,bydrawinga
I
inefromthe
compilererrortothe"bad"constructor.
publicclassBoo(
publicBoo(int
i)
I
~
publicBoo(Strings)(
publicBoo(Strlng
8,
int
i){}
classSonOfBooext:4ilndsBoo(
publicSonOfBoo()
super("boo");
publicSonOfBoo(int
i)(
super("Fred");
publicSonOfBoo(Strinqs){
supar(42);
publicSonOfBoo(inti,Strings){
}
publicSonOfBoo(Strinq
8.
Stringb,Stringc)(
8upar(a,b);
publicSonOfBoo(int
i,
lnt
j)(
supar("man",
j);
publicSonOfBoo(int
i,
intx,lnt
y){
super(i,"star");
constructorsandgc
I
I
Malee
i-/;
Siitle
I
RosesOrered.v
You,
pa,en~
Ci
'Ioletsareblue.
Th
omen,s,
It':
,e
superc/ass
r
ay
befo,eyou
Iformedb
~
parts
ofan
ob'.
,
elOTethlJectmu
exist.Just
I'k
e
newsUbc/as
sr
befU/ly_
beenb
I
e
there'sno
w
sObjectcan
Orn
before
You
ay
You
could
h
rparents.ave
youarehere.
257
public
void
sleep()
s
=
7;
J<::-
~-tP
\\\\-lat,
\c.oj
~f\~
.;
1It:<"t.\.
1Pt$
objectlifespan
NowweknowhowanobjectIsboyn,
buthow
IOt1g
doesanobject
live?
An
object's
lifedependsentirelyonthelifeofreferences
referringtoit-
If
thereference
is
considered"alive",the
objectisstillaliveon
theHeap.
If
thereferenced.ies
(andwe'll
look
atwhatthat
means
injustamoment).the
objectwiUdie.
So
if
anobject'slifedependsonthereference
variable'slife,howlongdoesa
variable
live?
Thatdependsonwhetherthevariable
is
a
localvariable
oran
instance
variable.Thecodebelowshowsthelifeofa
localvariable.
In
theexample,thevariable
isa
primitive.
butvariablelifetime
is
thesamewhetherit'saprimitive
orreferencevariable.
publicclassTeatLifeOne
publicvoidread(){
r,
int
s'"
42;
~(
__--
.s
;s
oSlo
sleep();
""rl:.hoc/
ped
to
th
d'
So
if.
td
,i
"'eddO
PlYWh&eelse
~
(;
be
~d
{
258
hapter
9
~
Alocalvariablelivesonly
withinthemethodthat
declaredthevariable.
publicvoidread()(
ints
=
42;
II's'
can
be
used.on.1y
II
within
th.ismethod.
II
Whenthismathodends,
II's'
disappeaLscompletely.
Variable's'canbeusedonlywithinthe
readOmethod.Inotherwords.thevariable
Is
Inscope
only
withIn
Its
ownmethod.
No
othercodeIntheclass(oranyotherclass)
cansee's'.
•Aninstancevariablelives
aslongastheobject
does.Iftheobjectisstill
alive,soareitsinstance
variables.
publicclassLife(
int
size;
publicvoidsetSize(int
s)
size
=
s;
II's'
disappearsat
the
/I
endofthismethod,
II
but'size'can
be
used
II
anywhere
in
theclass
Variable
'5'
(thistimeamethodparameter)
IsInscopeonly
withinthesetSize()
method.Butinstancevariablesizeis
scopedtothelifeoftheobjectasopposed
tothelifeofthemethod.
Thedifferencebetween
life
and
scope
forlocalvariables:
Life
Alocalvariableis
alioe
aslongas
its
Stack
frameisontheStack.
In
otherwords,
until
the
method.completes.
Scope
Alocalvariableis
in
scope
onlywithinthe
methodinwhichthevariable
was
declared.
Whenitsownmethodcallsanother,the
variableisalive,butnotinscopeuntilits
methodresumes.
Youcanusea
variableonly
when
it
is
in
scope.
constructorsandgc
publicvoiddoStuff(}
booleanb""true;
go
(4);
}
publiovoidgo(intx){
intz..x
+
24;
crazy();
//imaginemore
code
here
publicvoidcrazy()
char
c
III
'a';
Whilealocalvariableisalive,
its
statepersists.
As
longasmethoddoStuffOisontheStack,for
example,the'b'variablekeeps
its
value.Butthe
'b'variablecanbeusedonlywhiledoStuffO's
Stackframeisatthetop.Inotherwords,youcan
usealocalvariable
only
whilethatlocalvariable's
methodisactuallyrunning(asopposedto
waiting
forhigherStackframestocomplete).
o
doStuff()
goesonthe
stack.
Variable
'b'
is
aliveandInscope.
o
goO
plopsontopof
the
Stack.
'x'
and't
arealiveand
inscope,
and'b'
Is
alivebut
nof
inscope.
e
crazyO
Ispushedonto
theStack,
with
'c'now
aliveandInscope.The
otherthreevariables
arealivebut
outof
scope.
o
CfilZ'/O
completesand
Ispoppedoff
the
Stack,
so
'(j
isout
of
scope
anddead,
When
goO
resumeswhereItleft
off,
'x'
and'z'are
both
alive
and
back
Inscope.
Variable'b'16
stili
alive
butout
of
scope(until
goO
completes).
youare
here
~
259
object
lifecycle
Whataboutreferettcevariables?
Therulesarethesameforprimtivesandreferences.Areference
variablecanbeusedonlywhenit'sinscope.whichmeansyoucan'tuse
an
object'sremotecontrolunlessyou'vegotareferencevariablethat's
inscope.The
Teal
questionis,
"Howdoes
variable
lifeaffect
object
life?"
Anobjectisaliveaslongastherearelivereferencesto
it,
If
areference
variablegoesoutofscopebut
is
stillalive,theobjectit
refers
toisstill
alive
ontheHeap.Andthenyouhavetoask..."Whathappenswhenthe
StackframeholdingthereferencegetspoppedofftheStackattheend
ofthemethod?"
If
that
was
the
only
livereferencetotheobject,theobjectisnow
abandonedontheHeap.Thereferencevariabledisintegratedwith
theStackframe,sotheabandonedobjectisnow,officially,toast.The
trickistoknowthepointatwhichanobjectbecomes
eligible
for
garbage
collection:
Onceanobjectiseligibleforgarbagecollection
(Ge),
youdon'thave
toworry
aboutreclaimingthememorythatobject
was
using.
If
your
program
getslowonmemory,
GC
will
destroy
someor
all
oftheeligible
objects,to
keepyoufromrunningoutofRAM.Youcanstillrunoutof
memory,butnotbeforealleligibleobjectshavebeenhauledofftothe
dump.Yourjob
is
to
makesurethatyouabandonobjects(i.e,make
themeligibleforGC)whenyou'redonewiththem,sothatthegarbage
collectorhassomethingtoreclaim.lfyouhangontoobjects,GCcan't
helpyouandyouruntheriskofyourprogramdyingapainful
out-of-memory
death.
An
object'slife
has
no
value.
no
meaning.
no
rem.
unless
aomebody
hasareference
to
it.
n
you
can'tget
to
it.
you
can'task
it
to
do
anythingandit's
jUst
a
big
fat
waste
of
bit&.
But
i'
an
object
is
unreachable.
the
Garbage
CoUet:t«
will
f1gure
that
out..
Sooner
or
later.
that
object'8
gom'down..
Anobjectbecomes
eligibleforGCwhen
itslastlivereference
disappears.
260chapter9
Threewaystogetridofanobject'sreference:
G)
Thereference
goes
outofscope,permanently
L
,,dies
a~
voidgo(){
~t~t:YtrLt
z.
}Life
z
=
newLife();
~
e.-4
J
",dhod
®
The
reference
is
assignedanotherobject.
ha.-4~
~ ~ o'o~el.t.
,s
0,
-to
Lifez
=
newLife();,/the
~;y-S,
_YO",,,,e&
z'"
newLife();
~
"''''''
z.;1
yeyY-;,
a
TIt'"
o\:>jtt.t..
'3'
Thereferenceis
explicitly
settonull
L'
"L~~ed
\:!,J
~
t.
do"
tt.'{.
\1..
(1<1
I
Lifez'"new
Li
fa();
the
iyS.'
.1~
_yo...
",e&.
z
=
null;(-
",'neYl
z.
\S
l)
r"-.J
Object-killer#1
Referencegoes
outofscope,
permanently.
publicclassStaclcR.ef{
publicvoidfoof()(
barf();
publicvoid
barf()(
Duckd:new
Duck();
o
loof(J
Ispushedontothe
Stack,novariablesare
declared.
I
I
I
I
I
I
I
I
constructorsand
gc
o
barf(J
Ispushedontothe
Stack,where
It
declares
a
referencevariable,and
creates
anew
objectas-
signedto
that
reference.
TheobjectIscreatedon
the
Heap,andtherefer-
ence
Is
aliveand
In
scope.
e
bartO
completesand
pops
off
theStack.
Its
frame
disintegrates,so'd'Isnow
deadandgone.Execution
returnsto
100'0,
but
100(0
can'tuse'd'.
Uh-oh.
TIll:
'd'
variable
w~t
d'Na,!'Nne"
th~
bar∙W
SUlk
t..
a",e
'Na~
blo'Nft
o-f.f
the
stalk,
so
tht
Dutlt
is
aba"dClr\td.
~arba~t:­
lollak
bait.
youarehere
~
261
objectlifecycle
Dude,allyou
hadto
do
wasreset
the
r~ference.
Guess
theydidn'thave
memory
managementbackthen.
publicvoid
qo(){
d
=
naw
Duck();
Duckd
=
newDuck();
publicclass
ReRef{
Object-killer#2
Assignthereference
toanotherobject
o
o
Thenew
Du.tk.
~oes
onthe
!leaf,....
e~et"tnLeci
b~
'ei',
~nte
'0'
isclninSt.a!'ltevariable,tne
D",-\I.
willliveas
\Ol'l~
as
~e
ReRt.tobit.d:.
thatil\5-t.al'ltiaW
it
is
alive.
l.()\less-..
'£1'
is
as.si~\'IeO
a!'lew
Du.t\l.
objt.tt,
leav\!'I~
the
ori~i\'lal
ah'st)
DlAl.kobjed:.
ahal'loont.o.
That
tirstD",-kis
1\0,",
as
~ood
as
dead..
262chapter9
constructorsandgc
Object..killer#3
Explicitlysetthe
referencetonull
Tee
~
D\oll.k
~oes ~ th~
\-ledf'
y~.ftytyo,Ud
b'j'd'.
Sil'\U
'd'
isa"
inrtal'IU
vaW'i4bl~,th~
DlItlc.
will
live
as
l~~
as
th~ R~c.f obj~l:1:
that.
i~'I\tiat.ed
it.
is
alive.U"Ies.s-∙∙
Duckd
==
newDuck();
publicvoidgal)(
d
==
nul.l:
publicclassReRef{
If
youuse
thedotoperatoron
anullreference.you'll
geta
NullPolnterExceptlonatruntime.
You'll
learn
allaboutExceptionsIntheRisky
Behaviorchapter.
Whenyousetareferenceto
nuJ.l,
you're
deprogrammingtheremotecontrol.
In
otherwords,you'vegotaremote
control,
butnoTVattheotherend.Anull
referencehasbitsrepresentIng'null'
(we
don'tknoworcarewhatthosebitsare,as
long
as
the
NM
knows).
Ifyouhaveanunprogrammed
remote
control,Intherealworld,thebuttonsdon't
do
a
nythlngwhenyoupressthem.
But
InJava,you
ca
n'tpressthebuttons(I.e.
usethe
dotoperator)onanullreference,
becausethe
NM
knows(thisIs
a
runtime
Issue,
not
a
compliererror)thatyou're
expectingabark
butthere's
no
Dogthere
todo
Itl
Themeaningof
null
you
arehere
~
263
object
lifecycle
FiresideChats
~4
~
Tonight'gTalk:
An
instancevariableand
alooalvariablediscusslifeanddeath
(wi~
remarkablecivilliy)
InstanceVariable
I'dliketogofirst,because
I
tendtobemore
importanttoaprogramthanalocalvariable.
I'mthere
to
support
an
object,usually
throughouttheobject'sentirelife.Afterall,
what'san
objectwithout
slate?
Andwhatis
state?Values
keptin
instana
variables.
No,don'tgetmewrong,
I
dounderstandyour
roleinamethod,it's
just
thatyourlifeisso
short.Sotemporary.That'swhythey
call
you
guys
"temporaryvariables".
Myapologies.I
understandcompletely.
I
neverreallythoughtaboutitlikethat.What
areyoudoingwhiletheothermethodsare
runningandyou'rewaitingforyourframeto
be
thetopoftheStackagain?
264
chapter9
LocalVariable
I
appreciateyourpointofview,and
I
certainly
appreciatethevalueofobjectstateand
all,
but
I
don't
want
folkstobemisled.Local
variables
are
really
important.Touseyour
phrase,"Afterall,what'sanobjectwithout
behaviorr"
Andwhatisbehavior?Algorithms
in
methods.Andyoucan
bet
your
bits
there'll
besome
localvariables
in
theretomakethose
algorithmswork.
Withinthelocal-variablecommunity,the
phrase"temporaryvariable"
is
considered
derogatory.Weprefer"local","stack","auto-
matic",
or"Scope-challenged",
Anyway,it's
truethatwedon'thavealong
life,andit'snotaparticularly
good
lifeeither.
First,
we'reshovedintoaStackframewith
all
theotherlocalvariables,Andthen,ifthe
methodwe're
part
ofcallsanothermethod,
anotherframeispushedontopofus.And
if
that
methodcalls
another
method...andsoon.
Sometimeswehavetowaitforeverforallthe
othermethodsontopoftheStacktocom-
pletesothatourmethodcanrunagain.
Nothing.Nothingatall.It'slikebeingin
stasis-thatthingtheydotopeopleinscience
fictionmovieswhentheyhavetotravellong
distances.Suspendedanimation,really.We
justsitthereonhold.
As
longasourframeis
still
there,we'resafeandthevaluewehold
issecure,butit'samixedblessingwhenour.
IDstanceVariable
Wesawaneducationalvideoaboutitonce.
Lookslikea
prettybrutalending.Imean,
whenthatmethodhitsitsendingcurlybrace,
theframeisliterallyblownofftheStack!Now
that's
gottahurt.
IliveontheHeap,withtheobjects.Well,not
with
theobjects,actually
in
anobject.The
objectwhosestateIstore.Ihavetoadmitlife
canbeprettyluxuriousontheHeap.Alotof
usfeelguilty,especiallyaroundtheholidays.
OK,hypothetically,yes,if
I'maninstance
variable
oftheCollarandtheCollargets
GC'd,thentheCollar'sinstancevariables
wouldindeedbetossedoutlikesomanypizza
boxes.
ButI
was
toldthatthisalmostnever
happens.
Theyletusdrink?
constructorsand
gc
LocalVariable
framegetstorunagain.Ontheonehand,we
gettobeactiveagain.Ontheotherhand,the
clockstartstickingagainonourshortlives.
Themoretimeourmethodspendsrunning,
thecloserwe
gettotheendofthemethod.
Weallknowwhathappensthen.
Tell
meabout
it.
Incomputersciencetheyuse
thetermpoppedasin"theframewaspopped
offtheStack".Thatmakesitsoundfun,or
maybelikeanextremesport.But,well,you
saw
thefootage.Sowhydon'twetalkabout
you?IknowwhatmylittleStackframelooks
like,
butwheredoyoulive?
Butyoudon'talwaysliveaslongastheobject
who
declaredyou,right?Saythere'saDog
objectwithaCollarinstancevariable.Imagine
you'reaninstancevariableoftheCollarobject,
maybea
referencetoaBuckleorsomething,
sitting
thereallhappyinsidetheCollarobject
who'sallhappyinsidethe
Dog
object.But...
whathappensiftheDogwantsanewCollar,
ornullsoutitsCollarinstancevariable?That
makestheCollarobjecteligibleforGC.So...
ifyou
'reaninstancevariableinsidetheCollar,
andthewholeCollarisabandoned,what
happenstoyou?
Andyoubelievedit?That'swhattheysayto
keepusmotivatedandproductive.Butaren't
you
forgettingsomethingelse?Whatifyou're
aninstancevariableinsideanobject,andthat
objectisreferencedonlybyalocalvariable?If
I'mtheonlyreferencetotheobjectyou'rein,
wh
enIgo,you'recomingwithme.Likeitor
not,ourfatesmaybeconnected.SoIsaywe
forgetaboutallthisandgogetdrunkwhile
westillcan.
CarpeRAMandallthat.
youarehere
~
265
exercise:BetheGarbageColleclor
BE
theGarbageCtJTIector
Wlnch
01'
the
lines
of
code
onthe
rigbt,
ifadded
to
&
classontheleft
at
point
A,
wouldeaase
exactlyoneadditionalobject
to
heeliglhleforthe
GarbageCollector?(AsSUlJlethat
point
A
(licall
moremethods)
will
executeforalongtime,
giving
the
Garbage
Collector
time
to
do
its
stu1f.)
publicclassGC(
publicstaticGCdoStuff()
GCnewGC
=
newGCI)i
doStuff2(newGC);
returnnewGCi
pUblicstaticvoidmaln(String
[1
args)(
GCgel;
GC
gc2
=
new
GCI);
GCgc3
=
newGCI);
GCge4
=
gc3j
gel
=
doScuff();
II
callmoremethods
publicstaticvoiddoStuff2(GCcopyGC)
GC
localGC
266
chapter9
1
copyGC
=
nulli
2
gc2
=
null;
3
newGC
=
gc3;
4
gel
=
null;
5
newGC
=
null;
6
gc4
=
null;
7
gc3
=
gC2i
8
gel
=
gc4i
9
gc3
nu
Ll.;
classBees{
Honey
I]
beeHAj
}
classRaccoon{
KitXi
Boney
rh;
}
classKit(
Boney
kh;
}
classBear{
BoneyhunnYi
}
constructorsandgc
Inthiscodeexample,severalnewobjectsarecreated.
Yourchallengeisto
findtheobjectthatis'mostpopular;
i.e.theone
thathasthemostreferencevariablesreferring
toit.Thenlist
howmanytotalreferencesthereare
for
thatobject,andwhattheyare!We'llstartbypointing
au
t
oneofthenewobjects,anditsreferencevariable.
GoodLuck!
pUblicclassHoney{
publicstaticvoidmain(String[]arqs){
Roney
honeyPot
=
newHoneY()i
Boney
I]
ha
=
{honeyPot,honeyPot,honeyPot,honeyPot};
Beesbl
=
newBees():
bl.beeRA
=
ha;
Bear[)ba
=
newHearlS];
for(intx=O;x
<
5;x++)
ba!x]
=
newHear();
ba[x).hunny
=
honeyPot;
Here'sItsreference
variable
∙r'.
}
}
}
Kit
k
=
newKit()i
k.kh'"honeyPot;
Raccoonr'"newRaccoon()i
~
r.rh
=
honeypot:
r.k'"Xj
k
=
null;
II
endofmain
Here'sanew
~
Raccoonobjectl
youare
here
~
267
puzzle:FiveMinuteMystery
"We'verunthesimulationfourtimes,andthemainmodule'stemperatureconsistently
drifts
outofnominaltowardscold",Sarahsaid,exasperated."Weinstalledthenewtemp-batslast
week.
Thereadingsontheradiatorbats,designedtocoolthelivingquarters,seem
to
be
within
spec.so
we'vefocusedouranalysisontheheatretentionbats,thebatsthathelptowarmthequar-
ters."
Tomsighed,atfirstit
had
seemedthatnano-technologywasgoingtoreallyputthemahead
ofschedule.Now,withonlyfiveweeksleftuntillaunch.someoftheorbiter'skeylifesupport
systemswerestillnotpassingthesimulationgauntlet.
"Whatratios
are
yousimulating?",Tomasked.
"Well
if
Iseewhereyou'regoing,wealreadythoughtofthat",Sarahreplied.
"Mis-
sioncontrolwillnotsignoffoncriticalsystems
if
werunthemoutofspec.Weare
required
torunthev3radiatorbat'sSimUnilS
in
a2:1ratiowiththev2radiator's
SimUnits",Sarahcontinued."Overall,theratio
ofretentionbotstoradiatorbats
is
supposedtorun4:3."
"How'spowerconsumptionSarah?",Tomasked.Sarahpaused."Wellthat's
anotherthing,powerconsumptionisrunninghigherthananticipated.We
'vegotateam
trackingthatdowntoo,butbecausethenanosarewireless
it'sbeenhardtoisolatethepower
consumption
oftheradiatorsfromtheretentionbats.""Overallpowerconsumptionratios",Sarah
continued.
"are
designedtorun3:2withtheradiatorspullingmorepowerfromthewirelessgrid."
"OKSarah",Tomsaid"Let'stakealookatsomeofthesimulationinitiationcode.
We'vegottofindthisproblem,andfind
it
quick!"
importjava.util.∙;
classV2Radiator{
V2Radiator(ArrayListlist)(
for(int
~O;
x<57x++)(
list.add(newSlmUnit{MV2Radiator
U
));
}
classVJRadiatorextendsV2Radiator
V3Radiator{ArrayLlstlqlist)
super(19list);
for{lnt
gmO;g<107
q++){
lqlist.add(newSimUnit(MVJRadiator
H
»1
classRetentionBot{
RetentionBot(ArrayListrlist){
rlist.add(newSimOnit(MRetention-»)
268
chapter
9
rIVe-MInute
Mystery
C<intlnued...
publicclassTestLifeSupportSim{
publicstaticvoidmain(String
[J
args){
ArrayListaList=newArrayList();
V2Radiatorv2=newV2Radiator(aList);
V3Radiatorv3=newV3Radiator(aList);
for(intz=O;z<20;z++){
RetentionBotret=newRetentionBot(aList);
classSimUnit{
StringbotType;
SimUnit(Stringtype){
botType
=
type;
}
intpowerUse(){
if(URetentionu.equals(botType»
return2;
else{
return4;
}
constructorsandgc
Tomgavethecodeaquicklookandasmallsmilecreepedacrosshislips.Ithink
I've
foundtheproblemSarah,andIbetIknowbywhatpercentageyourpowerusagereadingsareoff
too!
WhatdidTomsuspect?Howcouldheguessthepowerreadingserrors,andwhatfew
linesofcodecouldyouaddtohelpdebugthisprogram?
youarehere
~
269
objectIifecycle
1
copyGC
=
null;
No-thislineattemptsto
access
avariable
thatisoutofscope.
2
ge2
='
null;
OK-9c2wastheonlyreferencevariable
referringtothatobject.
3
newGC
='
gc3;
No-anotheroutofscopevariable.
4
gel
=
null;
OK-gelhadtheonlyreferencebecause
G.C.
newGCisoutofscope.
5
newGC
=
null;
No-newGCisoutofscope.
6
gc4
null;
No-gc3isstillreferringtothatobject.
7
gc3gc2;
No-
9c4
isstillreferringtothatobject.
8
gclgc4;
OK-Reassigningtheonlyreferenceto
thatobject.
9
gc3
null;
No-
gc4
isstillreferringtothatobject.
Itprobablywasn'ttoohardtofigureoutthattheHoneyobJectfirstreferredtobythehoneyPotvariableis
by
farthemost-popular'objectInthisclass.Butmaybe
it
wasalittletrickiertosee
that
all
of
thevariablesthat
pointfromthecodetotheHoneyobjectrefertothe
same
ob}edl
Thereareatotal
of
12activereferencesto
thisobjectrightbeforethemaln()methodcompletes.The
Ic.kh
variableisvalidforawhile,butkgetsnulled
attheend.Since
r.k
stili
referstothe
KIt
object,
r.k.kh
(althoughneverexpllcitydeclared),referstotheobject!
}
Kitk
=
newKit();
k.kh
=>
honeyPot;
Raccoon
r•
newRaccoon();
publicclassBoney{
publicstaticvoidmain(Striog[)args){
Boney
honeyPot
~
newBoney();
Boney[)ha
=
{noneyPot,honeypot,
honeyPot,honeYPot};
Bees
bi
m
newBeesl);
bl.beeHA
=
ha;
Bear[)ba
=
newBearIS];
for(intx-OJx
<
5;x++){
ba{x]
=
newBear():
ba[xj.hunny
c
honeyPot;
L
(endsupnull)
1---
---J
T
I
1-
r.rh
=
honeyPot:
r.k-k;
k•null;
}}II
endofmain
270chapter9
constructorsandge
TomnoticedthattheconstructorfortheV2Radiatorclasstookan
ArrayList.ThatmeantthateverytimetheV3Radiatorconstructorwascalled,
itpassedanArrayListinitssupert)calltotheV2Radiatorconstructor.That
meantthatanextrafiveV2RadiatorSimUnitswerecreated.
IfTomwasright,
totalpowerusewouldhavebeen120,notthe100thatSarah'sexpectedratios
predicted.
SincealltheBotclassescreateSimUnits,writingaconstructorfor
theSimUnitclass,thatprintedoutalineeverytimeaSimUnitwascreated,
wouldhavequicklyhighlightedtheproblem!
youarehere
271
10
numbersandstatics
NumbersMatter
DotheMath.
Butthere'smoretoworkingwithnumbersthanJustdoingprimitive
arithmetic.You
mightwanttogettheabsolutevalueofanumber,orroundanumber,orflnd
thelargerof
twonumbers.YoumightwantyournumberstoprlntwithexactlytwodecImaI
places,oryou
mightwanttoputcommasIntoyourlargenumberstomakethemeasiertoread.
And
whataboutworkingwithdates?YoumightwanttoprintdatesInavarietyofways,oreven
manipulate
datestosaythingslike,
"add
threeweekstotoday's
date"
Andwhataboutparsing
aStringIntoanumber?
Or
turninganumberinto
a
String?You'reInluck.
The
Java
API
Is
full
of
handynumber-tweakingmethodsreadyandeasytouse.Butmostofthemare
static,
sowe'll
start
by
learningwhatitmeansfor
a
variableormethodtobestatic,includingconstantsIn
Java-static
final
variables.
this
IS
a
newchapter
273
Mathmethods
MArH
tMethods:ascloseasyou'll
evergettoa
globa/tMethod
Except
there'snoglobal
an),lhinginJava.
Butthinkabout
this:what
if
youhaveamethodwhosebehaviordoesn't
dependonaninstancevariablevalue.Taketheround()
methodintheMath
class,
forexample.Itdoesthesame
thingeverytime-roundsafloatingpointnumber(the
argumenttothemethod)tothenearestinteger.Every
time.
lfyouhad10,000instancesofclassMath,andran
theround(42.2)method,you'dgetanintegervalueof
42.Everytime.Inotherwords,themethodactsonthe
argument,butisneveraffectedbyaninstancevariable
state.
Theonlyvaluethatchangesthewaytheround()
methodruns
is
theargumentpassed
to
themethodl
Doesn'titseemlike
awaste
ofperfectly
good
heapspace
tomakeaninstanceof
class
Mathsimplytorunthe
round()method?Andwhatabout
other
Mathmethods
likemint),whichtakestwonumericalprimitivesand
returnsthesmallerofthetwo.Ormaxj).Orabst),which
returnstheabsolutevalueofanumber.
These
methods
never
we
instancevariablevalues.
Infactthe
Math
class
doesn't
have
anyinstancevariables.
So
there's
nothingtobegainedbymakinganinstanceofclass
Math.Soguesswhat?You
don'thaveto.
As
amatterof
fact.youcan't,
Ifyoutrytomakeaninstanceof
classMath:
Math
mathObject
=
new
Math()
i
You'llgetthiserror:
Methods
in
the.Mathclass
don'tuse
any
mstance
variablevalues.Amibecause
the
methodsare
'static',
you
don't
need
tohavean
illstance
of.Math.
All
you
need
is
the
Math
class.
-
intx-Math.round(42.2);
int
y
=
Math.min(56,12)
i
intz
=
Math.abs(-343);
274
chapter10
numbersandstatics
fhedifferet1cebetweeMregular
(.,on-static)at1dstatictttethods
Javaisobject-oriented,butonceinawhileyouhaveaspecialcase,
typicallyautility
method(liketheMathmethods),wherethere
is
noneedtohavean
instance
oftheclass.Thekeywordstaticlets
a
method
run
without
any
instanceo/the
class.
A
static
methodmeans
"behavior
notdependentonaninstancevariable,sonoinstance/object
is
required.Justtheclass."
regular(non-static)methodstaticmethod
-
publicclassSoog(
a
'.~'o\("a\~ ~tt.L~
I~,.{,e ~
....."\
.J)
Strine}title;
~
the
Otha"\~
cJ
tht
yar
publicSone}(String
t)
".~~o<!.
tiUe
=
ti
Math
minD
maxD
abs()
public
intmin(inta,intb)(
//returnsthelesserofa
and
b
Song
Song
}
public
void
play()
SoundPlayerplayer
=
newSoundPlayer()
i
player.playSound(tiUB)i
\'J
~e
'title'
nt
l."l'l'tJ\t..
"~I\~
Lhe
WTI~
that
L.1/.11'\<10
e
IS
~
i"sv"tt.
La\\
yl<l,/{)'
~\a'fS
...."e"
'to'J
tltIe
youarehere
~
275
static
methods
.min
(B8,86);
Math
mlnO
maxO
absO
Callastaticmethodusinga
class
name
Callanon-staticmethodusinga
referencevariable
name
V--
Song
t2
=
newSong();
.play();
WhatittHea.,stohavea
classwithstaticIttethods.
Often(althoughnotalways),aclasswithstatic
methodsisnotmeanttobeinstantiated.
In
Chapter
8wetalkedaboutabstractclasses,andhowmarking
aclasswiththe
abstract
modifiermakesit
impossible
foranyonetosay'new'onthatclasstype.
In
otherwords,
it'simpossibleto
instantiate
anabstract
class.
Butyoucanrestrictothercodefrominstantiating
anon,,∙abstractclassby
markingtheconstructor
private.Remember,a
method
markedprivatemeans
thatonlycodefromwithintheclasscaninvoke
themethod.A
constructor
markedprivatemeans
essentially
thesamething-onlycodefromwithin
theclasscaninvoketheconstructor.Nobodycan
say
'new'from
outside
theclass.That'showitworks
withthe
Math
class,forexample.Theconstructor
isprivate,youcannotmakeanewinstance
of
Math.
Thecompilerknowsthatyourcodedoesn'thave
accesstothatprivate
constructor.
Thisdoes
not
meanthataclasswithoneormore
staticmethodsshouldnever
be
instantiated.
In
fact,
every
class
youputamainOmethodinisaclasswith
astatic
methodinitl
Typically,youmakeamain
0
methodsothatyou
can
launchortestanotherclass,nearly
always
by
instantiatingaclassinmain,
andtheninvokinga
methodonthatnewinstance.
So
you'refreetocombinestaticandnon-static
methodsinaclass,althoughevenasinglenon-static
methodmeanstheremustbe
S~
waytomakean
instanceof
theclass.Theonlywaystogetanew
object
arethrough'new'ordeserialization(or
somethingcalledtheJavaReflectionAPIthatwe
don'tgointo).Nootherway.Butexactly
WM
saysnew
canbeaninterestingquestion,
andonewe'Ulookat
alittlelaterinthischapter.
276
chapter10
StatictMethodscaM'fuset1ot1...
statle
(instance)variables!
Staticmethodsrunwithoutknowingaboutanyparticular
instanceofthestaticmethod'sclass.Andasyousawon
thepreviouspages,theremightnoteven
be
anyinstances
ofthatclass.Sinceastaticmethodiscalledusingthe
class
(Math.random())
asopposed
LO
an
mstancereference
(t2.playO),
astatic
methodcan'trefer
to
anyinstancevariablesofthe
class.Thestaticmethoddoesn'tknow
which
instance'svariable
valuetouse.
Ifyou
try
tocompilethiscode:
publicolassDuck(
y,[nit,'I'I
'D.,.t.~~
~(f.e ~\1,.l..
privatelntsize;
~
(
publicstatic
voidmain(String[]arqs)(
~
System.out.println("SizfiIl
ofduck
is"+size):
1.(
fh~e's
d
DlAlk
on
publicvoidsetsize(int
09)
~e):eap
So"'ewhet-e,we
size
=
s;
on
~
KI'IO'w
dboc..i
it
numbersandstatics
If
you
trj
to
usean
inStance
variablefrom
inside
a
static
method.
the
compiler
thitiks.
"I
don't
"know
which
object'smstancevariable
you're
talking
about!"
If
you
haveten
DuCK
objectsontheheap.a
staticmethoddoesn't
"know
about
any
of
them.
}
publiciot
getSize()
returnsize;
You'llgetthiserror:
youarehere
~
277
staticmethods
publicvoidsetsize(int
s){
size
=
B;
Q:
WhatIf
you
try
tocallanon-static
methodfromastaticmethod,butthe
non-staticmethoddoesn't
useanyIn-
stancevariables.WIll
the
compilerallow
that?
A:
No.Thecompilerknowsthat
whetheryoudoordo
notuseInstance
variablesInanon-staticmethod,you
can.
Andthinkabouttheimplications...ifyou
wereallowed
tocompile
a
scenariolike
that,
thenwhathappensifinthefuture
youwanttochangetheimplementation
ofthatnon-staticmethodsothatoneday
It
does
useanInstancevariable?
Or
worse,
whathappens
ifasubclass
overrides
the
methodandusesanInstancevariablein
theoverridingversion?
Q:
IcouldswearI've
seencodethat
callsastaticmethoduslngareference
variableInsteadoftheclassname.
A:
You
can
dothat,but
as
yourmother
alwaystoldyou,
"Just
becauseit'slegal
doesn'tmeanit'sgood."AlthoughIt
works
tocallastaticmethodusinganyinstance
oftheclass,itmakesformisleading(less-
readable)code.You
can
say,
Duckd
=
newDuck():
String[]s
={};
d.main(s);
Thiscode
is
legal,butthecomplierJust
resolvesIt
back
totherealclassanyway
("01(d
IsoftypeDuck,andmalnOIsstatic,
soI'llcallthestaticmalnO
in
classDuck").
In
otherwords,using
d
toInvokemain£)
doesn'tImplythat
maln()
will
haveany
specialknowledgeoftheobject
that
d
Is
referencing.It'sJustanalternate
way
to
Invokeastaticmethod,butthemethodIs
stillstatic!
Rosesarered,
bl
m
late
and
knownto
00
StCJtlcscCJn'.see
instCJncevariablestate
publicclassDuck{
}
public
iot
getsize()
returnsize;
Whatdonon-staticmethodsdo?
They
usuaUyuse
instance
variable
state
tv
affect
the
behaviorof
the
method.A
getName()
methodreturnsthevalueofthenamevariable.Whosename?
TheobjectusedtoinvokethegetNameOmethod.
Thiswon'tcompile:
Cdl!il\~ ~efs.~()
.t.st
~~ ih~vji:db'e-4JS;~os)
tpolles
the
si.
L
J
IU
IA1l.s
U
I)UUI\le
variabje.
private
iot
size;
publicstaticvoidmain(Strinq[]args)(
System.out.println(~Size
is
~
+
getsize()):
StatictMethodscattJtuse"ott"'statlc
methods..either!
278chapter10
Staticvariable:
valueisthesatHeforALL
i"sta"cesoftheclass
ImagineyouwantedtocounthowmanyDuck
instancesarebeingcreatedwhileyourprogram
is
running.Howwouldyoudoit?Maybeaninstance
variable
thatyouincrementintheconstructor?
classDuck{
intduC](Count
=
0;
publicDuck(){
dUckCount++;
.ll'
l:",s
wOIA1d
I
~
dlAl.ke-
d
'WdYS
~t
d
D
k
"i
-&,J
~lh
ti
l.tt
WdS
r...id/!...
e
No,thatwouldn'tworkbecauseduckCountisan
instancevariable,
andstartsat
0
foreachDuck.You
could
try
calling
a
methodinsomeother
class,
but
that'skludgey.Youneeda
class
that'sgotonly
a
single
copy
ofthevariable,
and
allinstancessharethatone
copy.
That'swhatastaticvariablegivesyou:avalueshared
byallinstancesofaclass.Inotherwords,onevalue
per
class,
insteadofonevalueper
instance.
Duck
numbersandstatics
pub11c
Duck()(
Now
if.
will
~
dUckCountH;
~j"'rbnbli:i
tp
)the
DlAlk
lIS
c.ilh
b"'
t
bet.i~ d~t.ot.
"uls,
Gild
'fiIIOrl'f
bt
~i
is
sidfit
~i.oO.
publicvoidlfetSlze
(int
s)(
size
=
!!I;
•
publicintqetslze()
returnsize;
youarehere
~
279
static
variables
Static
variables
areshared.
Allinstances
01
thesame
classshareasinglecopy
01
thestaticvariables.
instancevariables:1perinstance
staticvariables:1per
class
280chapter
10
~J:V
BrainBarbell
Earlierinthischapter,wesawthataprivate
constructormeans
thattheclasscan'tbeinstantiated
fromcoderunningoutside
theclass.Inotherwords,
onlycodefromwithintheclasscanmakeanew
instance
ofaclasswithaprivateconstructor.(There's
akind
ofchlcken-and-eggproblemhere.)
WhatIfyou
wanttowriteaclassInsuchawaythat
onlyONEinstanceofItcanbecreated,andanyone
whowantstouseaninstanceoftheclasswillalways
use
thatone,singleInstance?
numbersandstatics
htitializhtgastaticvariable
Staticvariablesareinitializedwhena
class
is
loaded:
Aclass
is
loadedbecausethejVMdecidesit'stimetoloadit.
Typically,
thejVMloadsaclassbecausesornebody'stryingtomakea
newinstance
oftheclass,forthefirsttime,oruseastatic
methodorvariableoftheclass.
As
aprogrammer.youalso
have
theoptionoftellingthejVMtoloadaclass,butyou're
notlikelytoneedtodothat.Innearly
all
cases,you'rebetter
offlettingthejVMdecidewhento
wad
theclass.
And
therearetwoguaranteesaboutstaticinitialization:
Staticvariablesinaclassareinitializedbeforeany
object
ofthat
class
canbecreated.
Staticvariablesinaclassareinitializedbeforeany
staticmethod
oftheclassruns.
Allstaticvariables
inaclassare
Initializedbefore
any
objectof
thatclass
can
be
created.
olassPlayer{
staticintplayerCount;:;0;
private
Stringname;
public
Player(Stringn)
n&IIl8
=
n;
playerCount++;
publicclassPlayerTestDrive(
public
staticvoidmain(Strin'll]llrgs)(
Syabam.out.println(Player.playerCount);
Playerone
=
newPlayer("TiqerWooda
H
);
Syst8m.out.println(Player.playerCount);
\.AtuuastittVjly',able
j\<St.
likea
Sta-t'I(.
...d.hod-wit.h
thetlassl'Id",e.
Staticvariablesareinitializedwhentheclassisloaded.
If
you
don'texplicitlyinitializeastaticvariable(byassigningita
valueatthetimeyoudeclareit),itgetsadefaultvalue,soint
variables
areinitializedtozero,whichmeanswedidn'tneed
toexplicitlysay"playerflount
=0",
Declaring.butnotinitial-
izing,astaticvariablemeansthestaticvariablewill
getthede-
faultvaluefor
thatvariabletype,inexactlythesame
way
that
instancevariables
aregivendefaultvalueswhendeclared.
youarehere
~
281
staticfinal
constants
staticfh1alvariablesarecot1stat1ts
-
Avariablemarkedfinalmeansthat-s-onceinitialized-itcan
neverchange.
In
otherwords,thevalueofthestaticfinalvariable
will
staythesameaslongastheclass
is
loaded:LookupMath.PI
in
theAPI,andyou'llfind:
publicstaticfinaldoublePI
=
3.141592653589793;
Thevariableismarked
public
sothatanycodecanaccess
it.
Thevariableismarked
static
sothatyoudon'tneedan
instance
ofclass
Math
(which,remember,you'renotallowedto
create).
Thevariable
is
marked
final
becausePIdoesn'tchange(asfaras
Java
is
concerned).
Thereisnoother
way
todesignateavariableasaconstant,but
there
is
anamingconventionthathelpsyoutorecognizeone.
Constant
variablenamesshouldbeinallcaps!
OR
Initializea
Rnal
staticvariable:
•Atthe
timeyou
declQl"tIt:
publicclulS
]1'00(
publ~c
static
final
lotFCC_X
=
25;
~t.e
tJ,e
~
.'\
tj~}
I/ariabl
""~
lor.vblt
OPl
~"'~
shOlJ.}d
b
di-e
~)lb -~~i.lbt.
lAPldc....,._.e
all
"pp&
J
so
Ule
.-~ $Cpal"'ab.l,f.d$C,....,i~ all
~
Ule
'worcit
•In
0
staticInltfollzer:
publicclassBar{
public
IlltatiC
final
doubleBARSIGN;
If
youdon'tgiveavaluetoafinolvorlable
inoneof
thosetwoplaces:
publicclass
Bar(
public
static
finaldoubleBAR_SIGN;
110
i
ll
i'b_}i
l4t;olll
Thecomplier
will
catchIt:
fitlaliSKtjustforstatic
variables...
Youcanusethekeyword
final
tomodifynon-
staticvariablestoo,includinginstancevariables.
localvariables,
andevenmethodparameters.In
eachcase,itmeansthesame
thing:
thevaluecan't
bechanged.
BUl
youcanalsousefinal
to
stop
someonefromoverridingamethodormakinga
subclass.
non-staticfinal
variables
clanFoo!(
'f0!>
t.'!,,'f,
thd,,~e
S'IU
finalIntsize'"3;
f--
YI()W
finalintwhuffi.e;
Foof()(
I.H'
whuffie
=
42;
~
\'\ow
'fo...
t<lI'I't
Lha,,~e
Wh
re
)
voiddoStuff{finalietx)
II
youcan'
t
change
)Ii
voiddoMore()(
finalietz'"7;
II
youcan'tchangez
final
method
classPoo£(
finalvoidcalcWhuffi.e()
II
~rtant
things
II
thatmustneverbeoverridden
final
class
finalclassMyMostPer£ectClass
II
cannot
be
llIxtended
numbers
and
statics
AlinaLvariable
means
you
can'tchangeitsvalue.
Atinal
method
means
you
can'toverridethemethod.
Atinalclass
means
JOU
can'textendtheclass(i.e.
youcan'tmakeasubclass).
youarehere
~
283
staticandfinal
Q...:
Astaticmethodcan't
access
II
non-staticvariable.Butcananon-statlc
methodaccess
II
staticvariable?
A:
Ofcourse.Anon-staticmethodina
classcanalwayscallastaticmethodInthe
classoraccessastaticvariableoftheclass.
Q...:
Why
would
I
want
to
makeaclass
final1Doesn't
thatdefeatthewhole
purposeof
007
A:
Yesandno.
A
typicalreasonfor
makingaclassfinalIsforsecurity.
You
can't,forexample,makeasubclassofthe
Stringclass.Imaginethehavoc
Ifsomeone
extended
theStringclassandsubstituted
theirownStringsubclassobjects,
polymorphically,whereStringobjects
areexpected.Ifyouneedtocountona
particularImplementationof
themethods
Inaclass,maketheclassfinal.
Q...:
Isn't
It
redundanttohavetomark
themethods
finalIftheclassIsfinal?
A:
Iftheclass
Is
final,youdon'tneedto
rnarkthemethods
final.ThinkaboutIt-If
aclassIsfinalItcanneverbe
subclassed,
sononeofthemethodscaneverbe
overridden.
Ontheotherhand,
If
you
do
wanttoallow
otherstoextendyourclass,andyouwant
themtobeabletooverridesome,butnot
all,ofthemethods,thendon'tmarkthe
classfinalbutgoInandselectivelymark
specificmethodsasfinal.
A
finalmethod
meansthatasubclasscan'toverridethat
particularmethod.
284
chapter10
•A
staticmethod
shouldbecalledusingtheclass
nameratherthananobjectreferencevariable:
Mao
th.
random()
vs.
myFoo.go()
•AstaticmethodcanbeinvokedwithoutanyInstances
ofthemethod'sclassontheheap.
•Astaticmethodisgoodforautilitymethodthatdoes
not(andwillnever)dependonaparticularInstance
variablevalue.
•Astaticmethodisnotassociatedwithaparticular
instanee----onlythec1ass---soItcannolaccessany
Instancevanablevaluesofftsclass.Itwouldn'tknow
which
Instance'svaluestouse.
•Astaticmethodcannotaccessanon-staticmethod,
sincenon-staticmethodsareusuallyassociatedwith
instancevariablestate.
•If
youhaveaclasswithonlystaticmethods,andyou
donotwanttheclasstobeinstantiated,youcanmark
theconstructorprivate.
•A
staticvariable
isavariablesharedbyallmembers
ofagivenclass.Thereisonlyone
copy
ofastatic
variableinaclass,ratherthanonecopypereach
individualinstanceforinstancevariables.
•Astaticmethodcanaccessastaticvariable.
•TomakeaconstantinJava,markavariableasboth
staticandfinal.
•Afinalstaticvariablemustbeassignedavalueeither
atthetime
it
isdeclared,orinastaticinitializer.
static{
DOG_CODE::420;
}
•Thenamingconventionforconstants(finalstatic
variables)Is
to
makethenameaUuppercase.
•AfinalvariablevaluecannotbechangedonceIthas
beenassigned.
•Assigningavalue
to
afinal
Instance
variablemustbe
eitheratthetimeItIsdeclared,orintheconstructor.
•A
finalmethodcannotbeoverridden.
•Afinalclasscannotbeextended(subclassed).
~
yoor
pencil
What'sLegal?
Giveneverythingyou'vejust
learnedaboutstaticandfinal,
whichofthese
wouldcompile?
numbersandstatics
KEEP
...
RIGHT
•
publicclll.Sl!11'00
static:int
Xi
public:voidgo()(
Systam.out.println{x);
•
publicclassF004
BUtic
finalint
x
12;
•
publicc:lassFoo2{
int
Xi
publicstaticvoid
go()(
Syatem.out.println(x);
•
public:voidgo()(
Systam.out.println(x);
public:c1assFoo5(
statiotiDalint
X'"
12;
publicvoid
go
(final
intx)
System.out.println(x);
•
publicclassFoo3
finalint
Xi
public:void
go()(
Syatem.out.println(x);
•
publicclassFoo6
int
x'"
12;
publicstaticvoidgo(finalintx)(
SyatBm,out.println{xl;
youarehere)
285
Math
methods
MathlItethods
Nowthatweknowhowstatic
methodswork,let'slook
atsomestaticmethodsin
classMath.This
isn'tallof
them,justthehighlights.
CheckyourAPIfortherest
includingsqrtf),tant),ceilf),
floor'(),
andasint).
Math.random{)
Returnsadoublebetween0.0through(but
notincluding)1.0.
doublerl
=
Math.random
0;
intr2
=
(int)(Math.random()
*
5);
Math.absO
Returnsadoublethatistheabsolutevalueof
theargument.Themethodisoverloaded,so
ifyoupassitanintitreturnsanintoPassita
double
itreturnsadouble.
intx
=
Math.abs(-240);
II
returns240
doubled
=
Math.abs(240.45);
II
returns240.45
II
returns90876.49
Math.roundO
Returnsanintoralong(dependingon
whether
theargumentisafloatoradouble)
roundedto
thenearestintegervalue.
intx
=
Math.round(-24.8f);
II
returns-25
int
y
=
Math.round(24.45f);
II
returns24
t
Re"'e",bel"',
.fl oa'bn~
pointlitel"'alsal"'eass"''''ed
to
bedo",bles"'nless
yo",
add
the'.f',
Math.minO
Returnsavaluethatistheminimumofthe
twoarguments.Themethodisoverloadedto
takeints,longs,floats,ordoubles.
intx
=
Math.min(24,240);
II
returns24
double
y
=
Math.min(90876.5,90876.49);
Math.maxO
Returnsavaluethatisthemaximumofthe
twoarguments.Themethodisoverloadedto
takeints,longs,floats,ordoubles.
intx
=
Math.max(24,240);
II
returns240
double
y
=
Math.max(90876.5,90876.49);
II
returns90876.5
286
chapter10
numbersandstatics
~
object
primitive
..,.."
int
1I
~'feger o~f
When
you
needtotreat
a
primitive
like
anobject,
wrap
it.
Ii
you're
using
any
version
of
Java
before
5.0,
you'll
Jo
this
when
you
needtostoreaprimitive
valueinsideacollection
like
ArrayList
orlIashMap.
Note:the
plchJre
III
\hetop
Is
achocolateIneroll
wrapper.
Get
It?
WraPP6r?
Somepeople
thinkItlookslikeabakedpotato.bill
\hilt
Wlll1ls
100.
Double
Wrappit1gapritttifive
Sometimesyou
want
totreataprimitivelike
an
objectForexample,in
all
versionsofJava
prior
to
5.0,youcannotputaprimitivedirectly
intoacollectionlikeArrayListorHashMap:
intx::32;
ArrayListlist
=
newArrayList();
list.add
(xl
i
~
't
k
1
s:
\&Si~Java
'S.O
m-
This
'010"'"
wO'r
I""
t.:SS
dr.
L\
od
'11\
~a'J!-ist.
L
- ~II
Tht"e
s
J>O
a
,''v'"()
I_
L~ods
~\'"ea=..
.
LI
(b...~
!-.t.
01\1'1
has
add
"'CV'
t.hat.takesa"
,,,'t..
f"lYTiJ'f
~
L.'
t.iv)
that.
take
objed:.
""t~ueJl(.t.s,
fIO't.
~''''I
es∙
There's
a
wrapper
class
foreveryprimitivetype,
andsincethewrapperclassesareinthejava.
langpackage,youdon'tneedtoimportthem.
Youcanrecognize
wrapperclassesbecause
eachone
is
namedaftertheprimitivetypeit
wraps,
but
with
thefirstlettercapitalizedto
follow
theclassnamingconvention.
Ohyeah,forreasonsabsolutelynobodyonthe
planetiscertainof,theAPIdesignersdecided
nottomapthenames
exactly
fromprimitive
type
toclass
type.
You'llseewhatwemean:
Boolean
Chara~ter ~
Byte
Watth
0I<t.!
The
N",es
al"'~"J.t..
Short/
",ayyed
e'll4d.l'f
to
the
~1"'i~l\Jt
t~s.
The
tlolS
na...esare..
'f
Integer
sfelltd
o>J.t..
Long
Float
youarehere.
287
staticmethods
Thisisstupid,YoumeanIcan't
justmakeanArrayListofints??iI
havetowrapeverysingle
frickin'onein
a
new
Integerobject,thenunwrap
it
when
I
try
to
access
thatvalueintheArrayList?
That'sawasteoftimeandan
error
waitingtohappen..,
JeforeJava5:0,YOUhadtodothework...
-
She'sright.In
all
versionsofJavapriorto5.0,primitiveswereprimitives
andobjectreferenceswereobjectreferences.andtheywere
NEVER
treatedinterchangeably.It
was
always
uptoyou,theprogrammer,
to
do
thewrappingandunwrapping,There
was
nowaytopass
a
primitiveto
a
methodexpectinganobjectreference,andnowaytoassigntheresultofa
methodreturninganobjectreferencedirectlytoaprimitivevariable----even
whenthereturnedreferenceistoanIntegerandtheprimitivevariableis
an
int,
There
was
simplynorelationshipbetweenanIntegerandan
int,
otherthanthefactthatIntegerhasaninstancevariableoftypeint(tohold
theprimitivetheIntegerwraps).Allthework
was
up
to
you.
An
ArrayListofprimitiveints
Without
autoboxing
(Javaversionsbefore5.0)
\J
t,
t
'?
0
~~
tau
l.I
l'lO"{.
Arr
L:rt.-(Rt",t",'ber,be
oYt.'
~
Db'
c.h)
pub
Lic
voiddoNumsOldWay(){
Malual'l
a~/p'2-
all
l\rYa~L.i~b..n:r~\i~b ~e'
1feGi~~
t\o.t
T
1'
~
ArrayListlistOfNumbers
=
newArrayList();
l
.1.,
('l'
L
t.hl
lise-,
I
t
addt\o.e
yr"I"'IU
llt
?
\P.
listOfNumbers,
add
(new
Integer(3»
i
~
you
c.a~~
i.
wYa
o
"r\:.
'n'
dl'l
ll\u~~""~1""St.
so
'/0'0'
n<I\I~
\P
I
Integerone
=
(Inteqer)
lis
tofNumbers.ge
t
(0);
~""'lS
O'o't
as
t'fVl
Ob'td:.,
but.
~O'o>
Ga"l..dst.
intintone
=
ODe.
intValue();
t.h~
ObjtGt
to
al\
I"U~er.
Fihd/ly
y~
td"
t
t"
out
0+
the
Inu~.
hI!
pl"''''ltivt:'
2BBchapter
10
numbersandstatics
Autoboxing:blurringtheline
betweenpritMitiveandobject
TheautoboxingfeatureaddedtoJava5.0does
theconversionfromprimitivetowrapperobject
automatically!
Let'sseewhathappenswhenwewanttomakean
ArrayListto
holdints.
AnArrayListofprimitiveints
With
autoboxing(.Javaversions5.0orgreater)
l1.
L:
t
ok
t'j\'eIl'lteCjer.
publicvoiddoNumsNewWay(){
Makeal'l
f\rra~
IS
-l
ArrayList<Integer>listOfNumbersnewArrayList<Integer>();
listOfNumbers.add(3);
JlASt
add
it!
intnum
=
listOfNumbers.get(O);
"
:h':
I:~~~~~e:;uto",atilally
ul'lwraps
(IAl'lbo~es)
direli!toa:.lei""
~o yo ~
lal'lassi51'1theintva/loe
intVallA~()
fr
Itlve
'~/IthOlAt
havin5to
lall
the
....ethod
0\'1
theInte5erobjelt.
Q.:
WhynotdeclareanArrayList<int>ifyouwantto
holdints7
AH:ho lA~h
thereis
NOT
a",eihodil'lArrayList
.f01"add(iI'lV,thelon-pilerdoesallthewrafpil'l5
(bo)/,;n5).for'lOlA.11'1otherwords,thereI"eall'l
IS
a\'l
Il'Ite~el"
objeltstoredil'ltheAl"l"a'll-ist.blAt
'lOlA5et
to
"pl"etend"thatthe
~l"a'lList
takes
ints.
cy
OIA
lanaddbothintsal'ld
l\'Ite~ers
to
al'l
A'f'l"a'lList<lnte~er>.)
A.:
Because...you
can't.
Remember,theruleforgeneric
typesis
thatyoucanspecifyonlyclassorinterfacetypes,
not
primitives.
SoArrayList<int>willnotcompile.Butasyoucan
seefromthecodeabove,itdoesn'treallymatter,sincethe
compilerletsyou
putintsintotheArrayList<lnteger>.lnfact,
there'sreallynowayto
prevent
youfromputtingprimitives
intoanArrayListwherethetype
ofthelististhetypeofthat
primitive'swrapper,ifyou'reusingaJavaS.D-compliantcom-
piler,sinceautoboxingwillhappenautomatically.So,youcan
putbooleanprimitivesinanArrayList<Boolean>andchars
intoanArrayList<Character>.
youarehere
~
289
staUcmethods
Aufoboxit1Qworksal",osteverywhere
Autoboxingletsyoudomorethanjusttheobviouswrappingand
unwrappingtouseprimitivesinacollection...italsoletsyouuse
eitheraprimitiveoritswrappertype
virtually
anywhereoneorthe
otherisexpected.
Think
aboutthatl
Funwithautoboxing
Methodarguments
Ifamethodtakesawrappertype,you
canpassa
referencetoawrapperor
aprimitiveof
thematchingtype.And
ofcourse
thereverseistrue-ifo
method
takes(]primitive,youcan
passin
eitheracompatibleprimitive
ora
referencetoawrapperofthat
primitivetype.
Returnvalues
If
amethoddeclaresaprimitive
returntype,youcanreturneithera
compatibleprimitiveora
reference
tothewrapperofthatprimitivetype.
Andifamethoddeclaresawrapper
returntype,youcanreturneithera
referencetothewrappertypeor
a
primitiveofthematchingtype.
Booleanexpressions
Anyplaceabooleanvalueisexpected,
youcanusee
itheranexpressionthat
evaluatestoaboolean(4)2),ora
primitiveboolean,ora
referencetoa
Booleanwrapper.
290
chapter10
.~
\1
"''>1''ger
Ol:i~
/
int
voidtakeNumber(Integer
i){}
int
giveNumber()
return
X;
true
\1
~/ean o~f
boolean
~f
if
(bool){
System.out.println("true
H
);
Operationsonnumbers
Thisisprobablythestrangestone-yes,you
cannowuseawrapper
type
asanoperand
inoperations
wheretheprimitivetypeis
expected.Thatmeansyoucanapply,
say,
theincrementoperatoragainstareference
toanIntegerobject!
Butdon't
worry-this
is
justacompilertrick.
Thelanguagewasn'tmodifiedtomakethe
operatorsworkonobjects;thecompiler
simply
convertstheobjecttoitsprimitive
typebeforetheoperation.
It
surelooks
weird,though.
Integer
i
=
newInteger(42);
i++;
Andtnatmeansyoucanalsodothingslike:
Integerj:;newInteger(5);
Integerk:;
j..
3;
Assignments
Youcanassigneither
a
wrapperorprimitive
toavariable
declaredasamatchingwrapper
orprimitive.
forexample,aprimitiveint
variablecanbeassignedtoan
Integer
referencevariable,
and
vice-versa-o
referencetoanIntegerobjectcanbe
assignedtoavariable
declared
asan
jnt
primitive.
numbersandstatics
i++i
~
your
pencil
Will
this
codecompile?WillItrun?IfIIruns,
whatwill
~do7
Take
yourtimeand
think
about
thisone;it
bringsupan
implication
ofautoboxingthat
wedidn't
talk
about.
You'll
have
to
goto
yourcompiler
to
find
theanswers.
(Yes.we'reforclngyou
to
experiment,foryourown
good
of
course.)
publicclassTastBox
Integer
i;
int
j;
publicstatic
void
main
(String[]
ll%gs)(
T.stBox
t;
new
T.stBox()
i
t.qo();
}
publicvoidgo
0
j-ii
Systam.out.println(j);
Systam.out.println(i);
youarehere)
291
wrappermethods
Jut
waltl
There1s",ore!Wrappers
havestaticutilitytMethodstoo!
Besides
acting
likeanormalclass.
the
wrappers
have
a
bunchofreaJlyusefulstaticmethods.We','eusedonein
this
bookbefore--lnteger.parselntO.
TheparsemethodstakeaStringandgiveyou
back
a
primitive
value.
ConvertingaStringtoa
primitivevalueiseasy:
Strings"""2";
intx
=
Inteqer.parseInt(s);
doubled
=
Double.parSeDouble("420.24
H
);
You'llgetaruntimeexception:
%
javaWrappers
Exceptioninthread"main
N
java.lang.NumberFormatException:
two
atjava.lang.lnteger.parselnt(Integer.java:409)
atjava.lang.lnteger.parselnt(Integer.java:458)
atWrappers.main(Wrappers.java:9)
292
chapter10
Everymethodor
constructorthatparses
aStringcanthrowa
NumberFormatExceptlon.
It'sa
runtime
exception,
soyoudon'thaveto
handleordeclareIt.
Butyoumightwantto.
(We'UtalkaboutExceptionsinthe
next
chapter.)
Attd.,ow
i"
reverse...fuYttittga
prhMitivettutMberitttoaStrittg
Thereareseveral
ways
to
tum
anumberintoaString.
Theeasiestistosimplyconcatenatethenumbertoan
existing
String.
Lh
'+'
o~cra~
is
o...
~y\oa~,d
R,,,,t"'\'cr\.
t.
loadt.d
oycratoo-as
a
doubled'"
42.5;
~
i"
Java
(tht.
_I'f
t;-
A",,.l.\.iWl~
.loot.d
1:.0
a
Stt∙..o.
c.oWlu\:.t.Ni"LOr.1
v'
String
doubleString
=...."
+
d;
~"J
L
-COes
Shi,,~i-r't.d.
Sttl"!l
Dt:
0'"
doubled
=
42.5;
StringdoubleStrinq'"Dcuble.toStrinq(d);
\
A~t.I".
way
to
do
it
l.ISiJ\9
a
st.;-bt
"'ethod
Ih
dan
Do..bk
numbers
and
statics
youarehere
~
293
number
formatting
Nutttberfortttatti.,g
InJava,formattingnumbersanddatesdoesn'thavetobecoupledwithI/O.Think
aboutit.Oneofthemosttypicalwaystodisplaynumberstoauseristhrougha
GUI.You
putStringsintoascrollingtextarea,ormaybeatable.Ifformattingwas
builtonlyintoprintstatements,you'dneverbeabletoformatanumberintoanice
StringtodisplayinaGUI.BeforeJava5.0,
mostformattingwashandledthrough
classesinthejava.textpackagethatwewon'tevenlookatinthisversionofthe
book,nowthatthingshavechanged.
InJava5.0,theJavateamaddedmorepowerfulandflexibleformattingthrougha
Formatterclassinjava.util.Butyoudon'tneedtocreateandcallmethodsonthe
Formatterclassyourself,becauseJava5.0addedconveniencemethodstosomeof
theI/Oclasses(including
printf'(j)
andtheStringclass.Soit'sasimplematterof
callingastaticString.formatOmethodandpassingitthethingyouwantformatted
alongwithformattinginstructions.
Ofcourse,youdohavetoknowhowtosupplytheformattinginstructions,and
thattakesalittleeffortunlessyou'refamiliarwiththefrrintf()functionin
C/CH.
Fortunately,evenifyou
don't
knowprintf()youcansimplyfollowrecipesforthe
mostbasicthings(thatwe'reshowinginthischapter).Butyouwillwanttolearn
howtoformatifyouwanttomixandmatchtoget
anything
youwant.
We'llstart
herewithabasicexample,thenlookathowitworks.(Note:we'llrevisit
formattingagainintheI/Ochapter.)
Formattinganumbertousecommas
publicclassTestFormats(
publicstaticvoidmain(String[)args){
Strings
=
String.format
("lis,
d",
System.out.println(s);
~
1,000,000,000
294
chapter10
Do
this...
•
format("%,
d",
~
FortMaffit1gdecot1sfrucfed...
Atthemostbasiclevel,formattingconsistsoftwomainparts
(thereismore,butwe'llstartwiththistokeepitcleaner):
__FormattingInstructions
Youusespecialformatspecifiersthatdescribehow
theargumentshouldbeformatted.
e
Theargumenttobeformatted.
Althoughtherecanbemorethanoneargument,we'll
startwithjustone.Theargumenttypecan'tbejust
anything...ithastobesomethingthatcanbeformatted
usingtheformatspecifiersintheformattinginstructions.
Forexample,ifyourformattinginstructionsspecifya
floatingpointnumber,youcan'tpassinaDogorevena
Stringthatlookslikeafloatingpointnumber.
to
this.
•
1000000000);
~
i\
Usetheseinstructions...onthisargument.
WhatdotheseInstructionsactuallysay?
"Takethesecondargumenttothismethod,and
formatitasadecimalintegerandinsert
commas."
Howdotheysaythat?
Onthenextpagewe'lllookinmoredetailatwhatthe
syntax
"%,
d"actuallymeans,butforstarters,anytimeyouseethepercent
sign(%)inaformatString(whichisalwaysthefirstargument
toa
formatf)
method),thinkofitasrepresentingavariable,
andthevariableistheotherargumenttothemethod.Therest
ofthecharactersafterthepercentsigndescribetheformatting
instructionsfortheargument.
numbers
andstatics
you
arehere.
295
theformatOmethod
Thepercettt
(~)
says,"ittsertargutltet1t
here"
(a"dformatItuslt1gtheseit1structiottS)
Thefirstargumenttoa
formatj)
methodiscalledtheformatSuing,andit
canactuallyincludecharactersthatyoujustwantprintedas-is,withoutextra
formatting.Whenyouseethe
%
sign,though,thinkofthepercentsignasa
variable
thatrepresentstheotherargumenttothemethod.
Ihave476578.10bugstofix.
The
"%"
signtellstheformattertoinserttheothermethodargument(the
secondargumenttoformatf),thenumber)here,At"lDformat
it
usingthe
u
.2r
charactersafterthepercentsign.ThentherestofUteformatSuing,
"bugsto
fix",
isaddedtothefinaloutput.
Addingacomma
format("!have
%,.2£
bugstofix.
u
,
476578.09876);
Ihave476,578.10bugsto
f~.
296chapter10
numbers
and
statics
Buthowdoesit
even
KNOW
wheretheinstructionsendandthe
restofthecharactersbegin?Howcome
it
doesn'tprintoutthe
"f"
in
"%.2f'?
Or
the"2"(
Howdoesitknowthatthe.2f
was
part
oftheinstructionsandNOT
part
oftheStriT\9?
TheformatStri"Qusesits
ow.,
littlelattguagesytttax
Youobviouslycan'tputjust
an),thingafter
the
"%~
sign.The
syntax
forwhatgoesafterthepercent
signfollowsveryspecificrules,anddescribes
howto
formatmeargumentthatgetsinsertedat
thatpointintheresult(formatted)String.
You've
alreadyseen
two
examples:
%,
d
means"insertcommasandformatthe
numberasadecimalinteger,"
and
%.2£
means
"formatthe
number
as
afloating
point
with
aprecisionoftwodecimalplaces."
and
%,.2£
means"insertcommasand
format
the
numberasafloatingpoint
with
aprecisionof
twodecimalplaces."
Therealquestionisreally,"Howdo
I
knowwhat
to
putafterthepercentsigntoget
it
to
dowhat
I
want?"
Andthatincludesknowingthesymbols
(like
"d"
fordecimaland
"f"
forfloating
point)
aswellastheorderinwhichtheinstructions
mustbeplacedfollowingthepercentsign.For
example,ifyouputthecommaafterthe
"d"
like
this:
k%d,
~
insteadof"'%,d"
it
won't
workl
OrwillivWhatdoyouthinkthis
will
do:
String.for1llat("Ihave%.2£,bugs
to
fix.",
476578.09876);
(We'llanswerthatonthenextpage.)
youarehere
~
297
format
specifier
ThefortMatspecifier
Everythingafterthepercentsignuptoandincludingthetypeindicator(like
"d"or
"f')
arepartoftheformattinginstructions.Afterthetypeindicator,the
formatterassumesthenextsetofcharactersaremeanttobepanoftheoutput
String,untilorunlessithitsanotherpercent
(%)
sign.
Hmmmm...isthateven
possible?Canyouhave
morethanoneformattedargumentvariable?Putthat
thoughtonholdforrightnow;we'llcomebacktoit
in
a
few
minutes.Fornow,
let'slookat
thesyntaxfortheformatspecifiers-thethingsthatgoafterthe
percent
(%)
signanddescribehowtheargumentshould
be
formatted.
Aformatspecifiercanhaveupto
five
differentparts(not
Includingthe
MOJo").
EverythingInbrackets[]belowIsoptional,so
onlythepercent
(0J0)
andthe
type
arerequired.ButtheorderIs
alsomandatory,soanypartsyouDOusemustgoInthisorder.
%[argumentnumber][flags][width)[.precision)type
%[argumentnumber][flags][width)[.precision)
type
------~Jl
format("%,6.1f
N
,
42.000);
298
chapter10
numbersandstatics
Theot1lyrequiredspecifierisforTVPE
Althoughtypeistheonlyrequiredspecifier,rememberthatifyou
do
put
inanythingelse,typemustalwayscomelast!Therearemorethanadozen
differenttypemodifiers(notincludingdatesandtimes;theyhavetheirown
set),
butmostofthetimeyou'llprobablyuse%d(decimal)or%f(floating
point).Andtypicallyyou'llcombine%fwithaprecisionindicatortosetthe
numberofdecimalplacesyouwantinyouroutput.
TheTYPEismandatory,everythingelseisoptional.
42.000
decimal
format
("%d",
Youmustincludea
typeinyourtormat
instructions,
andityou
specitythingsbesides
type,thetypemust
always
COmelast.
Mostotthetime,
you'llprobablytormat
numbersusingeither
"d"
r
J'
l"
t»
ror
ecrma
or
l'
torlloatingpoint.
floatingpoint
format
("%.3£",
42.000000);
~
A
4-2.25
wcxo/d
ot
I
42);
wo",ld
beth
tIwork,
It
d'esallieastrt'tI
to
.,rettlyassi3t1a
do",bl
3
Itlt
variable.
eatl
Theargumentmustbecompatiblewithanint,sothatmeans
onlybyte,short,int,andchar(ortheirwrappertypes).
"kit
»e\"ewe
tOftlbil'le~ ~he
with
a
f\"etis',o\'\
'l'Id,t~tov-
".,11
weel'lded
",y
WIth
.7
so
th\"ee
u\"oes∙
Theargumentmustbeofafloatingpointtype,sothat
meansonlyafloatordouble(primitiveorwrapper)aswell
assomethingcalledBigDecimal(whichwe
don'tlookatin
this
book).
%d
%f
%xhexadecimal
format
("%x",
42);
Theargumentmustbeabyte,short,int,long(including
bothprimitiveandwrappertypes),andBigInteger.
%ccharacter
format
("%c",
42);
Theargumentmustbeabyte,short,char,orint(including
bothprimitiveandwrappertypes).
youarehere.299
formatarguments
Whathappens
if
I
havetltorethanoneargutltent?
ImagineyouwantaStringthatlookslikethis:
"Therankis
20,456,654
outof
100,567,890.24."
Butthenumbersarecomingfromvariables.Whatdoyoudo?Yousimplyadd
two
argumentsaftertheformatString(firstargument),sothatmeansyourcalltoformatt)
willhavethreeargumentsinsteadoftwo.Andinsidethatfirstargument(theformat
String),you'llhavetwodifferentformatspecifiers(twothingsthatstartwith
"%").
The
firstformatspecifierwillinsertthesecondargumenttothemethod,andthesecond
formatspecifierwillinsertthethirdargumenttothemethod.Inotherwords,the
variableinsertionsintheformatStringusetheorderinwhichtheotherargumentsare
passedintotheformatf)method.
intone
=
20456654;
doubletwo
=
100567890.248907;
Strings
=
String.format("Therankis
%,d
outof
%,.2£",
one,
twO);
~
Therank
is
20,456,654outof100,567,890.25
We
added
tOl'l\l'I\OS
to
bothvat'iables,
and
t'estt'ittedthe
.fIO<ltin~
point
n~l'I\bet'
(thesetondvariable)
to
two
detil'l\alplates.
As
you'llseewhenwegettodateformatting,youmightactuallywanttoapplydifferent
formattingspecifierstothesameargument.That'sprobablyhardtoimagineuntilyou
see
how
date
formatting(asopposedtothe
numberformatingwe've
beendoing)works.
Justknowthatinaminute,you'llseehowtobemorespecificaboutwhichformat
specifiersareappliedtowhicharguments.
Q:
Um,there'ssomethingREALLYstrangegoingonhere.Justhowmanyarguments
can
I
pass?Imean,howmanyoverloadedformat()methodsareIN
theStringclass?So,whathappens
ifIwanttopass,say,tendifferentargumentstobeformattedforasingle
outputString?
A:
Goodcatch.Yes,there
is
somethingstrange(oratleastnewanddifferent)goingon,and
nothereare
not
abunchofoverloadedformatOmethodstotakeadifferentnumberofpossible
arguments.Inorderto
supportthisnewformatting(printf-like)APIinJava,thelanguageneeded
anothernew
feature-variableargumentlists
(called
varargs
forshort).We'lltalkaboutvarargs
onlyin
theappendixbecauseoutsideofformatting,youprobablywon'tusethemmuchinawell-
designedsystem.
300chapter
10
numbers
and
statics
SotMuchfort1utMbers,whataboutdates?
ImagineyouwantaStringthatlookslikethis:"Sunday,Nov282004"
Nothingspecialthere,yousay?Well,imaginethatallyouhavetostartwithisavariable
oftypeDate-AJavaclassthatcanrepresentatimestamp,andnowyouwanttotakethat
object(asopposedtoanumber)andsenditthroughtheformatter.
Themaindifferencebetweennumberanddateformattingisthatdateformatsusea
two-charactertypethatstartswith
"t"
(asopposedtothesinglecharacter
"f"
or"d",for
example).Theexamplesbelowshouldgiveyouagoodideaofhowitworks:
Thecompletedateandtime%tc
String.format
("%tc",
newDate());
SunNov2814:52:41MST2004
Justthetime%tr
String.format
("%tr",
newDate());
03:01:47PM
Dayoftheweek,monthandday%tA%tB%td
Thereisn'tasingleformatspecifierthatwilldoexactlywhatwe
want,sowehavetocombinethreeofthemfordayoftheweek
(%tA),month(%tB),anddayofthemonth(%td).
Sunday,November28
Sameasabove,butwithout
duplicatingthe
arguments%tA%tB%td
Datetoday
=
newDate();
The
a\'l~le-bl"atkd:
"<"
isjlASta\'lothel"
String.format("%tA,%<tB%<td",today);
~Ia ~
ill
iht
speti+iel"that
tells
the
+o
l"",aHel"
to
"lASethe..fl"eviOlAS
al"~~"'el'lt
a~a il'l."
So
itsaves
'1~
hOM
l"efeat il'l~
the
al"~lA",e\'lts,
al'ldi\'lSuad
'i0~
+Ol"",atthe
SaMe
al"~~el'lt
thl"eediHel"el'ltways.
youare
here.
301
manipulatingdates
302
chapter10
Let'ssee...howmanywork
dayswilltherebe
if
the
projectstartsonFeb27thand
endsonAugust5th?
Workhtg
withPates
Youneedtodomore
with
datesthanjustget
UN:ldys
date.Youneedyourprogramstoadjust
dates,find
elapsedtimes,prioritizeschedules,
heck,makeschedules.Youneedindustrial
strengthdatemanipulationcapabilities.
You
couldmakeyourowndateroutinesof
course...(anddon'tforgetaboutleapyearsl)
And,ouch,thoseoccasional,peskyleap-
seconds.
Wow,
this
couldgetcomplicated.The
goodnews
is
thattheJavaAPIisrich
with
classesthatcanhelpyoumanipulatedates.
Sometimesitfeelsalittle
too
rich...
Movit1Qbackwardat1dforwardit1tittte
Let'ssayyourcompany'sworkscheduleisMondaythroughFriday.
You've
beenassignedthetaskoffiguringoutthelastworkdayin
eachcalendarmonththisyear...
Itseemsthatjava.util.DateIsactually•••outofdate
Earlierweusedjava.util.Datetofindtoday'sdate,soitseems
logical
thatthisclasswouldbeagoodplacetostartlookingfor
somehandydatemanipulationcapabilities,butwhenyoucheck
outtheAPIyou'llfindthatmostofDate'smethodshavebeen
deprecated!
TheDateclassisstillgreatforgettinga"timestamp"-anobject
thatrepresentsthecurrentdateandtime,souseitwhenyouwant
tosay,"givemeNOW".
ThegoodnewsisthattheAPIrecommends
java.util.Calendar
instead,solet'stakealook:
UseJava.util.Calendarforyourdate
manipulation
ThedesignersoftheCalendarAPIwantedtothinkglobally,
literally.
Thebasicideaisthatwhenyouwanttoworkwithdates,
youask
foraCalendar(throughastaticmethodoftheCalendar
classthatyou'llseeonthenextpage),andthe
JVM
handsyouback
aninstanceofaconcretesubclassofCalendar.(Calendarisactually
anabstractclass,soyou'realwaysworkingwithaconcretesubclass.)
Moreinteresting,though,isthatthe
kind
ofcalendaryouget
backwillbe
appropriateforyourlocale.
Muchoftheworldusesthe
Gregoriancalendar,butifyou'reinanareathatdoesn'tusea
GregoriancalendaryoucangetJavalibrariestohandleother
calendarssuchasBuddhist,orIslamicorJapanese.
ThestandardJavaAPIships
withjava.util.GregorianCalendar,
so
that'swhatwe'llbeusinghere.Forthemostpart,though,you
don'tevenhavetothinkaboutthekindofCalendarsubclassyou're
using,andinsteadfocusonlyonthemethodsoftheCalendarclass.
numbers
and
statics
v∙
rtt"
.roratime-stampo:tnow,
useDate.Butloreverything
else,useCalendar.
you
arehere.
303
gettingaCalendar
&ettit1gat'objectthatextendsCalendar
Howintheworlddoyougetan"instance"ofanabstractclass?
Wellyou
don'tofcourse,thiswon'twork:
ThisWON'Twork:
v---
nt
tompile¥.....
0I'I't
allow
this
I
Calendarcal
=
newCalendar();.
Youcan'tgetaninstanceofCalendar,
butyoucancangetaninstanceofa
concreteCalendarsubclass.
Obviouslyyou
can't
getaninstanceofCalendar,because
Calendarisabstract,Butyou'restillfreetocallstaticmethods
onCalendar,since
SUllie
methodsarecalledonthe
class;
ratherthanonaparticularinstance.Soyou
call
thestatic
getInstanceOonCalendarandit
gives
youback...
an
instance
of
a
concretesubclass.SomethingthatextendsCalendar
(whichmeansitcanbepolymorphicallyassignedtoCalendar)
andwhich-bycontract-s-canrespondto
the
methodsofclass
Calendar.
In
mostoftheworld,andbydefaultformostversionsofJava,
you'llbe
gettingbackajava.util.GregorianCalendarinstance.
Waitaminute.
Ifyoucan'tmakean
instanceof
theCalendar
class,whatexactly
areyou
assigningto
thatCalendar
reference?
Instead,usethestatic"getlnstanceO"method:
Calendarcal
=
Calendar.getlnstance();
304
chapler10
numbersandstatics
WorkittgwithCalettdarobjects
Thereareseveralkeyconceptsyou'Uneedtounderstandin
ordertoworkwithCalendarobjects:
•Fields
hold
state-
ACalendarobjectbasmanyfieldsthatareusedto
representaspectsofitsultimatestate,
its
dateandtime.Forinstance,you
cangetandsetaCalendar's
year
or
month.
•DatesandTimescanbe
incremented-
TheCalendarclasshasmethodsthat
allowyou
to
addandsubtractvaluesfromvariousfields,for
example
"add
one
to
themonth".or"subtractthreeyears".
•
Dates
and
TImescanberepresented
in
milhseconds-
TheCalendarclass
letsyou
convertyourdatesintoandoutofamillisecondrepresentation.
(Specifically,
thenumberofmillisecondsthathaveoccuredsinceJanuary
lst,1970.)Thisallowsyoutoperformprecisecalculationssuchas"elapsed
timebetween
twO
times"or"add63hoursand23minutesand12seconds
tothistime",
An
exampleofworkingwithaCalendarobject:
1
~o&r
at
\",~D.
.t.o
Ja'"
J
o-ba$td.1
Calendarc
=
Calendar.getInstance()
i
~
b"'\L
,..(l¥\\)1
i.s
z.l'"
,--_._~ n.JdUl.t.~nt.
c.set(2004,O,7,15,40);
~
.
L.LL'
t.o
a
hie>01'
ConV~
"{.I\\s
J
longdayl
=
c.
getTimelnMillis();
~
oJ
3W\OIo'l'It.
ot
",i\Iis«.ow-dS.
System.out.println("add35
days"
+
c.getTime());
~-------
dayl
+~
1000
*
60
*
60;
c.setTimelnMillis(dayl);(
System.out.println("newhour
c.add(c.DATE,
35);
"+
c.qet(c.HOUR_OF_DAY»);
Add
3'5da'f1to
the
dau,
whith
shOl.lld""ove
lAS
jPlto
FebYu.ilry.
System.out.println("roll35days"
+
c.getTime(»)i
c.roll(c.DATE,35);
c.set(c.DATE,
1);
<:~---~--
System.out.println("setto1"
+
c.qetTime(»);
This
outp",t,
ton~i_s
how...
illis.
add,
yoll,
dPld
set
w~k
youarehere
~
305
CalendarAPI
HighlightsoftheCalettdarAPI
We
JUSt
workedthroughusingafewofthefieldsand
methods
in
the
Calendarclass.This
is
abigAPI
so
we'reshowingonlyafew
ofthemostcommonfields
and
methods
that
you'lluse.Onceyouget
a
fewof
these
it
shouldbeprettyeasytobendtherestofthe
thisAPI
toyour
will.
KeyCalendarMethods
add(lntfield.
Intamount}
Addsorsubtractstimefromthecalendar'sfield.
get(lntfield)
Returnsthevalueofthegivencalendarfield.
-,
-
Key
CalendarFields
set(intfield.lntvalue}
SetsthevalueofagivenCalendarfield.
set(year.month.
day,
hour.minute)(allints)
Acommon
variety
ofsettosetacompletetime.
getTlmelnMllIIs()
ReturnsthisCalendar'stime
In
millis,as
a
long.
roll(intfield,booleanup)
Addsorsubtractstimewithoutchanginglargerfields.
II
more...
setTlmelnMfllis(longmillis)
Sets
aCalendar'stimebasedonalong
rnllli-tirne.
DATE
I
DAY_OF_MONTH
Get/set
the
dayof
month
HOUR/HOUR_OFDAY
Get!
Set
the12h-
OurOr24
hourvalue
MILLISECOND.
Get/
Set
the
milliseconds,
MINUTE
Get/set
the
mInute.
MONTH
Get/
setthemonth.
---...._..._-_.._--..,YEAR
Get/
Set
the
year.
ZONE_OFFSET
Get/setraw
offset
of
GMT
I
1/
nmUUs.
more...
06
chapter10
numbersandstatics
EvettttloreStatics!...staticjttlJ!orts
NewtoJava5.0...arealmixedblessing.Somepeoplelove
thisidea,
somepeoplehate
it,
Staticimportsexistonlytosave
you
sometyping.
[f
youhatetotype,yournightjustlikethis
feature.
Thedownsidetostaticimportsisthat-
if
you'renot
careful-usingthemcanmakeyourcodealothardertoread.
Thebasicideaisthatwheneveryou'reusingastaticclass,a
staticvariable,
oranenum(more
on
thoselater),youcan
importthem,andsaveyourselfsometyping.
Someold-fashionedcode:
importjava.lang.Math;
Use
CareluU
y
:
staticimportscan
makeyour
code
contusingto
read
classNoStatic{
publiCstaticvoidmain(String()argsl(
Math.tan(60});
Samecode,withstaticImports:
;importstaticjava.lanq.System.Outi
-Caw.aII
&
Gokhas
•
•
•
Ifyou'reonlygoing
to
useastaticmember
a
few
times,wethinkyoushouldavoid
staticImports,
to
helpkeepthecodemore
readable.
Ifyou'regoingtouseastaticmemberalot,
(likedoinglotsofMathcalculanons),then
it'sprobably
OK
to
usethestaticImport.
Noticethatyoucanusewildcards(."),in
your
staticImport
declaration.
•Abigissuewithstaticimportsisthatit's
not
too
hardtocreatenamingconflicts.For
example,ifyouhavetwodifferentclasses
with
an"addO'method,howwillyouand
thecompiler
know
whichonetouse?
publicstaticvoidmain(String[]args)
classWithStatic(
;importstaticjava.lanq.Math.*i
youarehere.307
static
vs.instance
FiresideChats
@
Tonight'sTalk:
An
instancevariable
takescheapsIlotsatastaticvariable
In.stanoe
Variable
Idon'tevenknowwhywe'redoingthis.
Everyoneknows
static
variablesarejustused
forconstants.Andhowmanyofthoseare
there?
I
thinkthewhole
API
musthave,what,
four?
Andit'snotlikeanybodyeveruses
them.
Fullof
it.
Yeah,youcansaythatagain.OK,
so
thereareafewintheSwinglibrary,but
everybodyknowsSwingisjustaspecialcase.
Ok,butbesidesa
few
GUIthings,givemean
exampleofjustonestaticvariablethatanyone
wouldactuallyuse.Intherealworld.
Well,
that'sanotherspecialcase.Andnobody
usesthatexceptfordebugginganyway.
308
chapter10
S1aticVariable
Youreallyshouldcheckyourfacts.When
was
thelasttimeyoulookedattheAPI?It's
frickiri'
loadedwithstatics!Itevenhasentire
classesdedicatedtoholdingconstantvalues.
There'saclasscalledSwingConstarus,for
example,that'sjustfuUofthem.
It
mightbeaspecialcase,butit'sareally
importantonelAndwhatabouttheColor
class?Whatapain
if
youhadtorememberthe
RGBvaluestomakethestandardcolors?But
thecolorclassalreadyhasconstantsdefined
forblue,purple,white,red,etc.Veryhandy.
How'sSystem.outforstarters?
Theoutin
System.outisastaticvariable
oftheSystem
class.Youpersonally
don'tmakeanew
instanceoftheSystem,youjustasktheSystem
classforits
outvariable.
Oh.Iikedebuggingisn'timportant?
Andhere'ssomethingthatprobablynever
crossedyournarrowmind-let'sfaceit,static
variables
aremoreefficient.Oneperclass
instead
ofoneperinstance.Thememory
savingsmightbehuge!
InstanceVariable
Urn,aren'tyouforgettingsomething?
Staticvariablesareaboutasun-OOasitgets!!
Geewhynotjustgotakeagiantbackwards
stepanddosomeproceduralprogramming
whilewe'reat
it.
You'relikeaglobalvariable,andany
programmerworthhisPDAknowsthat's
usuallyaBadThing.
Yeahyouliveinaclass,buttheydon'tcall
itClas.rOriented
programming.That'sjust
stupid.You'rearelic.Somethingtohelpthe
old-timersmaketheleaptojava.
Well,OK,every
onceinawhilesure,itmakes
senseto
useastatic,butletmetellyou,abuse
ofstaticvariables(andmethods)
isthe ~iDark
ofanimmature00programmer.Adesigner
shouldbethinkingabout
object
state,not
class
state.
Static
methodsaretheworstthingsofall,
becauseitusuallymeanstheprogrammeris
thinkingprocedurallyinsteadofaboutobjects
doingthingsbasedontheiruniqueobject
state.
Riiiiiight.
Whateveryouneedtotellyourself...
numbersandstatics
StaticVariable
What?
Whatdoyoumean
un-OO?
IamNOTaglobalvariable.There'snosuch
thing.Iliveinaclass!That'spretty00you
know,aCLASS.
I'mnotjustsittingoutthere
inspacesomewhere;I'manaturalpartofthe
stateofanobject;theonlydifferenceisthat
I'msharedbyallinstancesofaclass.Very
efficient.
Alrightjuststoprightthere.THATis
definitely
nottrue.Somestaticvariablesare
absolutelycrucialtoasystem.Andeventhe
onesthataren'tcrucialsurearehandy.
Why
doyousaythat?Andwhat'swrongwith
static
methods?
Sure,Iknowthatobjectsshouldbethefocus
ofan00design,butjustbecausethereare
somecluelessprogrammersoutthere...don't
throwthebabyoutwiththebytecode.There's
atimeandplaceforstatics,andwhenyou
needone,nothingelsebeatsit.
youarehere.
309
static{
System.out.println("superstaticblock");
bethecompiler
classStaticSuper{
BE
thecomriIer
TheJava
file
on
this
pagerepresentsa
completeprogrlU'l.Yourjoh
is
to
rIa)'
cOIlIpiler
and
deterrnne
whether
this
file
will
cOIllpile.
If
it
won't
cOIlIpile.
howwould
)'OU
1'lX
it.
and
if
it
doescompile.
whllt
wouldhe
~
output?
}
StaticSuper{
System.out.println(
"superconstructor");
}
}
publicclassStaticTestsextendsStaticSuper{
staticintrandj
static{
rand
=
(int)(Math.random()
*
6)j
system.out.println("staticblock
n
+
rand);
}
StaticTests(){
System.out.println("constructor");
}
publicstaticvcidmain{String[]args){
System.cut.println("inmain");
StaticTestsst
=
newStaticTests()j
}
}
310
chapter
10
If
it
complies,which
of
theseIs
the
output?
Possible
Output
RleEditWlndowHel
ell
%java
StaticTests
staticblock
4
inmain
superstaticblock
superconstructor
constructor
PossibleOutput
FileEditWlndowHetElectrle:l
%java
StaticTests
superstaticblock
staticblock3
inmain
superconstructor
constructor
numbers
and
statics
Thischapterexploredthewonderful,static,world
of
Java.
YourJobisto
decide
whethereachofthe
followingstatementsIstrueorfalse.
1.TousetheMathclass,thefirststepistomakeaninstanceofit.
2.Youcan
markaconstructorwiththe
static
keyword.
3.Static
methodsdon'thaveaccesstoinstancevariablestateofthe'this'object.
4.Itis
goodpracticetocallastaticmethodusingareferencevariable.
5.Staticvariablescould
beusedtocounttheinstancesofaclass.
6.Constructors
arecalledbeforestaticvariablesareinitialized.
7.MA)CSIZEwouldbeagood
nameforastaticfinalvariable.
8.
A
staticinitializerblockrunsbeforeaclass'sconstructorruns.
9.
If
aclass
is
markedfinal,allofitsmethodsmustbemarkedfinal.
10.Afinal
methodcanonlybeoverridden
if
its
classisextended.
11.Thereisnowrapperclassforbooleanprimitives.
12.Awrapperisused
whenyou
want
totreataprimitivelikeanobject.
13.
TheparseXxxmethodsalwaysreturnaString.
14.Formattingclasses(whichare
decoupledfrom
1/0),
areinthejava.format
package.
youarehere
~
311
codemagnets
LunarCodeMagnets
Thisonemightactuallybeusefullinadditiontowhatyou'velearnedinthelastfew
pagesaboutmanipulatingdates,you'llneed
a
littlemoreinformation...Firstfull
moonshappenevery
29.52
daysorso.Second,therewasafullmoononJan.7th,
2004.
YourjobistoreconstructthecodesnippetstomakeaworkingJavaprogram
thatproducesthe
outputlistedbelow(plusmorefullmoondates).(Youmightnot
needall
ofthemagnets,andaddallthecurlybracesyouneed.)Oh,bytheway,your
outputwillbedifferent
if
youdon'tliveinthemountaintimezone.
Calendarc
=
Calendar.get1nst&nce();
out.printlne.set{2004,O,7,15,40);
c.setT1meInHi
lliS(daYl);(string.format
I
long
dayl
=
c.getTimelnMillis();
I
I
c.
set
(2004,l,7,15,40);
I
r
imPort
static
java.lang.system.out;
-
\
staticintDAY
IM::60
Or
60
..
24;
~
1
("full
moononllitc",
c»;
•
.~ I
(c.format
J
L
Calendar
C-
new
Calendar();
•
l
"lass
(
FullMoo
ns
r
I
publicstaticvoid
main(Strinq
[]
arqs)
{
I
I
dayl
+=
(DAY_1M..
29.52);
I
I
for(int
x::
0;
X
<
60;
x++)
{a
~
L
stati.e
int
DAY
IM
=:
1000
Or
60
Or
60..24;-,
I
println
l
J..
-
1
\
("fullmoonon%t",
c));
l
~port
Java.i.o.*;
~
limportjava.util.*;
}
I
static
importjava.lanq.System.out;
~
I
r
312
chapter10
numbers
and
statics
TrueorFalse
1.TousetheMathclass,thefirststepisto
make
an
instanceofit.
2.
Youcanmarkaconstructorwiththekey-
word
'static'.
False
False
True
True
True
False
False
3.
Staticmethodsdon'thaveaccessto
an
object'sinstancevariables.
4.
Itisgoodpracticeto
call
astaticmethod
usingareferencevariable.
5.
Staticvariablescouldbeusedtocountthe
instancesofaclass.
6.
Constructorsarecalledbeforestaticvari-
ables
areinitialized.
7.MAX_SIZE
wouldbeagoodnamefora
staticfinalvariable.
8.A
staticinitializerblockrunsbeforeaclass's
True:
}
staticSuper(){
System.out.println(
usuperconstructor
H
);
StaticSuperisaconstructor,andmust
nave()
initssignature.Noticethoras
theoutputbelowdemonstrates,thestatic
blocksforbothclassesrunbeforeeither
oftheconstructorsrun.
constructor
runs.
9.
If
a
class
ismarkedfinal.allofitsmethods
mustbemarkedfinal.
]O.
A
finalmethodcanonlybeoverridden
if
its
class
isextended.
11.
There
is
nowrapper
classfor
boolean
False
False
False
PossibleOutput
File
Ed~
WIndOWHelelln
%javaStaticTests
superstaticblock
staticblock3
inmain
superconstructor
constructor
primitives.
12.A
wrapperisusedwhenyouwanttotreata
True
primitivelikeanobject
13.TheparseXxxmethodsalwaysreturna
False
String.
14.
Formattingclasses(whicharedecoupled
False
fromI/O),areinthejava.formatpackage.
youarehere.
313
codemagnets
solution
importjava.util.∙;
importstaticjava.lanq.Syatem.out;
olassFullMoons(
statiointDAY
rM:
1000•60•60•24;
publi~
staticvoidmain(String[)args)
Ca18nda~
c
=
Calendar.getlnstance();
c.aet(2004,O,7,15,40);
longday!
=
c.qetTimelnM1l1i9();
for(intx
~
0;x
<
60;x++)
day!
+:
(DAY_1M•29.52)
c.setTimslnMillis(dayl);
NotesontheLunarCodeMagnet:
You
mightdiscoverthatafewofthe
datesproducedbythisprognunare
offbyaday.Thisastronomicalstuff
isalittle
tricky,
and
if
wemadeit
perfect,itwouldbetoocomplexto
makeanexercisehere.
Hint:oneproblemyoumight
try
to
solveisbasedondifferencesintime
zones.Canyou
spottheissue?
out.println(Strlnq.format("fullmoonon%tc",e»;
314
chapter10
11
exception
handling
RiskyBehavior
Stuffhappens.Thefileisn'tthere.TheserverIsdown.
Nomatterhow
goodaprogrammeryouare,youcan'tcontroleverything.Thingscango
wronq,
Very
wrong.
Whenyouwriteariskymethod,youneedcodetohandlethebadthingsthat
mighthappen.
But
howdoyou
know
whenamethodIsrisky?Andwheredoyouputthecodeto
handle
the
exceptional
situation?Sofarinthisbook.wehaven't
really
takenany
risks.
We'vecertainlyhad
thingsgowrongatruntime,buttheproblems
were
mostlyflawsInourowncode.Bugs.And
thoseweshouldfixatdevelopmenttime.No,theproblem∙handllngcodewe'retalkingabout
hereisforcodethatyou
can't
guaranateewillworkatruntime.Codethatexpectsthefiletobe
intherightdirectory,theservertoberunning,ortheThreadtostayasleep.Andwehavetodo
this
now.
Becausein
this
chapter,we'regoingtobuildsomethingthatusestheriskyJavaSound
API.We'regoingtobuildaMIDIMusicPlayer.
thisisanewchapter
315
buildingtheMIOIMusicPlayer
Let"stMakeaMusicMachitte
Putcheckmarksintheboxesforeachofthe16'beats',Forexample,onbeat
1
(of16)theBassdrumandtheMaracaswillplay.onbeat2nothing,and
onbeat3theMaracasandClosedHi-Hat...yougettheidea.Whenyouhit
'Start',itplays
yourpatterninaloopuntilyouhit'Stop'.Atanytime,you
can"capture"
oneofyourownpatternsbysendingittotheBeatBoxserver
(which
means
any
otherplayerscanlistentoit).Youcanalsoloadanyofthe
incomingpatternsbyclickingonthemessagethatgoes
with
it.
Over
thenextthreechapters,we'llbuildafewdifferentsound
applications.includingaBeatBoxDrumMachine.Infact,
beforethe
bookisdone,we'llhaveamulti-playerversionso
youcan
sendyourdrumloopstoanotherplayer,kindoflike
a
chatroom.You'regoingtowritethewholething,although
youcanchoosetouseReady-bakecodefortheCUIparts.
OK.sonoteveryIT
departmentislookingforanewBeatBox
server,
butwe'redoingthisto
learn
moreabout
Java.
Building
aBeatBoxis
justawaytohavefun
while
we'relearningjava.
thefh11shedJeatJoxlookssotMethl"glike
this:
)
dancebeat
Andy:
groove112
Chris:groove2revised
Nigel:dancebeat
CrashCymbal
HandClap
HighTom
HiBongo
Maracas
Whistle
LowConga
Cowbell
Vibraslap
Low-midTom
0G
HighAgogo
OpenHICongaO
LJ
ILJ.=1..::,
~ I
LJ
316
chapter11
exceptionhandling
WeIllstartwiththebasics
youarehere.
317
MIDI
dtllit.eb\Owshow
to
\"caa'
a
MIDI.filt
al'lQflay
batl<.
the
S04.lI\d.
ntdtvite...
i~ht.
be
a
syr.thtsiuY
~oaYa
or
s.or..e
ot.h~
kitld
of
i~\II>\ent..
(,.(s.....
lIy,
a
MIDI
it'Sb--ellt.
tan
playaLOT
o.f
diH~tnt
~
(yi.1no,
d..,.,..1,
violil'l,
eitJ,
aliaallatthesa",e+'i",e.
So
aMIDItiltis,,'+'likeshed
"'Iolit
~ot"
jldi
Ot\e
"'1ol'ltiall
iPl
thebaPld--
it.
taft
hold
the
farh
for
ALL
t.ht"'lolitiar\5
flayi,,~
a
farbtlOlar
SOl'>5'
MIDI
~ih:
MIDIdatasays
what
todo(playmiddleC,andhere'showhard
tohitit,andhere'showlongtohold
it,
etc.)butitdoesn'tsay
anythingatall
abouttheactual
sound
youhear.MIDIdoesn't
knowhowtomakeaElute,piano,orJimmyHendrixguitar
sound,
Fortheactualsound,weneedaninstrument(aMIDI
device)that
canreadandplayaMIDIfile.Butthedeviceis
usually
morelikean
entirebandororchestra
ofinstrurnen
15.
And
thatinstrumentmightbeaphysicaldevice,liketheelectronic
keyboardsynthesizers
therockmusiciansplay.oritcould
evenbeaninstrumentbuiltentirelyinsoftware.livinginyour
computer.
For
ourBealBox,weuseonlythebuilt-in,software-only
instrumentthatyougetwithJava.It'scalleda
syntMsiu:r
(some
folksrefertoitasa
softumre
synth)
becauseit
creates
sound.
Soundthatyou
hear.
javaSoundisacollectionofclassesandinterfacesaddedto
javastartingwithversion1.3.Thesearen'tspecialadd-oris:
they're
partofthestandardJ2SEclasslibrary.javaSoundissplit
intotwoparts:MIDI
andSampled.WeuseonlyMIDIinthis
book.MIDIstands
forMusicalInstrumentDigitalInterface,
andisastandardprotocolforgertingdifferentkindsof
electronicsoundequipmenttocommunicate.Butfor
ourBeaiBoxapp,youcanthinkofMIDIas
akindoj
sheetmusic
thatyoufeedintosomedeviceyoucanthink
oflikeahigh-tech'playerpiano'.Inotherwords,MIDI
data
doesn'tactuallyincludeany
sound,
butitdoes
includethe
instructions
thataMIDI-reaclinginstrument
canplayback.Orforanotheranalogy,youcanthinkof
aMIDIfilelikeanHTML
document,andtheinstrument
thatrenderstheMIDIfile(i.e.
plays
it)isliketheWeb
browser.
fheJavaSou)1dAPI
Obviouslywe'vegotafewthingstolearnbeforethewhole
programisfinished,includinghowtobuildaSwingGUl,how
to
connect
toanothermachinevianetworking,andalittleI/O
sowecan
send
somethingtotheothermachine.
Ohyeah,andtheJavaSoundAPI.
That's
wherewe'llstartinthis
chapter.
Fornow,youcanforgettheGUl,forgetthenetworking
andtheI/O,andfocusonlyongettingsomeMIDI-generated
soundtocomeoutofyourcomputer.Anddon'tworry
if
you
don'tknowathingaboutMIDI,
Or
athingaboutreadingor
makingmusic.Everythingyou
needtolearniscoveredhere.
You
canalmostsmelltherecorddeal.
butItlookedsosimple
Firstwet1eedaSequet1cer
Beforewecangetanysoundtoplay,weneedaSequencerobject.The
sequencer
is
theobjectthattakes
all
theMIDIdataandsendsittotheright
instruments.It'sthethingthat
plays
themusic.Asequencercandoalotof
differentthings,butinthisbook,we'reusingitstrictlyasaplaybackdevice.Like
aCD-player
onyourstereo,butwithafewaddedfeatures.TheSequencerclass
is
inthejavax.sound.midipackage(partofthestandardjavalibraryasofversion
1.3).Solet's
startbymakingsurewecanmake(orget)aSequencerobject.
6.d\
~_e.\(-~~
import
j
avax.
sound.
midi.
'*;.
aM:.
t)-.~ i~ay...~
....,
Ii
~'\~tY
ob)tt.
t
It:
1
-tht
~
\llIY
We.l'Iee
~
ok
tne
MIDI
de~it.dll,sb-
.....er..
t
public
class
MusioTestl{
...d;nfd.
It:
-the
-thi,,~
t.hat,....
el\•
....eye
l.LS",~.
1
r
L,'
to
IItn,
MIDI
in-tO\""'auC7J\
I"
public
voidplay
0(
sc,\\OLnt.fS
6
b
,..d
,'Bllt.....
e
dO'l'>'t
Nlte6Y6
Sequencersequencer
=
MidiSys
tem.
ga
tSaquencer();
asonlj'have
to
asKt'ke
.....v-selve
s
__
....e
""",....Ol'le"'"
System.out.println("Wegotasequencer");
~ Mid~yst.e'"
to
~i~t.
lAj,
Ol'It∙
II
closeplay
public
static
voidmain(Strlng(]args)
MusicTestl
mt
=
Daw
MusicTestl(};
IDt.
play();
II
clOSE!main
II
closeclass
SOlMethinglwrong!
,Thist.«Jewon'tt.tm.pile!Theto",piler
~ys
t.nt\""e's
ah
IAhreporkd
e~epi.iOh'
thai
"'lASt
be
t.al.l~ht.
or
detlared.
318
chapter11
Whathappet1swhet1atMethodyouwartttocall
(probablyit'aclassyou
didt1~t
write)isrisky?
exceptionhandling
"Let'ssayyouwant
tocallamethodIna
classthatyoudidn't
write.
•Thatmethoddoes
somethingrisky,
somethingthatmight
notworkatruntime.
~
Youneedto
know
thatthemethod
you'recalling
is
risky.
@
Youthenwritecode
thatcanhandlethe
failureifIt
does
happen.Youneedtobe
prepared,justincase.
you
_t_1
--,
_f1,
classyou
didn'twrite
you
you
--.
-....111
_n,
o
~_ Q l
•...,.u.
yourcoce
voidmoo()(
if
(serverDown)
axplode()i
)
}
yourcoe
__II,
~-,
_I"
class
you
didn'twrite
~.-'
~=.I
crass
you
didn'twrite
youarehere
~
319
When
things
mIghtgowrong
Methods
iN
Javaose
except/om:
to
tell
theca/liM9code,
∙SotttethlftgBadHappeHed.Ifailed;'
Java'sexception.handliog
mechan~m",
adean,well∙lighted
way
to
handle"exceptional
shuations'thatpopupatruntime
;;tlets}'OuPOl
all
yourerror.handlingcode
in
one
easy-to-readplace.It's
based
Onyouknowingthatthemethodyou'recalhng;,risky
(i.e.thatthemethod
mighl
gene,",eanexception),
SO
thar
youcanwritecode
'0
deal
w;ththat
pos,,;bmty.
l£}'Oo
k_
you
mightgetanexceptionwhenyoucallaParUcuJar
method,youcanbe
fmP-
for-poss;bly
even
'''-from-theproblemthaIcaused
theexception.
So,
how
do}'Ou
know
if
amethodthrowsaneXception!Youfindathrow.clause;nthe
risky
method'sdeclaration.
The
getSequencer()
lIIethOdtakesarisk.ItCanfailatruntlllle.
SoItlIIust'declare'therisk
you
takeWhenyoucallit.
~
API
dots
it"
r-
M
~,"alta-()
-~
....
-
Un
thr-ow
an
tXQf'i;",,:
Mid iU..a\lai'ab'eE~o...
A
~od
hasfodulal"f!
the
~0fIS
it...
iShi
thl"o....
PI
((orm
SEvl.4.01@
MldlSvslem
(Java
2
a
Oblainsthe
defaultsequencer.
Rtturns:
cer
the
defaultsequcn..
I
available
due
.f
th
<N'IucnCCTIS
no
Throws:
Ibl"ExcCprlon
_I
e
seq
H!dHJo.)ya1
.J••
ns
t.~
It
f
Hl>rrIC
i
A ~ I c>R lI
Sll>pRdrt:Sh__
getSe-quencer
.ac.~ ( l h l~ Ex £~ Rt l Qn
i
~ C'a ll (l n s"r 9·ts~
.9
Mldll1oAv:ll1
pUblic
~ t a t
c'--
t h r o ~
__
L~~ ~I
eee
•
hck
~
~
...
/
g
~~:\':tOlJ rq
~
VOiceSlalys
5'
ExcepUons
,,1I
320
chapter
11
exceptionhandling
ThecOlMpilert1eedstokttow
that
YOU
kttowyou're
caUit1g
a
riskylMethod.
Ifyouwraptheriskycodeinsomethingcalleda
try/catch,
thecompiler
will
relax.
A
try/catchblocktellsthecompilerthatyou
knota
anexceptionalthingcouldhappeninthe
methodyou'recalling,andthatyou'reprepared
to
handleit.Thatcompilerdoesn'tcareIwwyou
handle
it;it
caresonlythatyou
say
you'retaking
careof
it,
import
j
AVax.
sound.
midi.
*;
publicclass
MusicT~stl
{
publicvoidplay()
---
try{
,J,
tM
yisk'f
iYl~
Sequencersequencer
=
MidiSystElm.getsequenCGr();
i:;-
!
'l..AJ'
h'ot't.
IYI
a
v
1
System.out.prlntln("Suceessfully
gota
sequencer");
}catch(MidiUnavailableExceptionex){
Systelll.
out.
println
("Bummer");
II
close
play
publicstaticvoidmain{Strinq[]args)
MusicTestlmt
=
new
MusicTestl():
mt.play{):
II
closemain
II
clositclass
youarehere.321
exceptionsareobjects
A"exceptio"isa"object...
oftypeExceptio"_
Whichisfortunate,becauseitwouldbemuchharder
to
remember
if
exceptionswereoftypeBroccoli.
Rememberfromyourpolymorphismchaptersthat
anobject
oftypeException
can
beaninstanceofany
subclass
ofException.
Becausean
Exception
isanobject,whatyou
catch
is
an
object.In
thefollowingcode.the
catch
argument
isdeclaredastypeException,andtheparameter
referencevariableis
ex,
II
try
to
recover
}
~
This
~od
I
E
tOllvr
I'
~tp£
,
I
Iqu
if'
Ii
Otl
Is
tJ.ro'Nrl,"
try{
th
.
I.
L
\',\:.t.
4tl.\a't"il'l~
II
do
risky
J..nq∙,ts
J~
\:..
.LI."O
ay~-tl'l
~a
",e'V'"
}catch(Exceptionex){
Whatyou
write
inacatchblockdependsonthe
exceptionthatwasthrown.Forexample,ifaserver
isdownyoumightuse
thecatchblockto
try
another
server.
If
thefileisn'tthere,youmightasktheuser
forhelpfindingit.
Throwable
getMeasage{)
printStackTraceO
'e.
~.Ltyt.\
OYI
l
T'IIl'/
all
T
T\I't"owa'ble
Exception
two
\I.e'(
.>
<,
IOElceeptlon
Intarrupl&dExceptlon
Part
J
t'he
dass
~lleYaYl.n
t~~O
l.\ass
61'10il'lheY'It
...
dho~
322chapter11
exception
handling
class
with
Q
riskymethod
--.
_':..::~
I
.
_...Jtn
I
_""J.
yourcode
-
Ifit's
your
codethatcatchestheexceptio",
the.,whosecodethrowsit?
You'llspendmuchmoreofyourJavacodingtimehandling
exceptions
thanyou'llspend
cnatingandthrowing
themyourself.
Fornow,justknowthatwhenyourcodecallsa
risky
method-a
methodthatdeclaresanexception-it'stheriskymethodthat
throws
theexceptionbackto
yfJU,
thecaller.
In
reality,
itmight
be
youwhowroteboth
classes.
Itreally
doesn'tmatterwhowritesthecode...whatmattersisknowing
which
methodthrowstheexceptionandwhichmethodcatchesit.
Whensomebody
writes
codethatcouldthrow
an
exception,they
must
declaretheexception.
Onemethqd
WIll
entch...
VhClt
£lncnher
-
tnetll
o
J
thr9'vv~.
J\n
-
exceptIon
'is
aJVY'ly':i
thl"O\Vn
back
[othe
elll
)e\".
The
111eth<)d
thnt
th\'o v v'~ ha~
t<:>
dechu-e
----=--
that
'It
nl'ir,-ht
thrq\\!
theexception.
)
publicvoidcrossFingers()
(
anObject.takeRisk()j
)(BadException
ex){
System.out.println("Aaarqh!");
If
y
04l
l.i
'.1
r
1I\.
rU,over
-tror"
ih
..J,.,
ex.
printStackTrace();../
~et.
a
sicltk
b-.
e
~er
\.Ion,
at
LMsT
~ ~i
II
~le ~'~
-theP""ini$tallcTrciteO....
tt.hod
a
e-,ttepiior.sIllherit.
\tnt
'foI0'I'\0
C'o'1
&od
MVS
1
-\:,t\
~ d~'f-l,eytIO"
•Risky,
exception-throwingcode:
~,~"'~
A)
-\:,hat
'I't
t,hyo'OlS
aa
~ ott~Y''''Y
publicvoidtakeRi.sk()BadExcepUon(
if
(abandonAllHope)(
newBadException();
'\l~t:G~
objett
i:;e
w
E~~
/:h.-ow
it.
•Yourcodethatcallstheriskymethod:
you
arehere
~
323
checkedanduncheckedexceptions
E.'Il.ttf"t1Ol\Sthaiaye
NOT
s~t1asu:s
of
Runti",eEuepiic»lcll"e
thet.ked
.for
by
~c
t.oto.pilcr.
Th~'rc ~Iled
"thetJccd
t"J'-UpiiOflS
Ii
Exception
Thecompilerchecksforeverything
exceptRuntimeExceptions.
Thecompilerguarantees:
Ifyou
throw
anexceptioninyourcodeyou
must
declareitusing
the
throws
keywordinyourmethoddeclaration.
Ifyou
call
amethodthatthrowsanexception(inotherwords,
amethod
that
declares
Itthrowsanexception),youmust
acknowledge
thatyou'reawareoftheexceptionpossibility.
Onewaytosatisfythecompileristowrapthe
call
inatry/catch.
(There's
a
secondwaywe'Hlookatalittlelaterinthischapter.)
InterruptedExceptlon
~:
WaltjustamlnutelHowcomethisIstheFIRSTtime
wevehadtotry/cate:hanEJcceptlon7Whataboutthe
exceptionsI'vealreadygottenlikeNullPolnterEJcception
andtheexceptJonforDlvldeByZero.Ievengota
NumberFormatExceptlonfrom
theInteger.parselntO
method.Howcomewedidn'thavetocatchthose?
A.:
ThecompilercaresaboutallsubclassesofException,
unless
theyareaspecialtype,RuntimeException.Any
exceptionclass
thatextendsRuntlmeExceptlongetsa
freepass.RuntimeExceptionscanbethrownanywhere,
withorwithoutthrowsdeclarationsortry/catchblocks.
Thecomplierdoesn'tbothercheckingwhetheramethod
declares
thatItthrows
a
RuntimeExceptlon,orwhetherthe
calleracknowledgesthattheymightgetthatexceptionat
runtime.
324
chapter11
Q.:
I'llbite.WHYdoesn'tthecompliercareaboutthose
runtimeexceptions?Aren'ttheyJustaslikelytobringthe
wholeshow
to
astop?
A:
MostRuntimeExceptlonscomefromaproblemin
yourcodelogic,ratherthanacondition
thatfailsatruntime
inwaysthatyoucannotpredictorprevent.You
cannot
guaranteethefileisthere.You
cannot
guaranteetheserver
isup.Butyou
can
makesureyourcodedoesn'tindexoffthe
endofanarray(that'swhatthe.lengthattributeisfor).
YouWANTRuntimeExceptionstohappenatdevelopment
andtestingtime.You
don'twanttocodeinatry/catch,for
example,andhavetheoverhead
thatgoeswithit,tocatch
somethingthatshouldn'thappenIn
thefirstplace.
Atry/catchisforhandlingexceptionalsituations,
notflaws
inyourcode,Useyourcatchblocksto
try
to
recoverfrom
situationsyoucan'tguaranteewlllsucceed.Oratthevery
least,
printoutamessagetotheuserandastacktrace,so
somebodycanfigure
outwhathappened.
•Amethodcanthrowanexceptionwhensomethingfailsatruntime.
•AnexceptionisalwaysanobjectoftypeException.(Which,
as
you
rememberfromthepolymorphismchaptersmeanstheobjectisfrom
a
classthaihasExceptionsomewhereupitsinheritancetree.)
•
ThecompilerdoesNOTpayattentiontoexceptionsthatareof
type
RuntlmeException.A
RuntimeExcepliondoesnothaveto
be
declaredorwrappedinatry/catch(althoughyou'refreetodoeitheror
bothofthosethings)
•AllExceptionsthecompilercaresaboutarecalled'checked
exceptions'whichreallymeans
compiler-<:hecked
exceptions.Only
RuntimeExceptionsareexcludedfromcompilerchecking.Allother
exceptionsmustbe
acknowledqed
inyourcode,according
to
the
rules.
•A
methodthrowsanexception
with
thekeyword
throw,
followedby
a
newexceptionobject:
thrownewNoCaffeineException();
•Methodsthat
might
throw
a
checkedexception
must
announceit
with
a
throwsException
declaration.
•Ifyourcodecallsachecked-exception-throwingmethod,
it
must
reassurethecomplierthatprecautionshavebeentaken.
•If
you'reprepared
10
handletheexception,wrapthecallInatJy/catch,
andputyourexceptionhandling/recoverycodeinthecatchblock.
•Ifyou'renotpreparedtohandleIheexception,youcanstillmakethe
compilerhappybyofficially'ducking'theexception.We'lltalkabout
duckingalittlelalerinthischapter.
~
your
penCil
Thingsyouwanttodo
exceptionhand
Ii
ng
~etaco"Mitive
tiP
\msomethIngnew,
\fyou'retryingto
ea
try
tolearn
makethat\he
/8s1
thln~O~nce
yOUputthis
beforegoIngtosleep.'cantearyourself
bookdown
.( a ss u ~ I ~~ ~ O~ n yth\n g
elsemore
awayfromIt)dont
b
I<
ofaCheerios'"
challenging
t~an
the
d
atlC
me
to
processwhat
boX.
YourbraInnBB
Sad
Thatcouldtake
you'vereadand
lea~
to'shovasomething
a
feW
hoUrs.
Ifyouf
urJava.
someofthe
newin
right
on
to~
0
.yo
Javamightnot'sllek.
.doesn'truleoullearning
Ofcourse,thISrldnonyourlatesl
a
physicalsk1\1.Wo
K~ICkBOXlng
routine
Ballroom
probablywon'l
affect
your
Java
leamlng.
b
t
res
ullsreadIhls
For
the
es'
book{oratleast
1001<
al
thepictures)rightbefore
go
in9
tosleep.
Whatmightgowrong
Which
of
thesedoyouthink
mightthrow
anexceptfon
that
thecompllerwouldcareabout?
We're
onlylooking
for
the
thingsthatyoucan'tcontrolIn
yourcode.
We
didthefirstone.
(BecauseItwastheeasiest.)
'v'
connectto
a
remoteserver
_access
anarray
beyond
its
length
_displayawindowon
thescreen
retrievedatafromadatabase
_seeifatextfileiswhereyou
think
Itis
create
a
newfile
readacharacterfromthecommand-line_
youarehere.
325
exceptionsandflowcontrol
Flow
eontrol
it1
try/catchblocks
Whenyoucallariskymethod,oneoftwothingscanhap-
pen.Theriskymethodeithersucceeds,andthe
try
block
completes,
ortheriskymethodthrowsanexceptionbackto
your
callingmethod.
(~ lsystem.
out.
println("Wemade
it!");
1
catch
(Exceptionex){
System.out.println("failed
U
);
Ifthe
trysucceeds
(doRiskyThlngOdoes
not
throwanexception)
try{
(j
Foo
f
intb
x.doRiskyThing();
f.
getNum();
}catch
(Exception
ex)(
~
System.
out.
println("failed");
~stem.out.println("We
made
it!");
-I
try(
.------i~!flH IFoo
f
'<::I'
iotb
Ifthe
tryfails
(becausedoRlskyThlngO
dOBS
throwanexception)
326chapter11
Fh,ally:for
thethlttQs
you
wattt
todo
no
fffatter
what.
If
you
try
tocooksomething,youstartbyturningon
the
oven.
If
thething
youtry
is
a
complete
failure,
you
haue
to
turn
off
the
oven.
If
thething
you
try
succeeds,
you
haue
to
turn
off
the
oven.
You
have
to
turn
off
the
ovennomatter
what!
Afinallyblockiswhereyouput
codethatmustrun
regardless
ofanexception.
try(
turnOvenOn();
x,baIce();
catch(BakingExceptionex)
ex.printStackTrace()i
)finally(
turnOvenOf£();
)
Withoutfinally,youhavetoputthe
tumOvenOffOin
both
the
try
andthecatch
because
you
have
to
turn
off
the
oven
JU>
matter
what.
Afinally
blocklets
you
putallyour
importantcleanupcodein
one
placeinsteadof
duplicating
it
likethis:
try{
turnOvenOn();
x.bake
o.
turnOvenOff();
}catch
(BakingExceptionex)(
ex.printStackTrace();
turnOvenOf
f();
exceptionandling
Ifthe
try
blockfails(anexceptIDn),flow
controlimmediatelymovestothecatchblock.
Whenthe
catch
block
completes,the
finally
blockruns.
When
the
finallyblockcompletes,
therestofthemethod
conUnues
on.
Ifthe
tr-y
blocksucceeds(noexception),
flow
control
skips
overthecatch
blockand
movesto
thefinally
block.Whenlhefinally
blockcompleles,
the
restofthe
method
continues
on.
Ifthe
try
orcatch
block
hasareturn
statement,finally
will
stillrunlFlow
jumps
lo
thefinally,thenback
to
therelum.
youarehere
~
327
flowcontrolexercise
~yourpendl
FlowContPoI
publicclassTestExceptions{
publicstaticvoidmain(String()args){
Lookatthec:odetotheleft.Whatdoyouthinkthe
outputofthisprogramwould
belWhatdoyouthink
It
wouldbe
If
thethirdline
of
theprogramwere
changedto:
Stringtest."yes",1
AssumeScaryExceptlonextendsException.
Outputwhen
test
='
"no"
Stringtest
=
"no
N;
try{
Systern.out.println("starttry");
doRisky(test);
System.out.println("endtry");
}catch(ScaryExceptioose){
Systern.out.println("sca:r:yexception");
}finally{
System.out.println("finally");
}
System.out.println("endofmain");
}
staticvoiddoRisky(Stringtest)throwsScaryException{
System.out.println("startrisky");
if
("yes".equals(test)){
thrownewScaryException();
System.out.println(UendriskyN);
return;
}
}
ulewJOpua.,(lIeuy.UOlldCl»)«l
've)~
.
~SIJ
lJelS.NluelS:.5i1,.{.
=
~al
U"4M
ulewlO
pUiI-Alleuy-
.tit
pua-
A~S!J
pUCI-
A~SIJ
lJl?1S-,VllJelS:.ou.
=
l5CllUCl1.!M
328
chapter11
Outputwhen
test="yes"
exceptionhandling
PidwelIte.,tio.,thatatltethodca.,
throwtMoretha.,o.,eexception?
Amethodcanthrowmultipleexceptions
if
it
dam
wellneeds
to.
But
a
method'sdeclarationmustdeclare
all
thecheckedexceptions
it
can
throw(although
if
twoormoreexceptionshaveacommonsuperc1ass,the
methodcandeclarejustthesuperclass.)
CatchlnQ
lHultlpleexceptlo"s
Thecompiler
will
makesurethatyou'vehandled
all
thecheckedexcep-
tionsthrownby
themethodyou'recalling.Stackthe
catch.
blocksunder
the
try,
oneaftertheother.Sometimestheorderinwhichyoustackthe
~:~::~~ ~::~~.~~~~:\r:t
tothata\Itdelate,
publicvoiddoLaundry()
throwsPantsException,
II
codethatcouldthroweitherexception
publicclassFoo{
publicvoidgo()
LaundrylaundrynewLaundry();
it
doLa~dr'f() ~
..o\WS
a
try{
Pa"b~uepiiCW\1
i.e
lands
ill
the
1/
Pa"b.~~O'r\
utth
blotk.
laundry.doLaundry();
~
}catch(PantsException
pex){
II
recoverycode
)
Catch(LingerieExcePti~)
(
".,..0''''')
t\lydOIS
a
II
recoverycode
~
J
d~
'T.
0'\.
it.
\a"as
i"
the
}
L.i~'t~~.~h
blot.\t.∙
U~ew'it~~tybOl'l
youarehere
~
329
polymorphicexceptions
ExceptiottsarepolytMorphic
Exceptionsareobjects,remember.There'snothing
all
that
specialaboutone,exceptthatitis
a
thingthat
canbe
thrown.
Solikeallgoodobjects,Exceptionscan
be
referredto
polymorphically.ALingerieException
object,
forexample,
couldbeassignedtoaClothingException
reference.
A
PantsExceptioncouldbeassigned
to
anExceptionreference.
You
gettheidea.Thebenefitforexceptions
is
thatamethod
doesn'thavetoexplicitlydeclareeverypossibleexceptionit
mightthrow;
it
candeclareasuperclassoftheexceptions.
Same
thingwithcatchblocks-youdon'thavetowriteacatch
for
eachpossibleexceptionaslongasthecatch(orcatches)
youhavecan
handleanyexceptionthrown.
@
YoucanDECLAREexceptionsusing
a
supertype
of
theexceptionsyou
throw.
All
eU~QtIS
ho'le
exception
f.~~
asa
SlI"
cY
to
lass-
IOExceptlonCloltilngExeeptlon
try(
@
YoucanCATCHexceptionsusinga
supertypeoftheexceptionthrown.
try(
~\,
""'I
1.<1".../...•
∙4-1-UT....
~
laundry.doLaundry();./
C\atn
l
~.~
If
Ie
\Jot\a.u
'.'0!
I/~
catch(ClothingExceptioncex){
II
recoverycode
330
chapter11
laundry.doLaundry();
<...∙r
t.
i-:-
\;I
':.l
catch(ShirtExceptionsex)
II
recoverycode
exceptionhand
JustbecauseyouCANcatcheverything
withonebigsuperpolymorphiccatch,
doesn'talwaysmeanyouSHOULD.
You
could
writeyourexception-handlingcodesothat
youspecifyonly
one
catchblock,usingthesupertype
Exceptioninthecatchclause,sothatyou'llbeableto
catch
any
exceptionthatmightbethrown.
try{
la
undry.doLaundry();
}
catch(Exceptionex){
blotkwill
w"~T?
Tn,s
tatt
n
,
II
recoverycode...
~
Rt.t.ol/t.'('(
.{:'(0f'I
-b
so
'(()II.
WOYl
t
L'h
~N'I
ay,Gall
t.~t.t.f
oY\S,
ta-u-\..
t
wt.\'It
WV'o\'l~'
a~~atit.all'f
k\'lowwna
Writeadifferentcatchblockforeach
exceptionthatyouneedtohandle
uniquely.
Forexample,ifyourcodedealswith(orrecovers
from)aTeeShirtExceptiondifferentlythanithandlesa
LingerieException,writeacatchblockforeach.Butifyou
treatallothertypesofClothingExceptioninthesameway,
thenaddaClothingExceptioncatchtohandletherest.
try{
l
aundry.doLaundry();
.J.i
"s
3Y10
:t.
S\iAt
1L
t.t
vO
0
o,~h'(eYl
}catch(TeeShirtExceptiontex){
~
Tee'.\:;IOYlSYlet.
I,;
ll.,t.'(iet
1Le\,
s
....ov.\o.
~e
II
recoveryfromTeeShirtExceptiol
'YI;.I
'-J
t,oOel
so
,!0II0"
~
fu
'(et,o\lt.'(
I
tt.....
'o\ot"s.
~ o,~~t.'t't.Ylt.
t,a
}catch(LingerieExceptionlex){
All
oihet-
CI
th'
E
o
/tI~
Xlt,nJ.∙
Ut"t,
talAaht
h
r
I./QtlS
J
et-t,.
II
recoveryfromallothers
}
youare
here.
331
orderofmultiplecatchblocks
MultiplecatchblocksiMustbeordered
froiM
stttaliesf
to
biggest
ClothingException
catch(TeeShirtExceptiontex)
catch(ShirtExceptionsex)
catch(ClothingExceptioncex)
332
chapter11
Thehigheruptheinheritancetree,thebiggerthe
catch'basket',
As
youmovedowntheinheritance
tree,towardmoreandmorespecializedException
classes,
thecatch'basket'issmaller.
Ir'sjust
plainold
polymorphism.
A
ShirtExceptioncatchisbigenoughtotake
aTeeShirtExceptionor
a
DressShirtException
(andanyfuturesubclassofanythingthatextends
ShirtException).
A
C1othingExceptionisevenbigger
(i.e.
therearemorethingsthatcanbereferenced
usingaClothingException
type).
It
can
takean
exceptionoftypeClothingException
(duh),and
anyClothingExceptionsubclasses:PantsException,
UnifonnException,Lingerielixception,
and
ShirtException.Themotherof
all
catcharguments
istype
Exception;
itwillcatch
any
exception,
including
runtime(unchecked)exceptions,soyou
probablywon'tuse
it
outsideoftesting.
\
Youcat1"t
putbiggerbaskets
abovestMalierbaskets.
Well,you
can
butitwon'tcompile.Catch
blocksare
notlikeoverloadedmethods
wherethebestmatch
is
picked.Withcatch
blocks,theJVMsimplystartsatthefirst
one
andworksitswaydown
until
itfindsacatch
that's
broadenough(inotherwords,high
enoughontheinheritancetree)
to
handle
theexception.lfyourfirstcatchblock
is
catch(Exceptionex).
thecompiler
knowsthere'snopointinadding
any
others-they'llneverbereached.
try(
laundry.doLaundry();
catch(ClothingExceptioncex){
IIrecoveryfromClothingException
catch(Linge.rieExc:eptionlex){
IIrecoveryfromLingerieException
catch(ShirtExceptionsex){
IIrecoveryfromShirtException
exception
handling
Sizematterswhen
you
havemultiplecatch
blocks.
The
one
withthe
biggest
baskethastobeon
thebottom.
Otherwise,
theoneswith
smallerbasketsareuseless.
Siblings
can
be
in
anyorder,
because
they
can't
catch
one
another's
e~tions.
Youcould
put
ShirtExceptionabove
Unger
ieExceptionandnobodywouldmind
BecauseeventhoughShlrtExceptionisabigger
(broader)
type
becauseItcaneatehotherclasses
(its
own
subdasses),ShirtExceptioncan'tcatch
a
UngerieExceptlonsothere'snoproblem.
you
arehere
~
333
polymorphic
puzzle
~n
your
pencil
try{
x,
doRisky();
catch(AlphaExa){
II
recoveryfromAlphaEx
catch(BetaEx
b){
II
recoveryfromBetaEx
ca
toh
(GammaExc)
II
recoveryfromGammaEx
cateh(DeltaExd){
II
recoveryfromDeltaEx
BazEl
T
FooElr
.>
<,
8esEJ
BIIlEJ
<.
334chapter11
Assumethetry/catchblockhereIslegallycoded.Yourtaskistodraw
twodifferentclassdiagrams
thatcanaccurately
reflect
theException
classes.Inotherwords,
whatclassInheritancestructureswouldmakethe
try/catchblocks
in
thesamplecodelegal?
Yourtaskistocreatetwodifferent
legal
try/catchstructures(similarto
theoneaboveleft),toaccuratelyrepresenttheclassdiagramshown
on
theleftAssume
ALL
oftheseexceptionsmight
be
thrown
by
themethod
with
the
try
block.
exceptionhandling
Whe.,you
dO.,/t
wa.,ttoha.,dle
a.,
exceptiott...
iust
dUCK
it
Ifyoudon'twanttohandlean
exception,youcan
duck
itby
declaring
it.
Whenyoucallariskymethod,thecompiler
needsyoutoacknowledge
it.
Mostofthetime,
thatmeanswrappingtheriskycall
ina
try/
catch.Butyouhaveanotheralternative,simply
d1Uk
it
andletthemethodthatcalled
you
catch
theexception.
It'seasy-allyouhavetodois
declare
that
you
throwtheexceptions.Eventhough.
technically,
you
aren'ttheonedoing
the
throwing.
it
doesn'tmatter.You're
still
theone
lettingtheexceptionwhizrighton
by.
But
if
youduckanexception,thenyoudon't
haveatry/catch,sowhathappenswhenthe
risky
method
(dol.aundry/))
does
throwthe
exception?
Whenamethodthrowsanexception,that
methodispoppedoffthestackimmediately,
andtheexceptionisthrowntothenext
methoddownthestack-the
caller.
But
if
the
calleris
a
ducker,
thenmere'snocatchfor
it
so
the
caller
pops
off
me
stack
immediately,and
theexceptionisthrowntothenextmethod
andsoon...wheredoesitend?You'llseea
liul
elater.
publicvoidfoo()throws
II
callriskymethod
laundry.doLaundry();
}
!
!
youare
here.
335
handleordeclare
Uuckhtg
(by
declaring)
only
delaystheinevitable
Soonerorlater,somebodyhasto
deal
with
it.ButwhatIf
MainO
duckstheexception?
publicclassWasher(
Laundrylaundry
=
newLaundry(J;
publicvoidfool)
throwsClothingException
laundry.doLaundry();
publicstaticvoidmain(String[]argsl
throwsClothingException(
Washera
=
newWasher();
a.fooO;
o
doLaundryOthrowsa
ClothingException
fooDducksthe
exception
mainOducks
the
exception
The
JVM
shuts
down
mainOcallsfocO
fooOcallsdoLaundryO
doLaundryOis
runningand
throwsa
ClothingException
doLaundryOpops
offthe
stackimmediatelyand
theexceptionisthrown
backtofooO.
ButfooDdoesn
'thavea
try/catch.
so...
fooDpopsoffthe
stackimmediatelyand
theexceptionisthrown
backto...who?What'?
There'snobody
left
butthe
JVM,
andit's
thinking."Don't
expect
MEtogetyououtof
this."
We'reus)ngthetee-shirttorepresentaClothing
Exception.Weknow,weknow...youwould
havepreferredtheblueJeans.
336
chapter11
}
exceptionhandling
HandleorDeclare.It'sthelaw.
Sonowwe'veseenbothwaystosatisfythecompiler
whenyoucallarisky(exception-throwing)method.
•HANDLE
Wraptherisky
call
inatry/catch
Thishadbetta-bb'
try{
»<"">
ha",dle
all
extepti
e
a
thl~ e",o~h
tatth
laundry.doLaundry();
~
...
iaht
~
I'\.
OI'IS,
at
doLa~",dt"yC)
J
t"ow.
vr
e
se
th
t
'1
}catch(ClothingExceptioncex){
stillto...
pl'
~1L
1-
I
e
OIftPI
et"will
a,,,,
'toa't
yo~
toe
t
Lh
//recoverycode
of
th••
v.
,.,L.
"'0
tau
i",~
all
...."",er"IOI'IS.
•DECLARE(duck
it)
Declarethat
YOUR
methodthrowsthesameexceptions
oil
tnvoo-"s
a
as
theriskymethodyou'recalling.
.1
1
",W'dvo'.l)...
e-\:.n\.
Q
tnt
int
lo'o\..A01~ b~t
b'(
dtt.
avo''';,
voidfoo()throwsClothingException{
C\otni,,~~1Ltyti;"~O
...ttnod
~c\:.s
to
laundry.doLaundry();
~ ~tytio",
tnt
..J.'OY\'
No
tVO'fIt.atJ,n.
d~\c.
tnt
t1L
t
r'"
ButnowthismeansthatwhoevercallsthefooOmethod
hastofollow
theHandleorDeclarelaw.IffooDducks
theexception(bydeclaringit),andmainOcallsfooO,then
mainOhastodealwiththeexception.
pUblicclassWasher{
Laundrylaundry
=
newLaundry();
publicvoidfoo()throwsClothingException
laundry.doLaundry();
publicstaticvoidmain(String[]args)
W
ashera
=
newWasher();
a
c
foo
Ij
r
~
Beta~e
the
+000...
tihod
d~ks
the
CI~hi",~ExteptiOl'l
tht"OWl'lby
doLa~",dt"vI')
...a,,,,()
has
to
a,.()
T:
I
Wt"
P
a∙1"OO
i",
a
tt"y/
tatth
at"
...ai",O
has
to
detlat"ethatit,
too,,
ih...
ows
Cloihi",~ExtertjOl'l!
youarehere.337
fixingtheSequencercode
G-effittgbacktoourtMusiccode...
Nowthatyou'vecompletelyforgotten,westartedthischapter
withafirstlookatsomeJavaSoundcode.WecreatedaSe-
quencerobjectbutitwouldn'tcompilebecausethemethod
Midi.getSequencerOdeclaresacheckedexception(MidiUnavail-
ableException).Butwecanfixthatnowbywrappingthecallina
try/catch.
publicvoidplay()
try{
Sequencersequencer
=
MidiSystem.getSequencer();
System.out.println(~Successfully
gotasequencer");
}
II
closeplay
ExceptionRules
•Youcannothaveacatchorfinally
withoutatry
voidgo(){
t-/Oi
~~~~~\
?
Faaf
=
newFaa();
wnt.V"i
s
-tnt-t
y
'1'
f.
foof();
catch(FooExceptionex){}
•
Youcannotputcodebetweenthe
tryandthecatch
NOTLf..&:A
try{"':
L!VOlA".
'1
lode
h
t....
11
1;
P"t
x,doStUff/();
1.
e
weellthe
try
~~
)"Ule
ldtth.
Ii""
inty
=
43;
}catch(Exceptionex){}
try{
x.doStuff();
finally{
II
cleanup
•Atrywithonlyafinally(nocatch)
muststilldeclaretheexception.
voidgot)throwsFooException{
try{
x.doStuff();
}
finally{}
338chapter11
CodeKitchen
exceptJonhandling
.:
(
Youdon'thaveto
do
it
yourselt,but
it'sa
lot
more
fun
if
you
do.
Tlte
rest
01
tlUs
chapter
is
optionaLyou
can
use
ReaJy-
bakecode
tor
all
the
music
apps.
But
it
you
wanttolearn
more
about
JllvaSouncl,
turn
the
rage.
youarehere
~
339
JavaSoundMIDIclasses
Makingactualsound
Remembernearthebeginningofthechapter,welookedathowMIDIdataholds
theinstructionsfor
what
shouldbeplayed(and
how
it
shouldbeplayed)andwe
alsosaid
thatMIDIdatadoesn'tactually
create
any
sound
that
you
hear.
Forsound
tocomeoutofthespeakers,theMIDIdatahastobesentthroughsomekindof
MIDI
devicethattakestheMIDIinstructionsandrenderstheminsound,either
bytriggeringahardwareinstrumentora'virtual'instrument(softwaresynthe-
sizer).Inthisbook.
we'reusingonlysoftwaredevices,sohere'showitworksin
JavaSound:
YouneedFOURthings:
Theactualmusic
Information:
notes
to
play,
how
long,etc.
e
9
e
9
AMIDIeventisamessage
thattheSequencercan
understand.AMIDIevent
mightsay(ifItspoke
English),"Atthis
moment
Intime,playmiddleC,play
Itthisfastandthishard,
and
holdItforthislong."
AMIDIeventmight
alsosaysomethinglike,
"Changethecurrent
instrumentto
Flute."
holds
Thepartofthe
Sequencethat
holds
the
actual
Information
Track
Forthisbook,weonly
needoneTrack,soJust
ImagineaamusicCD
withonlyonesong.A
singleTrack.ThisTrack
Iswhereallthesong
data{MIDIInformation)
I1ves.
•
TheSequenceisthe
song,themusicalpiece
thattheSequencerwill
play.Forthisbook,think
oftheSequenceasa
musicCD,
butthewhole
CD
playsjustonesong.
•The
musictobe
playtd...
o
song.
playshas
a
Sequencer
~
Sequence
~
eD
Thethingthat
plays
themusic
TheSequencerIsthething
thatactuallycausesasong
tobeplayed.ThinkofItlike
amusic
CD
player.
340
chapter11
AndyouneedFIVE
steps~
..Geta
Sequencer
andopenit
Sequencerplayer
=
MidiSyscem.gecSequencer();
player.openl);
..Makeanew
Sequence
Sequenceseq
=
newSequenceltiming,4);
•Getanew
Track
fromtheSequence
Track
t
=
seq.createTrack();
•Fill
theTrackwith
MidiEvents
and
give
theSequencetotheSequencer
exceptionhandling
player.start();
t.add(myMidiEventl);
player.setSequencelseq);
youarehere
~
341
asound
application
Yourveryfirstsoundplayerapp
Typeitinandrunit.You'llhearthesoundofsomeoneplayinga
single
noteonapiano!(OK,maybenot
someone,
but
something.)
importjavax.sound.midi.*;
publicclassMiniMiniMusicApp{
pUblicstaticvoidmain(String[]args){
MiniMiniMusicAppmini
=
newMiniMiniMusicApp();
mini.play();
II
closemain
(
try{
publicvoidplay()
a.·.~
"
•
Sequencerplayer
player.open();
Sequenceseq
=
new
MidiSystem.getSequencer();
Tracktrack
=
seq.createTrack();
ShortMessageb
=
newShortMessage()i
b.setMessage(128,1,44,100);
MidiEventnoteOff
=
newMidiEvent(b,
track.add(noteOff);
ShortMessagea
=
newShortMessage();
a.setMessage(144,1,44,100);
MidiEventnoteOn
=
newMidiEvent(a,1);
track.add(noteOn);
PlAtSOMeMidiEvetl'tsintothe
T-sek.
This
fart
isMostlyReady-baketode.Theonly
thin~
YOlA'1l
havetotareabolAtal'"ethe
al'"~llMents
tothe
setMessa~e()
""ethod,andthe
al'"~llMents
to
the
MidiEventt.onshlAtk.We'/Ilookatthose
al'"~llMents
onthene1l.t
ra~e.
player.setSequence(seq);
~
qivetheSe,\llent.etotheSe,\llent.er(like
player.start();
4:--
flAH in~
the
CD
inthe
cD
fla-yel'")
Sfdl'"i()the
catch(Exceptionex){SeC(llehter
Oike
PlASh'
ex.printStackTrace();
'n~
PLAy)
}II
closeplay
II
closeclass
342
chapter11
exceptionhandling
Makit1gaMidiEvettt(SOttgdata)
AMidiEventisaninstructionforpartofasong.AseriesofMidiEventsis
kindoflikesheetmusic,oraplayerpianoroU.MostoftheMidiEventswe
care
aboutdescribe
a
thing
to
do
andthe
momentin
time
to
do
it.
Themoment
intimepart
matters,
sincetimingiseverything
in
music.Thisnotefollows
this
noteandsoon.AndbecauseMidiEventsareso
detailed,
youhavetosay
at
whatmomentto
start
playingthenote(aNOTEONevent)andatwhat
momentto
step
playingthenotes(NOTEOFFevent).Soyoucanimagine
thatfiringthe"stopplayingnote
G"
(NOTEOFFmessage)
before
the
"start
playingNote
en
(NOTEON)messagewouldn'twork.
TheMIDIinstructionactuallygoesintoaMessageobject;
the
MidiEventis
a
combinationoftheMessageplusthemomentintimewhenthatmessage
should'fire'.Inotherwords,theMessagemightsay,"StartplayingMiddle
C"
whiletheMidiEventwouldsay."Triggerthismessageatbeat4".
So
wealwaysneedaMessageandaMidiEvent.
TheMessagesays
what
todo,andtheMidiEvent
says
when
todoit.
•Makea
Message
ShortMessagea=new
Shor~Message();
1
MidiEVent
says
whBt
to
do
and
~todo~
Everg~on
must
include
the
~s.fortbat
in8tJtuction..
In
other
words,
at
which
beat
that
-
thing
ahould
happen.
•Make
Q
new
MidlEvent
usingtheMessage
•Put
the
Instruction
intheMessage
"start
y\a'li,,~ ~ ~.y
a.
se~Message
(144,1,44,100);
~(- Th~
...
~~e s.a~
othtT
""",'oeYS
Ol\
~e
(~e'\\
\oo\tat
&e
"Vot.
ya~e)
•AddtheMidiEventtothe
Track
you
are
here
~
343
contentsofaMidievent
MIPltttessage:theheart
of
aMidiEvet1f
AMIDImessageholdsthe
part
oftheeventthat
says
toha:
todo.Theactualinstruction
youwantthesequencertoexecute.Thefirstargumentof
an
instruction
is
always
thetype
ofthe
message.The
valuesyoupasstotheother
three
argumentsdependonthetypeof
message.Forexample,amessageoftype
144
means
UNOTE
O~'·.
Butinorderto
carry
out
a
NOTEON.thesequencerneedstoknowafew
things....
fuiaginethesequencer
saying.
~OK,
I'llplayanote,
but
whu:h
chantul?
Inotherwords.dc/youwantmetoplaya
Drum
noteor
a
Pianonote?And
which
note?
Middle-C?DSharp?Andwhilewe'reatit.at
which
I
vekJcity
should
I
playthenote?\
,
Tomake
a
MIDImessage,make
a
ShortMessageinstanceandinvokesetMessageO
I
passing
inthefour
argumentsforthemessage.Butremember,themessage
says
only
iahiu
u»
do.so
youstill
needtostuffthemessageintoaneventthatadds
when
thatmessageshould'fire'.
Anatomyofamessage
The
first
argumenttosetMessageOalways
represents
themessage'type',whilethe
other
threeargumentsrepresentdifferentthings
dependingon
themessagetype.
~t.~"\
-:>r>f"
il'c.
Jd,
V
~ ~~
....t;
~
'(P-
~f:j
a.setMessage(144,
1,
44,100);
neldsf.3~
tyP'.
~
Yd'ry
dej>eJldj
e.
Thl$1$
i
NOTE
~
0I'l
~ ~
~~ ~~~ ~
f.o
~
.il"t
tot"
tJ..
.1,
~t,
sothe
k"o'ol
i"
ot"d
.1
'~s
U1t
St,~
~
"[D
rl.y•
"ote.
"eedt
~
Message
type
344
chapter11
The
Message
says
whattodo,the
MidiEvent
says
whentodoit,
•ChoMel
Thinkofachannellikeamusicianin
aband.Channellismusician1
(the
keyboardplayer),channel9isthe
drummer,etc.
•Noteto
play
Anumberfrom0to127,going
fromlowtohighnotes.
•Velocity
How
fast
andhard
youpress
thekey?0issosoftyou
probablywon'thearanything,
but100isa
gooddefault.
Chat1geatMessage
Nowthatyouknowwhat'sina
Midi
message,youcanstartexperimenting.You
canchangethenotethat'splayed,howlongthenoteisheld,addmorenotes,
andevenchangetheinstrument.
exceptionhandling
•Changethenote
Tryanumberbetween0and127inthenote
onandnote
offmessages.
a.setMessage(144,1,
20,
100);
-
•Changethedurationofthenote
Changethenoteoffevent(notthe
message)
so
thatithappensatanearlierorlaterbeat.
b.setMessage(128,1,44,100);
MidiEvencnoteotf
=
newMidiEvent(b,
3);
-
Changetheinstrument
Addanewmessage,BEFOREthenote-playingmessage,
thatsetstheinstrumentinchannelltosomethingother
thanthedefaultpiano.Thechange-instrumentmessage
is'192',and
thethirdargumentrepresentstheactual
instrument
(tryanumberbetween0and127)
youarehere
345
changethe
instrument
and
note
andnoteargs");
,/
//thiS£'thefirstone
I
args;)(
Mini~usiccmdL ine();
publicstaticvoidmain(Scringl)
MiniMusicCmdLinemini
=
new
if
(arqs.length
<
2)(
System.ouc.println("Don'Cforgetcheinstrument
else(
intinstrument
=
Integer.parselnt(argsIO])i
intnote
=
Integer.parselnC(args[l)l;
mini.play(instrumenc,note);
publicclassMiniMusiccmdLine
Thisversionstillplaysjustasinglenote,butyougettousecommand-lineargu-
meritsto
changetheinstrumentandnote.Experimentbypassingintwointvalues
from0to127.
Thefirstintsetstheinstrument,thesecondintsetsthenotetoplay.
importjavax.sound.midi.*;
)1/
close
mai.n
publicvoidplay(intinstrument,intnote){
try
Sequencerplayer
=
MidiSystem.getSequencer();
player.open();
Sequenceseq
=
newSequence(Sequence.PPQ,
4);
Tracktrack
=
seq.createTrack(),
MidiEventevent
=
null;
ShortMessage
first
=
newShortMessage();
first.setMessage
(192,1,
instrument,
0);
MidiEventchangelnstrument.
=
newMidiEvent(first,
track.add(changelnstrument);
1);
ShortHessage
a
=
newShortMessage();
a.setMessage(144,
1,
note,
100);
MidiEventnoteOn
=
newMidiEvent(a,
1);
track.add(noteOn);
Rvr.
rt
wi~
two
i"i
~
-h-Ot'<'.
D
iD
J'}..
7.Try
that:
few
~
ShortMessage
b
~
new
Shor~essage();
b.setMessage(12B,
1,
note,
100);
MidiEventnoteOff
=
newMidiEvenc(b,
16);
track.add(noteOffl,
player.setSequence(seq);
player.start();
%javaMiniMusicCmdLine10230
%javaMiniMusicCmdLine8020
~ j a v a
MiniMusicCmdLine4070
I
catch(ExCeptionex)(ex.printStackTrace();)
I//
closeplay
/I
close
class
346chapter11
Wherewe'reheadedwiththerest
oftheCodeKitchens
exceptJon
handling
Chapter15:thegoal
Whenwe'redone,we'llhaveaworking
BeatBox
that'salsoaDrumChatClient.
We'llneed
tolearnaboutGUIs(includ-
ingeventhandling),
I/O,networking,and
threads.Thenextthreechapters(12,13,
and14)
willgetusthere.
Chapter12:MIDIevents
ThisCodeKitchenletsusbuildalittle
"musicvideo"(bitofa
stretchtocallit
that...)thatdrawsrandomrectanglesto
thebeatoftheMIDImusic.We'lllearn
howto
constructandplayalotofMIDI
events(insteadof
justacouple,aswedo
in
thecurrentchapter).
0.11
!l!.
Chapter13:Stand.-alone
BeatBox
Nowwe'llactuallybuildtherealBeatBox,
GUIandall.Butit's
limited-asSoonasyou
changea
pattern,thepreviousoneislost.
There'snoSaveandRestore
feature,and
itdoesn'tcommunicatewith
thenetwork.
(Butyoucanstilluseit
toworkonyour
drum
patternskills.)
Chapter14:Saveand
Restore
You'vemadetheperfectpattern,and
nowyoucanseveittoafile,andreloadit
whenyouwanttoplayitagoin.This
gets
usreadyforthe'finalversion(chapter15),
whereinsteadofwriting
thepatterntoa
file,wesenditoveranetworkto
thechat
server.
youarehere
~
347
exercise:True
or
False
Thischapterexploredthewonderfulworldof
exceptions.Yourjobistodecidewhethereachofthe
followingexception-relatedstatementsistrueorfalse.
~rl\\I-
01\
F9~~
1.Atryblockmustbefollowedbyacatch
ind
afinallyblock.
2.
If
youwriteamethodthatmightcauseacompiler-checkedexception,you
must
wrapthat
risky
codeinatry
I
catchblock.
3.
Catchblockscanbepolymorphic.
4.Only
'compilerchecked'exceptionscanbecaught
5.
If
youdefineatry/catchblock,amatchingfinallyblock
is
optional.
6.
If
youdefineatryblock,youcanpairitwithamatchingcatchorfinallyblock,
orboth.
7.
If
youwriteamethodthatdeclaresthatitcanthrowacompiler-checkedex-
ception,youmustalsowraptheexceptionthrowingcode
in
atry/catchblock.
8.
Themain()method
in
yourprogrammusthandleallunhandledexceptions
thrownto
it.
9.Asingletryblockcanhavemanydifferentcatchblocks.
10.A
methodcanonlythrowonekindofexception.
11.Afinallyblockwill
runregardlessofwhetheranexception
is
thrown.
12.Afinallyblockcanexistwithoutatryblock.
13.Atryblock
canexistbyitself,withoutacatchblockorafinallyblock.
14.
Handlinganexceptionissometimesreferredtoas.ducking'.
15.
Theorderofcatchblocksnevermatters.
16.A
methodwitha
try
blockandafinallyblock,canoptionallydeclarethe
exception.
17.
Runtimeexceptionsmustbe
handled
or
declared.
348
chapter11
exception
handling
CodeMagnets
AworkingJavaprogramisscrambleduponthefridge.(anyou
reconstructallthecodesnippetstomakeaworking
Javaprogram
thatproduces
theoutputlistedbelow?Someofthecurlybracesfell
onthefloorandtheyweretoosmalltopickup,sofeelfreetoaddas
many
of
those
as
youneedl
/.t(Ur
U)"
,system.
out
.pr1.n
I
\
system.out.print(ut
u
);
doRisky(test)i
system.out.println(UsU);
}finally
classMyExextendsException
<}
public
class
ExTestDrive(
lU
ye
~
S
.equalslt»){
system.out.print(Ua
U
);
thrownew
MyEX()i
}
catch(MyExe){
staticvoiddoRisky(String
t)
throwsMyEx(
Systern.out.print(Uh");
.stiog
[J
args){
publicstatic
void
ma1.n(
r
string
test
=
args[O);
you
arehere.
349
puzzle:crossword
-
/"10
JavaOr~ss
r.
O
.'
.
.
I
I
-
You
know
whattodol
-
I
1
16
I'~
--
-
r
I
flJ
I
I
f--
LY
Across
20.
Classhierarchy
Down
12.
Javac
saw
itcoming
1.
Togivevalue
21.
Too
hot
tohandle
2
Currentlyusable
14.
Attemptrisk
4.Flew
off
thetop
24.
Commonprimitive
3.
Template'screation
16.
Automaticacquisition
6.Allthisandmorel
25.
Coderecipe
4.
Don'tshowthekids
17.
Changing
method
8.Start
27.
Unrulymethodaction
5.
Mostlystatic
API
class
19.
Announcea
duck
10.The
familytree
28.
NoPicasso
here
7.Not
about
behavior
22Dealwithit
13.No
ducking
29,Start
a
chainofevents
9.The
template
23.
Create
badnews
15.
Problemobjects
11.
Rollanotheroneoff
26.
Oneofmyroles
18.
OneofJava's
'49'
theline
MoreHints:
.J3U36.PION'll
ilUntJQl,(II
UJ
I!la4\--
'91
111l2jap
JO
'lI<lnd,(IUO'6
350
chapter11
,..SJ3qwnN
'S
(3Idw~IOUl
--'0;1'£
4Sl!M1I1now
l'
'0
'z
llMOQ
PetlSq\llON'SZ
W31<lOJd
~
QJl!\S
∙Ll.
l(~pntl
'iz
U0I-I><lUro
10
ad.<l
e
0Sfd
'oz
~ep,}p
10
P~ul
'£\
P0413WeIJl!lS
"9
P1l4'
l!IIprv
'9
~
1.False,eitherorboth.
2.
False,youcandeclare
the
exception.
3.
True.
exceptionhandling
CodeMagnets
classMyExextendsException{}
publicclassExTestDrive{
publicstaticvoidmain(String
[J
arqs){
Stringtest
=
args[O]:
try{
syatem.out.print(Nt"):
doRisky(teat):
4.
False,runtimeexceptioncanbecaught.
5.
True.
6.
True,bothareacceptable.
7.
False.thedeclarationissufficient.
8.
False,butifitdoesn'ttheJVMmayshut
down.
9.
True.
10.False.
11.True.
It'softenusedtoclean-uppartially
completed
tasks.
12.False.
13.
False.
14.
False.duckingis
synonornous
withdeclar-
ing.
15.
False,broadestexceptionsmustbecaught
bythelastcatchblocks.
16.False,
if
youdon'thaveacatchblock,
you
must
declare.
17.
False.
}
System.out.print(Ho");
}catch(MyEx
e){
}finally{
System.out.print(Hw");
}
System.out.println(Ns")j
}
staticvoiddoRisky(Stringt)throwsMyEx{
System.out.print(Hh
H);
if("yesH.equals(t)
thrownewMyEx();
}
System.out.print(Wr")j
youare
here.351
puzzle
answers
•
362
chapter11
12
gettingQui
AVeryGraphic
Story
Wow!Thislooksgreat.
Iguess
presentation
really
is
everything.
Faceit,yo
U
needtomakeGUIs.
Ifyou'rebuiIdlngappllcationsthatother
peoplearegoingtouse,you
need
agraphicalinterface.Ifyou'rebuildingprogramsforyourself.
you
want
agraphicalInterlace.Evenifyoubelievethattherestofyournaturallifewillbe
spent
writingserver-sidecode,wheretheclientuserinterlaceIs
a
webpage,soonerorlater
you'llneedtowritetools,andyou'llwant
a
graphicalInterface.Sure,command-lineappsare
retro.
butnotInagoodway.They'reweak,inflexible,andunfriendly.We'llspendtwochapters
workingonGUls,andlea
rn
keyJavalanguagefeaturesalongthewayIncluding
Event
Handling
and
InnerClasses.
Inthischapter,we'llputabuttononthescreen,andmakeItdo
somethingwhenyouclickIt.We'llpaintonthescreen,we'lldisplay
a
Jpegimage,andwe'lleven
do
someanimation.
thisisa
newchapter353
yourfirstgui
Itallstarts
with
a
WiMdow
A]Frameismeobjectthatrepresents
awindowonthescreen.It'swhereyou
putalltheinterfacethingslikebuttons,
checkboxes,textfields,andsoon.Itcan
haveanhonest-to-goodnessmenu
bar
withmenuitems.Andithas
all
thelittle
wiodowingicons
forwhateverplatform
you're
00,
forminimizing,maximizing,and
dosingmewindow.
TheJFr.amelooksdifferentdependingon
theplatformyou'reon,ThisisaJFrameon
MacOSX:
"IfIseeonemore
command-lineapp,
you'refired."
"660
File
Panlc
~ D e v l a l e
'"
t
c1lc\cme-"@chooseme
~ ~
MakingaGUIiseasy:
•Makeaframe
(0
JFrame)
JFrameframe
=
newJFrame();
Put
wldge1's
it1
the
wh,dow
OnceyouhaveaJFrame,youcanput
things(widgets')initbyaddingthem
totheJFrame.ThereareatonofSwing
componentsyoucanadd;lookforthem
inrhejavax.swingpackage.Themost
commoninclude]Button,JRadioBuHon,
JCheckBox,jLabel,jList,jScroIIPane,
JSlider,JTextArea,]TextFie1d.and
]Table.Mostarereallysimpletouse,but
some(likeJTable)canbeabitmore
complicated.
354
chapter12
@)
Make
a
widget
(button,
text
field,etc.)
JButtonbutton
=
newJButton("clicJcms");
•Displayit
C9ive
itasizeandmakeiT
visible)
frame.setsize(300,300);
frame.setvisible(true);
geWngQui
Yourfirst&UI:abutton
Ott
afrattte
importjavax.swinq.*;
public
class
SimpleGuil{
~
public
staticvoid
DlAi.n
(String£]
&rgll)(
~
a.....ear-da
~
",a'tt.
a
Y
cb-\Ol.~
~r.ame
frame::newJFrame();
~
rc"
('/0'"
Ul'l
~aS$
tne
hv-cbm
t,o~
JButtonhutton'"newJButton("click
meN);
tM
W~
'(0"
....,al'l~
0l'I
the
h
Let'sseewhathappenswhenwerunIt:
%javaSimpleGuil
Whoa!
That's
a
Really
Big
Rutton.
Thebuttonfillsallthe
availablespaceintheframe.
Laterwe'lllearntocontrol
where
(and
how
big)
the
buttonisontheframe.
youarehere)
355
userInterfaceevents
Jutttothh1ghappettswhettIclick
it...
That'snotexactlytrue.Whenyoupressthebuttonitshowsthat
~pressed'
or'pushedin'look(whichchangesdependingonthe
plcttfonnlook
andfeel,butit
always
does
something
toshowwhen
it'sbeing-pressed).
Therealquestionis,"HowdoIgetthebuttontodosomething
specificwhentheuserclicks
it?"
Weneedtwothings:
~
A
method
to
becalledwhentheuser
clicks
(the
thingyou
wanttohappen
as
a
result
ofthe
button
click).
@
A
way
to
know
when
to
trigger
thatmethod.
In
otherwords,
a
way
to
know
when
the
userclicksthe
buttonl
Whentheuserclicks,wewant
toknow.
We're
interestedintheuser-
takes-action-on-a-buttonevent.
358chapter12
Q:
Will
a
buttonlooklike
a
Windowsbuttonwhenyourunon
Wlndows7
i\.:
Ifyouwantitto.Youcan
choosefroma
few~look
and
feels~-c1asses
inthecorelibrary
thatcontrolwhattheinterfacelooks
like.Inmostcasesyoucanchoose
betweenatleast
twodifferentlooks:
thestandardJava
lookandfeel,also
knownas
Metal,
andthenativelook
andfeelforyourplatform.TheMac
OSXscreensinthisbookuseeither
the
asx
AquQ
lookandfeel,orthe
Meta/lookandfeel.
Q:
CanImakeaprogramlook
likeAquaall
thetJme7Ellenwhen
It'srunnIngunderWindows7
A:
Nope.Notalllookandfeels
areavailableoneveryplatform.If
you
wanttobesafe,youcaneither
explicitlysetthelookandfeelto
Metal,sothatyou
knowexactlywhat
yougetregardlessofwheretheapp
isrunning,ordon'tspecifyalook
andfeelandacceptthedefaults.
Q:
1
heard
Swing
was
dog-slow
andthatnobody
usesIt.
A:
Thiswastrueinthepast,
butIsn'tagivenanymore.Onweak
machines,you
mightfeelthepainof
Swing.Butonthenewerdesktops,
and
withJavaversion1.3andbe-
yond,youmight
notevennoticethe
differencebetweenaSwingGUIand
anativeGUI.SwingIsusedheavily
today,inall
sortsofapplications.
gettinggui
First,thebuttonneedstoknow
thatwecare.
1)
Howcouldyoutellabuttonobjectthatyou
careaboutItsevents?Thatyou'reaconcerned
listener?
Second,thebuttonneedsaway
tocallusbackwhenabutton-
clickedeventoccurs.
~C'f\l~,
I
ta--e
aW
•
...,~t.
haffe¥\S
-to
yt»-
r>
2)Howwillthebuttoncallyouback?Assume
thatthere'snowayforyoutotellthebuttonthe
nameofyouruniquemethod(changeltOl.So
whatelsecanweusetoreassurethebuttonthat
wehaveaspecificmethodItcancallwhenthe
eventhappens?(hint:thinkPet)
I
yourcode
I
public
void
changelt()(
button.setText("I'vabeanclickedl");
&ettit1gauserevettt
Imagineyouwantthetextonthebuttonto
changefrom
cuckme
to
I'vebeenclicked
when
theuserpressesthebltton.Firstwecanwritea
methodthatchang51'thetextofthebutton(a
quicklook.Jhr.ougfi
the
APIwill
showyou
the
method):
But
now
what?How
will
we
know
when
this
methodshouldrun?
How
will
we
knowwhen
the
button
is
clidred?
In
java,theprocessofgettingandhandling
a
userevent
is
called
event-handling.
Thereare
manydifferentevent
types
inJava,although
most
involve
GUI
useractions.
If
theuserclicks
a
button,that'sanevent.
An
eventthat
says
-Theuserwantstheactionofthisbuttonto
happen."
If
it's
a
"SlowTempo"button,theuser
wants
theslow-tempoactiontooccur.
If
it's
a
Sendbuttonon
a
chatclient,theuserwantsthe
send-roy-messageactiontohappen.Sothemost
straightforwardeventiswhentheuserclicked
thebutton,indicatingtheywantanaction
to
occur.
Withbuttons,youusually
don'tcareaboutany
intermediateeventslikebutton-is-being-pressed
andbutton-is-being-released.Whatyouwantto
sa)'
tothebuttonis,
"I
don'tcarehowtheuser
playswiththe
button,howlongtheyholdthe
mouseoverit,howmanytimestheychangetheir
mind
and
roll
offbeforelettinggo,etc.
Just
teD
me
whenthe
usermeans
business!
Inotherwords,
don'tcall
me
unlesstheuserclicksin
a
way
that
indicateshewantsthe
darn
button
[0
do
whatit
says
it'lldol"
youarehere)
351
event
listeners
Ifyoucareaboutthebutton'sevents,
"'1W.i~iM"''''''''''''''IIiiII''''''-ii1that
says,
ClI'm~or
yourevents."
A
listenerinterlaceis
thebridgebetweenthe
',istener(you)andeventsource(thebutton).
JThe
SwingGUIcomponentsareeventsources.InJavaterms,
an
eventsource
is
anobjectthatcantumuseractions(dick
a
mouse,typeakey,closeawindow)intoevents.Andlike
virtuallyeverythingelsein
lava,aneventisrepresentedasan
object.
An
objectofsomeeventclass.
If
youscanthroughthe
java.aWl.eventpackageinthe
API,
you
'I)
see
a
bunchofevent
classes(easy
to
spot-theyallhave
Event
inthename).You'll
findMouseEvent,KeyEvent,'-\'indowEv
ent,ActionEvent,and
severalothers.
An
event
source
(likeabutton)createsan
eventobject
whenthe
userdoessomethingthatmatters(like
click
thebutton).Most
ofthecodeyouwrite(andallthecodeinthisbook)will
receive
eventsratherthancreateevents.Inotherwords,you'lJspend
mostofyourtimeasaneventlistenerratherthananevent
source.
Everyeventtypehasamatchinglistenerinterface.
If
youwant
MouseEvents,implement
theMouseListenerinterface.Want
WindowEvents?ImplementWindowListener.Yougettheidea.
Andremember
your
interface
rules-e-tc
implementaninterface
you
declare
thatyouimplementit
(class
DogimplementsPet),
which
meansyoumustwriteimplementationmethodsforevery
methodintheinterface.
Someinterfaceshavemorethanonemethodbecausethe
eventitselfcomesindifferentflavors.Ifyouimplement
Mousel.istener,
forexample,youcan
get
eventsfor
mousef'ressed,
mouseReleased,mouseMoved,etc.Eachof
thosemouseeventshasaseparatemethodintheinterface.
even
though
they
alltakeaMouseEvent.
If
youimplement
Mousel.istener,themousePressedOmethodiscalledwhenthe
user(youguessedit)pressesthemouse.Andwhentheuserlets
go,
themouseReleased()methodiscalled.Soformouseevents,
there'sonlyoneevent
object;
Mouseliveru,butseveraldifferent
eventmethods,representingthedifferent
types
ofmouseevents.
358
chapter12
\lJhen
you
imPlementa
listener
interface,
you.
give
the
hutton
a
way
to
call
you
hack.Theinterface
is
wherethecall-hackmethod
is
declared.
<:</nfS.....
Ki
""C8»
eYLl8fener
keyprassed
keYRaJ(kaY£Venlev)
BaSed(ke
keYTYl>&dYEvantev)
(keYcven/ev)
Howthelistenerandsource
communicate:
"Button,pleaseaddmeto
yourJistoflistenersandcall
my
actionPerformedOmethod
when
the
user
clicks
you."
.1
0Act
ionList
enef'(
<:>0
11...
o~·
r"S)
",'"
'0'"
TheListener
Ifyourclasswantstoknowabout
abutton'sActionEvents,you
implementtheActionLlstener
interface.The
buttonneedsto
knowyou'reInterested,soyou
register
withthebuttonbycallingIts
addActionLlstener(this}andpassingan
ActionListenerreferencetoIt(Inthiscase,
you
aretheActIonListenersoyoupass
this).The
buttonneedsawaytocallyou
back
whentheeventhappens,so
it
calls
the
methodinthelistenerInterface.
As
an
ActionUstener,you
must
Implementthe
interface'ssolemethod,actlonf'erformedt).
ThecompilerguaranteesIt.
gettinggui
"OK,
you'reanActionListener,
so
I
knowhowto
call
you
back
whenthere'san
event--I'llcall
theactionPerformedOmethod
that
I
knowyou
have."
TheEventSource
AbuttonisasourceofActionEvents,
so
it
hastoknowwhichobjectsare
interestedllsteners.The
buttonhasan
addActionUstenerO
methodtogive
Interestedobjects(listeners)awayto
tell
thebuttonthey'reinterested.
When
thebutton's
addAetionLlstenerOruns(because
apotentiallistenerinvokedit),
the
buttontakestheparameter(a
referencetothelistenerobject)and
storesitinalist.When
theuserclicks
thebutton,thebutton
'fi
res'theevent
by
cal/JngtheactionPerformedO
methodoneachlistenerInthelist.
youarehere
~
359
getting
events
Gettingabutton'sActionEvent
•
•ImplementtheActionListenerinterface
I)
Registerwiththebutton(tellityou
wanttolisten
forevents)
•Define
theevent-handlingmethod(implement
theactionPerformedOmethodfromthe
ActionListenerinterrface)
publicstaticvoidmain(String[]args)
SimpleGuilBqui
=
newSimpleGuilB();
quLgoO;
<,
tt--
button.addActionListener(this);
I
frame.getContentPane().add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);.
tty~attS
frame.setSize(300
r
300);
th
At:t\O¥IL-is-\:.t"tY'".
t;
frame.setVisible(true);
\",y\t"'t"t.ttdO",tt.
hod
..ih\SISht
.»<:":
at..t.io,,?tY~OV'"'
d\'
~
"'tt.
hod
!
•
~
.at..-tv.a\t>le"t.-haY\IYI
publicvoidactionPerformed(ActionEventevent){
button.setText("I'vebeenclicked!");
160
chapter12
gettinggui
llsfetters,Sources,attdEvettfs
FormostofyoursteUarJavacareer,
yO'll
will
notbethe
source
\
ofevents.
J
~=\er
howmuchyou
/ci
yourselfthecenterofyoursocial
Get
used
to
it.
Your
~
to
bea
good
listener.
(Which.
if
youdo
it
sincerely,
can
improveyoursocial
life.)
Cb
SourceSENDS
II
theevent
As
ane.ventsource,myjobisto
accept
rt9istrations(fromlisteners),
get
eventsfromthe.
user.
and
call
thelistener'sevent-handling
method(when
theuserclicksme)
Event
object
HOLDSDATA
abouttheevent
Hey,whataboutme?rm
a
playertoo,you
knowI
Asan
eventobject,I'mthe
argument
totheeventcall-backmethod(from
the
interface)endmyjob
is
to
carry
data
about
'keevent
back
tothelistener.
As
alistener,myjob
is
to
Implement
theinterface,
register
withthebutton,and
provide
theevent-handling.
ListenerGETSthe
event
youarehere)361
event
handling
Q:
Whycan'tIbe
a
sourceofevents?
..A..:
YouCAN.Wejustsaidthat
most
ofthetime
you'llbethereceiverand
nottheoriginatorofthe
e~nt
(atleastinthe
early
daysofyourbrilliantJava
care~(he
eventsyoumightcareabout
are'fired'
by
classesintheJavaAPI,andallyouhave
todoIsbealistenerforthem.Youmight,however,
designaprogramwhereyouneedacustomevent,
say,
StockMarketEventthrownwhen
your
stockmarket
watcherappfindssomethingItdeemsImportant.In
that
case,you'dmaketheStockWatcherobjectbean
eventsource,andyou'ddothesamethingsa
button
(oranyothersource)does-makealistenerinterface
foryourcustomevent,providearegistrationmethod
(addStockListener()),andwhensomebodycallsIt,add
thecaller(alistener)tothelistoflisteners.Then,when
astockeventhappens,Instantiate
aStockEventobject
(anotherclassyou'llwrite)andsendIttothelisteners
InyourlistbycallingtheirstockChanged(StockEvent
ev)method.Anddon'tforgetthatforeveryevent
type
theremustbea
matchinglistenerInterface(so
you'll
createaStockLlstenerInterface
withastockChangedO
method),
Q:
J
don'tseetheImportaneeof
the
eventobject
that'spassedtothe
event
call-backmethods.
If
somebodycallsmymousePressedmethod,what
otherInfowouldIneed?
A:
Alotofthetime,formostdesigns,youdon't
needtheeventobject.It'snothingmorethanalittle
datacarrier,tosendalongmoreinfoabouttheevent.
Butsometimesyou
mightneedtoquerytheeventfor
specificdetails
abouttheevent.Forexample,If
your
mousePressedOmethodiscalled,
you
knowthemouse
waspressed.ButwhatIfyouwanttoknowexactly
wherethemousewaspressed?Inotherwords,whatIf
youwantto
knowtheXandYscreencoordinatesfor
wherethemousewaspressed?
Orsometimes
you
mightwanttoregisterthe
some
listenerwith
multiple
objects.Anonscreencalculator,
forexample,has10numerickeysandsincetheyalldo
thesamething,youm
ightnotwanttomakeaseparate
listenerforeverysinglekey.Instead,you
might
registerasinglelistenerwitheachofthe10keys,and
whenyou
getanevent(becauseyoureventcall-back
methodiscalled)youcancallamethodontheevent
objecttofindout
who
therealeventsourcewas.In
otherwords,
whichkeysentthisevent.
Eachofthesewidgets(userInterfaceobjects)arethe
sourceofoneormoreevents.Matchthewidgets
with
theeventstheymightcause.Somewidgetsmightbea
sourceofmorethanoneevent,andsomeeventscanbe
generatedbymorethanone
widget.
Widgets
Eventmethods
checkbox
wlndowClosing()
textfield
actionPerfonned()
scrollinglistItemStateChanged
0
button
mousePressed()
dialogbox
keyTyped()
radiobuttonmouseExlted()
menuItem
focusGalned()
362
chapter12
gettingQui
&ettittg
back
tographics...
Nowthatweknowalittleabouthoweventswork(we'lllearn
morelater),let'sgetbacktoputtingstuffonthescreen.
We'll
spendafewminutesplaying
with
somefun
ways
toget
graphic,before
returningtoeventhandling.
ThreewaystoputthingsonyourGUI:
~ets
on
Q
frame
Addbuttons,menus,radiobuttons,etc.
frame.getcont&ntPane().add(myButton);
Thejavax.swingpackagehasmorethanadozen
widget
types.
•Drow2
t>
graphicson
Q
widget
Useagraphicsobjecttopaintshapes.
graphics.fi110val(70,70,lOO,lOO);
Youcanpaintalotmorethanboxesandcircles;
theJava2DAPIisfulloffun,sophisticated
graphicsmethods.
;'f'\.
/
c.h3~1
<J~
L.,.1\1'ICSS
•C;,
sa,..
l)
si
,,/.}J..
es,
~a~"'iC.~,
Qo~)
-c:
~c\:t
.
•Put
Q
JPEGon
Q
widget
Youcanputyourownimagesonawidget.
qraphics.drawImage(myPic,lO,lO,this);
youarehere
~
363
makingadrawing
panel
Makeyourow.,drawi.,gwidget
If
youwanttoputyourowngraphicsonthescreen,yourbest
bet
is
tomakeyourownpaintablewidget,Youplopthatwidget
on
theframe.justlikeabuttonoranyotherwidget,butwhenit
showsupitwillhave
yourimageson
it.
Youcanevenmakethose
imagesmove,inananimation,ormakethecolorsonthescreen
changeeverytimeyouclick
a
button.
"i~i~
ofcake.
MakeasubclassofJPanelandoverrideone
method,palntComponentO.
AllofyourgraphicscodegoesinsidethepaintComponentO
method.ThinkofthepaintComponentOmethodasthemethod
calledbythesystemtosay,"Heywidget,timetopaintyourself."
If
youwanttodrawacircle,thepaintComponentOmethod
will
havecodefordrawingacircle.Whentheframeholdingyour
drawingpanel
is
displayed,paintComponentOiscalledandyour
circleappears.
If
theusericonifies/minimizesthewindow,the
JVM
knowstheframeneeds"repair"whenitgetsde-iconified,
soitcalls
paintComponentOagain.Anytimethe
JVM
thinksthe
displayneedsrefreshing,yourpaintComponentOmethod
will
be
called.
Onemorething,
yflU
never
call
this
method
Yfnl;T$e1j!Theargumeo
t
to
thismethod(aGraphicsobject)
is
theactualdrawingcanvas
thatgetsslappedontothe
real
display.Youcan'tgetthisby
yourself;it
mustbehandedtoyoubythesystem.You'llsee
later,however,
thatyou
can
askthesystemtorefreshthedisplay
(repaint()),whichultimatelyleadstopaintComponen
t()
being
called.
J.
lc."t~
importjava.awt.
*
i_
¢(.o
b~
,
~ ~oI'
import
j
avax.swing.
*;
~
}
364
chapter12
•
Dls~G
Futtfhit1Qs
to
do
ittpaittfCotMpottet1fU
Let'slookata
few
morethingsyoucandoinpaintflomponentj).
Themostfun,though,iswhenyoustartexperimentingyourself.
Try
playingwiththenumbers,andchecktheAPIforclass
Graphics(laterwe'llsee
thatthere'seven
more
youcandobesides
what's
in
theGraphicsclass).
~s
't.eY
t
~',\t
...a",t.
~
....,ov'(
publicvoidpaintComponent(Graphics
g){
r
I
Imageimage
=
newImagelcon("catzilla.
jpqU).
getImage();
J
Paintarandomly-coloredcircle
onablackbackground
publicvoidpaintComponant(Graphics
g)
g.fillReot(O,O,this.getWidth(),
intred
=
(int)(Math.random()
*
255);
intgreen
=
(int)(Math.random()
*
255);
intblue
=
(int){Math.random(}
*
255);
ColorrandomColor
=
newColor(red,green,
g.setColor(randomColor);
g.fillOval(70,70,lOO,lOO);
~idrf
70.
f~t
to
pll(dsfro",
fh
J
t:
J
00.
p,
~ke
it
100.
t:
t"tt,
70
tr
Plxds
~II.
pl'l<.e/s....
id
e
,
il"d
0",
gettinggui
youarehere.365
pubU.cvoidpa..intcomponent(G:r:a.phiclI
q)(}
-
drawinggradientswithGraphics2D
'ehit1deverygoodc.raphicsreferettce
isaOraphies!eobject.
Theargument
to
paintComponentO
is
declaredastype
Graphics(java.awt.Graphics).
\
I
So
theparameter
'g'
IS-A
Graphicsobject.Whichmeansit
could
bea
subclass
ofGraphics(becauseofpolymorphism).
Andinfact,it
is.
The
object
referenced
by
the
tg'
parameter
is
adually
an
instance
of
the
Graphics2D
class.
Whydoyoucare?Becausethereare
things
youcando
with
aGraphics2Dreferencethatyoucan'tdowithaGraphics
reference.
A
Graphics2Dobjectcandomore
than
aGraphics
object,anditreallyis
a
Graphics2Dobjectlurkingbehindthe
Graphicsreference.
Rememberyourpolymorphism.Thecompilerdecideswhich
methodsyoucan
call
basedonthereferencetype,notthe
objecttype.
If
youhave
a
DogobjectreferencedbyanAnimal
referencevariable:
Animal
a
=
new
Dog();
YoucanNOT
say:
a.bark()
i
Eventhoughyouknowit'sreallyaDogbackthere.
The
compilerlooks
at'a',
seesthatit'softypeAnimal,andfinds
thatthere'sno
remote
controlbuttonfor
barkr)
in
theAnimal
class.
ButyoucanstillgettheobjectbacktotheDog
it
really
is
bysaying:
Doq
d""
(Doq)
Ai
d.buk();
Sothebottomline
with
theGraphicsobject
is
this:
If
youneedtouseamethodfromtheGraphics2Dclass,you
can't
use
thethepaintComponentparameter
('g')
straight
fromthemethod.Butyoucan
cast
it
withanewGraphics2D
variable.
Graphics2D
q2d
B
(Graphics2D)qi
366
chapter12
Methodsyoucancallon
8
Graphics
reference:
drawlmageO
drawLlneO
drawPolygon
draw
RectO
drawOvalO
fillRectO
fillRoundRect()
setColor()
Tocastthe
Graphlcs2D
objectto
a
Graphlcs2D
reference:
Graphics2D
g2d
=
(Graphics2D)g;
Methodsyoucancallon
a
Graphlcs20
reference:
-
Ii
II3DRecl
0
draw3DRectO
rotate
0
scaleO
sheerO
transformO
selRenderingHlntsO
(theseare
~ot
t.mr.pltf:t
",ethodlish,
thetkthe
API
.few",ewe.>
gettinggui
'ecauselife"stooshorttopaintthe
circleasolidcolorwhenthere"sa
gradientblendwaithtgforyou.
~ublic
voidIntComponent(Graphicsg)(
Graphic2Dq2d:(Graphics2D)g:
~
tastitso
'Nt
tar-
tall
~ir-~ tha~
~.iphiul.D
roas
b~ ~rarhits
aocsr-'i.
GradientPalntgradient:newGradientPaint(70,70,Color.blue,150,150,COlor.orange);
st.rf:j
r
~rtih
't
~.~ ~~d;"~
h~ Poi~t
s
4>J
or
'''.9
poi,,/;
s
toJ
or
~
thissets
tht
vi
rboa
I.
1.
L.
d'
1..
falPl~
urush
to
.i
g2d.aetPaint(gradi.ent):
~ra I~l;;
Ilumd
0+
a
solid
lolor
g2d.filloval(70,70,100,100);
"'"1\
OY\S
"~ i
\\
tht
~i\\O~~\(~:~~t~\1:~eo
(J'rI
'foVr
the
O~d\~I~.
Lhe
~rddit"t)
.LL...l>Shu.e-'{.
J
yal"~'
~llc
voidpaintComponent(Graphics
q)(
Graphics2Dg2d
=
(Graphlcs2D)g;
intred
D
(lnt)(Math.random()..255);
intgreen:(int)(Math.random()..255);
lntblue
e
(lnt)(Math.random()..255);
ColorstartColor
=
newColor(red,green,blue);
red
=
(lnt)
(Math.
random()..255);
green:(lnt)(Math.random()..255);
blue:(lnt)(Math,random()
*
255);
ColorendColor
=
newColor(red,green,blue);
GradientPalntgradient
=
newGradientPalnt(70,70,startColor,150,150,endColor);
q2d.setPaint(qradient);
g2d.fillOval(70,70,100,100);
youarehere
~
367
eventsandgraphics
,...-----EVENTS--------------,
•TomakeaGUI,start
with
awindow,usuallyaJFrame
JFrameframe
=
newJFrame();
•Youcanaddwidgets(buttons,textfields,etc.)tothe
JFrameusing:
frame.getcontentPane()
.add(button);
•Unlikemostothercomponents,theJFramedoesn'tlet
youaddto
it
directly,soyoumustadd
to
theJFrame's
contentpane.
•Tomakethewindow(JFrame)display,youmustgiveIt
a
sizeandtell
it
bevisible:
frama.setSize(300,300);
frame.sBtVisihle(true);
•Toknowwhentheuserclicksabutton(ortakessome
otheractionontheuserinterface)youneed
to
listenfor
a
GUIevent.
•Tolistenforanevent,youmustregisteryourInterest
with
an
eventsource.
An
eventsourceIsthething(but-
ton,checkbox,etc.)that'fires'aneventbasedonuser
interaction.
•ThelistenerInterfacegivestheeventsource
a
way
to
callyouback,becausetheInterfacedefinesthe
method{s)theeventsourcewillcallwhenanevent
happens.
•
Toregisterforeventswithasource,callthesource's
registrationmethod.Registrationmethodsalwaystake
theformof:
add<Event'TYpe>Usfen&r.
Toregisterfora
button'sActlonEvents,forexample,call:
button.addActionListener(this);
•Implementthelistenerinterfacebyimplementingallof
theinterface'sevent-handlingmethods.Putyourevent-
handlingcodeinthelistenercall-backmethod.For
ActionEvents,themethodis:
publie
void
actionPerfoCll8d(ActionEvant
event){
button.setText("youelicked!");
)
•Theeventobjectpassedintotheevent-handlermethod
carriesInformationabouttheevent,InclUdingthesource
oftheevent.
368
chapter12
,----------GRAPHICS-------,
•Youcandraw20graphicsdirectlyon
to
awidget
•Youcandrawa,glfor,jpegdirectlyontoawidget
•Todrawyourowngraphics0ncludinga.gifor
.jpeg),
makeasubclass
of
JPanelandoverridethepaintCom-
ponentOmethod.
•
ThepaintComponentOmethodiscalledbytheGUI
system.YOUNEVERCALLITYOURSELF.Theargu-
ment
to
paintComponentOis
a
Graphicsobjectthat
givesyouasurfacetodrawon,whichwillendupon
thescreen.Youcannotconstructthatobjectyourself.
•TypicalmethodstocallonaGraphicsobject(thepaint-
Componentparamenter)are:
graphic5.setColor(Color.blue);
g.fillRect(20,SO,lOO,120);
•Todraw
a
.jpg,constructanImageusing:
Image
~qe
=
newDmageIoon("catzilla.
jpg").getImage();
anddrawtheImagineusing:
g.drawDmage(image,3,4,this);
•TheobjectreferencedbytheGraphicsparameter
topalntComponentOisactuallyaninstanceofthe
Graphlcs2Dclass.TheGraphics20classhas
a
variety
ofmethodsIncluding:
tiIl3DRect().draw3DRect().
rotateO.
scaleO,shearO,
transformO
•ToinvoketheGraphics2Dmethods,youmustcastthe
parameterfromaGraphicsobject
10
aGraphlcs2D
object
Graphies2D
g2d
=
(Graphics2D)g;
gettinggui
Wecattgetattevet1t.
Wecattpaitttgraphics.
&ufcattwepaitttgraphics
when
we
getattevettt?
Let's
JOOk
upan
eventto
achange
in
ourdrawing
panel.
We'll
makethe
circle
chanlecolors
each
timeyou
click
the
button.
Here's
how
theprogram
flows:
Starttheapp
o
Theframeisbuiltwiththetwowidgets
(yourdrawingpanelandabutton).A
listeneriscreatedandregisteredwith
thebutton.Thentheframeisdisplayed
andit
justwaitsfortheusertoclick.
e
Theuserclicksthebuttonandthe
buttoncreatesoneventobjectand
calls
thelistener'seventhandler.
e
TheeventhandlercallsrepaintOonthe
frame.ThesystemcallspaintCompone.ntO
onthedrawingpanel.
o
Voila!Anewcolorispaintedbecause
paintComponentOrunsagain,fillingthe
circlewitharandomcolor.
youarehere
~
369
buildingaGUIframe
doyou
put
TWO
thingsonaframe?
WecoverGUIlayouts
in
the
next
chapter,butwe'lldo
a
quickielessonheretogetyougoing.Bydefault,
a
frame
hasfiveregionsyou
can
add
to.
Youcan
add
only
one
thing
toeachregion
of
aframe,butdon'tpanic!
That
onething
mightbe
a
panel
that
holdsthreeotherthings
includinga
panelthatholdstwomorethingsand...youget
the
idea.In
fact,wewere'cheating'whenweaddeda
buttontotheframe
using:
&Ullayouts:putti"gtttorethatto.,e
widgetOttafrattte
------
dd~u/t ~iOll
Giventhepicturesonpage351,writethe
codethataddsthebuttonandthepanelto
theframe.
-
370
chapter12
gettinggui
Thecirclechangescoloreachtimeyou
clickthebutton.
importjavax.awing.*;
importjava.awt.*;
importjava.awt.event.*;
~
publicclassSimpleGui3C(implemantsActionListaner(
JFrameframe;
publicstaticvoidmain(String[]arqs)
SimpleGu13C
qui'"
newSimpleGui3C():
qui.
go
(J;
publicvoid
go(){
frame'"
new
JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButtonbutton'"newJButton("Changecolors");
button.addActionListener(this);
~
_
MyDrawPaneldrawPanel
=
newMyDrawPanel();
A
dd
tile
two
wid~e-b
(b"i-
frame.
getContentPane().
add
{BorderLayout.
SOUTH,
button);
~
/
k
dl'ld
d\"..
w i,,~ r~l'Iel)
to
frame.98tContentPane().
add
(BorderLayout.
CENTER,
drawPanel);
I(
~he
two
\"e~ iOf\.S
cJ
the
frame.setSize(300,300);
-tra"'e.
frame.setVisible(true);
classMyDrawPanelextendsJPanel(
publicvoidpaintComponent(GraphicB
q)(
//Codeto1Ultheovalwl
th
arandomcolor
//Seepage347
for
thecode
youarehere)371
So.,owwet1eed
FOUR
widgets
Thesouthbuttonwillactasitdoesnow,simplycallingrepaint
00
the
frame.Thesecondbutton
(which
we'llstickintheeastregion)will
changethetextonalabel.(Alabelisjusttextonthescreen.)
multiple
listeners
/Let'stryitwithTWObuttons
(
-
372
chapter12
labelwill
~o
na-e
e
d__
awin~
panel
~oes
~
in
the
tenu__
-
~t>t
toICK-t~n~in~
b~
will
~o
htre
Attdwetteedtoget
rwo
events
Uh-oh.
Is
thatevenpossible?Howdo
ChangeLabel
youget
two
eventswhenyou
haveonly
O11C
actionPerfonnedO
method?
geWnggui
Howdoyougetactio"eve"tsfor
two
dlffere"tbutto".,
whe~
eachbutto""eedstodosolttethi"Qdffferettt?
i
I
-.
•optionone
ImplementtwoactionPerformedOmethods
.--
class
MyGui
implementsActionListener(
II
Iotaofoodebere
and
then:
publi~
void
actionPerfo~d(ActionEvent
event)(
frame.repaint();
~ ~t.
this
isi"'possible'
~
.
publicvoidactionPerformed(ActionEventevent){
label.setText("Thathurt!
/I);
Flaw:Youcan'ti
Youcan'tImplementthesamemethodtwiceInaJavaclass.Itwon'tcompile.
Andeven
if
youcould,howwouIdtheeventsourceknowwhichofthetwomethodsto
call?
•option
two
Registerthesamelistenerwithbothbuttons.
-
class
MyGui
implementsActionLletaner(
II
declareabunchofinstancevariablesbere
publi~
voidgo()(
II
buildqui
eolorButton
~
newJButeon():
labelButton
=
new
JButton();
colorButton.addActionListener
(th1
e);
~ R.l!~isUr
the
~",e
lisU-"e"
labelBu
t
ton.addActionListener
(this);
l(
'NI8,
b~
blottoru
II
more
qW.
codehere...
publicvoidactionPerformed(ActionEvantevent){
if
(event.gatSource()
=
colorButton)(
t,
ab'
~d.
frama.repaintO;
~ G.~
t,nt
l!'1l!'\tt.
~~8:Pn
elee(
to
~i)\d
ov-t.
'01".
"d
lASt
label.setText("Thatburt!/I);
at~\\'( ~·,ye.ci
It..
a
L
to
do-
-lhd-t
t.o
dl!tid~",,"41~
Flaw:thisdoeswork,butInmoatcasesIt'snotvery00.
Oneeventhandler
doingmanydifferentthingsmeansthatyouhaveasinglemethoddoingmanydifferentthings.
Ifyouneedtochange
how
one
sourceishandled,youhavetomesswith
everybody's
event
handler.Sometimes
It
isagoodsolution,butusually
it
hurtsmaintainabilityandextensibility.
youarehere.
373
multiplelisteners
Howdoyougetactio"evetttsfortwodffferetttbutfotts,
whetteachbuttotttteedstodosotltethittQdifferettt?
•option
three
CreatetwoseparateActlonListenerclasses
alassMyGui(
JFraIDeframe;
JLabe.l
label;
voidgui()(
/J
code
to
instantiate
thetwolistenersandreqister
one
1/
wi
ththecolorbutton
and
theotherwiththelabelbutton
)
II
clos.class
classColorButtonLiatenerimplementsActionListaner{
public
voidactionPer£ol:m8d(ActionEventevent)(
frame.
repaint();
,WO'I\lwot"k!Tnis
tlau
dool'l't
ha~t
a
~e~tr'Cl'lU
tp
tl\e
't~a"'t'
variable
o.f
the
M'1~\oi
dau
cla.ssLabelButtonListenerimplementsActionLiatener(
publicvoid
actionPerfo~(ActionEvent
event)(
la.bel.setText("Tha.thurt!H);
~
Proble...
1
n°
I
has
r
°
IS
t..
au
1'0
re-tere'lt..e
to
thevariable'label'
Flaw:theseclasseswon'thaveaccesstothevariablestheyneed
toacton,'frame'and'label'.
Youcould
fix
Itbutyou'dhavetogiveeachofthe
listenerclassesareferencetothemainGUIclass,sothatInsidetheaetlonPerformedO
methodsthelistenercoulduse
theGUIclassreferencetoaccessthevariablesoftheGUI
class.Butthat'sbreakingencapsulatIon,sowe'dprobablyneed
tomakegettermethods
for
thegulwidgets(getFrameO.qetl.abelf),etc.).Andyou'dprobablyneedtoadda
constructorto
thelistenerclasssothatyoucanpasstheGUIreferencetothelistenerat
thetimethelistenerisInstantiated.And,well,itgetsmessierandmorecomplicated.
There
hQS
gottobe
Q
better
wayl
374
chapter
12
getting
gui
youarehere.
375
innerclasses
Itttterclasstotherescue!
You
can
haveone
class
nestedinsideanother.It's
easy.
Justmakesurethatthedefinitionfortheinner
class
is
inside
thecurlybracesoftheouterclass.
An
innerclassgetsaspecialpasstousetheouterclass'sstuff.
Even
the
privatestuff.
Andtheinner
class
canusethoseprivatevariables
andmethodsoftheouterclassas
if
thevariablesandmembers
weredefinedintheinner
class.
That'swhat'ssohandyaboutinner
classes---theyhavemost
of
thebenefitsofanormal
class.
but
with
specialaccessrights.
Simpleinnerclass:
classMyOuterClass
classMylnnerClass
voidgoO(
)
{
Aninner
class
can
useaU
tIle
metltOJs
and,'at'ial)les
ofthe
outer
class,
evert
till'
lwi"atrones,
TIleinnerclassgets
to
use
tlto...e
"ariahles
anJ
metltOds
just
as
if
tile
mctltoJ...
andvariables
wel'C
Jeclat'eJwithin
tlu~
innerclass.
Innerclassusinganouterclassvariable
classMyOuterClass{
privateintx;
c1809
MylnnerClas8(
voidgo(){
x
=
42;
~
}
II
close
inne~
class
II
close
outer
class
376
chapter
12
getting
gUi
Aninnerobject
shares
a
special
bondwithan
outerobject."
Makeaninstanceof
theinner
class,
by
usin~
instance
oftheouterclass.
~
.;p
:Yl'"nner
o'O~
<D
Makeaninstanceof
theouter
class
®
G)
Theouterandinnerobjects
arenowintimatelylinked,
A.,f.,.,erclassit1sfa.,cetMustbetiedto
at1outerclassit1stat1ce*.
---
Remember,whenwetalkaboutaninner
class
accessing
something
in
theouter
class,
we'rereally
talking
about
an
illstan ~
ofthe
inner
class
accessing
somethinginan
instance
of
the0tler
class.
But
which
instance?
Can
dry
arbitrary
instance
of
me
innerclassaccessthemethods
and
~'l-iables
of
any
instance
of
meouter
class?
No!
"-
Aninnerobjectmustbetiedtoaspec
fie
outerobjecton
theheap.
"There'sanexceptiontothis,foraveryspecialcase-anInnerclassdefined
within
a
staticmethod.
BUI
we'renolgoIngthere,andyoumightgoyourenUre
Javalifewithouteverencounteringoneofthese.
youare
here
~
37i
Innerclassinstances
Howto"'akeaninstanceofaninnerclass
If
youinstantiateaninner
class
fromcode
wilhin
anouterclass,theinstance
oftheouterclassistheonethattheinnerobject
will
'bond'with.For
example,
if
codewithinamethodinstantiatestheinnerclass,theinner
object
will
bondtotheinstancewhosemethod
is
running.
./'
Code
in
an
outer
classcan
instantiateoneof
its
owninner
classes,
inexactly
thesamewayitinstantiatesanyother
class...
new
MyInner()
{
\!is
a
ro-i'laU
n~~
t.\au
t
J
privateintx;
~\~fIU"aYiilb\~
..,.
MyInnerinner'"n_MyInnar
0;
~ ~dkt
dl\
instal'lU
0+
in
11I"tt"
dilSS
e
classMyOuter
publicvoiddoStuff(){
inner
.go();II_
u.
_.I
.LL(
}
~
ta
il...
nnou
01\
"ton
iJ\l'l~
t.\au
MyOuter
Side
bar---------------------,
MyInner
MyOuter
-
}
II
closeinnerclass
class
MyInner{
void
goO{
2
('4r"--_
You
can
InstantiateanInnerInstancefromcoderunning
outside
theouterclass,butyou
have
to
useaspecialsyntax.Chances
are
you'llgothroughyourentireJavalifeandnever
needtomakeanInner
classfromoutside,butjustIncaseyou'reInterested...
classFaa{
:publiestatievoidmairl(String[]
arqll)(
MyOutA!llr
outarObj'"
newMyOutar();
MyOuter.MyInnerinnerObj..outarObj.newMyInner()
i
}II
closeouterclass
378
chapter12
gettinggui
Cllong.LaMI
publicvoid
got)(
frame
=
newJFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
(+,h
J
tot.
he
JButtonlabelButton
=
newJButton("ChangeLabel");
~
.,..rttad
ere
~assi,,~
.:o..abO'/'l
labelButton.aCldACtionLilltener
(~"
LabelLia1:aner())
;1'\
~"tton'~\·~h.,.eY ~e~'
ta"te
o.c
..J
61S
a
",'OJ\
Y\1
...e1:.
hOU
'
~
.
t.t
\i~t.e"ey
c.\ass.
JButtoncolorButton
=
newJButton("ChangeCircle");
~
t.
he
ilW~'il
colorButton.addActionListener(n_ColorLiStaMr()):
publicclassTwoButtons
JFr)
frame;
JL~
labAl;
/
~ l i C
staticvoidmainCStrinq[)arqs)
TwoButtonsqui
=
newTwoButtODS();
qui
.go();
Nowwecangetthetwo-button
codeworking
label
=
newJLabel("I'malabel");
MyDrawPaneldrawPanel
=
newMyDrawPanel():
TwoButtorlS
object
frams.qetContentpane().add(BorderLayout.SOOTH,colorButton):
frame.getContentPane().add(BorderLayout.
CENTER,
drawPanel);
frame.getContentpaneC).add(BorderLayout.EAST,labelButton);
frame.getContentpane().add(BorderLayout.
WEST,
label):
frame.setSize(300,300):
frame.setVisible(true):
ColorListener
object
e:
classLahelt.1atener
~l.amanta
_
Ac ~ _~~ls ~ ~!.
(
publicvoidactionPerformed(ActionEventevent)(
lab&l.setTaxt("Ouch!"):
),
~ iPl"~
tldSS
kPlows
II
closeinnerclass
ilbowt'Iabd'
I
II
closeinnerclass
youarehere
~
379
Innerclasses
HeadFirst:What
makes
inner
classes
important?
Innerobject:
Wheredo
I
start?Wegiveyou
a
chance
to
implementthesameinterfacemore
than
onceina
class.
Remember,you
can't
implement
a.
methodmore
than
onceinanormalJavaclass.Butusing
inner
classes,each
innerclasscanimplementthe
same
interface,soyoucan
haveallthese
diffemu
implementationsoftheverysame
interfacemethods.
HeadFirst:
Whywouldyouever
warn
toimplementthe
same
methodtwice?
Innerobject:
Let's
revisit
GUI
eventhandlers.Think
aboutit...
if
youwantthrubuttons
to
eachhave
a
differenteventbehavior,thenuse
three
inner
classes,
all
implementingActionl.istener-r-whichmeanseach
class
gets
toimplement
its
ownacrionPerformedmethod.
HeadFirst:
So
are
eventhandlerstheonlyreasontouse
innerclasses?
Innerobject:Oh,
goshno.Eventhandlers
are
justan
obviousexample.Anytimeyouneedaseparate
class,
but
still
wantthatclasstobehaveas
if
itwerepartof
another
class,aninnerclass
is
thebest-andsometimes
only-way
to
doit.
HeadFirst:
I'mstillconfusedhere.
If
youwanttheinner
classto
behave
likeitbelongstotheouterclass,whyhave
aseparateclassinthe
first
place?Whywouldn'ttheinner
classcodejustbe
in
theouter
class
inthefirstplace?
Innerobject:
I
just
glIl.lt
youonescenario,whereyou
needmorethan
oneimplementationofaninterface.But
even
whenyou'renot
wing
interfaces,youmightneed
twodifferent
classes
becausethoseclassesrepresenttwo
different
tlting.s.
It'sgood
00.
HeadFirst:
Whoa.Holdonhere.Ithoughtabigpartof
00
designisaboutreuseandmaintenance.Youknow,the
idea
that
if
youhavetwoseparateclasses,theycaneach
bemodified
andusedindependently,
as
opposedtostuffing
it
all
intooneclassyadayadayada.Butwithan
inner
class,
you'restill
just
workingwithone
real
classin
theend,right?
Theenclosing
class
is
theonlyonethat'sreusableand
380
chapter12
Ja¥a·~ed'
This
weeksInterview:
InstanceofanInnerClass
separatefromeverybodyelse.Innerclassesaren'texactly
reusable.
In
fact,I'veheardthemcalled"Reuseless-
uselessoverandover
again."
Innerobject:
Yesit'struethatmeinnerclass
is
not
as
reusable,
in
factsometimesnotreusableat
all,
becauseit's
intimatelytiedtotheinstancevariables
andmethodsof
theouter
class.
Butit-
HeadFirst:
-whichonlyproves
my
point!
If
they'renot
reusable,whybotherwith
a
separateclass?Imean,other
thantheinterfaceissue,whichsoundslikeaworkaround
tome.
Innerobject:
As
Iwas
saying,
youneedto
think
about
IS-A
andpolymorphism.
HeadFirst:OK.
AndI'mthinkingaboutthembecause...
Innerobject:
Becausetheouterandinnerclasses
mightneedtopass
differtm
IS-Atests!Let's
start
withthe
polymorphic
GUI
listenerexample.What'sthedeclared
argumenttypeforthebutton'slistenerregistration
method?
In
otherwords,
if
yougototheAPIandcheck,
whatkind
of
thing
(class
orinterfacetype)doyouhaveto
passtotheaddActionLstener()method?
HeadFirst:
Youhavetopassalistener.Something
that
implementsaparticularlistenerinterface,in
this
case
ActionListener.Yeah,weknow
all
this.
What'syourpoint?
Innerobject:
Mypointisthatpolymorphically,you
have
amethodthattakesonlyoneparticular
rype.
Something
thatpassesthe
IS-A
testfor
Actionl.istener,
But-and
here'sthebigthing-what
if
your
class
needstobeanIS-
Aofsomethingthat'sa
cum
typeratherthananinterface?
HeadFIrat:
Wouldn'tyouhave
yourclass
just
extend
the
class
youneedto
be
apartof?Isn'tmatthewholepoint
ofhowsubclassingworks?
If
Bisasubclassof
A,
then
anywhereanA
is
expected
a
B
can
be
used.Thewhole
pass-a-Dog-where-an-Animal-is-the-declared-type
thing.
Innerobject:
Yes!Bingo!Sonowwhathappens
if
you
needtopasstheIS-Atestfor
two
differentclasses?Classes
thataren'tinthesameinheritancehierarchy?
HeadFirst:
Oh,weUyoujust,..hrnmm.IthinkI'mget-
ting
it.Youcanalways
implement
morethanoneinterface,
butyoucan
extend
only
one
class.Youcanonlybeonekind
\
of
IS-Awhen
itcomesto
elms
types.
\
'Innerobject:
Welldone!Yes,youcan'tbebothaDog
andaBurton.BUt
if
you'reaDogthatneeds
to
some-
timesbea
Burton
(in
ordertopassyourselftomethods
thattakeaBuuon),theDogclass
(which
extends
Animal
soitcan'textendBurton)canhavean
inner
classthatacts
onthe
Dog'sbehalf
asa
Button,byextending
Burton,
andthuswhereveraButtonisrequiredtheDogcan
passhisinnerButtoninsteadofhimself.Inotherwords,
insteadofsaying
x.takebunoruthis),theDogobjectcalls
x.takeButton(newMylnnerfluttoruj).
HeadFirst:
Can
I
geta
clear
example?
Innerobject:
Rememberthe
drawing
panelweused,
wherewe
madeourownsubclassofJPanel?Rightnow.
that
class
is
aseparate,non-inner,class.Andthat'sfine,
becausetheclassdoesn't
needspecialaccesstotheinstance
variables
ofthemain
GUI.
Butwhat
if
itdid?What
if
we'redoing
an
animationonthatpanel,andit'sgettingits
coordinatesfromthe
main
application(say,basedonsome-
thing
theuserdoeselsewhereintheGUI).Inthatcase,if
wemakethe
drawingpanelaninnerclass,the
drawing
panel
class
getstobe
a
subclassof]panel,whiletheouter
class
is
still
freetobe
a
subclassofsomethingelse.
HeadFirst:
Yes
I
see!
And
thedrawingpanelisn'treus-
able
enoughtobeaseparate
class
anyway,sincewhatit's
actually
painting
is
specifictothisone
GUI
application.
Innerobject:Yes!
You'vegotit!
HeadFirst:
Good.Thenwe
can
moveontothe
nature
of
the
relatirmshi/J
betweenyouandtheouterinstance.
Innerobject:
Whatisitwithyoupeople?Notenough
sordidgossip
in
a
serioustopicLikepolymorphism?
HeadFirst:
Hey,youhavenoideahowmuchthepublicis
willingto
payforsomegoodoldtabloid
dirt.
So,someone
createsyouandbecomesinstantlybondedtotheouter
object,isthatright?
Inner
object:
Yesthat'sright.
And
yes)somehave
comparedittoanarrangedmarriage.Wedon'thaveasay
inwhichobjectwe're
bondedto.
HeadFirst:
ALight,
I'll
gowiththemarriageanalogy.
Canyougela
divorce
andremarrysomething
else?
Innerobject:
No,it'sforlife.
getting
gui
HeadFirst:
Whoselife?Yours?Theouterobject?Both?
Innerobject:
Mine.
I
can'tbetiedtoanyotherouter
object.Myonlywayout
is
garbagecollection.
HeadFirst:
Whatabouttheouterobject?Canitbe
associated
with
anyotherinnerobjects?
Innerobject
Sonowwehave
it.
This
iswhatyou
really
wanted.Yes,yes.Myso-called'mate'canhaveasmany
innerobjectsasitwants.
HeadFirst:
Is
thatlike,serialmonogamy?Orcanithave
them
all
atthe
same
rime?
Innerobject:
All
atthesametime.There,Satisfied?
HeadFirst:
Well,
it
doesmakesense.Andlet'snOI
forget,it
wasyou
extollingthevirtuesof"multiple
implementationsofthesameinterface",Soitmakessense
that
if
theouter
class
hasthreebuttons,itwouldneed
threedifferentinner
classes
(and
thus
threedifferentinner
classobjects)tohandletheevents.
Thanks
foreverything.
Here's
a
tissue.
youare
here)
381
Innerclasses
Ushtgattitttterclassforatthttatiott
Wesaw
why
innerclassesarehandyforeventlisteners,because
you
gettoimplementthesameevent-handlingmethodmore
thanonce.Butnowwe'Ulookathow
useful
an
innerclassiswhen
used
asa
subclassofsomethingtheouterclassdoesn'textend.In
otherwords.whentheouterclass
and
innerclass
are
indifferent
inheritance
trees]
Ourgoal
is
tomake
a
simpleanimation,wherethecirclemoves
acrossthescreenfromthe
upperleftdowntothelower
right,
1.81'1
•
•
Howsimpleanimationworks
•Paintanobjectotaparticularxand
y
coordinate
q.fillOval(20,50,lOO,100);
~
t
2-0
piuls
+r-0I'tI
thelett,
c;o
ril(~ls ~r-0I'tI
the
top
•Repainttheobjectatadiffere'1!xand
y
coordinate
g.fillOval(25,55,lOO,lOO);
~
t2?
piuls
~rOl'tl
thelett,
97
piuls
kr-Of'Il
-the
iof
(theobjett""ovedalittle
dOWJl
a...
d
to
the
\"i~nt.>
•Repeatthepreviousstepwithchangingxand
y
values
foraslongastheanimationis
supposedto
continue.
382
chapter12
Q:
Whyarewelearningabout
animationhere11doubt
if
I'm
goingtobemakinggames.
A:voumightnotbemaking
games.
butyoumightbe
creatIngsimulations,where
thingschange
over
timetoshow
theresultsofaprocess.Oryou
mightbebuildingavisualization
toolthat,forexample,updates
agraphictoshowhowmuch
memoryaprogramisusing,
ortoshowyouhowmuch
trafflc
iscomingthrough
yourload-balancingserver.
Anythingthatneedstotakea
setofcontinuously-changing
numbersandtranslatethemInto
somethingusefulforgetting
Informatlonoutofthenumbers.
Doesn'tthatallsoundbusiness-
like?That'sJusttheMofficial
justlflcatlon:
of
course.Thereal
reasonwe'recoveringithereis
Justbecauseit'sasimpleway
todemonstrateanotheruse
ofInner
classes.(Andbecause
weJust
like
animation,andour
nextHeadFirstbookIsabout
J2EE
andwe
know
wecan'tget
animationinthatone.)
gettinggui
MyDrawPanelextendsJPanel{
publicvoidpaintcomponent(Graphicsg){
g.setColor(Color.orange);
g.fillOval(x,y/100,lOO)i
~
eaL\I
b",e
Y'II"~&:~a'I~t.
il
t,d\\ecl.-\:)Ie
O"Iil
~
d\~~er",t.\~
w\
we!eallywantissomethinglike...
t
ss
/
~
your
penCil
Butwheredowegetthenewxand
y
coordinates?
And
whocallsrepaint()?
See
if
youcan
design
a
simplesolution
to
gettheballtoanimatefromthetopleftofthe
drawingpaneldowntothe
bottomrightOuranswerIsonthenextpage,sodon'ttum
thispageuntilyou'redone!
BigHugeHintmakethedrawingpanelaninnerclass.
AnotherHint
don't
putanykind
of
repeatloopInthepalntComponentOmethod.
WriteyourIdeas(orthecode)here:
youare
here
~
383
importjavax.swing.*;
importjava.awt.*;
animationusinganinnerclass
~
completesimpleanimationcode
\)
publicolassSimplQAnimation
~ ~yo,U
IIOtiab\es,,,
t,hL
",a\c.L
t.'WC
,YIS
~
t,hL""
d"d
'I
intx
=
70
it
~
",d'l'I
~V.\
daS1.
(/f"
l.i'f'Ck
tnt
y
:II
70;
~ ~d"~ ~
t.ht.
publicstaticvoid
main
(Strinq[]
arqa)(
SimpleAnimation
qu.i
=
newSi.mpleAnimation();
qui
.go();
publicvoid
go()(
JFramaframe'"
MlW
JFrame();
lrame.setDefaultCloa8Operat!on(JFrama.EXIT_ON_CLOSE)i
MyDrawPaneldrawPanel
=
new
MyDrawPanel();
traMa.qetcontentpane().add(drawPanel);
frame.setSize(300,300);
frame.setVis~le(true);
for
(int
1-0;
i
<130;
i++){
}
}/I
close
got)method
class
MyDrawpanel
extendsJPanel(
publicvoidpaintcomponent(Graphicsg)
I
g.setcolor(Color.qreen);
q.filIOval(x,y,40,40);
II
closeinnerclass
II
closeouterclass
384
chapter12
u~.
Itdidn'tmove•••it
smeared.
What
di'~e.
dowrong?
There'sonel
ittleflawinthepaintComponentO
method.
Weforgottoerasewhatwas
alreadythere!Sowegottrails.
Tofixit,allwehavetodoisfillintheentirepanelwith
thebackgroundcolor,beforepaintingthecircle
each
time.Thecodebelowaddstwolinesatthestartofthe
method:onetosetthecolortowhite(thebackground
colorof
thedrawingpanel)andtheothertofillthe
entirepanelrectanglewiththatcolor.InEnglish,
the
codebelowsays,
"Fill
arectanglestartingat
x
andyof
0(0
pixelsfrom
the
leftand
0
pixelsfromthetop)and
makeit
as
wideand
as
high
as
thepanel
is
currently.
ee
6"---
-1
1--
geWnggui
publiovoidpaintComponent(Graphics
q)(
g.setColor(Color.white);
g.fillRect(0,0,this.qatWidth
0,
this.qetHeigbtO);
q.aetColor(Color.qreen);
~
1l
g.
fUIOva.l
(x,
y,
40,40);
~etw;dt.h()
ar,d
9dl+ti
~t()
~
"'tthod$
il'lhtyoiUdr
~
drt
i"l-0I0I
JP
a
l'ItI.
~
IJ:
'Sharpen
yu
peooIloptional.just
forfunl
Whatchangeswouldyoumaketothexandycoordinatestoproducetheanimationsbelow?
(assumethefirstoneexamplemovesin3
pixel
Increments)
l[]Q
x
+3
v--±L
x
y--
2[][3
startfinish
'DD
'DO
startfin
ish
'DD
start
start
finish
finish
x
y--
x
v
__
start
start
finish
finish
x
y--
x
y--
youarehere
~
385
Code
Kit~en
beat
tow...
§.~--- --1
...
•
160B
let's
make
amusicvideo.We'lluseJava-generatedranJom
graphics
that
keep
time
withthemusicbeats.
Along
tbe
way
we'llregister(andlisten
lor)
anewlund
ol
non-GUIevent,triggered
by
themusic
itseLt.
Reme>r>be-,
this
paH:
is,)11
orti-al.
Bl>t
we
thirJc.i-t's500<.\
.fot'
yo....
And
yo~,.'11
likt
it.
And
y~
tdn
~
it
to
i""f'YW
ftoplt.
(Ole,
Slol't,
it
mi5htwot'kcw.1'I
Of>
ptoplt
who
.ll'e
I'tallytasy
to
i"'fl"~
bllt
still...)
186
chapter12
OK,maybenotamusicvideo,butwe
wiU
make
a
programthatdrawsrandomgraphicsonthe
screenwiththebeatofthemusic.Inanutshell,
theprogramlistensforthebeatofthemusic
anddrawsarandomgraphicrectanglewitheach
beat.
Thatbringsupsomenewissuesforus.Sofar,
we'velistenedforonlyGUIevents,
butnow
we
needtolistenforaparticularkindofMIDI
event.Turnsout,listeningforanon-GUIeventis
justlikelisteningforGUIevents:youimplement
alistenerinterface,registerthelistenerwithan
eventsource,thensitbackandwaitfortheevent
sourcetocall
yourevent-handlermethod(the
methoddefinedinthelistenerinterface).
Thesimplestwaytolistenforthebeatofthe
musicwouldbetoregisterandlistenforthe
actualMIDIevents,sothatwheneverthe
sequencergetstheevent,ourcodewillgetit
too
andcandrawthegraphic.But...there'sa
problem.A
bug,actually,thatwon'tletuslisten
fortheMIDIevents
we're
making(theonesfor
NOTEON).
Sowehavetodoalittlework-around.
There
isanothertjpeofMIDIeventwecanlisten
for,calledaControllerEvent.
Oursolution
istoregister
forControllerEvents,andthen
makesurethatforeveryNOTEONevent,
there'samatchingControllerEventfiredat
thesame'beat'.Howdowemakesurethe
ControllerEventisfiredatthesametime?We
add
it
tothetrackjustliketheotherevents!In
otherwords,ourmusicsequencegoeslikethis:
BEATI-NOTEON,CONTROLLEREVENT
BEAT2-NOTEOFF
BEAT3-
NOTEON,CONTROLLEREVENT
BEAT4-NOTEOFF
andsoon.
Beforewedive
intothefullprogram,though,
let'smakeitalittleeasiertomakeandaddMIDI
messages/eventssincein
this
program,we're
gonnamakealotofthem.
gettinggu
Whatthemusicartprogram
needstodo:
•MakeaseriesofMIDImessages/
eventstoplayrandomnotesonapiano
(orwhateverinstrumentyouchoose)
•Registeralistener
fortheevents
•
Startthesequencerplaying
•Eachtime
thelistener'sevent
handlermethodiscalled,drawa
randomrectangleon
thedrawing
panel,andcallrepaint.
We'llbuilditinthreeiterations:
•VersionOne:Codethatsimplifiesmak-
ingandadding
MIDIevents,sincewe'll
bemakinga
lotofthem.
•VersionTwo:Registerandlisten
for
theevents,butwithoutgraphics.
Printsa
messageatthecommand-line
witheachbeat.
•VersionThree:Therealdeal.Adds
graphics
toversiontwo.
youarehere
~
387
Util~
methodforevenls
/
At'
easierwayto'Make
'Messages/eVet1ts
Rightnow,makingandaddingmessagesand
eventstoatrackistedious.Foreachmessage,
wehavetomakethemessageinstance(inthis
case,ShortMessage),
call
setMessageO,makea
MidiEventfor
themessage,andaddtheevent
to
thetrack.
In
lastchapter'scode,wewent
througheachstepforeverymessage.That
meanseightlinesofcodejusttomakeanote
play
andthenstopplayinglFourlinestoadda
NOTEONevent,andfourlinestoaddaNOTE
OFFevenl
ShortM8ssagea
=
newShortMessage();
a.setNessage(144,1,note,100);
MidiEvent
noteOn::newMidiEvant(a,
1);
track.
add
(noteOn);
ShortM8ssaqab
=
newShortMessage();
b.setMessagB(128,1,note,100);
MidiEventnoteOff
=
newMid..iEvent(b,
16);
track.add(noteOff);
Thingsthathavetohappenfor
eachevent:
..Makeamessageinstance
ShortMsssageDrst::newSbortHessage();
•Call
setMessogeO
with
the
instructions
first.setMessage
(192,1,
instrument,
0)
(I
MakeaMidiEventinstance
forthemessage
MidiEvent
noteOn'"
newMidiEvent(first,
1);
•Add
the
eventtothetrack
track.add(noteOn);
Let'sbuild
a
staticutilitymethodthat
makesamessageandreturnsaMidlEvent
try(
ShortMessllgBa'"newShortMess&ge()
J'
a.setMessag8(Comd,
chan,
one,two);
event
=
newMidiEvent(a,
ticJc);
public:staticMidiEvantmakeEvent(intcomd,int
chan,
intone,inttwo,
int
tick)(
MidiEventevent
=
null;
}catch(Exceptione){}
returnevent;LLL
L
{a
H ·di~'w
..
t
all
~
yn"Yl'I
"{;Ilt
tVeT\"{;
I~I\
loaded
lI.y
'With
t.ht...
ess.a~()
388
chapter12
publicclassMiniMUsicPlayer1{
II
endloop
track.add(makeEvent(144,1,i,100,i»;
track.add(makeEvent(128,1,i,lOO,i
+
2»;
gettinggui
Exatttple:howtousethenewstatic
I\takeEvet1tOtttethod
There'snoeventhandlingorgraphicshere,justasequenceof15
notesthatgoupthescale.Thepointofthiscodeissimplytolearn
howtouseournewmakeEventOmethod.Thecodeforthenext
twoversionsismuchsmallerandsimplerthankstothismethod.
importjavax.sound.midi.
*;
~
dOh
it
tot-et
!Jthei"'pot-t
publicstaticvoidmain(String[]args){
try
)a
st,~t"t~
Sequencersequencer
=
MidiSys
tem.
getsequencer
0;"-
av.t
(a"deyt"
L'"
sequencer.open();
~
Sequenceseq
=
newSequence(Sequence.PPQ,4);
+-...
akea
se,\~nte
Tracktrack
=
seq.createTrackO;
~
andahatk
for(inti
=
5;i
<
61;
i+=
4)
{~
...
ake
a
b~nth
0+
events
to...
ske
thenoteskeel'
~oin~ ~l'(~YOftl
l'ianonote.;
to
l'ianonote
bD
tall
~r
hewrr.akeEventO"'ethod
to
k
rr.essa~e
ahd
eventth",a
e
the
MidiCveht
rd;~rh:d
/1'1
add
thereslA/t(the
thetratk
Th
i,0rr.rr.akeEvehtW
to
NOTE.
ese
are
,.OTEON
att)
sequencer.setSequence(seq);
~
ta.
OFF
a
29)
pairsahd
sequencer.setTempolnBPM(220);s
rf.
It
r.....
hih!J
sequencer.start();
}catch(Exceptionex)(ex.printStackTrace();}
II
closemain
publicstaticMidiEventmakeEvent(intcomd,intchan,intone,inttwo,inttick){
MidiEventevent
=
null;
try{
ShortMessagea
=
newShortMessage();
a.setMessage(comd,chan,one,two);
event
=
newMidiEvent(a,tick);
}catch(Exceptione){}
returnevent;
}II
closeclass
youarehere
~
389
controllerevents
import
javax.sound.Ulidi.
*;
publicclassMiniMuaicPlayer2
publicstaticvoidmain(String[]args)(
~n£MusicPlayer2
mini:newMiniMusicPlayar2();
mini-goO;
Sequenceseq
=
newSequence(Sequence.PPQ,4);
Tracktrack
=
s&q.createTrack();
sequencer.setsequence(seq);
sequencer.setTempoInBPM(220};
sequencer.start();
}catch
(Exception
ax)
II
close
(~ -I:h~
CO'I'tr
ol1ty
-
L-
T'nL
~"ty\t
ha"cilty
"'~ ~c:
t.,i...
e
'fo/t.
~d ~e
~
.l\"
l_
i,,~-tat~.
1
I"r.(..
~..,e""
'S""'∙.
t.
KIl
to
the
tD",,,,a,,a-,
e..,e"t"
'/ole'n
F'"
publicMidiEventmakeEvent(int
cOJDd,
int
chan,
intone,
int
two,int
tick)(
MidiEventevent..null;
try(
ShortMassagea
~
newShortNessage():
a.
BetM&ssage
(comd,chan,on8,two);
evant
=
newMicli.Event(a,
tick);
I
catch
(Exceptione)
I}
returnevent:
}
I
II
close
class
390
chapter12
Codethat'sdifferentfromtheprevious
version
ishighlightedingray.
(andwe're
notrunningitallwithinmainO
thistime)
gettinggui
Version
Ihree:
drawinggraphicsinthttewiththetltusic
ThisfinalversionbuildsonversiontwobyaddingtheGUIparts.Webuilda
frame,
addadrawingpaneltoit,andeachtimewegetanevent,wedrawa
newrectangle
andrepaintthescreen.Theonlyotherchangefromversion
twois
thatthenotesplayrandomlyasopposedtosimplymovingupthe
scale.
Themostimportantchangetothecode(besidesbuildingasimpleGUI)
is
thatwemakethedrawingpanelimplementtheControllerEventListener
ratherthantheprogramitself.Sowhenthedrawingpanel(aninnerclass)
gets
theevent,itknowshowtotakecareofitselfbydrawingtherectangle.
Completecodeforthisversionisonthenextpage.
Thedrawingpanelinnerclass:
I'
alist.eYltV'
C
Tht
clV'a..,iYl~
ya
Ylt
's
classMyDrawPanelextendsJPanelimplementsControllerEventListener
booleanmsg
=
false;
t--
r'~
Lsd:a
.fla~
to
.faist,
a",d
..,~'"
Sttit
W
1;1"\Ot
OI'Ilywht'"
Wt
g~t
a",
~ve",t.
publicvoidcontrolChange(ShortMessageevent)(
msg
=
true;
f..--..
repaint();
r-
W
e
~ot
a",
~vtnt,
so
w~
set
the.flag
to
tl"\Otand
tall
l"~pai"'tO
publicvoidpaintComponent{Graphicsg){
if(msg)
(~
W
e
hav~
to
l.lS~
a
.fla~ b~tal.lS~
OT»ER
th∙
a",d
w~
want
to
Dai",i
ONL\/
hLh
Iln~sCllli~~~ t\"i~~~\"
a
\"tpainiO,
r
T
wtn
1;
ere
S
a
OI'IvolJt\"Evtnt
Graphics2Dg2
=
(Graphics2D)g;
intr
=
(int)(Math.random{)
*
250);
intgr
=
(int)(Math.random()
*
250);
intb
=
(int)(Math.random()
*
250);
g.setColor(newColor(r,gr,b»;
ThtI"estis
tod~
to
~t"'t\"aie
a
\"andOlll
tolO\"
andpaint
a
Stllli-\"andolll
\"tttan~lt.
intht
=
(int)«Math.random()
*
120)
+
10);
intwidth
=
(int)«Math.randomO
*
120)
+
10);
intx
=
(int)«Math.random()
*
40)
+
10);
inty
=
(int)({Math.random()
*
40)
+
10);
g.fillRect(x,y,ht,width);
msg
=
false;
}II
closeif
}II
closemethod
II
closeinnerclass
youarehere
~
391
MiniMusicPlayer3code
importjavax.sound.midi.*;
importjava.io.*;
importjavax.swing.*;
importjava.awt.*;
publicclassMin1MusicPlayer3
~}V~
ThisisthecompletecodelistingforVersion
Three.
It
buildsdirectoyonVersionTwo.Try
toannotateityourself,withoutlooking
atthe
previouspages.
staticJFramef=new
JFrame(~My
FirstMusicVideo");
staticMyDrawPanelml;
publicstaticvoidmain(String[]args)(
Min1MusicPlayer3mini=newMin1MusicPlayer3();
mini.goO;
)//closemethod
publicvoidsetUpGuiO(
ml=new
MyDrawPanel();
f.setContentPane(ml);
f
.setBounds(30,30,300,300);
f.setVisible(true);
//closemethod
publicvoid
qo()
setUpGui();
try{
Sequencersequencer=MidiSystem.getSequencer();
sequencer.open();
sequencer.addControllerEventListener(ml,newint[]{127»;
Sequenceseq=newSequence(Sequence.PPQ,4);
Tracktrack=seq.createTrack();
intr=0;
for(inti=0;i
<
60;i+=4)
r=
(int)«Math.random()*50)+1);
track.add(makeEvent(144,1,r,100,i»;
track.add(makeEvent(176,1,127,0,i»;
track.add(makeEvent(128,1,r,100,i+2»;
II
endloop
sequencer.setSequence(seq);
sequencer.start();
sequencer.setTempoInBPM(120);
}catch(Exceptionex){ex.printStackTrace();}
//closemethod
392chapter
12
exercise:WhoAmI
Who
am
IP
AbunchofJavahot-shots,infullcostume,areplayIngthepartygame-Who
amIrTheygiveyouaclue,andyou
try
toguesswhotheyare,basedon
whattheysay.Assumetheyalwaystellthetruthaboutthemselves.Ifthey
happentosaysomethingthatcouldbetrueformorethanoneguy,then
writedownall
ios
whomthatsentenceapplies.FillIntheblanksnexttothe
sentencewiththenames
of
one
or
moreattendees.
Tonight's
attendees:
Anyofthecharmingpersonalitiesfromthischapterjust
mightshowupl
IgotthewholeGUI,Inmyhands.
Everyeventtypehasoneofthese.
The
listener'skeymethod.
ThismethodgivesJFrameitssize.
You
addcode
to
thismethodbutnevercallIt.
When
theuseractuallydoessomething,It'san__.
Mostoftheseareeventsources.
Icarrydatabacktothelistener.
AnaddXxxLlstener()methodsaysanobjectisan__.
Howalistenersignsup.
The
methodwhereallthegraphicscodegoes.
I'mtypicallyboundtoanInstance.
The'g'In(Graphicsg),Isreallyofclass.
ThemethodthatgetspalntComponent()roiling.
The
packagewheremostoftheSwingersreside.
394
chapter12
importjavax.swing.*j
importjava.awt.event.*;
importjava.awt.*;
classInnerButton
JFrameframe;
Jauttonbi
publicstaticvoidmain(String
II
args)
InnerButtanqui
=
newInnerButton();
guL
go();
}
publicvoidgal){
frame
=
newJFrame();
frame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
b=newJButton(UA
n
);
b.addActionListener()j
frame.getContentPane().add(
BorderLayout.SOUTH,b);
frame.setSize(200,lOO);
frame.setVisible(true)i
}
classBListenerextendsActionListener{
publicvoidactionPerformed(ActionEvent
e){
if(b.getText().equals(MAn»{
b.setText(uBn);
}else{
b.
setText(UA
to)
i
}
gettingQui
BE
the
eomriler
The
Java
nle
on
this
pagerepresentsa
completesourcet\le.Yourjah
is
to
play
compiler
and
detertrtinewhether
this
file
will
cOl1Ipile.
If
it
won't
co11IPile,haw
wouldyout'xx
it,
and
if
it
does
compile,
what
would
it
do?
youarehere
~
395
public
static
void
main(String
[I
args)
InnerButtonqui
~
newInnerButton():
qui-go(
I:
WhoamI?
Igot
the
wholeGUI.
in
my
hands.
JFrame
Every
event
typehas
oneofthese.
listenerinterface
Thelistener'skeymethod.
actionPerlormed()
ThismethodgivesJFrame
its
size.
setSize()
You
addcodetothismethod
but
nevercallit.
paintCompone.nt()
importjavax.swing.*;
import
java.awt.event.*;
importjava.awt.*
J
classInnerButton
JFrameframe;
JButtonb;
getting
gui
Oncethiscode
isfixed,
itwill
createa
GUI
with
abuttonthat
togglesbetween
A
and
Bwhen
you
click
it.
Whentheuseractuallydoes
something,
it'san__
event
Mostoftheseareeventsources.
swingcomponents
I
carrydata
back
tothelistener;
eventobject
AnaddXxxListener()method
says
an
object
is
an_
eventsource
Howalistenersignsup.
addActionListe.ner()
Themethodwhere
all
the
graphicscodegoes.
paintComponent()
publicvoid
go(l{
frame
=
newJFrame();
frame.setDefaultCloseOperation(
JPrame.
EXIT_ON_CLOSE);
TheaddActionListener()
methodtakesaclass
that
implementsthe
Actionl.is-
tenerinterface
b
=
newJButton("A")j
b.addActionLiBtener(
lIiW
JLlstettar(I)
l
I'm
typically
bound
toaninstance.
innerclass
ActionListeneris
an
interface.interlaces
are
implemented,
not
extended
The
's'
in
(Graphicsg).
is
reallyofthisclass.
Themethodthatgets
paintCornponent()rolling.
Thepackagewheremost
ofthe
Swingers
reside.
Graphics2d
repaint()
javax.swing
frame.getContentPane().add(
BorderLayout.SOOTB,
bl;
frame.setSize(200,lOO)l
frame.setVisible(true);
classBListener
hllpltJll8l1t1
ActionListener{
publicvoidactionPerformed(ActionEventel
if
(b.getText().equals(UA"ll{
b.BBtText
(»B'"):
else{
b.setText
(»A"
Ii
youare
here.
397
puzzleanswers
TheAmazing.Shrinking,
Blue
Recta
ngle.
398
chapter12
pool
puzzle
importjavax.swing.*;
importjava.awt.*;
publicclassAnimate{
int
x
=
1;
int
y:
1;
publicstaticvoidmain(String[]args){
Animategui
=
newAnimate();
guLgo();
pUblic
voidgo()
JFrarne
frame
newJFrame(
1
j
frarne.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE)j
MyDrawPdrawP
=
newMyDrawPOi
frame.getcontentPane().add(drawP)j
f
rame.setSize(500,270);
frame.setViaible(true);
for(int
i
=
0;
i
<
124;
i-X++,Y++){
x-;
drawP
.repai
ntO;
try{
Thread.sleep(50);
}catch(Exceptionex){}
}
classMyDrawPextendsJPanel{
public
void
paintComponent(Graphics
9
1{
g.setColor(Color.white);
g.fiIIRect(O,0,500,250);
g.setColor(Color.blue);
g.
filJRect(x
,y
,500-x∙
2
,250-y""2);
}
13
usingswing
WorkonYour
Swing
Swingiseasy.
Unlessyouactually
care
wherethingsenduponthescreen.Swingcode
looks
easy,butthenyoucompileit,run
it,
lookatitandthink-
'h~y,
that's
notsupposedtogo
there."
Thethingthatmakesit
easy
to
code
IsthethingthatmakesIt
hard
to
canuo/-the
layoutManager.
LayoutManagerobjectscontrolthesizeandlocationofthewidgetsina
Java
GUJ.Theydoatonofworkonyourbehalf,butyouwon'talwaysliketheresults.Youwant
twobuttonsto
be
thesamesize,buttheyaren't.Youwantthetextfieldtobethreeincheslong,
butIt'snine.Orone.And
under
thelabel
instead
of
next
toIt.Butwithatittlework,youcanget
layoutmanagerstosubmittoyourwill.Inthischapter,we'llworkonourSwingandinaddition
tolayoutmanagers,we'lllearnmoreaboutwIdgets.We'llmakethem,display
them(where
we
choose),andusethem
In
aprogram.It'snotlooking
100
goodforSuzy.
thisisa
newchapter
399
componentsandcontainers
Camponent
isthemorecorrecttermforwhatwe'vebeencallinga
widget.
The
things
youputinaCUI.
Thethingsauserseesandinteracts
with.
Text
fields,buttons,scrollable
lists,
radiobuttons,etc.are
all
components.In
fact,they
all
extend
javax.swing.JComponent.
COlMpo.,etdscanbenested
InSwing,virtually
all
componentsarecapableofholdingother
components.Inotherwords,
youcansiUkjustaboutanythingintoanything
else.
Butmostofthetime,you'lladd
userinteractive
componentssuchas
buttonsandlistsinto
background
componentssuchasframesandpanels.
Althoughit's
possible
toput,say,apanelinsideabutton,that'spretty
weird,
andwon'twinyouanyusabilityawards.
With
theexceptionofJFrame,though,thedistinctionbetween
interactive
componentsand
ba.ckground
componentsisartificial.AJPanel.for
example,
is
usuallyusedasabackgroundforgroupingothercomponents,
butevenaJPanelcanbeinteractive.Justaswithothercomponents,you
canregisterfortheJPanel'seventsincludingmouseclicksandkeystrokes.
Awidget
is
teduucal.l
y
a
Swing
Com~ent._
Almost
every
thing
you
can
stick
in
a
GUI
extends!rom
javaLSWing.JComponent.
FourstepstomakingaGUI(review)
•Makeawindow(eJFrame)
JFrameframa""n_JFrame();
•Makeacomponent(button,
text
field,erc.)
JButtonbutton-ne.JButton("clickme
U
);
•Addthecomponenttotheframe
frame.getContantPane().
add
(BordarLayout.EAST•button);
•Display
it
(give
it
asizeandmakeitvisible)
frame.setsize(300,300);
frame.setVisible(true)i
Putinteractivecomponents:
Into
backgroundcomponents:
J?al\t\
....
o ~
400chapler13
usingswing
PanelA
AlayoutmanagerisaJavaobjectassociated
with
aparticularcomponent,almost
always
a
background
component,Thelayoutmanager
controlsthecomponentscontained
within
the
componentthelayoutmanagerisassociated
with,
Inotherwords,
if
aframeholdsapanel,
andthepanelholdsabutton,thepanel'slayout
managercontrols
thesizeandplacementof
the
button,whiletheframe'slayoutmanager
controlsthesizeandplacement
of
the
_IIIIII!IIII!!!II------~~,
panel.Thebutton.ontheotherhand.
doesn'tneedalayoutmanagerbecausethe
buttonisn'tholdingothercomponents.
If
apanelholdsfivethings.even
if
those
five
thingseachhavetheirownlayout
managers,
thesizeandlocationofthefive
things
inthepanelare
all
controlledbythe
panel'slayoutmanager.
If
thosefivethings,
in
tum,hold
other
things,theathose
other
thingsareplacedaccordingtothelayout
managerofthethingholdingthem.
Whenwesay
hold
wereallymean
add
asin,a
oanel
holds
abuttonbecausethebutton
was
added
tothepanelusingsomethinglike:
~Panel.add(button);
Layoutmanagerscomeinseveralflavors,and
eachbackgroundcomponentcanhaveitsown
yout
manager.Layoutmanagershavetheir
wn
policiestofollowwhenbuildinga
layout,
Forexample,onelayoutmanagermightinsist
that
all
componentsinapanelmustbethesame
size,
arrangedin
a
grid,
whileanotherlayout
managermightleteach
componentchoose
its
ownsize,but
Slack
themvertically.Here'san
example
ofnestedlayouts:
JPanelpanelA
=
newJPanel();
JPanelpanelB
=
newJPanel();
panelB.add(newJButton("button1"»;
panelB.add(newJButton("button2");
panelB.add(newJButton("button3"));
panelA.add(panelB);
Layout
Mahagers
you
are
here•401
layout
managers
How
does
thelayouttttat1ager
decide?
Differentlayoutmanagershavedifferentpoliciesforarranging
components(like,arrangeinagrid.makethem
all
thesamesize,
stack
themvertically,etc.)butthecomponentsbeinglayedoutdo
getatleast
some
smallsayinthematter.Ingeneral,theprocessof
layingoutabackgroundcomponentlookssomethinglikethis:
@)
Addthepaneltoaframe.
@
Theframe'slayoutmanagerasksthepanelhowbigthepanel
preferstobe.
@
Thepanel'slayoutmonagerusesitslayoutpoliciestodecide
whether
it
shouldrespectall,part,ornoneofthebuttons'
preferences.
o
o
Let'sseehere...the
firstbuttonwantstobe
30pixelswide,and
thetextfield
needs50,and
theframeis200pixels
wideandI'msupposedtoarrange
everythingvertically...
<D
Makeapanelandaddthreebuttonstoit.
@
Thepanel'slayoutmanageraskseachbutton-howbig
thatbuttonpreferstobe,
Alayoutscenario:
@
Theframe'slayoutmanagerusesitslayoutpoliciestodecide
whetheritshould
respectall,part,ornoneofthepanel's
preferences.
VlffereMt
layout
IMattagershavedlfferettfpolicies
Somelayoutmanagersrespectthesizethecomponent
wants
to
be.
If
thebuttonwantstobe30pixelsby50pixels,that'swhatthe
layout
managerallocatesforthatbutton,Otherlayout
managers
respectonlypartofthecomponent'spreferredsize.
If
thebutton
wantstobe30pixelsby50pixels,it'llbe30pixelsbyhowever
wide
thebutton'sbackground
panel
is,Stillotherlayoutmanagers
respectthe
preferenceofonlythe
largest
ofthecomponents
beinglayedout,andtherestofthecomponentsinthatpanel
areall
madethatsamesize.
In
somecases,theworkofthelayout
managercangetverycomplex,butmostofthetimeyoucan
figure
outwhatthelayoutmanagerwillprobablydo,onceyouget
toknowthatlayoutmanager'spolicies.
402
chapter
13
usingswing
Ihe
Jigfhreelayouttttat1agers:
border;
flo~
andbox.
-----
\-------
U
I
BorderLayout
ABorderLayoutmanagerdividesabackground
componentintofive
r~ions.
You
can
addonlyone
component
perregionto
a
backgroundcontrolled
byaBorderLayoutmanager.Componentslaid
out
by
thismanagerusuallydon'tgettohavetheir
preferredsize.
9orderlayoutIs
the
default
layout
II\Qna~
for
Q
fromel
FlowLayout
A
FlowLayoutmanageractskindoflikeaword
processor,
exceptwithcomponentsinsteadof
words.Eachcomponentis
thesizeitwantstobe,
and
they'relaidoutlefttorightintheorderthat
they'readded.with∙word-wrap"turnedon.So
whenacomponentwon't
tit
horizontally,itdrops
to
the
next
"line"inthelayout.
FlowLayout
Is
the
defaultlayout
mo~,.
fora
pone"
BoxLayout
ABoxLayoutmanagerislikeFlowLayoutinthat
eachcomponentgetstohaveitsownsize,and
thecomponentsareplacedintheorderinwhich
they'readded.But.unlikeFlowLayout.aBoxLayout
managercan
stackthecomponentsvertically
(or
horizontally,butusuallywe'rejustconcernedwith
vertically).
It'slikeaFlowLayoutbutinsteadof
havingautomatic'componentwrapping',youcan
insertaSortof'componentreturnkey'andforce
-
thecomponentstostartanewline.
[J
o
0..-.
1\
:§)
(~
0
youarehere)
403
borderlayout
r
BorderLayoutcares
aboutfiveregions:
east,west,north,
south,andcenter
\---------
u
Let'saddabuttontothe!!!!region:
importjavax.swing.
*;
t'.
\Alld.a...,t
y.)t\(a¥
importjava.an.
*;
~
BcKdlYLa'fOlO
I'In.r
publicclassButtonl
publicstaticvoid
ma.in
(Strinq[l
argos)
I
Buttonl
qui
=
newButtonl()
i
qui-goO;
publicvoidgo()(.
~
\}If.
'"t.~iO"
JFrameframe
=
newJFrame();
SVf.C,I
'f
JButtonbutton
=
newJButton("cliclcme");('
frame.qetContentpane().lldd(BorderLayout.EAST
I
button)
i
frame.Betsi~e(200/200);
frame.setVisible(true);
~
'f.tttII'.J.':V
IraillBarllell----------,
HowdidtheBorderLayoutmanagercomeupwith
thissizeforthebutton?
Whatarethefactorsthelayoutmanage.rhasto
consider?
Whyisn
't
it
widerortaller?
eee
-
-
clickme
I ~ -
1---
,j,
404
chapter13
Watchwhathappenswhenwegive
thebuttonmorecharacters•..
publicvoidgo()(
JFrameframe
=
newJFrame();
JButtonbutton
=
newJButton("c1icklikeyoumeanit");
!rame.getConcentPane().add(BorderLayout.EAST,button);
frame.setSize(200,200);
frame.setVisible(true);
usingswing
o
o
Sinceit'sinthe
east
regionofaborder
layout,
rll
respect
its
preferred
width.
But
r
don't
carehow
tallitwants
tobe:
it's
gannabeastallas
the
frame,
because
that'smypolicy.
eee
-a
--
,
.
clicklikeyoumeanII
r"
o
o
youarehere
~
405
border
layout
Let'stryabuttonintheNORTHregion
publicvoidgo()(
J~rame
frame
=
newJFrame();
.muttonbutton'"
new
.JButton("Thereisnospoon...");
frame.getCohtentPane().add(BorderLayouL.~,
button);
frame.setSize(200,200);
frame.setVisible(true);
Nowlet'smakethebuttonasktobe
~II!!,
Howdowedothat?Thebuttonisalreadyaswide
asit
canever
be-aswide
as
theframe.Butwe
can
try
tomakeittaller
by
giving
it
abiggerfont.
pub
Lfcvoid
go()(
~.\\~o'(t.~
t,\.e
JFrameframe
=
newJFrame();
'D\oll(
~O¥'\:.
'01'
.,.,.tJrl
$~al.t.
JButtonbutton
=
new.mutton("ClickThis!");
~
...
a"'t.
-to
a\\~ t.i,~ht..
FontbigFont
=
new
Font("serif",Font.BOLD,28);
~oY
t,'nt'D\lt.tor-
button.aetFont(bigFont);
frame.getContentPane().add(BorderLayout.NORTB,button);
frame.setSlze(200,200);
frame.setVisible(true);
406
chapter13
usingswing
Ithink
rm
getting
it...
if
rm
in
eesr
or
west,
I
get
my
preferredwidth
butthe
heightisupto
the
layout
manager.And
if
rm
in
north
or
south,
it's
just
the
opposite-Iget
my
preferredheight,but
notwidth,
But
wltsthappens
intltecenterregion?
Thecenterregiongetswhatever'sleftl
(exceptinonespecialcasewe'lllookatlater)
publicvoidgo()
JFrameframenewJFrame();
JButtoneastnewJButton("East");
JButtonwestnewJButton("West
H
);
JButtonnorth
=
newJButc:.on("North");
JButtonsouth
=
newJButton("South
H
);
JButtoncenter
=
newJButton("Center
H
);
frame.getContentPane().add(BorderLayout.&AST,east);
frarne.getContentPane().add(BorderLayout.WEST,west);
frame.getContentPane().add(BorderLayout.NORTH,north);
frame.gec:.ContentPane().add(BorderLayout.SOUTH,south);
frame.getContentPane().add(BorderLayout.CENTER,center);
~-----_J.
rue);
Le;ee
=-
;;;
;.;;;-d
;;;;.
(
North
!
~ei
r----
~
e-,
IO~
),
West
C~nl~r
£an
1\ti
width∙
aN:i
t.6.
{
South
~
frame.setsize(300,300);
frame.setVisible
(t
youarehere
~
407
flowlayout
FlowLayoutcares
abouttheflowofthe
-
components:
lefttoright,toptobottom,in
theordertheywereadded.
Let'saddapaneltotheeastregion:
AJPanel'slayoutmanagerisFJowLayout,bydefault.Wnenweadd
apaneltoaframe,
thesizeandplacementofthepanelisstill
undertheBorderLayoutmanager'scontrol.Butanytning
inside
the
panel
(inotherwords,componentsaddedtothepanel
by
calling
panel.add(aComponent»)
areunderthepanel'sFfowLayout
manager'scontrol.We'll
startbyputtinganemptypanelinthefl'"£lme's
eastregion,andonthenextpageswe'lladdthingstothepanel.
importjavax.8winq.*;
importjava.awt.∙;
publicclassPanel1
publiostaticvoid
main
(SuingIlllrgs)(
Panellqui:newPanel1();
qui.
go();
806
-
-
--
_
..
publicvoidgo()(
JFrameframe
:D
newJFrame();
~Milkt.
iht.
pilPlt.1
~yz
so
\lJt.
tar.
s
JPanelpanel
=
newJPanel();
Yih-.
'.1'.1\
ee
.....I"{;IS
0fI"Lllt.;}...
t.
panel.setBackqround(Color.d&rkGray)
i.
frame.getContantpane().add(BorderLayout.EAST,panel);
frams.setsize(200,200)i
frame.setVisible(true)
i
408
chapter13
publicvoidgo(){
Jframeframe
=
newJframe();
JPanelpanel
=
newJPanel();
panel.setBackground(Color.darkGray);
using
swing
Let'saddabuttontothepanel
th
aYlt:\aYld
add
-tht:
Add
t,hf
~
1:.0
eY
Cll'le\'
s
la'fOl>t
...ar.d~('f"
Cll'le\t.ot.'ne
~ya",e.-r-:~.!-
a
d
t.ht:
~ya",e)s
JButtonbutton'"newJButton("shock
me");
rHo...,)
l-Ot'Ihol
s
the
'0)"
hol
s
-I:'ne
yaYlel.
J
~
I
t.
n>d'l\d~t:Y
(bcordty
toOYl
panel.add{button);
~ ~ a~OI>
frame.getContentPane().add(BorderLayout.EA$T,panel);
frame.setSize(250,200);
frame.setVisible(true);
00
controls
Theframe's
8orderLayoutmanager
controls
~
The
panel's
FlowLayoutmanager
youarehere.
409
flowlayout
Whathappens
if
weaddTWObuttons
tothepanel?
publicvoidgo()
JFrameframenewJFrame();
JPanelpanelnewJPanel();
panel.setBackground(Color.darkGray);
-rw
D
'o...
\:;\:P...s
JButtonbutton
=
newJButton("shockme");
~
.,.jjy.e
JButtonbuttonTwo
=
newJButton("bliss");
V
panel.add(button);-'--
add
B
panel.add(buttonTwo);
~
OT»
to
thl!:
rand
frame.getContentPane().add(BorderLayout.EAST,panel);
frame.setSize(250,200);
frame.setVisible(true);
whatwe
wanted:
»
:uc
eee
~en
your
penCil
Ifthecodeaboveweremodifiedtothecodebelow,
what
wouldtheGUllooklike?
JButtonbutton
=
newJButton("shockme");
JButtonbuttonTwo
=
newJButton("bliss");
JButtonbuttonThree
=
newJButton("huh?H);
panel.add(button);
panel.add(buttonTwo);
panel.add(buttonThree);
410chapter
13
whatwegot:
.--=>
~L
__.•
Drawwhat
you
thinktheGUIwould
looklike
If
youran
thecode
to
theleft.
(Then
try
ltl)
usingswing
[J
o
o~
c=::fl
f-
0
BoxLayouttotherescue!
Itkeepscomponents
stacked,evenifthere'sroom
toputthemsidebyside.
UnlikeFlowLayout,BoxLayoutcanforcea
'newline'tomakethecomponentswrapto
thenextline,evenIfthere'sroomforthem
tofithorizontally.
Butnowyou'llhavetochangethepanel'slayoutmancgerfromthe
defaultFlowLayouttoBoxLayout.
panel);
JButtonbutton=-
new
JButton
("shock
me");
JauttonbuttonTwo
=
newJautt.on("bliss");
panel.add(button);
panel.add(buttonTwo);
frame.getContentPane().add(BorderLayout.EAST,
frame.setSize(250,200);
frame.setVisible(true);
publicvoidgot){
JFrameframe
=
newJFrame
(l;
...a,.a~C"
to
~
a
~
JPanelpanel
=
newJPanel();
C\\ae-t\oIe\a'fO'l"t.
t-
panel.setBackground(Color.
darkGr:~ iY\S~~
J
'rJo"..u~o~
panel.s8tLsyout(newBoxLayout(panel,BoxLayout.Y_AXIS»;
~T
n~ Bo~yovt
toMb-ill
k
-th~
to"'POhblt
if;s
I'
huds
to
know
.ihd
whilhd)(i!
to
tlY'F~
O\.lt
(i,~"B.~
pal'ltl)
vertildl
~lH ~
we
lASe
Y_AXI~ +~
a
eee
youarehere
~
411
layoutmanagers
Q:
Howcomeyoucan'tadddirectly
to
aframethe
way
youcantoapanel?
A:AJFrameIsspeciaIbecauseit'swheretherubber
meetstheroadInmakingsomethingappearon
thescreen.
Whllea
II
you
r
SWingcomponentsarepureJava,
a
JFrame
hastoconnecttotheunderlylngOSInordertoaccess
the
dlsplay.Thin
k
ofthecontentpaneasa
100%
pureJavalayer
thatsitson
top
oftheJFrame.Orthin
k
ofitasthoughJFrame
isthe
windowframeandthecontentpaneIsthe...glass.You
know,the
window
pane.
And
yo
u
ca
neven
swap
thecontent
panewith
yourownJPanel,tomakeyourJPaneltheframe's
contentpane,using,
myFrama.•etcontantpane(myPanel);
Q:canIchangethelayoutmanageroftheframe?
WhatIfIwant
theframetouseftowInsteadofborder1
A:TheeasiestwaytodothisIstomakeapanel,build
theGUIthewayyou
wantInthepanel,andthenmakethat
paneltheframe'scontentpaneusingthecodeIntheprevl-
ousanswer(ratherthanusingthedefaultcontentpane).
Q:WhatIfIwantadifferentpreferredsize?Istherea
setSlzeOmethodforcomponents1
A:Yes,thereIsasetSlzeO,butthelayoutmanagerswill
IgnoreIt.There'sadistinctionbetweenthe
preferredsize
of
thecomponentandthesize
you
wantIttobe.Thepreferred
sizeIsbasedonthesizethecomponentactually
needs
(thecomponentmakesthatdecisionforItself).Thelayout
managercallsthecomponent'sgetPreferredSlzeOmethod,
and
tho:
methoddoesn't
care
Ifyou've
prevlously
called
setSlzeOonthecomponent.
Q:can'tIJustputthingswhereIwantthem?canItum
thelayoutmanagersoff?
A:vep.onacomponentbycomponentbasis,youcancall
setLayout(null)andthenIt'suptoyouto
hard-code
theexactscreenlocationsanddimensions.Inthelongrun,
though,It'salmostalwayseasiertouselayoutmanagers.
412
chapter13
•Layoutmanagerscontrolthesizeandlocationof
componentsnestedwithinothercomponents.
•Whenyouaddacomponenttoanothercomponent
(sometimesreferred
10
asa
backgroundcornporent
butthat'snotatechnicaldistinction),theadded
componentiscontrolledbythelayoutmanagerofthe
background
componenl
•A
layoutmanageraskscomponents
for
their
preferredsize,beforemakingadecisionabout
thelayout.Dependingonthelayoutmanager's
policies,
it
mightrespectatl,some,ornoneofthe
component'swishes.
•TheBorderLayoutmanagerletsyouadda
component
to
oneoffiveregions.Youmustspecify
theregion
when
youaddthecomponent,usingthe
followingsyntax:
add(BorderLayout.EAST,panel);
•Wrth
Bordertayout,componentsinthenorthand
south
gettheirpreferred
heigh~
butnotwidth.
ComponentsIntheeastandwestgettheirpreferred
width,butnotheightThecomponentinthecenter
getswhateverisleffover(unlessyouuse
pack()).
•The
pack()
methodIslikeshrink-wrapforthe
components;
It
usesthefullpreferredsizeofthe
centercomponent,thendeterminesthesizeofthe
frameusingthecenterasastartingpoint,building
therestbasedonwhat'sintheotherregions.
•FlowLayoutplacescomponentslefttoright.top
to
bottom,Intheordertheywereadded,wrappingtoa
newlineofcomponentsonlywhenthecomponents
won'tfithorizontally.
•RowLayoutgivescomponentstheirpreferredsizein
bothdimensions.
•BoxLayoutletsyoualigncomponentsstacked
vertically,even
If
theycouldfitside-by-sida.Uke
FlowLayout.BoxLayoutusesthepreferredsizeof
thecomponentinbothdimensions.
•BorderLayoutisthedefaultlayoutmanagerfora
frame;FlowLayoutIsthedefaultforapanel.
•Ifyouwantapanel
to
usesomethingotherthanflow,
youhave
to
call
setLayout()
onthepanel.
using
swing
Playit1Q
withSwittgcolitpottettts
You'velearnedthebasicsoflayoutmanagers,sonowlet's
try
outa
few
ofthemostcommoncomponents:atextfield,scrollingtextarea,
checkbox,
andlist,Wewon'tshowyouthewhole
darn
APIforeachof
these,
justafewhighlightstogetyoustarted.
JTextFleld
.866
A
t
1.D
y∙rah.
W
t.o\l>JI'I~1
,,0.
dt'h
~
Constructors
~
W.
~af
ts
t'llt
Y"'e~tyYtd
'HI
It:
T'''~
(l.t'",,,
JText:F1&1dfield
%
n_JTex.tField(20);
~e ~.,rl ~'t\d.
J'TextFieldfield:
new
JTAXtFi8ld(~Your
nameff)i
HowtouseIt
•Gettextoutof
it
Systam.out.println(5eld.getTQXt());
•Puttextinit
field.1I8tText("whatever");
field.
lIetText("\\)
i\
~t.~\e\d
"--'This
t
e.lI's
•GetanActionEventwhentheuser
VOlA
l,dll
alSo
l'e~isk
.f
pressesreturnorenter
rtally
'N.1l'1t
iD
htar
a~t ~iY
evel'lh
it
yOlA
l/.1tt-
P'r't:~s
d
kty.
I
every
ti...
ethe
fiald.addActionLiataner(myActionListener)i
•Select/Highlightthe
text
inthefield
fiald.aelectAll();
•Putthecursorbackinthefield(sotheuser
can
juststarttyping)
field.requeatFocua();
you
arehere
~
413
HowtouseIt
•Make
it
haveaverticalscrollbaronly
textarea
JTextArea
UnlikeJTextField,JTextAreacanhavemorethanonelineoftext.
It
takes
Q
littleconfigurationtomakeone,becauseitdoesn'tcomeoutof
theboxwithscrollbarsorlinewrappi"9.
To
makeaJ'TextAr'e(]scroll,you
haveto
stickitinaScroliPane.AScroJiPaneis
an
objectthatr'e(]11yloves
toscroll.andwilltakecare
ofthetextereo'sscrolli"9needs.'-.
\o..\)
JeY't'c6
nC\~
10
\,~ (~the
Y'"
~~o.
Ifj'o..\;,\,,)
10
""tal'S
~
l'S
(~
-thC
yrt
Constructor
t
r
VJ
""ul'S
VJ
to......
JTaxtAreataxt
m
newJTaxtArea(lO,20);
6
',IJC
it
&c~
J~~o\\?a~
4".
~ ~ st;~o\\
dt'.
Mi~C
a
~t
It
~ ~,,~
~
U'llt
a
'ft.6
JSarollPaneIIc:roller-ne.JSc:rollPane(taxt);
Tell
thestrollpal\t
io,
text.lIetLineWrap(true);
~
T",,"II
01\
line
~affi~
f
a
~
st\"ollba\"
l&SC
Ofty
sc:roller.aetvertiea1Sc:rol1BarPolicy(ScrollPaneConlitants.VERTlCAL
SCROLLBAR
AL~
IIcroller.set8orizonta1Sc:rol1BarPolicy(Sc:rollPaneConatants.BORIZONTAL_SCROLLBAR_NEVER);
•Appendtothetextthat's
init
taxt.append("buttoncliaked
H
);
•Select/Highlightthe
text
in
thefield
taxt.lIelectAll();
•Putthecursorback
in
thefield
(so
theuser
canjuststarttyping)
text.requelltFocua();
414
chapter13
usingswing
JTextAreaexample
"eee
~
-
,.,
~ ~ cHcJced
.~
-cHcJced
but.
tonelleked
z:
-
0:-
~-~
1'=
-
:
r
JusttUck
It
~
JTextAreatext;
publicvoidgo()(
JFrameframe-newJFrame();
JPanelpanel
=
newJPanel();
JButtonbutton::;newJButton("JustClickIt");
button.addActionListener(this);
text::;newJTaxtArea(lO,20);
text.setLinewrap(true);
}
publicstaticvoidmain(String[]&rqs)
TextArealqui
c
newTextAreal();
qui
.go();
publicclassTaxtArealimplements
ActionL~staner
{
importjaYaX.swing.*;
importjava.art.*;
importjava.art.event.*;
JScrollPanescrollar
~
newJScrollPane{taxt);
scroller.setVerticalScrolLBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AL~YS);
scrollar.setBorizontalScrollBarPolicy(ScrollPaneConstants.80RIZONTAL_SCROLLBAR_NEVER);
panel.add(scroller);
frame.qetContentpane
(l.add
(BorderLayout.
CENTER,
panel);
frame.qetContentpane().add(BordarLayout.
SOO'TB,
button);
frame.setsize(350,300);
frame.setVisible(trlle);
publicvoidactionPerformed(ActionEventev)(
text.append("buttonclicked\n");
i
I~t
d
new
lihC:
$0
B.c:
w<J\-ds
stpd'ra~
line:
eatl
L'L\
b
S
~.o
0"
a
/
.k
I)
l;1",C:Ole:
~
.
e
It
ed.
Other-wi~
B.
'II
n
IS
I
ey
'rl/.n
-togetha-.
"""left
I.hcu"._u_
(H ~~t
..eh
'.....t...
(\1~'CJ"c tl d....-t
..(H
(ll....,..\O'Il"llc........
l_(h~ l
f ~ ~ l;~:=:;'~ U ~
....
t
..,t\I ~'_ [\l o........,c\t U.
.'toI\(a l c:\~ c- H ~ ~ teoI c.l t
.Ill"
c:1~tOO'l [ Hdl""'~
(ttf'\:
1( ~ -:;':~ =;l~;~:::::;1 ~
I
youarehere.
415
checkbox
JCheckBox
Constructor
JCheckBoxcheck
=
newJCheckBox("Goesto11");
HowtouseIt
•Listenforanitemevent(whenit'sselectedordeselected)
check.addltemListener(this);
..Handletheevent(andfindoutwhetherornotit'sselected)
publicvoiditemstateChanged(ItemEventev)
StringonOrOff
=
"off";
if(check.isSelected(»onOrOff
=
"on";
System.out.println("Checkboxis"
+
onOrOff);
.,Selectordeselectitincode
check.setSelected(true);
check.setSelected(false);
416chapter
13
O
th
e
re
1
atE}{l?"
UUlD
~uesti9ns
Q:
Aren'tthelayoutmanag-
ers
justmoretroublethanthey're
worth?IfIhavetogotoallthis
trouble,Imightaswell
justhard-
code
thesizeandcoordinatesfor
whereeverythingshouldgo.
A:
Gettingtheexactlayout
youwantfromalayoutman-
agercanbeachallenge.But
think
aboutwhatthelayoutmanager
isreallydoingforyou.Eventhe
seeminglysimpletaskoffiguring
outwherethingsshouldgoon
thescreencanbecomplex.For
example,thelayoutmanagertakes
careofkeepingyourcomponents
fromoverlappingoneanother.
Inotherwords,itknowshowto
managethespacingbetween
components(andbetweenthe
edgeoftheframe).Sureyoucan
do
thatyourself,butwhathappens
ifyouwantcomponentstobe
very
tightlypacked?Youmightget
themplacedjustright,byhand,
butthat'sonlygoodforyourJVM!
Why?
Becausethecomponents
canbeslightlydifferentfrom
platformtoplatform,especially
if
theyusetheunderlyingplatform's
native'lookandfee
1/,
Subtlethings
like
thebevelofthebuttonscan
bedifferentinsuchaway
that
componentsthatlineupneatly
ononeplatformsuddenlysquish
togetheronanother.
Andwe'restill
notatthereallyBig
Thingthatlayoutmanagersdo.
Thinkaboutwhathappenswhen
theuserresizesthewindow!Or
yourGUIisdynamic,wherecom-
ponentscomeandgo.Ifyouhad
tokeeptrackofre-Iayingoutall
thecomponentsevery
timethere's
achangeinthesizeorcontentsof
abackgroundcomponent...yikes!
using
swing
~List
Constructor
String[]H.atEntries
'"("a..lpha",
"beta",
\'ga:nmta",
"delta",
"apailon","zeta","eta
H
,
"theta
"I;
list.addListSelectionListenar(this);
list'"newJLlst(liatEntrie.);
HowtouseIt
•Makeithaveaverticalscrollbar
JSerollPaneacroller'"
new
JScrolIPane(liat);
scroller.setVerticalScrol~Poliey(ScroIIPaneConstanta.VERTlCAL_SCROLL8AR_ALMAYS);
acroller.setaorizontalScrollBarPolicy(ScrollPan8Constants.HORIZONTAL_SCROLLBAR_NEVER);
panel.add(acroller);
Setthenumberoflinestoshowbeforescrolling
liat.setVisibleRowCount(4);
•RestricttheusertoselectingonlyONEthingatatime
list.setselectionMode(ListSeleotioDModel.SrNGLE_SELECTION);
Registerforlistselectionevents
L
TWIC~
J
'10\>
ooY\'t.
y
~\\
¥*-
t.nee\la.'t.
•Handleevents(findoutwhichthinginthelistwas
selected~
/
fllt.
j"
this
i~
test.
publicvoidva.lueChanqed(ListselectionEventlse)
(E;".
if(
Ilse.getValueIsAdjullting())(
~
StringselecUon."(String)list.getSelectedValue
0;
~eiSdttudV~lueO
ad:.
I~
SysteJD.out.println
(lteleotion);
_1.
~"
rcwn.s
a"
Objett,
A
list
i
'f.
li...iud
to
OYII"
oL.•
b'
S:.
/
~U"'''5
0
:,)etu.
youarehere.
417
CodeKitchen
This
part's
optional
We're
~ing
thelull
BeatBox,
GUI
andallIn
the
SavingObjects
chapter,we'll
learn
how
to
saveandrestoredrum
patterns.
Finally
I
in
the
networlung
chapter
(Mak
aConnedionl,
we'U
turntheBeatBox
into
a
wor~ing
chat
client.
418
chapter13
Makit1QtheJeatJox
ThisisthefullcodelistingforthisversionoftheBeatBox,withbuttonsforstarting,
stopping,
andchangingthetempo.Thecodelistingiscomplete,andfully-
annotated,buthere'stheoverview:
usingswing
•
•
•
•
BuildaGUIthathas256checkboxes(JCheckBox)thatstartout
unchecked,16labels(JLabel)
fortheinstrumentnames,andfour
buttons.
RegisteranActionListener
foreachofthefourbuttons.Wedon't
needlisteners
fortheindividualcheckboxes,becausewearen't
tryingtochangethepatternsounddynamically(i.e.assoonasthe
userchecksabox).Instead,wewaituntiltheuserhitsthe'start'
button,andthenwalkthroughall256checkboxestogettheirstate
andmakeaMIDItrack.
Set-up
theMIDIsystem(you'vedonethisbefore)includinggetting
aSequencer,
makingaSequence,andcreatingatrack.Weareusing
asequencermethod
that'snewtoJava5.0,setLoopCount().This
methodallowsyoutospecify
howmanytimesyouwantasequence
to
loop.We'realsousingthesequence'stempofactortoadjustthe
tempoupordown,andmaintainthenewtempofromoneiterationof
thelooptothenext.
When
theuserhits'start',therealactionbegins.Theevent-handling
method
forthe'start'buttoncallsthebuildTrackAndStartOmethod.
Inthatmethod,wewalkthroughall256checkboxes(onerowat
atime,asingleinstrumentacrossall16beats)togettheirstate,
thenusetheinformationtobuildaMIDItrack(usingthehandy
makeEventOmethodweusedin
thepreviouschapter).Oncethetrack
isbuilt,westartthesequencer,whichkeepsplaying(becausewe're
loopingit)untiltheuserhits'stop'.
youarehere
~
419
BeatBoxcode
importjava.awt.*;
importjavax.swing.∙;
import
j
avax.sound.
midi..
*;
importjava.util.*;
importjava.awt.event.*;
publicelassBeatBox{
~
The'S(
dre
~e
I\d"'CS
~
the
i~""LlftIents,
dSa
Shi"
'"an-dY,
to'<"
bl.tildi"~
t.hcqUI
labels
(oneJth'row)
~
("BassDrum","ClosedHi-Bat",
Snare","Crash
Cymbal",
"BandClap",
"Maxacas","Whistle","LowConga",
"Low-midTom","High
Aqoqo",
JPanelmainPanel;
ArrayList<JChecltBox.>
Sequencersequencer;
Sequen~e
sequence;
Tracktrack;
JFrametheFrame;
String[]instrumentNames
=
"OpenHi-Hat","Acoustic
"H1ghTom","HiBongo",
"Cowbell","Vibraslap",
"0pQn
HiConga");
int[]instruments:(35,42,46,38,49,39,50,60,70,72,64,56,59,47,67,63);
publicstaticvoidmain(String[]args){
new
BestBox2().buildGUI
(J;
checkboxList::newArrayList<JCheckBox.>();
Box
buttonBox:newBox(BoxLayout.Y_AXIS);
JButtonstart
c
newJButton("Start");
start.addActionListener(newMyStartListener());
buttonBox.add(start);
JSuttonstop:newJButton("Stop");
stop.addActionListener(nawMyStopListaner(»;
buttonBox.add(stop);
JButtonupTempo:newJButton("TempoCpU);
upTempo.addActionListener(newMyUpTempoListener());
buttonBox,add(upTempo);
JSuttondownTempo::newJButton("TempoDown");
420
chapter
13
downTempo.
addActionListener
(n_MyDownTempoListener());
buttonBox.add(dovnTempo);
BoxnameBox
=
newBox(80xLayou
t.
Y
_AX!
S);
for(int
i
=
0;
i
<
16;
i++){
nameBox.add(new
Label
(i.nst..rumentNa.mes
[i]»;
using
swing
background.add(BorderLayout.EAST,
but
tonBox);
background.add(80rd.erLayout.
WEST,
namaBox);
theFrame.getcontentpane().add(background);
GridLayoutgrid
=
newGridLayout(16,16);
grid.setVgap
(1);
grid.setHqap
(2);
mainPanel
=
new
JPanel
(grid);
background.add(BorcierLayou
t.
CEN"l'ER,
mainPanel);
for(int
i
=
0;
i
<
256;
i++){
JCheckBoxc
=
new
JCheckBox();
c.setselected(false);
checkboxList.add(c);
mainPanel.add(c);
II
end
loop
setOpMidi();
theFrame.setBounds(50,50,300,300);
th9Frame.pac:k();
theFrama.setVisible(true);
II
elose
method
publicvoid••
t~~()
{
tz:y(
sequencer
=
MidiSystem..getsequencer();
sequencer.apan();
sequence
=
n_Sequence(Sequence.PPQ,4);
track
=
eequence.creat8Track();
sequencer.aetTampolnBPH(120);
}catah(Exceptione)(e.printStaakTrace();}
II
clos9method
youarehere•
421
BeatBox
code
sequence.deleteTrack(track);
track
=
sequence.createTrack();
for(int
i
=
0;
i
<
16;
i++)
trackList
=
newint[16];
intkey
=
instruments[i);
~
for(intj
=
0;j
<
16;j++){
~
Dothis
~OV"
eath
~
the
BE.ATS
~OV"
this
YOW
JCheckBoxjc
=
(JCheckBox)checkboxList.get(j+(16*i»;
if(jc.isSelected(»(
3
trackList[j)
=
key;
r
else{
Ist.hethetkbo"l.at.t.hisbeat.sdett.ed?
I~
yes,fIAt.
trackList[j)
=
0;
thekeyvall.leinthisslotinthe
ayyay
(theslotthat.
}
Ye~esents
thisbeaV.Otheywise,theinshWl'lentis
II
closeinnerloop
NOT
slAffosed
to
flayatthisbeat,sosetit.
to
Uyo∙
makeTracks(trackList);-,.-..::-----
roYthisi\'\StYWI'Ient.,and
~OV"
all
Ib
beats,
track.add(makeEvent(176,1,127,0,16));
",akeeve"tsandaddthe",
to
thehade
II
closeouter
~ Wealwayswant
to
",alceSlAyethatH,tye
IS
aneventat
track.add(makeEvent(192,9,1,0,15));
beat.
IE.
(it~oes
0
to
,'S).
OH,tywise,the'BeatHo"l.",i~ht
try(
not
~o
the
.flAil
I
b
beatsbe+oYeitstaYtsovty∙
sequencer.setSequence(sequence);
sequencer.setLoopCount(sequencer.LOOP_CONTINUOUSLY);
sequencer.start();
sequencer.setTempoInBPM(120);
}
catch(Exceptione){e.printStackTrace();}
II
closebuildTrackAndStartmethod
publicclass
~!iI ~ ~:£!DI ~ f M
implementsActionListener
publicvoidactionPerformed(ActionEventa)(
buildTrackAndStart();
}
II
closeinnerclass
422
chapter13
usingswing
publicclass
( mJ.H R a,~ g ~
implementsActionListener
publicvoidactionPerformed(ActionEventa)(
sequencer.stop();
}
II
closeinnerclass
publicclass
r ~ E t I t l =i!i i j ~j imp l em e n t s
ActionListener
publicvoidactionPerformed(ActionEventa)(
floattempoFactor
=
sequencer.getTempoFactor();
sequencer.setTempoFactor«float)(tempoFactor
*
1.03»;
}
II
closeinnerclass
ublicclass
"'"".c"'!.'T )::"* 9i':mr':~ ii l
implementsActionListener
p
:m %",~,'.w,~,.,."iI.,,,.,,,,,,,,.A'
publicvoidactionPerformed(ActionEventa)(
floattempoFactor
=
sequencer.getTempoFactor();
sequencer.setTempoFactor«float)(tempoFactor
*
.97»;
}
}II
closeinnerclass
Theothetoil'll'letodass
listel'letos
tOt"
thebl<ttol'lS
TheTeMpoFattotostales
these,\\I.f:\'\te\'"'steMPOby
the
tatkpY'o\fideGl.The
~
deta",ltis
J.O,
so
we'toe
adjlASti\'\5
+/-3'0
pe\'"
diek.
~
publicvoid llll l.l l ~(int[] list)
for(inti
=
0;i
<
16;
i++)(
intkey
=
list[i];
if
(key
!=
0){
track.add(makeEvent(144,9,key,100,
track.add(makeEvent(128,9,key,100,
~)
);L
Makethe
NOT~
ON
a\'\d
1+1»;)
NOT
oFF
e'le\'\ts.
a\'\d
addthew>
to
theT
\'"atk.
publicMidiEvent
~~,ij ( i n t
comd,intchan,
MidiEventevent
=
null;
try{
ShortMessagea
=
newShortMessage();
a.setMessage(comd,chan,one,two);
event
=
newMidiEvent(a,tick);
catch(Exceptione){e.printStackTrace();
returnevent;
}II
closeclass
intone,inttwo,inttick){
youarehere.423
exercise:
WhichLayout?
Whichcode
goes
with
which
layout?
Fiveoftheslxscreensbelowweremadefromone
ofthecodefragmentsontheoppositepage.Match
eachofthefivecodefragmentswiththelayoutthat
fragmentwouldproduce.
o
6SC
walari
o
ee
(
~
.
le5ujl
•
G
606
lesuJI
tesuJi
424
chapter13
G
e
codeFragments
JFrameframe
=
newJFrame();
JPanelpanel
=
newJPanel();
panel.setBackground(Color.darkGray);
JButtonbutton
=
new
JButton(~tesuji")
;
JButtonbuttonTwo
=
new
JButton(~watari")
;
frame.getContentPane().add(BorderLayout.NORTH,panel);
panel.add(buttonTwo);
frame.getContentPane().add(BorderLayout.CENTER,button);
JFrameframe
=
newJFrame();
JPanelpanel
=
newJPanel();
panel.setBackground(Color.darkGray);
JButtonbutton
=
new
JButton(~tesuji");
JButtonbuttonTwo
=
new
JButton(~watari")
;
panel.add(buttonTwo);
frame.getContentPane().add(BorderLayout.CENTER,button);
frame.getContentPane().add(BorderLayout.EAST,panel);
JFrameframe
=
newJFrame();
JPanelpanel
=
newJPanel();
panel.setBackground(Color.darkGray);
JButtonbutton
=
new
JButton(~tesuji");
JButtonbuttonTwo
=
new
JButton(~watari")
;
panel.add(buttonTwo);
frame.getContentPane().add(BorderLayout.CENTER,button);
JFrameframe
=
newJFrame();
JPanelpanel
=
newJPanel();
panel.setBackground(Color.darkGray);
JButtonbutton
=
new
JButton(~tesuji");
JButtonbuttonTwo
=
new
JButton(~watari")
;
panel.add(button);
frame.getContentPane().add(BorderLayout.NORTH,buttonTwo);
frame.getContentPane().add(BorderLayout.EAST,panel);
JFrameframe
=
newJFrame();
JPanelpanel
=
newJPanel();
panel.setBackground(Color.darkGray);
JButtonbutton
=
new
JButton(~tesuji");
JButtonbuttonTwo
=
new
JButton(~watari");
frame.getContentPane().add(BorderLayout.SOUTH,panel);
panel.add(buttonTwo);
frame.getContentPane().add(BorderLayout.NORTH,button);
using
swing
youarehere;
425
puzzle:
crossword
GtJI-Or~ss
,.0
Youcan
do
It.
AaOS5
17.ShakeItbaby
Down
13.Manager'srules
1.
Artist'ssandbox
21.Lotstosay
2.Swing'sdad
14.
Source'sbehavior
4.
Border'scatchall
23.Choosemany
3.
Frame'spurview
15.Borderbydefault
5.
Javalook
25.
Button'spal
5.
Help'shome
18.
User'sbehavior
9.Genericwalter
26.Homeof
6.Morefunthantext
19.
Inner'ssqueeze
11.Ahappening
actionPerformed
7.Component
slang
20.Backstagewidget
12.Applyawidget
8.
Romulincommand
22.Maclook
15.
JPanel'sdefault
9.
Arrange
24.Border'sright
16.Polymorphictest
10.
Border'stop
426
chapter13
~
ExerciSeSolutions
usingswing
~
JFrameframe..DewJFrame();
V'
JPanelpanel
C
DewJPanel();
paDel.setBackground(Color.darkGray);
JButtOD
button
=
DewJButton("tesuji
H
);
JButtonbuttonTwo..newJButton(".auri
N
);
panel.add(buttonTwo);
frame.getCoDtentPane().add(BorderLayout.CENTER,button);
A
JFrameframe=DewJFrame();
~
JPanelpanel'"newJPanel
Cl;
panel.setBaokqround(Color.darkGray);
JButtonbutton..newJButton("tesuji
N
);
JButtonbuttonTwo..newJButton("wauri
N
);
frame.getContentPane().add(BordarLayout.NORTS,panel);
panel.add(buttonTwo);
frame.qetContentPane().add(BorderLayout.CENTER,button);
~
JFrameframe=newJFrame();
...,JPanelpanel"newJPanel{);
panel.setBaekqround(Color.darkGray);
JButtonbutton
=
newJButton("tesuji
H
);
JButtonbuttODTwo
=
newJButton("watari");
frame.qetContentPane().add(BordarLayout.SOUTH,panel);
panel.add(buttonTwo);
frame.getContantpane().add(BorderLayout.NORTH,button);
o
~ e e o
.......
JFrameframe'"n_
JYram.();
JPanelpanel
=
newJPanel();
panel.aetBackground(Color.darkGray);
JButtoDbutton'"newJButton("tesuji");
JButtonbuttonTwo'"newJButton("watari
H
):
panel.add(button):
frame.qetConbentpane().addlBordarLayout.NORTH,buttonTwo):
frame.qetContentpane().add(BorderLayout.EAST,panel);
O
JFrameframe
=
new
JFr_():
•JPanelpanel..n_JPanel():
panel.a8tBackqround(Color.darkGray);
JButtonbutton
=
newJButton("taauji
H
);
JButtonbuttonTvo
CI
newJButton("watari");
panel.add(buttonTwo):
framo.qlltContantpane
Cl•
add(BordllLLayout.CENTE:R,button);
frame.getContentPane().addl80rderLayout.EAST,panel);
youarehere
~
427
puzzle
Answers
eaI-Or~ss
z.o
14
serialization
and
fileI/O
SavingObjects
Objectscanbeflattenedandinflated.
Objectshavestateandbehavior.
Behavior
livesinthe
dOH,
but
state
liveswithineachindividual
object.
Sowhathappenswhen
it'stimetosavethestateofanobject?Ifyou'rewritingagame,you'regonnaneedaSavel
RestoreGamefeature.Ifyou'rewritinganappthatcreatescharts,you'regonnaneedaSavel
Open
File
feature.Ifyourprogramneedstosave
state/youcan
do
It
the
hard
way,
interrogating
eachobject,thenpainstakinglywritingthevalueofeachinstancevariableto
a
file,In
a
formatyoucreate.Or,
youcandoIttheeasy00
way-yousimplyfreeze-dry/flatten/persistJ
dehydratetheobjectitself,andreconstltute/lnflate/restore/rehydrate
It
togetitback.Butyou'll
stillhavetodoitthehardway
sometimes,
especiallywhenthefileyourappsaveshastoberead
bysomeothernon-Javaapplication,sowe'lllookatbothInthischapter.
thisIsanewchapter
429
savingobjects
Capture
the
feat
Youhavelotsofoptionsforhowtosavethestateof
yourJavaprogram.andwhatyouchoose
will
probably
dependonhowyouplanto
use
thesavedstate.Here
aretheoptionswe'llbelookingatinthischapter.
If
yourdata
will
be
usedbyonlytheJava
programthatgeneratedIt:
~
Use
~erializQtion
Write
0
tilethatholdsflattened(serialized)
objects.Thenhaveyourprogramreadthe
serializedobjectsfromthefileandinflatethem
backinto
living,breathing,heap-inhabitingobjects.
If
yourdata
will
be
used
by
other
programs:
@Writeaplain
text
file
-
Writeatile.withdelimitersthatotherprogramscanparse,
Forexample,atab-delimitedfile
thataspreadsheetor
databaseapplicationcan
USe.
Thesearen'ttheonlyoptions,ofcourse.Youcansavedatain
any
formatyouchoose.Insteadofwritingcharacters,forexample,
youcanwriteyourdata
as
bytes.Oryoucanwriteoutanykind
ofJavaprimitive
as
aJavaprimitive-therearemethodstowrite
ints,longs.booleans,etc.BUtregardless
ofthemethodyouuse,
the
fundamental
lIO
techniquesareprettymuchthesame:
writesomedatato
something,
andusuallythatsomethingiseither
afileondiskorastreamcomingfromanetworkconnection.
Readingthedataisthesameprocessinreverse:
readsomedata
from
eitherafileondiskoranetworkconnection.Andofcourse
everythingwetalk
aboutinthispartisfortimeswhenyouaren't
usinganactualdatabase.
430
chapter14
Savl"QState
Imagineyouhaveaprogram,say,afantasy
adventuregame,thattakesmorethanone
sessiontocomplete.
As
thegameprogTesses,
charactersinthegamebecomestronger,weaker,
smarter,
etc.•andgatheranduse(andlose)
weapons.You
don'twanttostartfromscratch
eachtimeyoulaunchthegame-ittookyou
foreverto
getyourcharactersintopshapefor
a
spectacularbattle.
So.
youneedawaytosave
thestateofthecharacters,andawaytorestore
thestatewhenyouresumethegame.Andsince
you'realsothegameprogrammer,you
want
the
wholesaveandrestorething
to
beaseasy(and
foolproof)aspossible.
•Optionone
Write
thethreeserialized
characterobjectstoafile
Createafileandwritethreeserialized
characterobjects.Thefilewon'tmake
senseifyoutrytoreaditas
text:
-l.uGa.meoharaot
-"'~ava/1anIJ
8t:rIDSi
[weapoQt
Nava/lang/
8t:r'lDS;QBtlfUrl:I4java.Jant.8t:rln4;..
uvA.
i{Gzptbowt8wordtdUSUq-nt'l'rolluq-tb
are
h.Ilndabig
IIDq-
ztMagloiaDuq-tepe
u.tInvialbWty
•
Optiontwo
Write
aplaintextfile
CreateafileandwritethreeJinesoftext.
onepercharacter,separatingthepieces
of
statewithcommas:
80.mt,bow,lJWQrcl,dlUt
8OO,Troll,barebanlb,big
ur:
18O,Megictl
n
,ape!h,lnviaibUity
GameCharacter
11'1
power
Stringtype
WeaponDweapons
gelWeaponO
usaWeaponO
IncreasePower()
II
more
serializationandfile1/0
Imagine
you
l1a-ve
t
1
r
.1
m"ee
game
Cllaract
erstosal'e...
youarehere
~
431
savingobjects
Wrlti"Qaserializedobjecttoafile
Herearethestepsforserializing(saving)anobjectDon'tbother
memorizing
all
this;we'l1gointomoredetaillater
in
this
chapter.
o
Makea
FileOutputStream
Wrlt~
the
obj~ct
r
..I
'o~h.1Yat-tc--
-lLL'
to
L
yt:-t&fY\UU
..I
'a\"~
Ult:ODjt:
~
Uv
veedl'lU
os.
writeObject(characterOne)
i
it:---/.
O:~,~nayad:.t.yT'fIo,il~d ~nil"'~~",c,~"'''.
I
os.
wri
teObject(characterTwo);
~
,./l'+tt-s
thCJ'II
to
tnt:
~11t:N1~
oB.writeObject(characterThree);
~
e
432
chapter14
serializationandfileI/O
PatalMoves
itt
streatMsfrotMot1eplacetoat1other.
CO"t1ectio"
strealMsreprese)tt
aeOt1t1ectlot1
toasourceor
destlt1aflot1
(file,
socket
etc.)while
chal"streatMs
-
cat1't
oot1"ecf
Ot1
their
OW"
3"d
tMust
bechal"edtoa
cot1t1ectfo"dna",.
ThejavaI/OAPIhas
amnection
streams,thatrepresentconnectionstodestinationsand
sourcessuch
as
filesornetworksockets,and
chain
streamsthatworkonly
if
chainedto
otherstreams.
Often,ittakesatleasttwostreamshookedtogether
to
dosomethinguseful-oneto
representtheconnectionand
another
tocallmethodson.\\Thytwo?Because
connection
streamsareusuallytoolow-level.FileOutputStream
(a
connectionstream),forexample,
has
methodsforwriting
byles.
Butwedon'twanttowrite
byusl
Wewanttowrite
objects,
so
we
needahigher-level
chain
stream.
OK,
thenwhynothavejustasinglestreamthatdoes
exactly
whatyouwant?Onethatlets
youwriteobjects
butunderneathconvertsthemtobytes?Thinkgood00.Eachclass
does
one
thingwell.
File
OurpurStreamswritebytesto
a
file.ObjectOurputStreamsturn
objectsintodatathatcanbewrittentoastream.SowemakeaFileOutputStreamthatlets
us
writeto
a
file,andwehookanObjectOutputStrearn(achainstream)ontheendofit.
WhenwecallwriteObject()ontheObjectOutputStream.theobjectgetspumpedintothe
streamandthenmovestotheFileOutputStreamwhereitultimatelygetswrittenasbytes
to
a
file.
Theabilitytomixandmatchdifferentcombinationsofconnectionandchainstreams
givesyou
tremendous
flexibilitylIf
youwereforcedtouseonly
a
single
stream
class,
you'd
beatthemercy
of
the
API
designers.hopingthey'dthoughtof
everythitlgyou
mightever
wanttodo.Butwithchaining,youcanpatchtogetheryourown
custom
chains.
objectiswrittenasbytesto
is
written
to
object
isflattened(serialized)
is
chained
to
ObjectOutput
Streom
(a
choin
stream)
011010010110111001
FileOutputStream
(a
connectionstream)
01101001
01101110
01
File
youarehere
~
433
serializedobjects
Whatreally
happens
toa.,object
whet'
itl
serialized?
o
Objectontheheap
Objectsonthe.heaphavestate-the
valueoftheobject'sinstance
variables.Thesevaluesmakeone
instanceofaclass
differentfrom
anotherinstanceof
thesameclass.
FoomyFoo
=
newFoo();
myFoo.setwidth(37);
myFoo.setBeight(70);
434
chapter14
G
Objectserialized
Serializedobjectssavethevalues
of
theinstancevariables.sothat
anidenticalinstance(object)canbe
broughtbacktolifeon
theheap.
00100101
01000110
'utwhat
exactly
ISatt
object~
state?
-
What
needs
to
besaved?
Nowitstartstogetinteresting.
Easy
enoughtosavethe
primitive
values37and70.Butwhat
if
anobjecthasaninstancevariable
that'sanobject
reference?
Whataboutanobjectthathasfive
instancevariablesthatareobjectreferences?What
if
thoseobject
instancevariablesthemselveshaveinstancevariables?
Thinkaboutit.Whatpartofanobject
is
potentiallyunique?
Imagine
whatneedstoberestoredinordertogetanobjectthat's
identicaltothe
onethat
was
saved.Itwillhaveadifferentmemory
location.
ofcourse.butwedon'tcareaboutthat,Allwecareabout
isthatoutthereontheheap.we'llgetanobjectthathasthesame
state
theobjecthadwhenit
was
saved.
Vi!iiJlj1
IraillBarbell
serlallzatlon
and
fileI/O
WhathastohappenfortheCar
object
to
be
saved
in
such
a
way
that
Itcan
berestoredbackto
its
original
state?
Thinkof
what-and
how-you
might
need
to
save
the
Car.
And
what
happens
if
anEngine
object
has
areference
toa
Carburator7
And
what's
inside
the
nre
0
array
object?
TheCarobjecthastwo
Instancevariablesthat
referencetwoother
objects.
Whatdoe8Ittaketo
saveaCarobject?
youare
here.
435
serialized
objects
Serializationsavesthe
entire
objectgrapb..
All
objectsreterenced
by
instance
variables,
startingwiththe
objectbeingserialized.
/\∙l:-
~9[
)
arrcri
o'o~
When
you
savetheKennel,all
of
this;ssavedl
~
-
Whenanobjectisserialized,alltheobjects
itreferstofromInstancevariablesarealso
serialized.Andalltheobjectsthoseobjects
refertoareserialized.Andalltheobjectsthose
objectsrefertoareserialized•••andthebest
partis,
it
happensautomaticallyl
ThisKennelobjecthasareferencetoaDog[]arrayobject.The
Dog[]holdsreferencestotwoDogobjects.EachDogobjectholds
areferencetoaStringandaCollarobject.TheStringobjects
haveacollectionof
charactersandtheCollarobjectshaveaninto
436
chapter14
Serializable
Ifyouwantyourclasstobeserializable,
itMpletMet1t
serializationandfile
110
publicstaticvoidmain(String[]args){
BoxmyBox
=
newBox();
myBox
.setWidth(50};
myBox.setHeight(20);
TheSerializableinterfaceisknownasa
marker-ortag
interface,
because
theinterfacedoesn'thaveanymethodstoimplement.Its
sole
purposeistoannouncethattheclassimplementingitis,well,
serializable.
Inotherwords,objectsofthattypearesaveablethrough
theserializationmechanism.Ifanysuperclassofaclassisserializable,
thesubclassisautomaticallyserializableevenifthesubclassdoesn't
explicitlydeclare
implementsSerializable.
(Thisishowinterfacesalways
work.
Ifyoursuperclass"IS-A"Serializable,youaretoo).
MIASI
i",y\c",e'llt.
~ ~"eY
O;,ot.
s
'neY
c
r'\t.
Yu.f\t.i",c,
objectOUtputStream.writeObject(myBox);
~'h\C
t:J(
it....i\\-tala
Sey\a\\~
,'lhc'a'la,ioyat.\l.aO;,C.so
,
~'~\)\t
'S
I'll",)
importjava.io.
*;
~
SeYli
e..
d
t.'nt
i""'y~'
'1011'
'II..
publicclassBoximplementsSerializable
.........
~
../
publicvoidsetWidth(intw)
width
=
w;
publicvoidsetHeight(inth}
height
=
h;
))
d
\\~oo,seY
l
to
i
~i\C
YId.,.,.C
I
¥.ea
COY\'IItt.".
~
'It.dot.s,",
t.
",i
lL
eue...l.io\llS.!
r.t.
e'Jl.
Ists
∙\"
1
10
ovtV'abo"st.a""nYO'"
r-
i"l'
Id
\\~oo·seY
.
I"c'"
~i\t
YId"'c
try{
~
FileoutputStreamfs
=
newFileOUtputStream("foo.ser");
ObjectOUtputStreamos
=
newObjectOUtputStream(fs);
os.writeObject(myBox);
~
Make
ah
Ob'etto
os.close();.........
thaihed
to
:J
"tp"tstrea",
catch(Exceptionex){
thetOhhettiohst
ex.printSt&ckTrace();
Tell
it
to
W\-'te
1
rea""
I
l::heobjett.
youarehere.437
serializedobjects
Eithertheentire
objectgraphis
serializedcorrectly
orserializationfails.
Youcan'tserialize
aPondobjectif
itsDuckinstance
variablerefusesto
besenallzed(by
notimplementing
Seriafizable).
Eeewww!That
creepsmeoutjustthinking
aboutitlLike,what
if
aDogcomes
backwith
rIO
weight.Ornoears.Or
thecollarcomesbacksize3instead
of30.
Thatjustcan'tbeallowedl
catch(Exception
ex)(
ex.printStackTrace();
publicstaticvoidllIain(Strinq[]
PondmyPond
=
newPond();
try(
FileOutputstreAm
fs:
newFileOUtputStream("Pond.'ser");
ObjectOUtputStreamos:newObjeotOutputStream(fs);
...,e--.
Wh
os.writeOb)8ct(myPond);.
bl.yo....
so-ia'i~
""yPond(
P
os.close();
obJuV,ih
Dlotk
i>\lUa
ol'ld
a
ui:o-....a
tit...iII
1.-.
I'I~~
variable
y
3
c
't-\
serlall~d.
.
PO'PIO:
to
YWI
~t
",ai"
I"
dass
Serializationisallornothing.
Canyouimaginewhatwould
happenIfsomeoftheobject's
statedidn'tsavecorrectly?
~
POI'IO
obj~eL
ea"
b~
so-ializ..ed.
publicclassPondimplementsSerializable(
CIa
"
POl'ld
has
ont
'INtaTlee
private
Duckduck
=
newDuck();
~
,..
D
Ie.
va~iable,
a
vl.,
arqs){
import
java.io.*;
438
chapter14
serializationandfile
110
It'shopeless,
then?
I'm
completely
screwedif
the
idiotwho
wrote
theclassfor
my
instance
variable
forgottomakeit
Serializable?
MarkanInstancevariableastransient
IfItcan't(orshouldn't)
be
saved.-
If
youwantaninstancevariabletobeskipped
by
the
serializationprocess,markthevariablewiththe
transient
keyword.
•importjava.net.*:
.t
!o4i'r'
"Otil'C.
~
class
Chat
implementsSerializable{
b-a.,.s~~iS ~aV"\a'o\tl O~~Il\~t.)I~
transientStrinqcurrentID;
sa"t
v'.
'I>S~
n.'"
J---
~V"ia\i-z.abO"f\,~
~
StrinquserNamej
lI..SC'rNa....
evariable//
morecode
will
be
saved
aspari}
o.f
~t.
obJt.d:'sst.dte
dUY"'9
st.\"laliz.aiiol'l.
lfyouhaveaninstancevariablethatcan'tbesavedbecause
itisn'tserializable,youcan
markthatvariable
with
the
transientkeywordandtheserializationprocesswillskipright
overit.
Sowhywouldavariable
notbeserializable?
It
couldbe
thattheclassdesignersimply
/ClTgot
tomaketheclass
implementSerializable,Oritmightbebecausetheobject
reliesonruntime-specific
informationthatsimplycan'tbe
saved.
Althoughmostthingsinthe
java
classlibrariesare
serializable,youcan'tsavethingslikenetworkconnections,
threads,
orfileobjects.They'realldependenton(and
specificto)aparticularruntime'experience'.Inotherwords,
they'reinstantiatedinawaythat'suniquetoaparticularrun
ofyoorprogram,onaparticularplatform,inaparticular
JVM.
Oncetheprogramshutsdown,there'snowaytobring
thosethingsbacktolifeinanymeaningfulway;theyhaveto
be
createdfromscratcheachtime.
youarehere
~
439
serializedobjects
therelm-~?
DUmb
~uest19n8
Q:
Ifserializationissoimportant,
whyisn'titthedefaultforallclasses?
Whydoesn'tclassObjectimplement
Serializable,andthenallsubclasses
willbeautomaticallySerializable.
A:
Eventhoughmostclasseswill,
andshould,implementSerializable,
youalwayshaveachoice.Andyou
mustmakeaconsciousdecisionon
a
c1ass-by-c1assbasis,foreachclass
youdesign,to'enable'serialization
byimplementingSerializable.
First
ofall,ifserializationwerethe
default,howwouldyouturnitoff?
Interfacesindicatefunctionality,
not
a
lack
offunctionality,sothemodel
ofpolymorphismwouldn'twork
correctlyifyouhadtosay/implements
NonSerializable"totelltheworld
that
youcannotbesaved.
Q:
WhywouldIeverwriteaclass
that
wasn't
serializable?
A:
Thereareveryfewreasons,but
youmight,forexample,haveasecurity
issuewhereyou
don'twantapassword
objectstored.Oryou
mighthavean
object
thatmakesnosensetosave,
becauseitskeyinstancevariablesare
themselves
notserializable,sothere's
nousefulwayforyoutomake
your
classserializable.
Q:
Ifa
classI'm
usingisn't
serializable,butthere'snogood
reason(except
thatthedesignerjust
forgotorwasstupid),canIsubclass
the
'bad'classandmakethe
subclass
serializable?
440
chapter14
A:
Yes!Iftheclassitselfis
extendable(i.e.
notfinal),youcan
makeaserializablesubclass,andjust
substitute
thesubclasseverywhere
yourcodeisexpectingthesuperclass
type.(Remember,polymorphism
allowsthis.)Whichbringsupanother
interestingissue:
whatdoesit
mean
if
thesuperclassis
notserializable?
Q:
Youbroughtit
up:what
does
it
meantohaveaserializablesubclass
ofanon-serializablesuperclass?
A:
Firstwehavetolookatwhat
happenswhenaclassisdeserialized,
(we'll
talk-about
thatonthenextfew
pages).Inanutshell,whenanobject
isdeserializedanditssuperclassis
not
serializable,thesuperclassconstructor
willrun
justasthoughanewobjectof
thattypewerebeingcreated.Ifthere's
nodecentreasonforaclassto
not
beserializable,makingaserializable
subclass
mightbeagoodsolution.
Q:
Whoalljustrealized
somethingbig•••ifyoumakea
variable
'transient~
thismeansthe
variable'svalueisskippedover
duringserialization.Then
what
happenstoit?Wesolvetheproblem
ofhavinganon-serializableinstance
variablebymaking
theinstance
variabletransient,
butdon'tweNEED
thatvariablewhentheobjectis
broughtbackto
life?
In
otherwords,
isn'tthewholepointofserialization
topreserveanobject'sstate?
A:
Yes,thisisanissue,but
fortunatelythere'sasolution.Ifyou
serializeanobject,atransientreference
instancevariablewillbe
broughtback
as
null,
regardlessofthevalueithad
atthe
timeitwassaved.Thatmeans
theentireobjectgraphconnectedto
thatparticularinstancevariablewon't
besaved.Thiscouldbebad,obviously,
becauseyouprobablyneedanon-null
valuefor
thatvariable.
Youhave
twooptions:
1)Whentheobjectis
broughtback,
reinitialize
thatnullinstancevariable
backtosomedefaultstate.This
worksifyourdeserializedobjectisn't
dependentonaparticularvaluefor
thattransientvariable.Inotherwords,
it
mightbeimportantthattheDog
haveaCollar,
butperhapsallCollar
objectsarethesamesoitdoesn't
matterifyougivetheresurrectedDog
abrandnewCollar;
nobodywillknow
thedifference.
2)Ifthevalue
ofthetransientvariable
does
matter(say,ifthecoloranddesign
ofthetransientCollarareuniquefor
eachDog)thenyouneedtosavethe
keyvalues
oftheCollarandusethem
whentheDogis
broughtbackto
essentiallyre-createabrandnewCollar
that'sidenticaltotheoriginal.
Q:
Whathappensiftwoobjectsin
theobjectgrapharethesameobject?
Like,ifyouhave
twodifferentCat
objectsin
theKennel,butbothCats
haveareferenceto
thesameOwner
object.Does
theOwnergetsaved
twice?I'mhoping
not.
A:
Excellentquestion!Serialization
issmartenoughto
knowwhentwo
objectsinthegrapharethesame.In
thatcase,only
one
oftheobjectsis
saved,andduringdeserialization,any
referencesto
thatsingleobjectare
restored.
serlallzatJonandfile
1/0
Peserializatiot1=restorit1Qattobject
Thewholepointofserializinganobject
is
sothatyoucan
restoreitbacktoitsoriginalstate
atsomelaterdate,ina
different'run'oftheJVM(whichmightnotevenbethesame
JVM
thatwasrunningatthetimetheobjectwasserialized).
Deserialization
is
alotlikeserialization
in
reverse.
serializ.ed
J,.
e
~
theobjects
Objectone
=
os.readObject();
Objecttwo
=
os.readObject();
Objectthree
=
os.readObject();
o
e
MakeaFilelnputStreQtn
FilelnputStreamfileStream
=
new
cast
theobjects
-
youare
here,
441
deserlallzlngobjects
Whathappe.,sdurhtgdeserializatio.,?
Whenanobjectisdeserialized,thejVMattemptstobring
theobjectbacktolife
by
makinganewobjectontheheap
thathasthesamestatetheserializedobjecthadatthetime
it
was
serialized.Well,except
for
thetransientvariables,which
comebackeithernull(forobjectreferences)orasdefault
primitivevalues.
Object
ObjectInputStream
(achainstream)
∙.r
~e
JVM
CJW:I~
.\\
~'(O-.l
ell'
e
\his
stty
-.II\
d
~e
dass.
-:t
~\"d'"
ea
classisfoundandloaded,saved
instancevariablesreassigned
is
chainedto
FiJeInputStream
(0
connectionstream)
objectis
readas
bytes
is
readby
__
----~
011010010110111001
File
01101001
01101110
01
o
Theobjectisreadfromthestream.
e
The
JVM
determines(through
info
storedwith
theserializedobject)theobject'sclass
type.
The
JVM
attempts
t?
findandloadtheob-
ject'sclass.
If
the
JVM
can'tfindand/orload
theclass,the
JVM
throwsanexceptionand
thedeserializationfails.
Anewobjectisgivenspaceon
theheap,but
theserIalizedobJedsconstructordoes
NOTrunlObviously,
if
theconstructorran,it
wouldrestorethestateoftheobjectback
toitsoriginal'new'
state,andthat'snotwhat
wewont.Wewant
theobjecttoberestored
tothestateithad
whenitwasserialized,
not
whenit
was
firstcreated.
442
chapter14
serializationandfileI/O
G
Iftheobjecthasanon-serializableclass
somewhereupitsinheritance
tree,the
constructorforthatnon-serializableclass
will
runalongwithanyconstructorsabove
that(evenifthey'reserializable).Oncethe
constructorchainingbegins,youcan'tstopit,
whichmeansallsuperclasses,beginningwith
thefirstnon-serializableone,willreinitialize
theirstate.
CD
Theobject'sinstancevariablesaregiventhe
valuesfromtheserializedstate.Transient
variables
aregivenavalueofnullforobject
referencesanddefaults(0,false,etc.)
for
primitives.
:t1e
re
1lU'H?
0
DUmb
~uestl9n8
Q:
Whydoesn'ttheclassgetsavedaspartoftheob"
ject?Thatwayyou
don'thavetheproblemwithwhether
theclasscanbefound.
A:
Sure,theycouldhavemadeserializationworkthat
way.Butwhatatremendouswasteandoverhead.And
whileitm
ightnotbesuchahardshipwhenyou'reusing
serializationtowriteobjectstoafileonalocalharddrive,
serializationisalsousedtosendobjectsoveranetwork
connection.Ifaclasswasbundled
witheachserialized
(shippable)object,
bandwidthwouldbecomeamuchlarger
problemthanitalreadyis.
Forobjectsserializedtoshipoveranetwork,though,there
actually
is
amechanismwheretheserializedobjectcanbe
'stamped'
withaURlforwhereitsclasscanbefound.This
isusedin
Java'sRemoteMethodInvocation(RMI)sothat
youcansendaserializedobjectaspartof,say,amethod
argument,andiftheJVMreceivingthecalldoesn'thave
theclass,itcanusethe
URltofetchtheclassfromthe
networkandloadit,allautomatically.(We'lltalkaboutRMI
inchapter17.)
Q:
Whataboutstaticvariables?Aretheyserialized?
A:
Nope.Remember,staticmeans"oneperclass"not
"oneperobject"Staticvariablesarenotsaved,andwhenan
objectisdeserialized,itwillhavewhateverstaticvariable
itsclass
currently
has.Themoral:don'tmakeserializableob-
jectsdependentonadynamically-changingstaticvariable!
It
mightnotbethesamewhentheobjectcomesback.
youarehere
~
443
serializationexample
Savit1gat1drestorit1gthegatttecharacters
importjava.io.*;
publicclassGameSaverTest{Make
sow-t
tna~atte'rt-· ·
publicstaticvoidmain(String(]axgs}{
GameCharacterone
=
newGameCharacter(50,
"Elf",
newStrinq{]
("bow",
"sword","dust"});
GameCharactertwo
=
newGameCha.racter(200,"Troll",newString!
1
{"barehands"
J
"bigax"});
GameCharacter
three
=
newGameCharacter(120,"Magician",newString[l("spells","invisibility"});
//imaginecode
that
does
thingswith
the
charactersthatmightchangetheirstatevalues
try{
ObjectOutputStream
09
=
newObjectOutputstream(newFileoutputstream
("Game.
ser"));
os.writeObject(one);
os.writeQbject(two);
os.writeQbject(three)
i
os.
close();
catch(IOExceptioD
ex)(
ex.printStackTrace();
}
one
=
null;
Wt
stt
tnt...
tD
""IIso
'\lit
un't
two
=
null;
~
alUSSt.ht
objttts
0l'I
-\:he
ht.af∙
three
=
null;
Now
\'"tadtht...balK
j"
+\'"0'"
the
tilt...
~{ ~
Objectlnputstream
is
=
newObjectlnputstream(newFilelnputstream("Game.ser"));
GamecharacteroneRestore
=
(GameCharacter)is.readObject();
GameCharactertwoRestore
=
(GameCharacter)is.readObject();
GameCharacterthreeRestore
=
(GameCharacter)is.readObject();
~.t.
oVlt.t4∙
System.out.println
("One'
B
type:
\I
+
oneRestore.
g8tType());
Chtt'tt.
-to
see
i\....
Sys
tern.au
t.
println("Two'stype:"
+
twoRestore.getType());
~
System.out.println("Three's
type:"
+
threeRestore.getTypeO)
j
catch(Exceptionex)(
ex
.printstackTrace();
444chapter
14
fheG-atl1eCharacferclass
importjava.io.
t
;
publicclassGameCharacterimplementsSerializable{
intpower;
Stringtype;
String[]
weapons;
publicGameCharacter(intp,Stringt,String[]w){
power
=
p;
type
=
t;
weapons
=
w;
publicintgetPower()
returnpower;
publicStringgetType()
returntype;
publicStringgetWeapons(){
String
weaponList
="":
for(inti
=
0;i
<
weapons.length;iff){
weaponList
+=
weapons[i]
+"";
}
returnweaponList;
serializationandfile110
youarehere"445
saving
objects
446
chapter14
Ol.jed
Serialization
)-YoucansaveanobjecfsstatebyserializJngtheobject.
)-Toserializeanobject,youneedanObJectOutputStream(fromthe
java.lopackage)
)-Streamsareeitherconnectionstreamsorchainstreams
..Connectionstreamscanrepresentaconnection
to
asourceor
destination,typicallyafile,networksocketconnection,orthe
console.
)-Chainstreamscannotconnecttoasourceordestinationandmust
bechainedto
a
connection(orother)stream.
)-
Toserializeanobjectto
a
file,makeaRleOuputStreamandchain
~
intoanObjectOutputStream.
..Toserializeanobject,call
writeObject(theObject)
onthe
ObjectOutputStream.Youdonotneed
to
callmethodsonthe
FUeOutputSlream.
)-
To
be
serialized.anobjectmustImplementtheSeriallzableinterface.
ItasuperclassoftheclassImplementsSerializabls,thesubclasswill
automatically
be
seria\lzableeven
If
~
doesnotspeclficallydeclare
implementsSeri8/1zable.
)-WhenanobjectIsserialized,
its
entireoblectgraphIsserialized.That
meansanyobjectsreferencedbytheserializedobject'sinstance
variablesareserialized,andanyobjectsreferenced
by
those
obJects...
andsoon.
•If
anyobjectinthegraphIsnotserializable,anexceptionwill
be
thrownatrunlime,unlesstheInstancevariablereferringtotheobject
Isskipped.
..Marieaninstancevariablewiththe
transient
keywordif
you
want
serializationtoskipthatvariable.Thevariablewillberestoredasnull
(forobjectreferences)ordefaultvalues(forprimitives).
.•Duringdeseriallzation,theclassofallobjectsInthegraphmust
be
availabletotheJVM.
•
YoureadobjectsIn(usingreadObjeet())IntheorderIn
which
they
wereoriginallywritten.
•
Theretum
type
ofreadObjectOis
type
Object,sodeserialized
objectsmust
be
casttotheirreal
type.
•StaticvariablesarenotserializedIItdoesn'tmakesensetosave
astaticvariablevalueaspartofaspecificobjecfsstate.sInceall
objectsofthat
type
shareonlyasinglevalu&-theoneIntheclass.
serializationandfileI/O
Writi"gaStrittgtoafextFile
Savingobjects,throughserialization,istheeasiestwaytosaveand
restoredatabetweenrunningsofaJavaprogram.Butsometimesyou
needtosavedatatoaplainoldtextfile.ImagineyourJavaprogram
hastowritedatatoasimpletextfilethatsomeother(perhapsnon-
Java)
programneedstoread.Youmight.forexample,haveaservlet
(Java
coderunningwithinyourwebserver)thattakesformdatathe
usertypedintoabrowser,andwritesittoatextfilethatsomebodyelse
loads
intoaspreadsheetforanalysis.
Writingtext
data(aString,actually)issimilartowritinganobject,
exceptyouwriteaStringinsteadofanobject.andyouusea
FileWriterinstead
ofaFileOurputStream(andyoudon'tchain
it
toan
ObjectOutputStream).
60,Elf,how,sword,dust
200,Troll,ba.reha.ndB,hlg
ax
120,Maglolan,spel1B,invisibillty
Towrite
Q
serializedobject:
ObjQctOutputstream.vriteObject(someObject);
Towrite
Q
String:
fileWriter.
wri
te
("My
firstString
to
save")
j
import
classWriteAFile{
publicstaticvoidmain(String[]args){
foo
!");
~
Tht-.-iuO
"'«hoduk
a
St.ril'l~
es
writer.close();
~
Cl
'l-
aSt
'"1:.....
hCtl
YO\l.'rt
dO"ll
catch(IOException
ex)(
ex.printStackTrace();
try{
/
FileWriterwriter
=
\
/0
sb>~~
t\\...L-
t)I~
b-
I
t.a-u.~.
writer.
wri
te("
hello
II-$t.
~
',1'1
a
'(~
...
o'tJ
d1'l\
...vl-''ri'
~.,..
"
't:.'J!'C'lv
\1'1~
1\
\0
'2-
.,I.t.~y-b
0'/1•.
)
}
youarehere
~
447
fextFileExatMple;e-Flashcards
88e
()I~
card"-,
fj"
,WhathappensIfyoucall
l:0bject.getPrimaryKeyO
ona
sianbean'sremotereference?
I ~
::
,
10
LA)
(ShoW_,)
"-
~
writingatextfile
Rememberthoseflashcardsyouusedinschool?Whereyou
hadaquestionononesideandtheanswerontheback?
Theyaren'tmuchhelpwhenyou're
trying
tounderstand
something,butnothingbears'emforrawdrill-and-practice
androtememorization.
When
JfYU
have
to
burnina
faa.
And
they'realsogreatfor
triviagames.
We'regoingtomakeanelectronicversion
that
has
three
classes:
1)
QuizCardBuilder.
asimpleauthoringtoolforcreatingand
savingaset
of
e-Flashcards,
2)
QuizCardPlayer.
a
playback
enginethatcanloada
flashcardset
andplay
it
fortheuser.
3)
QuizCard,
asimpleclassrepresentingcarddata.We'll
walk
throughthecodeforthebuilderandtheplayer,and
haveyoumaketheQuizCardclassyourself,usingthis
~
180e
Qvlz
CMd",lIdo,
I
FI..
Quullon:
,
WhichuniversityIsfeaturedInthe
,
film
-Good
Will
Huntlng~
,
~
I
I
J
,,~
..
An....
r:
I
M.I.T.
~
I
,
--
-
II
(Wulc.id)
i
-
;
-
~
QulzCardBullder
QulzCard
QuizCard(q,a)
question
answer
gelQuestion
0
gelAnswerQ
QulzCardPlayer
Hasa
Filemenu
witka
~SaveH
optionforsaving
thecurrentsetofcardstoa
text
file.
448
chapter14
Hasa
Filemenuwith
a"Load"
optionforloading
a
setofcardsfromatextfife.
QuizCard'uilder(codeoutli.,e)
publicclassQuizCardBuilder{
serialization
and
file110
publicvoid
goO{
//buildanddisplaygui
IMev-t.lass
privateclassNextCardListenerimplementsActionListener{
publicvoidaction
Performed(ActionEventev){
//
addthecurrentcardtothelistandclearthetextareas
IlIlIev-dass
privateclassSaveMenuListenerimplementsActionListener{
publicvoidactionPerformed(ActionEventev){
//
bringupafiledialogbox
//lettheusernameandsavetheset
IlIlIev-dass
privateclassNewMenuListenerimplementsActionListener{
publicvoidactionPerformed(ActionEventev){
II
dearoutthecardlist,anddearoutthetextareas
priv
atevoidsaveFIle(Filefile){
//iterate
throughthelistofcards,andwriteeachoneouttoatextfile
//inaparseableway(inotherwords,with
clearseparationsbetweenparts)
Called
by
theSa\leMell...L.istenev-;
doestheat.hal
~ i le WV"ib n~.
youarehere
~
449
QuizCardBuildercode
import
import
import
imp
ort
import
java.util.*;
java.awt.event.*;
,.*
J
avax.
swmq,;
java.awt.*;
..*
j
ava
i
i
o.;
publicclass
QuizCardBuilder
privateJTextAreaquestion;
privateJTextAreaanswer;
privateArrayList<QuizCard>cardList;
privateJFrameframe;
publicstaticvoidmain(String!]args){
QuizCardBuilder
builder
=
newQuizCardBuilder();
builder.go();
publicvoidgot){
//
buildgui
frame
=
newJFrame(uQuizCardBuilder");
JPanelmainPanel
=
newJPanel();
FontbigFont
=
newFont(Usanserif",Font.BOLD,24);
question
=
newJTextArea(6,20);
question.setLineWrap(true);
question.setWrapStyleWord(true);
question.setFont(bigFont);
JScrollPaneqScroller
=
newJScrollPane(question);
qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICALSCROLLBARALWAYS);
qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
answer
=
newJTextArea(6,20);
answer.setLineWrap(true);
answer.setWrapStyleWord(true);
answer.setFont(bigFont);
JScrollPaneaScroller
=
newJScrollPane(answer);
aScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICALSCROLLBARALWAYS);
aScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
JButtonnextButton
=
newJButton(UNextCard");
cardList
=
newArrayList<QuizCard>();
JLabelqLabel
=
newJLabel(uQuestion:");
JLabelaLabel
=
newJLabel(UAnswer:");
mainPanel.add(qLabel);
mainPanel.add(qScroller);
mainPanel.add(aLabel);
mainPanel.add(aScroller);
mainPanel.add(nextButton);
nextButton.addActionListener(newNextCardListener());
JMenuBarmenuBar
=
newJMenuBar();
JMenufileMenu
=
newJMenu(UFile");
JMenultemnewMenultem
=
newJMenultem(UNew");
450chapter14
serializationandfileI/O
JMenultemsaveMenultem
=
newJMenultem("SaveH)i
newMenultem.addActionListener(newNewMenuListener());
saveMenultem.addActionListener(newSaveMenuListener());
tileMenu.add(newMenultem)i
fileMenu.add(saveMenultem)i
menuBar.add(fileMenu);
frame.setJMenuBar(menuBarli
frame.getContentPane().add(BorderLayout.
CENTER,
frame.setSize(500,600)i
frame.setVisible(true)i
public
classNextCardListenerimplementsActionListener(
publicvoidactionPerformed(ActionEventev)(
QuizCard
card
=
newQuizCard(question.getText(),answer.getText());
cardList.add(card)
i
clearCard();
public
classSaveHenuListenerimplementsActionLiatener(
publicvoidactionPerformed(ActionEventev)(
QuizCard
card
=
newQuizCard(question.getText(),
cardList.add(card);
answer.getText());
-b
CI'f\
t.n
IS
\)<I....
ar-d'OIa\
l~
a
~i\e dia\~'s.a~e
tY'O"',;
e
j
'O-ri....
~ ~ ~
t.MoSV.
~BO'\a~
0=;:..._-
\i...e
W'lB\
~\\
tM
~i\e
di.1\:1
r.o~'11
01>
'0'1
b'>e
d'Id\~
bo'1-
r.
~
'IS
aOfle
o>r
\
't.
bl\e>
a...
,\el\\'1
is
HilSdS'f'
se
~ C~!
It.
~ed
public
classNewManuListenerimplements
ActiOnListen~f\\f
publicvoidactionPerformed(ActionEventev)(
cardList.clear(li
clearCard()i
privatevoid
clearCard()(
question.setText("")j
answer.setText(KHl
j
question,requestFocuS()i
c>:
privatevoid
saveFile(Filefile)/
try{
e:-:
BufferedWriterwriter
~
newBufferedWriter(newFileWriter(file))i)
for(QuizCardcard:cardList)(
~l!
t.h.ai"
d
B~.f(l-edW\"ik
writer.write/card.getQuestion()
+...
i")
ij
FJleWI"'ite--
to
IR,)lce
't;
Ot!
to
a
'lew
writer,write(card.getAnswer()
+
"'\n")j
(We11
i:.llk
abow!
th
i-
"~fI-e
eHitie"f..
I
<.
a
''I
d
1'ew
fa~e.v
writer.close/);.
catch(IOExceptionex){
Walle
thr~h
the
ArrayL'~
0+
System.out.println("couldn'twritethecardListout");
~rd.s
ar.d
Wl"i~
tJ,
t,'
ex.pr!ntStackTrace()
i
f(l-
lillC
wiLl
1..
e...~"
One
tdrd
,
~
=t
Q
lotS'bOt!
ad.>
.s~t\"~pdraud
b\"""..,,-
add/.
y
a/",
and
ihbl
a
IItW'lIt
thardt.te--
("\11")
youare
here.
451
writingfIles
fhe
java.ioJiIe
class
Thejava.io.Fileclass
represents
afileondisk,butdoesn't
actuallyrepresentthe
contents
ofthefile.What?Thinkof
aFileobjectassomethingmorelikea
pat/manu
ofafile
(orevena
directory)
ratherthanTheActualFileItself.
TheFileclassdoesnot,forexample.havemethodsfor
readingandwriting.One
VERY
usefulthingaboutaFile
objectis
thatitoffersamuchsafer
way
torepresenta
file
thanjustusingaStringfilename.Forexample.most
classesthattakeaStringfilenameintheirconstructor
(likeFileWriterorFileInputStream)cantakeaFile
objectinstead.Youcan
constructaFileobject,verify
thatyou've
gotavalidpath,etc.andthengivethatFile
objecttotheFileWriter
orFilelnputStream.
Somethings
you
candowith
B
Fileobject:
..MakeaFileobject
repr~ntlng
an
existing
tHe
File
f
=
new
File(~MyCode.txtUI
j
@Make
Q
newdirectory
File
dir
=
newFile("Chapter7
n
l;
dir.mkdir();
•List
thecontentsof
a
directory
if(dir.isDirectory()I{
String
[1
dirContents
=
dir.list();
for
(int
i
=
0;
i
<
dirContents.length;iH){
System.out.println(dirContents[i]);
8)
Gettheabsolutepath
of
Q
fileordirectory
System.out.println(dir.getAbsolutePath(»;
I)Delete
afile
ordirectory(returnstrue
If
successful)
booleanisDeleted
=
f.delete()j
452
chapter14
AFileobjectrepresentsthename
andpathof
a
fileordirectoryon
disk,forexample:
JUsersJKathy/DataJGameFile.txt
Butitdoes
NOT
represent,orgive
youaccessto,thedata
in
thefilel
serializationandfile
1/0
Thebeautyofbuffers
Iftherewerenobuffers,
It
would
be
like
shoppingwithoutacart.You'dhaveto
carryeachthingouttoyour
car.
one
soup
canortoiletpaperrollatatime.
"Boulder"
Stringisputintoabuffer
Whenthebuffer;sfull.the
Aspen
with
otherStringsStringsareallwrittento
Denver
...
"Boulder
H
U~eD"
•AspenDenverBoulder
M
Boulder
,
ischainedto
writtento
"Denver"
String
is
BufferedWrlter
(achainstreamthat
workswithcharacters)
FlleWrlter
(aconnection
stream
thatwritescharacters
asopposedtobytes)
File
BufferedNriterwriter
=
newBufferedKriter(newFileWriter(aFile))i
~
Thecoolthingaboutbuffersisthatthey're
much.
moreefficientthan
workingwithoutthem.YoucanwritetoafileusingFileWriteralone,by
callingwrite(someString),
butFileWriterwriteseachandeverythingyou
passto
thefileeachandeverytime.That'soverheadyoudon'twantor
need.sinceeverytrip
to
thediskisaBigDealcomparedtomanipulating
datainmemory.BychainingaBufferedWriterontoaFileWriter,the
BufferedWriterwillholdallthestuffyouwriteto
it
untilit's
full.
Only
when
thebuffer
is
fullwilltheFUe
Writer
actuallybetold
to
unite
tothefileondisk.
Ifyoudo
want
tosenddata
beftn»
thebufferisfull,youdohavecontrol.
Just
FlushIt.
Calls
La
writer.flush()say."sendwhatever'sinthebuffer,
now!
h
youarehere)
453
readingfiles
ReadittgfrotHa
fext
File
Readingtextfromafileissimple,butthistimewe'lluseaFile
objectto
representthefile,aFileReadertodotheactualreading,
andaBufferedReadertomakethereadingmoreefficient.
Thereadhappensbyreadinglinesina
while
loop,endingtheloop
whentheresultofa
readl.inej)
isnull.That'sthemostcommon
styleforreadingdata(prettymuchanythingthat'snotaSerialized
object):read
stuffinawhileloop(actuallyawhileloop
tesf),
terminatingwhenthere'snothinglefttoread(whichweknow
because
theresultofwhateverreadmethodwe'reusingisnull).
~
I
~ dthti"""~
importjava.io.
*;
DO'I'I
t
dr~
What's
2
+
2?/4
What's
20+22/42
MyText.txt
classReadAFile{
pub1icstaticvoidmain(Strinq(Jarqs){
A
Fild(eadty
~
a
f.ctr.,
t
t∙
..L.,.
tha
b
L'
~
oor,
:ou-ea...
i"or
try{(
yat,
V1at
(.OnnUts
to
a
UlI.t
.filt
FilemyFile
=
newFile("MyText.txt");
FileReaderfileReader
=
newFileReader(myFile);
BufferedReaderreader
=
.'bIt
t.o
nold
Makta
s.b-'Il'~
"a'(l".
Ii
.tl-lt
linc
IS
yea
t4t.I-I
Il't\tas'\,
Stringline
=
null;
while«line
=
reader.readLine(»
!=
null)(
System.out.println(line);
}
reader.close();
catch(Exceptionex){
ex.printStackTrace();
454
chapter14
serialization
and
file
1/0
QuizCardPlayer(codeoutli"e)
publicclassQuizCardPlayer{
publicvoidgoO{
//
buildanddisplaygui
classNextCardlistener
implementsActionListener(
publicvoidactionPerformed(ActionEventev){
//ifthisisa
question,showtheanswer,otherwiseshownextquestion
//s
etaflagforwhetherwe'reviewingaquestionoranswer
}
}
classOpenMenuListenerimplementsActionListener{
publicvoidactionPerformed(ActionEventev){
//
bringupafiledialogbox
//lettheusernavigatetoandchooseacardsettoopen
privatevoidloadFile(Filefile){
//
mustbuildanArrayListofcards,byreadingthemfromatextfile
//calledfrom
theOpenMenuListenereventhandler,readsthefileonelineatatime
//andtellsthe
makeCardf)
methodtomakeanewcardoutoftheline
//
(onelineinthefileholdsboththequestionandanswer,separatedbya
"I")
privatevoidmakeCard(StringlineToParse){
//called
by
theIoadf'ilemethod,takesalinefromthetextfile
//
andparsesintotwopieces-s-questionandanswer-andcreatesanewQuizCard
//
andadds
it
totheArrayListcalledCardList
youarehere
~
455
QuizCardPlayercode
import
import
import
import
import
java.util.*;
java.awt.event.*;
javax.swing.*;
java.awt.*;
.'*
JaVa.10.;
publicclass
QuizCardPlayer
privateJTextAreadisplay;
privateJTextAreaanswer;
privateArrayList<QuizCard>cardList;
privateQuizCardcurrentCard;
privateintcurrentCardIndex;
privateJFrameframe;
privateJButtonnextButton;
privatebooleanisShowAnswer;
publicstaticvoidmain(String[]args)(
Qu
izCardPlayerreader
=
newQuizCardPlayer();
reader.go();
publicvoid
go()
II
buildgui
frame
=
newJFrame("QuizCardPlayer");
JPanelmainPanel
=
newJPanel();
FontbigFont
=
newFont("sanserif",Font.BOLD,24);
display
=
newJTextArea(lO,20);
display.setFont(bigFont);
display.setLineWrap(true);
display.setEditable(false);
JScrollPaneqScroller
=
newJScrollPane(display);
qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICALSCROLLBARALWAYS);
qScr
oller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTALSCROLLBARNEVER);
nextButton
=
newJButton("ShowQuestion");--
mainPanel.add(qScroller);
mainPane
l.add(nextButton);
nextButton.addActionListener(newNextCardListener());
JMenuBarmenuBar
=
newJMenuBar();
JMenufileMenu
=
newJMenu("File");
JMenuItemloadMenuItem
=
newJMenurtem("Loadcardset");
loadMenultem.addActionListener(newOpenMenuListener());
fileMenu.add(
loadMenuItem);
menuBar.add(fileMenu);
fr
ame.setJMenuBar(menuBar);
frame.getContentPane().add(BorderLayout.CENTER,mainPanel);
frame.setSize(640,500);
frame.setVisible(true);
II
closego
456
chapter14
serializationandfile110
publicclassNextcardListanerimplementsActionListener(
publicvoidactionperformed(ActionEventeu)(
if(isShowAnswer)(
II
showtheanswerbecausethey'veseenthequestion
display.setText(currentCard.getAnswer(»);
nextButton.setText(~Next
Card");
isShowAnswer
=
false;
else{
II
showthenextquestion
if(currentCardIndex<cardList.size(»)
showNextCard();
else
I
II
therearenomorecards!
display.setText(~That
waslastcard");
nextButton.setEnabled(false);
catch(Exceptionex){
System.
out.println("couldn'treadthecardfile")
i
ex.printStackTrace();
I
II
nowtimetostart
by
showingthefirstcard
showNextCard();
I
reader.close();
publicclassOpenManuLiatanarimplementsActionListener
publicvoidactionPerformed(ActionEventev)(
JFileChooserfileOpen
=
newJFileChooser();
~
fileOpen.showOpenDialog(frame);
r
'loadFile(fileOpen.getSelectedFile(»:
)
~l
privatevoidloadFile(Filefile)(
cardList
=
newArrayList<QuizCard>();
try(
BufferedReader
reader
=
newBufferedReader(new
Stringline
=
null:
while((line
=
reader.readLine()
I
!
=
null)(
makeCard
(line);
I
privatevoid
makeCUd(StxinglineTOi'U88)(
I
~
Eat.h
liYlt:
o.f
U1\.-t
t..on-uyonds
to•
s i,,~le
String()result
=
lineToParse.split("
I");
~.fl~hu
...d
blAt.'foIt:h6\1e
to
yal"~ ~
-the
QuizCardcard
=
newQuizCard(result{Oj,
resu.l
t
lLl
j
r
Iot:S'ti
~
dal\S'W£\'"asstf.lYab:yiet.e1,We
cardList.add(card);
~
Otl
~,
l'tO
tthoa
to
b...eak+.he
System.
out
i
prIntLn("madeacard")
j
~
the
SU"I~
s.?
I...
r.1L
st.i
IiI\(
i'llto
t'folOtokC'llS
(oM.
.,-«
VIe
'\\Iot
071
arod
0YIe
.t«
-the.1\1"",£\'"),We'lllookat
tht:
privatevoid
showNextCardO(
\itO
...dhod
Of!
theYlt:1\.-t
y,,~t,
currentCard
=
cardList.get(currentCardlndex);
~
currentCardIndex++;
display.setText(currentCard.getQuestion();
nextButton.setText("ShowAnswer");
isShowAnswer
=
true;
}
II
closeclass
youarehere
~
457
parsingStringswith
splitO
ParsittgwithStrhtgsplitCJ
Imagineyouhaveaflashcardlikethis:
SavedInaquestionfilelikethis:
What
is
blue
+
yellow?
clJ\S'fie\"
green
WhB.t
is
blue
+
yellow?
j
green
Wha.t1Bred
+
blue?jpurple
Howdoyouseparatethequestionandanswer?
Whenyoureadthefile,thequestionandansweraresmooshed
togetherinoneline,
separatedbyaforwardslash"
r
(because
that'showwewrotethefileintheQuizCardBuildercode).
StringsplitOletsyoubreakaStringIntopieces.
ThespJitOmethodsays,"givemeaseparator,andI'llbreakoutell
thepiecesofthisStringforyouandputthemin
0
Stringarray:
separator
token1
468
chapter14
Q:
OK,IlookIntheAPIandthereareaboutfive
mUllonclasses
IntheJava.lopackage.
How
theheckdo
youknowwhichones
touse?
A..:
TheI/OAPIusesthemodular'chaining'conceptso
thatyoucanhook
togetherconnectionstreamsandchain
streams(alsocalled'filter'streams)Inawiderange
of
combi
nations
togetJust
a
boutanythIngyoucouIdwant.
ThechaInsdon'thavetostopat
twolevels;youcanhook
multiplechainstreamstooneanothertogetjusttheright
amountofprocessingyouneed.
Most
ofthetime,though,you'llusethesame
sma
IIha
ndfu
I
ofclasses.Ifyou'rewrltingtextflies,
BufferedReaderandBufferedWriter(chainedtoFlIeReader
and
Fll
eWriter)
a
reprobablyallyouneed.Ifyou'rewrlting
serializedobjects,youcanuseObJeetOutputStreamand
ObJectlnputStream
(chained
toFllelnputStreamand
FileOutputStream).
In
otherwords,
90%
ofwhatyoumighttypicallydowith
JavaI/Ocanusewhatwe'vealreadycovered.
Q:
WhataboutthenewI/OnloclassesaddedIn1.41
A.:
The
[ave.nlo
classesbringa
big
performance
improvementandtakegreateradvantage
ofnative
capabilities
ofthemachineyourprogramIsrunning
on.One
ofthekeynewfeaturesofnloisthatyouhave
directcontrolofbuffers.AnothernewfeatureIs
non-
blockingI/O,whichmeansyourI/Ocodedoesn'tjustsit
there,waItIng,ifthere's
noth
Ingtoreadorwrite.Some
oftheexistingclasses(IncludingFllelnputStreamand
FlleOutputStream)takeadvantageofsome
ofthenew
features,underthecovers.Thenioclasses
are
more
complicatedtouse,however,sounlessyou
really
needthe
newfeatures,you
mightwanttostickwiththesimpler
versionswe'veusedhere.Plus,Ifyou're
notcareful,niocan
leadtoaperformance
loss.
Non-nloI/OIsprobablyright
for
90%
ofwhatyou'llnormallydo,especiallyifyou'reJust
gettingstartedInJava.
But
youcan
ease
yourwayIntothenloclasses,byusing
FilelnputStreamandaccessingits
channel
throughthe
getChannelOmethod(addedtoFllelnputStreamas
of
version1.4).
serializationand
file
1/0
Makeit.St.itk
Roses
arefirst,violetsarenext.
ext
Redders
and
w,lters
areonlyfor
t.
•Towrileatextfile,startwithaFileWriler
connectionstream.
•
Chain\heFileWritertoaBufferedWriterfor
efficiency.
•AFileobjectrepresents
a
fileataparticular
path,
but
doesnotrepresenltheactual
contents
of
thefile.
•With
a
File
obiect
you
can
create,traverse,
anddeletedirectories.
•
Moslstreams
that
can
use
aString
filename
can
use
a
Fileobjectaswell,anda
FJleobiect
canbesafer
10
use.
•
Toreadatextfile,
start
withaFileReader
connectionstream.
•Chain\heFileReaderto
a
BufferedReaderfor
efficiency.
•
Toparseatextfile.youneed
10
besurethe
fileiswrittenwithsomeway
to
recognizethe
differentelements.Acommonapproachisto
usesomeklndofcharacter
to
separatethe
individualpieces.
•Use
the
StringsplitOmethod
10
splitaString
upintoindiVidualtokens.AString
with
one
separatorwillhavetwotokens,oneoneach
sideof\heseparator.
Theseparator
doesn~
count
asa
token.
youare
here.
459
savingobjects
Versio"IP:AJigSerializatio"&otcha
Nowyou'veseenthatI/OinJavaisactuallyprettysimple,especially
if
yousticktothemostcommonconnection/chaincombinations.But
there'soneissueyoumight
really
careabout.
VersionControliscrucial!
!fyouserializeanobject,youmusthavetheclassinorderto
deserialize
andusetheobject.OK,that'sobvious.Butwhatmight
belessobviousiswhathappens
if
you
change
the
class
inthe
meantime?Yikes.ImaginetryingtobringbackaDogobjectwhen
oneofitsinstancevariables(non-transient)haschangedfroma
doubletoaString.ThatviolatesJava'stype-safesensibilitiesinaBig
Way.
Butthat'snottheonlychangethatmighthurtcompatibility.
Thinkaboutthefollowing:
Changestoaclassthatcanhurtdeseriallzatlon:
Deletinganinstancevariable
Changingthedeclaredtypeofaninstancevariable
Changinganon-transientinstancevariabletotransient
Movingaclassupordowntheinheritancehierarchy
Changingaclass(anywhereintheobjectgraph)fromSerializable
to
notSerializable(byremoving'implementsSerializable'froma
classdeclaration)
Changinganinstancevariabletostatic
•
•
•
•
YouwriteaDogclass
10UOl
101101".
\1"'1
10101000010∙∙\
,,~S\()Y\·
v
~~;~o
10
1
Q
taSS
1010101
~ ~~ ~~~~~O l ~;Ar;
Dog.class
YouserializeaDogobject
usingthatclass
Youchange
theDogclass
~ ~~i~ ~
\.
\D
~:~:O ~ ~':
tlas
s
>JeYSIO'l\
Ol010
1.
;o ~~ ~o:~:o:H=12-~
1.
01.1010
Dog.c1ass
YoudeserializeaDogobject
usingthechangedclass
ChangestoaclassthatareusuallyOK:
Addingnewinstancevariablestotheclass(existingobjectswill
deserializewith
defaultvaluesfortheinstancevariablestheydidn't
havewhentheywereserialized)
Addingclassestotheinheritancetree
Removingclassesfromtheinheritancetree
Changingtheaccesslevelofaninstancevariablehasnoaffecton
theabilityofdeserializationtoassignavaluetothevariable
Ch
anginganinstancevariablefromtransienttonon-transient
(previously-serializedobjectswillsimplyhaveadefaultvalueforthe
previously-transientvariables)
460
chapter14
101101
10UOl'"
101000010
1010100
01.0101
C
1000011010
o
00110101
1.
011010
Dog.class
t\a
ss
>Jeys',OYl'IS
:H=12-~
•Serailizationfails!!
The
JVM
says,
"youcan't
teachanoldDognewcode".
Usi.,gtheserialVersio.,UIP
Eachtimeanobjectisserialized.theobject(including
everyobjectinitsgraph)is'stamped'
with
aversion
ID
numberfortheobject'sclass.Theilliscalled
the
serialVersionUlD,andit'scomputedbasedon
information
abouttheclassstructure.
As
anobjectis
beingdeserialized,
if
theclasshaschangedsincethe
object
was
serialized,theclasscouldhave
a
different
serialVersionUID,
and
deserialization
will
faill
Butyou
cancontrolthis.
IfyouthinkthereIsANYpossibilitythat
yourclassmight
evolve,
putaserialversion
IDInyourclass.
WhenJavatriestodeserializeanobject,itcompares
theserializedobject'sserialVersionUIDwiththatofthe
class
the
JVM
isusingfordeserializingtheobjectFor
example,ifaDoginstance
was
serializedwithanillof,
say
23
(inreality
a
serialVersionUID
is
muchlonger).
whentheJVM
deserializes
theDogobjectit
will
first
comparetheDogobjectserialVersionUIDwiththe
DogclassserialVersionUID.
If
thetwonumbersdon't
match,rhejVMassumesthe
class
isnotcompatible
withthepreviously-serializedobject,andyou'llgetan
exceptionduring
deserialization.
So,thesolution
is
toputaserialVersionUID
in
yourclass,andthenastheclassevolves,the
serialVersionUIDwillremainthesameandthe
JVM
willsay.
"OK,
cool,theclassiscompatiblewiththis
serializedobject."even
thoughtheclasshasactually
changed.
Thisworks
()1lly
if
you'recarefulwithyour
class
changes!
In
otherwords.
YQU
are
taking
responsibility
for
any
issuesthatcomeupwhen
an
olderobject
is
broughtbacktolifewithanewer
class.
TogetaserialVersionUIDforaclass,usetheserialver
tool
thatshipswithyourJavadevelopment
kit.
serializationandfile110
Whenyouthinkyourclass
mightevolveaftersomeonehas
serializedobjectsfrom
it•••
@
Use.theserialvercommand-linetoo'
togettheversionIDforyourcloss
CD
Pastetheoutputintoyourcloss
publicclassDog{
long.erialVersionOZD-
-6849194410154667110L;
privateStrinqname;
privateintsize;
//methodcodehere
~
Besurethatwhenyoumakechangesto
thecloss,youtakeresponsibilityinyour
codefortheconsequencesofthechanges
youmade
tothe
clossl
Forexample,be
surethatyournewDogclosscandealwith
an
old
Dogbeingdeserializedwithdefault
valuesforinstancevariablesadded
to
the
doss
after
theDogwasserialized.
youarehere
~
461
CodeKitchen
'*
*
Code
Kitchen
Let's
mak
theBeatBoxsaveand
restoreourlavoritepattern
462
chapter14
for(inti
=
0;i
<
256;i++){
serializationandfileI/O
SavinGa'eatJoxpattern
Remember,intheBeatBox,adrumpatternisnothingmorethanabunchof
checkboxes.Whenit'stimetoplaythesequence,thecodewalksthroughthe
checkboxestofigureoutwhichdrumssoundsareplayingateachofthe16
beats.Sotosavea
pattern,allweneedtodoissavethestateofthecheckboxes.
We
canmakeasimplebooleanarray,holdingthestateofeachofthe256
checkboxes.Anarrayobjectisserializableas
longasthethings
in
thearrayare
serializable,sowe'llhavenotroublesavinganarrayofbooleans.
To
loadapatternbackin,wereadthesinglebooleanarrayobject(deserialize
it),
andrestorethecheckboxes.Mostofthecodeyou'vealreadyseen,inthe
CodeKitchenwherewebuilttheBeatBoxGUI,sointhischapter,welookat
only
thesaveandrestorecode.
ThisCodeKitchengetsusreadyfor
thenextchapter,whereinsteadofwriting
thepatterntoa
file,
wesenditoverthe
network
totheserver.Andinsteadof
loadingapattern
in
fromafile,wegetpatternsfromthe
server,
eachtimea
participantsendsonetotheserver.
Serializingapattern
Thisisaninnert\assi'llSide
t.he
Beat.Bo~
zede.
publicclassMySendListenerimplementsActionListener{
l'\.,,,
t.he
It.allhappens..,hen"he
~er
".s
publicvoidactionPerformed(ActionEventa)
{~b~Hon
andt.heAd:ionE.'Ient..{\res.
boolean[]checkboxState
=
newboolean[256];
t--
Zt
arbooleatlarray
to
hold
t.he
01"
eath
the'kbo~.
JCheckBoxcheck
=
(JCheckBox)
if(check.isSelected(»{
checkboxState[i]
=
true;
checkboxList.get(i);
Walk
t.hro~
ht.h
(ArrayList.gote
thetkbo~List
gett.hestate
thetkbo~ s),
atld
add
it
to
t
0+
eathOtle,
and
heboo/
eatl
array.
try{
FileOUtputStreamfileStream
=
newFileOUtputStream(newFile("Checkbox.ser"»;
ObjectOUtputStreamos
=
newObjectOUtputStream(fileStream);
os.writeObject(checkboxState);
catch(Exceptionex){
ex.printStackTrace();
}II
closemethod
II
closeinnerclass
youarehere).463
deserlallzlngthepattern
Resfori.,g
a
Jea1tox
patter"
Thisisprettymuchthesaveinreverse...readtheboolean
array
anduseit
torestore
thestateoftheGUIcheckboxes,Itallhappenswhentheuserhits
the"restore"
'button.
Restoringapattern
public
class
MyReadInListenerimpleJDentaActionLiataner
publiCvoid
actionPerfor.med(ActionEventa)
boolean[]checkboxState:;;;;null;
try(
FilelnputStreamfilaIn:;;;;newFilelnputstream(newFile("Checkbox.aer"»;
ObjectInputstreamis•newObjectInputStream(fileIn);
checkboxState
=
(boolean[])
is.
readObject();
t---
Rao
-the
s"",~'e ~jed:
i".
the
kil~~e
boolea"array>o"d
ta1-tIt
W.0
catch(Exceptionex)(ex.
printstackTrac.();}
boolea"
arr0'i
(Yl:1"etI'w.
ytaoObjett
\'"d~."s
ayet
~a-.te
ok
~e
Ob}et
for
(int
i:;;;;
0;
i
<
256;
i++)(
JCb.eckBoxcheck
:::r
(JCheckBox)
if
(eheckboxState
till(
ohaek.satsalected(trua);
}elae(
eheck.aetselected{false);
aheokboxLillt.
get
(1);
sequencer.stop();
buildTrackAndStart();
}II
close
I118thod
II
closeinnerclass
rpenyour
penCiI-----------------,
ThisversionhasahugeIImltatlonlWhenyouhitthe"serlatlzelt"button,It
serlaIIzesautomatlca
lIy,
toafilenamed"Checkbox.ser"(whichgetscreatedIfIt
doesn'texist).Buteach
timeyousave,youoverwritethepreviously-savedflIe.
Improve
thesaveandrestorefeature,byIncorporatingaJFlleChoosersothat
youcannameandsaveasmanydifferentpatternsasyoulike,andloadlrestore
from
any
ofyourprevIously-savedpatternflies.
464chapter14
~yourpenCii
serializationandfile
110
can
they
he
saved?
Whichofthesedoyouthinkare,orshouldbe,
serlallzable?If
not,whynot?Notmeaningful7
Securityrls
k7Onlyworksforthe
CU
Trent
execution
oftheJVM?Makeyourbestguess,
withoutlookingitupintheAPI.
Objecttype
Serlallzable?
If
not,
why
not?
Object
Ves
I
No
String
Yes
I
No
FileYes
I
No
DateVes
I
No
OutputStreamYes
I
No
JFrame
Yes
I
No
IntegerYes
I
No
System
Ves
I
No
WharsLegalil
:lrclethecodefragments
nat
wouldcompile(assuming
:hey'rewithInalegaIdass).
KEEP
+-
RIGHT
FileReaderfileReadar
~
newFileReader()
i
BufferedReaderreader::new
BufferedReader(fileReader);
FileC>utputStream
f::
newFileOutputStream(newFile
("roo.
se.r"));
ObjectOutputstream
08::
newObjectOutputStream(f);
BufferedReaderreader::newBufferedReader(newFileReade.r(file));
Stringline
=
null;
whila(line•
reader.readLine())!=
null)(
malcecard(line);
ObjectInputStreamis
=
newObjectInputstream(newFil&Outputstream("Game.ser"));
GameCharacteroneAgain
=
(Gamecharacter)is.readObject();
youarehere
~
465
exercise:TrueorFalse
Thischapterexploredthewonerfulworldof
Java
110.YourJob
Is
todecidewhethereach
ofthefollowinglID-relatedstatementsis
trueorfalse.
1.Serializationisappropriatewhensavingdatafornon-javaprogramstouse.
2.
Objectstatecanbesavedonlybyusingserialization.
3.
ObjectOutputStream
isa
classusedtosaveserializedobjects.
4.
Chainstreamscanbeusedontheirownor
with
connectionstreams.
5.A
singlecalltowriteObjectOcancausemanyobjectstobesaved.
6.Allclasses
areserializablebydefault.
7.
Thetransientmodifierallowsyoutomakeinstancevariablesserializable.
8.
If
asuperclassisnotserializablethenthesubclasscan'tbeserializable.
9.
Whenobjectsaredeserialized,theyarereadbackinlast-in,
first
outsequence.
10.Whenanobjectisdeserialized,itsconstructordoesnotrun.
11.Bothserializationandsavingtoatextfilecanthrowexceptions.
12.BufferedWriters
canbechainedtoFileWriters.
13.Fileobjects
representfiles,butnotdirectories.
14.You
can'tforceabuffertosenditsdatabeforeit'sfull.
]5.Bothfilereadersandfilewriterscanbebuffered.
16.
TheStringsplitOmethodincludesseparatorsastokens
in
theresultarray.
17.Any
changetoaclassbreakspreviouslyserializedobjectsofthatclass.
466
chapter14
-
C
J
u
serialization
and
file110
o
elYlaonets
Thisone'stricky,
~
we
promoted
itfromanExercisetofullPuzzlestatus.
Reconstructthecodesnippetstomakeaworking
Javaprogramthat
producesthe
outputlistedbelow?(Youmightnotneedallofthemagnets,
andyoumayreuseamagnetmorethanonce.)
return
Zi
short
getZ(){
009.
close():
e.printStackTrace()i
fos
=
new
FileOutputstrearn
(
"drr,ser")i
FileOutputs
tream
~
seriali'Zabl
e
{
classDungeonGameimplements
ObjectlnputStreamois
=
new
ObjectlnputStream(fis);
int
geU(){
return
Xi
System.out.println(d.getX()+d.getY()+d.getZ())i
Filelnputstreamfis
=
newublicintx
=
3;
FilelnputStream("dg.ser")j
ransient
long
y
=
4;
private
short
z
=
5;
longgetY(){
return
y;
class
D
ungeOnTest
<
ois,close();
fos.writeObject(d);
import
java.io'~i
~
----••"I}
catch(Exceptione){
d
=
(DungeonGame)ois.readObject()j
youarehere
~
467
'dmain(String
I
J
arg9){
public
static
vo~
d
DUngeonGame():
DungeonGame
=
new
ObjectOutputstream009
=
new
ObjectOutputStream(fos):
oos.writeObject(d);
exercise
solutions
1.Serializationisappropriatewhensavingdatafornon:Javaprogramstouse.
False
2.Objectstatecanbesavedonlybyusingserialization.
False
3.ObjectOutputStreamisaclassusedtosaveserializedobjects.
True
4.Chainstreamscanbeusedontheirownorwithconnectionstreams.
False
5.AsinglecalltowriteObjectOcancausemanyobjectstobesaved.
True
6.Allclassesareserializablebydefault.
False
7.Thetransientmodifierallowsyoutomakeinstancevariablesserializable.
False
8.Ifasuperclassisnotserializablethenthesubclasscan'tbeserializable.
False
9.Whenobjectsaredeserializedtheyarereadbackinlast-in,firstoutsequence.
False
10.Whenanobjectisdeserialized,itsconstructordoesnotrun.
True
11.Bothserializationandsavingtoatextfilecanthrowexceptions.
True
12.BufferedWriterscanbechainedtoFileWriters.
True
13.Fileobjectsrepresentfiles,butnotdirectories.
False
14.Youcan'tforceabuffertosenditsdatabeforeit'sfull.
False
15.Bothfilereadersandfilewriterscanoptionallybebuffered.
True
16.TheString
splitf)
methodincludesseparatorsastokensintheresultarray.
False
17.Any
changetoaclassbreakspreviouslyserializedobjectsofthatclass.
False
468
chapter14
Fit
~ ~ W1~
HelpEs:apo
\javaDungeonTest
12
8
serialization
and
file
110
classDungeonGameimplementsSerializable{
publicintx
=
3;
transientlong
y
=
4:
privateshort
z
=
5:
intgetX(){
return
Xj
}
longgety(){
return
Yj
}
shortgetZ(){
return
2:
}
}
classDungeonTest{
publicstaticvoidmain(String[)args)(
DungeonGamed
=
newDungeonGame{)j
System.out.println(d'getX()
+
d.getY()
+
d.getZ{»j
try(
FileOutputStreamfOB
=
newFileOutputStream{Udg.ser
H
):
ObjectOutputStreamoos
=
newObjectOutputStream(foB)j
oos.writeObject(d);
oos.close():
FilelnputStreamfis
=
newFilelnputStream(Udg.ser
n
):
ObjectlnputStreamois
=
newObjectlnputStrearn{fis):
d
=
(DungeonGame)ois.readObject();
ois.close();
catch(Exceptione){
e.printStackTrace()j
)
system.out.println(d.getX()
+
d.getY{)
+
d.getZ{»;
}
youarehere.
469
15
networkingandthreads
MakeaConnection
Connectwiththeoutsideworld.
YourJavaprogramcanreachoutandtoucha
programonanothermachine.It'seasy.Allthelow-levelnetworkingdetailsaretakencareofby
classesInthejava.netlibrary.OneofJava'sbigbenefitsisthatsendingandreceivingdataover
anetworkIsJustI/O
withaslightlydIfferentconnectionstreamattheendofthechain.Ifyou've
gotaBufferedReader.youcan
read.
AndtheBufferedReadercouldcarelessifthedatacame
outofafileorflewdownanethernetcable.Inthischapterwe'llconnecttotheoutsideworld
withsockets.We'llmake
cllent
sockets.We'llmake
server
sockets.We'llrnake
clients
and
servers.
Andwe'llmakethemtalktoeachother.Beforethechapter'sdone,you'llhaveafully-functional,
multithreadedchatclient.Oldwejustsay
multithreaded?
Yes,nowyou
will
learnthesecretof
howtotalktoBobwhilesimultaneouslylisteningto
Suzy.
thisisanewchapter
471
tbo)(.
chat
You'reworkingonacomputergame.Youandyourteam
are
doingthesounddesignforeachpartofthegame.
Usinga'chat'versionoftheBeat
'Box,
your
team
can
collaborate-Youcansendabeatpatternalongwith
your
chatmessage,andeverybody
in
theBeat
BB:O"~C:h:a:t
__
-:r~~~;si~~~@~c::~~;1
getS
.i~
So
yO,u
don'tjustgetto
rtad\
th
d
e
othder...""'\<IO.sl'I"...•
0>"
"I<.t
pa",clpa.
lS
",,,sages.yoUgel
10
oaan
e....-..
;;;;.<""...
pl<ry
abea
l
patterns,,,,ply
by
chclcingthe,-'
<en
me"'".....ee,.
messageintheincomingmessagesarea.
~~ ~
Inthischapterwe'regoing
10
learnwhat
,t
Go
,.f'∙..
_t\
t\
1\
t''-
l'\\
to\!.
.
.'
'
.'-'
,.
....
"",
,."
,"-
,
takes
10
",akeachatchenlhketh".We're
oc
,,.n"
,<t."""
evengoing
10
,earnahlde.boUI",akinga
If
>;'f""'".....
<1'-;
cba
IS,,"'"
We
'n
savethe
fun
Beat
Be'
Chat
t:..',
In..."
r\~
"'"
fortheCodelGochen.butinmischapteryou
\00""""
",iUwn""LudicrouslySi",pleChatClientand
t"''''''
VerySi",pleChatSe",erthatsendand,eceive
~~
""
,.,fI'''''''
"'''m"",g'"
<;t,
s."""",
472
chapter'\5
networkingandthreads
ChatProgramOverview
The
Client
has
to
know
ahoutthe
Server.
The
Server
has
to
know
about
ALL
theClienti.
How
it
Works:
ClientC
ClientA
Server
Server
~V~,
I'd
lik~
to
l.o9I~t
-to
tht
t~
stHite
ClientA
ClientB
G
Theservermakesa
connectionandadds
theclient
to
thelistofparticipants
e
Anotherclientconnects
o
Clientconnectstotheserver
o
ClientAsendsamessageto
thechatservice
"Whotook
~
lava
liMf__
---1
-
~---.
My
OOhtl
f
---
ClientA
-~~
I ~
.
I
~.
'.-
Server
o
Theserverdistributesthe
messagetoALLparticipants
(including
theoriginalsender)
ClientA
Server
ClientB
youarehere
~
473
socketconnecllons
Thethreethingswehavetolearntogettheclientworkingare:
1)Howtoestablish
theinitialconnectionbetweentheclientandserver
2)How
to
sendmessages
UJ
theserver
S)How
to
receivemessagesjromtheserver
There'salotoflow-levelstuffthathastohappenforthesethingstowork.Butwe're
lucky,becausetheJavaAPInetworkingpackage(java.net)makesitapieceofcake
forprogrammers.You'llseealotmoreGUIcodethannetworkingandI/Ocode.
Andthat'snot
all.
Lurkingwithinthesimplechatclientisaproblemwehaven'tfacedsofarinthis
book:
doingtwothingsatthesametime.Establishingaconnectionisaone-time
operation(thateitherworksorfails).Butafterthat,achatparticipantwantsto
sendoutgoingmessages
andsimultaneously
receiveincoming7TU'.SSages
fromtheother
participants(viatheserver).Hmmmm...thatone'sgoingtotakealittlethought,but
we'llgetthereinjustafewpages.
ClientA
o
Connect
Clientconnectstotheserverby
establishinga
Socket
connection.
Ma~
a
sotlcd:.
l.mIPlettiO'll
to
J~I>.lbt.r.rO;
.if.
rort
c;ooo
•Send
Client
sends
amessage
tothe
server
Client
A
e
Receive
Client
gets
amessagefromtheserver
ClientA
474
chapter15
networkingandthreads
Client
MakeattetworkSocketcotntectiott
=
new
Socket(~196.164.1.103H,
lr:ci
rt1S
~or
thesa-vt:r
7
Port
1l""'ba-
5000);
TomakeaSoc"ket
connection,
you
need
to
know
~
things
aboutthe
server:
%0
it
is,
and
whichport
itsrunning
OIL
In
otherwords,
IP
addressand
TCP
portl11U1lher.
SocketchatSocket
Toconnecttoanothermachine,weneedaSocketconnection.
ASocket(java.ner.Socketclass)isanobject
thatrepresents
anetwork
connectionbetweentwomachines.What'sa
connection?Arelationshipbetweentwomachines.where
two
piecesofsoftwareknowabouteachother.
Mostimportantly,
thosetwopieces
ofsoftwareknowhowto
communicatewith
eachother.Inotherwords.howtosendbitstoeachother.
We
don'tcareaboutthelow-leveldetails,thankfully,because
they're
handledatamuchlowerplaceinthe'networking
stack'.
If
youdon'tknowwhatthe'networkingstack'is,don't
worryabout
it.
It'sjustawayoflookingatthelayersthat
information(bits)musttravelthroughtogetfromaJava
programrunningin
aJVM
onsomeOS,tophysicalhardware
(ethernetcables,forexample).andbackagainonsomeother
machine.
Somebody
hastotakecareofallthedirtydetails.
But
notyou.Thatsomebodyis
a
combinationof
O~pecific
softwareandthe
Java
networking
API.
Thepartthat
you
have
toworry
about
is
high-level-makethat
v~
high-level-and
shockinglysimple.Ready?
A
Socketconnection
means
thetwo
machineshave
inforztlationabouteach
other,
including
networl
location
(IP
address)
and
TCPport.
youarehere
~
475
well-knownports
A
rep
port
IsJustattutltber.
A16...bitttutMber
that
identifies
aspecificprograttt
Ott
theserver.
Yourinternetweb(HTTP)server
runs
onport80.That's
a
standard.
If
you'vegotaTelnetserver,itsrunningonport
23.FTP?20.POP3
mailserver?110.
SMTP?25.
TheTime
serversitsat37.Think
of
portnumbers
as
uniqueidentifiers.
Theyrepresent
a
logicalconnection
to
aparticularpieceof
softwarerunningontheserver.That'sit.Youcan'tspinyour
hardwareboxaroundandfind
a
TCP
port.Foronething,
youhave
65536
ofthemonaserver
(0-65535).
Sothey
obviouslydon'trepresent
a
placetopluginphysicaldevices.
They'rejust
a
numberrepresentinganapplication.
Withoutportnumbers,theserverwouldhavenowayof
knowingwhichapplication
a
clientwantedtoconnectto.
Andsinceeachapplicationmighthaveitsownunique
protocol,
think
ofthetroubleyou'dhavewithoutthese
identifiers.What
if
yourwebbrowser,forexample,landed
atthe
POPS
mailserverinsteadofthe
HTTP
server?The
mailserverwon'tknowhowtoparse
an
HTTPrequest!And
even
if
itdid,the
POPS
serverdoesn'tknowanythingabout
servicingthe
HTTP
request
Whenyouwriteaserverprogram.you'llincludecodethat
tellstheprogramwhichportnumberyouwantitto
nul
on
(you'llseehowto
do
this
inJavaalittlelaterinthischapter).
IntheChatprogramwe'rewritinginthischapter.wepicked
50DD.Justbecausewewantedto.
And
because
it
metthe
criteriathatitbeanumberbetween
1024
and
65535.
Why
I024?Because0
through1023arereservedforthewell-
knownserviceslike
theoneswejusttalkedabout,
And
if
you'rewritingservices(serverprograms)torunon
a
companynetwork,youshouldcheckwiththe
sys-admins
to
findoutwhichports
are
alreadytaken.
Yoursys-admins
might
tell
you,forexample,thatyoucan'tuseanyport
numberbelow,
say,
3000.
Inanycase,
if
youvalueyourlimbs,
you
won'tassignportnumberswithabandon.
Unless
it's
your
home
network.Inwhich
case
youjusthavetocheck
with
your
kids.
476
chapter
15
Well-knownTCPportnumbers
for
commonserverapplications
A
seY"'er"
l.4...
helVe
"p
to
b&5~b
diHf"r'etltserve-apps
'nIIInil'\~
~
per"pori:.
The
TCPport
tuU1lbersfrOttl
0
to
1023
arereservedforwell-
"known
services.
Don't
usethem
foryour
own
server
programs!'"
The
chatserverwe're
writing
uses
port
5000.
We
just
}tie"keda
tuU1lber
between
1024
and
65535.
'Well,you
might
be
able
10
useoneof
these.
bul
thesys-adrnlnwhere
you
work
willprobablykill
you.
Q:
Howdoyouknowtheport
numberofthe
server
programyou
wantto
talk
to7
A.:
Thatdependsonwhetherthe
programisoneofthewell-known
services.Ifyou'retryingtoconnect
toawell-knownservice,liketheones
ontheopposItepage
(HTIp'
SMTP,
FTP,etc.)youcanlooktheseupon
theInternet(Google"Well-Known
TCPPort").Oraskyourfriendly
eighborhoodsys-adrnin.
Butiftheprogramisn'toneofthe
well-knownservices,youneedto
find
outfromwhoeverIsdeploying
theservice.Askhim.Orher.Typically,
if
someonewritesanetworkservice
andwantsothersto
writeclientsfor
it,they'llpublishthelPaddress,
port
number,andprotocolfortheservice.
~
orexampie,ifyouwanttowritea
clientforaGOgameserver,youcan
visitone
oftheGOserversitesand
findInformationabout
howtowritea
client
for
thatparticularserver.
networking
and
threads
IPaddressislikespecifyinga
particularshoppingmoll,
soy,
"FlatironsMarketplace"
or
number
is
likenaming
a
specificstore,
soy,
"Bob'sCDShop"
OK,yougotaSocketconnection.Theclientandthe
serverknowtheIPaddressand
Tep
portnumberfor
eachother.Nowwhat1
Howdoyoucommunicate
over
thatconnection11notherwords,howdoyou
movebits
fromonetotheother?Imaginethekindsof
messagesyourchatclientneedstosendandreceive.
Q:
Can
there
ever
be
more
than
oneprogramrunningon
a
single
port7
Inotherwords,cantwo
applicationson
thesame
server
have
thesame
port
number7
A.:
NolIfyoutrytoblndaprogram
:0
aportthatIsalreadyinuse,you'll
getaBindException.To
bind
aprogram
:0
aportjustmeansstartingupa
serverapplicationandtellingIttorun
aparticularport.Again,you'lllearn
~ o r e
aboutthiswhenwegettothe
serverpartofthischapter.
Client
Server
youarehere
~
477
To
readdatafrotH
aSocketusea
SufferedReader
TocommunicateoveraSocketconnection,youusestreams.
Regularold
I/Ostreams.justlikeweusedinthelastchapter.One
ofthecoolestfeatures
in
javaisthatmostofyourI/Oworkwon't
carewhatyourhigh-levelchainstream
is
actuallyconnectedto.In
otherwords,youcanuseaBufferedReaderjustlikeyoudidwhen
youwerewritingtoafile,
thedifferenceisthattheunderlying
connectionstreamis
connectedtoaSocketratherthanaFile!
e
MakeaBufferedReaderandreadI
readingfromasocket
L\-.
ii,n
'foU
kno-.l
TM
forl:.
,",""g~b
-.I
+.hat
"000
is
h~t.1\OU -.I~
TOL
~
'fou
t.hat
~t:r.
o
MakeaSocketconnectiontotheserver/
t.\It
~
"",",ht:r
~(K
oU'r
SocketchatSocket
~
newSocket("127.0.0.1",5000);
"-../27.0.o.J
i$
t.h
z:
'N~ds J +f.~ I~:d~~~
tor
'11~lhoti
...
"
~
Ulis
'oIh)
I.lI
t.od~
i.s....)
'n
S~Vtt-
bI
Yot.
r~
tub
"")\11\901\.
You
01\d
.sjI\SI~
rt.
~
you.r
tJ
t
I
)\d-aIOtlt
"'clth.
'bI
dnd
e
MakeanInputStreamReaderchainedtotheSocket's
rr>e.
low-level(connection)inputstream
1L.
&oH~(dReAdt:r
b:>
~~
d
1-
tnt
10-.1-
Chai"
V'C'
d(
nit\-.
wast\-.ai"t
'UJ,...\•
..l.)
(
\"ovtSb-ta""Rea~_
w
AJ.
~'r()7f\
tr.(
~
I1:
S"t.Tta'"
-.It
'J"'''
\('<It!
to'l\,,(tuOl\
BufferedReaderreader
=
newBufferedReader(stream)
i
Stringmessage
=
reader.readLine();
Client
bufferedcharactersconvertedtocharactersbytesfromserver
buffered
~
I
characte.rs,.
I
011010011
1'+∙---
characters
chained
to
chained
to_
BufferedReader
InputStre.amRe.aderSocket'sinput
stream
(we.don'tneedtoknow
the.aCf\JQ1class)
-
-
----
-
I
:'
r.
I
Server
478chapter15
e
~
(print)something
networkingandthreads
fo
writedatato
aSocketuse
a
Prh1tWriter
Wedidn'tusePrintWriterinthelastchapter,weusedBufferedWriter.Wehave
achoicehere,
butwhenyou'rewritingoneStringatatime,PrintWriteristhe
standardchoice.Andyou'llrecognizethetwokeymethodsinPrintWriter,
printOandprintln()IJustlikegood
01'
System.out,
o
MakeaSocketconnectiontotheserver
SocketchatSoeket
=
newSoeket("127.0.0.1",
e
MakeaPrintWrlterchainedtotheSocket'slow-level
(connection)outputstream
PrintWriterwriter
=
newPrintWrit8r(chatsocket.qetoutputStream(»;
I
\
.l
~t
ClIO
~
..,\\at
it.
se..o.s∙
.1I
0
ods
a
I\tfoI
,roeaT.
writer.println("messaqetosend");
~rrl"U"
a.
'L
J
o
-tht
"CW\I"t.∙
writer.print("anothermessage");
~rri"t() cl.~""
iu
characters
----+~
I.
message..."
PrintWriter
bytestoserver
I
~
011010011
chainedto
'----_--I
Socket'soutput
stream(wedon'tneed
toknowtheactual
class)
you
arehere)479
writing
aclient
fhePailyAdvieeCliet1t
BeforewestartbuildingtheChatapp,
let'sstartwith
somethingalittlesmaller.
TheAdviceGuyisaserverprogramthat
offersuppractical,inspirationaltips
to
getyouthroughthoselongdaysof
coding.
We'rebuildingaclientfor
TheAdvice
Guyprogram,whichpullsamessage
fromtheservereachtimeitconnects.
Whatareyouwailingfor?Who
kncws
whatopportunitiesyou'vemissed
withoutthis
app.
The
Advice
Guy
o
Connect
Clientconnectstotheserverandgetsan
inputstream
fromit
Client
eRead
ClientreadsamessQgefromtheserver
ClientA
480
chapter15
catch(IOExceptionex){
reader.close();
~th is
doses
AI-I-
thestreaMS
networkingandthreads
PailyAdviceCliet1tcode
ThisprogrammakesaSocket,makesaBufferedReader(withthe
helpofotherstreams),andreadsasinglelinefromtheserver
application(whateverisrunningatport4242).
importjava.io.*;
r_.,.-L
isin,o"a.
nt1
:.
L-_~
tla
ss
;:,Q<o~~
.,}
import
java.net.*;~
publicclassDailyAdviceClient
InputStreamReaderstreamReader
=
newInputstreamReader(s.getlnputstream(»;
BufferedReaderreader
=
newBufferedReader(streamReader);
thaina
B~~e\'"edRe o d e\'"
to
f---""
art
Irty~+.s treaMRe a de\'"
to
the
i n f ~ t
str'ea",t\'"OMthe
Sotkd
:..
stringadvice
=
reader.readLine();
~
thisreadL'
o.
thIhe
IS
EXAc
System.out.println("Todayyoushould:"
+
advice);
Be
sa"'e
a s;~
0'"
TL'(
",UeredR.
d
't
were
~ih~
a
Ih
otherweaer
lhaihed
to
a
FI
lall
a
B.
r
r-
ds
,
by
the
1;'
LE..
fAot-teredW"'t''''e
yOl.t
writerdOt;sh't
k
h
r.er"'ethod,the
thelharalters
la
ow
0:
larewhere
"'e-tro",.
ex.printStackTrace();
publicstaticvoidmain(String[]args)
DailyAdviceClientclient
=
newDailyAdviceClient();
client.go();
youarehere.
481
socketconnecUons
Testyourmemoryofthestreams/classesforreadingandwritingfroma
Socket.Try
nottolookattheoppositepagel
To
read
textfromaSocket:
Client
To
send
texttoaSocket
Client
'M'iU!
dra..,
il'l
t.h~
thaill
o-f
sttea....s
t.he
tlitl'lt.
I.I$tS
to
read
.f"'OM
t.ht
st'r'/er
'M"iW
draw
illthethaill
o-f
sttUMSthe
t1iblt
lAStS
to
smd
~i"5
to
the
~ver
-
..
-
.
,
!
\
\'
server
rpenyour
pencU------------------.
FillIntheblanks:
WhattwopiecesofInformationdoestheclientneedinordertomakea
Socketconnection
withaserver?
Which
TCPportnumbersarereservedfor'well-knownservices'likeHTTPandFTP7
TRUEorFALSE:TherangeofvalidTCPportnumberscanberepresented
byashortprimitive?
482
chapter15
networkingandthreads
Wrifittgasitttpleserver
Sowhat'sittaketowriteaserverapplication?Justa
couple
ofSockets.Yes,acoupleas
in
two.
AServerSocket,
which
waits
forclientrequests(whenaclientmakesa
new
Sockett)
andaplainoldSocketsockettousefor
communication
with
theclient.
How
it
Works:
~ ~ ~ ~
.)
...
\
Thisstartstheserverapplicationlistening
forclientrequestscominginforport4242.
o
ServerapplicationmakesaServerSocket,onaspecificport
SarverSocketserverSock:newS&rV8rSocket(4242);
'II'':~;';;;~'
.,
....
l
Clie.ntknowstheIPaddressandportnumber
(publishedorgiventohimbywhomever
configures
theserverapptobeonthatport)
e
ClientmakesaSocketconnectiontotheserverapplication
Socketsock
=
newSocket("190.165.1.103",
42(2);
SD",,~~et.
rs::~~ ~
.
.
.
...
.
~ ~
.
e
ServermakesanewSockettocommunicatewiththisclient
Socketsock
=
serverSock.accept();
TheacceptOmethodblocks(justsitsthere)while
it'swaiting
forac1ie.ntSocketconnection.Whena
client
finallytriestoconnect,themethodreturns
aplainoldSocket(ona
different
port)thatknows
howtocommunicatewiththedient(i.e..knowsthe
client's
IPaddressandportnumber).TheSocketison
Cl
differentportthantheServerSocket,sothatthe
ServerSocketcangobacktowaitingforotherclients.
youarehere.483
importjava.io.*;
importjava.net.*;
writingaserver
PailyAdviceServercode
ThisprogrammakesaServerSocketandwaitsforclientrequests.When
it
gets
a
clientrequest(i.e.clientsaidnewSockett)forthisapplication),theserver
makesanewSocket
connectiontothatclient.TheservermakesaPrintWriter
(using
theSocket'soutputstream)andsendsamessagetotheclient.
(
Ley
t.hese
St.yiYl~
Ye",e",v
I
db
weyewov-d-wYa""N
'f
t.helodeeditov-∙e.veYe
hit.
Yet.~yYI
iYlt.he
",I(ldl
ubl
'1D'lAd'S,.
0'"
t.hisatta'f
r
1"1...'
I)
1
paccassaa,yva.ceerver
dail'fadvilelO"'CS
n
O't
a
.:>"YlYI~.
'?
String[]adviceList
=
{"Takesmallerbites",
"Go
forthetightjeans.NotheydoNOT
makeyoulookfat.","Oneword:inappropriate","Justfortoday,behonest.Tellyour
bosswhatyou*really*think","Youmightwanttorethinkthathaircut."};
publicvoidgo()(
try
PrintWriterwriter
=
newPrintWriter(sock.getOutputStream(»;
St~ing ad~ice
=
ge~vice();~
wrJ.ter.prJ.ntln(advJ.ce);
~
1'I0W
we
~
thSot
writer.close();.
~
...
aked
P
~
W.
ketlOlll'lettiol'l
to
thet1iel'lt
to
System.out.println(advice);
advile
1'"11,
I'"T'Uhl'"
dl'ldselldit(pt"il'ltlI'lO>aStl'"il'lQ
I...
tssa~t.
tl'lwedostthSotk-1.
b
J
weredOl'ltwiththis
ll'
1.e
q
tta~t
Itl'll:,
catch{IOExceptionex)(
ex.printStackTrace();
)
}II
closego
privateStringgetAdvice(){
intrandom
=
(int)(Math.randomO*adviceList.length);
returnadviceList[random];
publicstaticvoidmain(String[]args)(
DailyAdviceServerserver
=
newDailyAdviceServer();
server.go{);
484chapter15
,.,JI
BrainBarbell
How
does
the
server
knowhow
to
communicatewiththedlent?
TheclientknowstheIPaddressandport
numberoftheserver,buthowistheserver
abletomakeaSocketconnection
withthe
client(andmake
Inputandoutputstreams)?
Thinka
bouthow/when/wheretheserver
getsknowledgeabout
theclient.
therelare~~
DUmb
~uestl9ns
~:
Theedvlceservercodeontheopposite
pagehas
IJ
VERYseriouslimitation-itlooks
likeItcanhandleonly
oneclientatatlmel
.A:
Yes,that'sright.Itcan'tacceptarequest
fromaclientuntllithasfinishedwiththe
currentc/lentandstartedthenextIterationof
theinfiniteloop(whereItsitsattheacceptO
calluntila
requestcomesIn,atwhichtimeIt
makesaSocketwith
thenewclientandstarts
theprocessoveragain).
Q.:
Letmerephrasetheproblem:howcan
youmakeaserver
thatcanhandlemultiple
clientsconcurrently???Thiswould
never
workforachatserver,forInstance.
A:
Ah,
that'ssimple,really.Useseparate
threads,andgiveeachnewclientSockettoa
newthread.We're
just
abouttolearnhowto
do
that!
networkingandthreads
•ClientandserverapplicationscommunicateoveraSocket
connection.
•A
Socketrepresents
a
connectionbetweentwoapplications
whichmay(ormaynot)
be
runningontwodifferentphysical
machines.
•AclientmustknowtheIPaddress(ordomainname)and
rcp
portnumber
of
theserverapplication.
•A
rcp
portis
a
16-bi1unsignednumberassigned
to
a
specificserverapplication.
TCP
portnumbersallowdifferent
clientstoconnect
to
thesamemachinebutcommunicate
withdifferentapplicationsrunningonthatmachine.
•The
portnumbersfrom
0
through
1023
arereservedfor
'well-knownservices'Including
HTTP,FTP,SMTP,
etc.
•A
clientconnects
to
a
serverbymakingaServersocket
Socket
9
=
new
Socket(~127.0.0.1n,
4200);
•Onceconnected,aclientcangetInputandoutputstreams
fromthesocket.Thesearelow-level'connection'streams.
9ock.getInputstream();
•Toreadtextdatafromtheserver,create
a
BufferedReader,
chained
to
anInputStreamReader.whichIschainedtothe
inputstreamfromtheSocket.
•InpulStreamReaderIsa'bridge'streamthattakesin
bytesandconvertsthemtotext(character)data.
Irs
used
primarily
to
actasthemiddlechainbetweenthehigh-level
BufferedReaderandthelow-levelSocketinputstream.
•Towritetextdata
to
theserver,createaPrintWriterchained
directlytotheSocket'soutputstream.Callthe
prin~)
or
prinUnOmethodstosendStringstotheserver.
•
ServersuseaServerSocketthatwaitsforclientrequestson
aparticularportnumber.
•WhenaServerSocketgets
a
requestit'accepts'therequest
bymaking
a
Socketconnectionwiththeclient.
youare
here
~
485
asimplechatclient
Writit1gaChatCliet1f
We'll
write
theChatclientapplication
in
twostages.Firstwe'll
makeasend-onlyversionthatsendsmessagestotheserverbut
doesn'tgettoreadanyofthemessagesfromotherparticipants
(anexciting
andmysterioustwisttothewholechatroom
concept).
Thenwe'llgoforthe
full
chatmontyandmakeonethatboth
sends
and
receiveschatmessages.
VersionOne:send-only
Codeoutline
publicclassSimpleChatClientA
JTextFleldoutqoing;
PrintWrieerwriter;
Socketsock;
publicvoidgo()(
II
makeguiandregist8r
a
listenerwiththesendbutton
II
callthe
setOpNetworkiDg()
method
privatevoidsetOpNetworking()(
II
makea
Socket,
then
malc.e
a
PrintWriter
II
assignthePrintWritertowriterinstancevariable
publicclassSendButtonListenerimplementsActionLiatener
publiovoidactionPer£ormed(ActionEventev)(
II
getthiltext
fromthe
text
fieldand
II
sendit
to
theserverusingthewriter(aPrintWritar)
)
II
closeSendButtonLiatenerinnerclass
II
closeouterclass
486
chapler15
networking
and
threads
importjava.io.*;
importjava.net.∙;
import
j
avax.swing.•;
import:.
java.awt.∙;
importjava.awt.event.";
publioclass
SimpleChatClientA
JTextFieldoutgoing;
Pr:intWriterwriter;
Socketsock;
publicvoidgo()
JFrameframe
~
new
JFrame(nLudierouslySimple
ChatelientH);
JPanel
mainPanel
=
new
JPanel();
outgoing
=
newJTextField(20);
JButtonsendButton
=
new"Button
("sand");
sendButton.addActionListener(newSendButtonListener(»;
mainPanel.add(outgoing);
mainPanel.add(sendButton);
frame.
getconten
tPane().add
(Bord.erLayout.
CENTER
I
mainPa.nel);
setUpNetworking():
frame.setSize(400,500):
frama.setViaible(true);
II
closego
W~'re lI.Sjh~
Iota/host
so
y~
ld"
~
the
tlitnt
priv~ ~id
aetUpNetworkinq(){
tL"an
$tl"V&
011
one
"'dthine
Bock
=
newSocket(U127.0.0.1
H
,
5000);
-n"
L•
u'.I'I\clk.e
the
Sotkd
I
nil
IS
wn(Y'.._..
writer
=
newPrintWriter(sock.getoutputstream(»;
,..d
thePY;l'Itw.,.itev
(itst.dUed
System.
out.println("networkingestabliBhed
H
):
f
t.he
01.)....
~od.,.i~ht bC~o'fe
CAtch
(IOException
ex)(
d:Oft'\
il'l
~c
aff
~UP
8x.printSt&cxTrace();
u~a~ ~
•
II
closesetUpNetworking
/'Jow
we
cfttlodlly
do
the
W'rit.in~.
Re"'e...be__,theW'rif.t.,.
is
thained
to
the
il'l\'1"t
~Cd'"
.f.,.o....
tht
Sotket,se
whehtveYwc
do
cf
rriPltll'lO,
it
~oa
oveY
the)ltt.W<Wk
-to
the
SCTVeY!
catch
(Exceptionex)(
ex.printstackTrace{);
I
outgoing.setText(U");
outgoing.requestFocua();
publicstaticvoidmain(String'
CI
U'gll)(
DeW
Simpl&ChatClientA().
qo();
publicclassSendButtonLiBtenerimplementsActionListener(
publicvoidactionPerformed(ActionEvent
.v)(
try(
writer.println(outqoing.getText(»;
writer.flush();
)
II
closeoueerclass
}
II
closeSendButtonListenerinnerclaas
youarehere
~
487
improvingthechatclient
VersionTwo:
sec:,n:d~_o:;:::;;;;;;;;;~~~~~ ~ ~
andreceive_
IlhInkA...
~
o.,'&SU
1
--- ~
..
-
T~e
Strllt\"
sends
il
ftltssa5e
to
all
tlltlltpariitipallts.as
~
CIstJ,e
ftlessa~t
is
rtl.eived
by
thc
~VCT.
When,
a
t1ieflt
s.e"ds
d
"'tssa5
c,
it
does"
t
afPeal'"
i"
the
il\tOfloi"5
ftleUil5e
display
area\Antil
the
$.Crllel'"$.Cl'ods
it
to
eVt\"yt:n.e.
BigQuestion:
HOW
doyougetmessagesfromtheserver?
Shouldbeeasy;whenyou
set
upthenetworkingmakeaninputstreamaswell
(probablyaBufferedReader).
Thenreadmessagesusing
readl.ine/).
BlggerQuestion:
WHEN
doyougetmessagesfromtheserver?
Thinkaboutthat.Whataretheoptions?
•OptionOne:
Polltheserverevery20seconds
Pros:
Well,
it'sdo-able
Cons:Howdoes
theserverknowwhatyou'veseenandwhatyouhaven't?Theserver
wouldhavetostorethemessages,
ratherthanjustdoingadistribute-and-forgeteachtime
itgetsone.Andwhy20seconds?Adelaylikethisaffectsusability,
butasyoureducethe
delay,youriskhittingyourserverneedlessly.Inefficient.
•Option
Two:ReadsomethingInfromtheservereachtimetheuser
sendsamessage.
Pros:
Do-able,very
easy
Cons:
Stupid.Whychoosesuchanarbitrarytimetocheckformessages?What
if
auseris
a
lurkeranddoesn'tsendanything?
•OptionThree:
ReadmeSAagesassoon
as
they'resentfromtheserver
Pros:
Mostefficient,bestusability
Cons:Howdoyou
doyoudotwothingsatthesametime?Wherewouldyouputthiscode?
You'd
needaloopsomewherethat
was
always
waitingtoreadfromtheserver.Butwhere
would
thatgo?OnceyoulaunchtheCUI,nothinghappensuntilanevent
is
firedbyaCUI
component.
488
chapter15
networking
and
threads
MultithreadingInJava
Javahasmultiplethreadingbuiltright
intothefabricofthelanguage.Andit'sa
snaptomake
a
newthreadofexecution:
Thread
t
=
new
Thread();
t.
start();
That'sit.BycreatinganewThread
object,
you'velaunchedaseparate
threadoj
execution,
withitsveryowncallstack.
Except
fin"
one
problem.
That
threaddoesn'tactually
do
anything,
so
thethread
"dies"
virtuallytheinstant
it's
born.
Whenathreaddies,itsnew
stack
disappearsagain.Endofstory.
So
we'remissingonekeycomponent-
thethread's
job.
Inotherwords,weneed
thecodethatyouwanttohaverunbya
separatethread.
MultiplethreadinginJavameanswe
havetolook
atboththe
thread
and
the
job
that's
ron
bythethread.Andwe'llalso
havetolookat
theThread
class
inthe
java.langpackage.(Remember.
java.lang
is
the
packageyougetimportedfor
free,implicitly,
andit'swheretheclasses
most
fundamentaltothelanguagelive,
includingStringandSystern.)
.In
Java
youreally
CAN
walk
and
chew
gum
at
thesame
time.
Wewantsomethingtoruncontinuously,
checkingformessagesfromtheserver,
but
withoutiruerruptingtheusersabilityto
interactwiththeCUI.'
Sowhiletheuseris
happilytyp
ingnewmessagesorscrolling
throughtheincomingmessages,we
want
something
behindthescenes
tokeep
readinginnewinputfromtheserver.
Thatmeanswefinallyneedanewthread.
A
new,separate
Slack
Wewanteverythingwe
did
intheSend-
Onlyversion(versionone)toworkthe
same
way,
whileanew
process
runsalong
sidethatreadsinformationfromthe
serveranddisplaysitintheincomingtext
area.
Youknow
by
nowthatwe're
goingwithoptionthree.
Well,notquite.Unlessyouhavemultiple
processorsonyourcomputer,eachnew
Javathreadisnotactuallyaseparate
processrunningontheOS.Butitalmost
feels
asthoughitis.
youarehere
~
489
threadsandThread
JavahastMultiplethreadsbut
o.,ly
oneThreadclass
Wecanralkabout
thread
withalower-case
't'
andThread
with
acapital
'T'.
Whenyousee
thread,
we'retalking
aboutaseparatethreadofexecution.
In
otherwords,
a
separatecallslack.WhenyouseeThread,thinkof
theJavanamingconvention.What,inJava,
starts
witha
capitalletter?Classes
andinterfaces.Inthiscase.Thread
isaclassinthejava.langpackage.
A
Thread
object
representsa
thread.ojexecution;
you'llcreateaninstanceof
classThreadeachrimeyouwanttostartupanew
thread
ofexecution.
!hread
i\
theeadis
aseparate
'Lhr'eud
of
execution'.
r
[1
othet;words.a
1l'}Jal'alccall
slack.
J\'-rhrcadis
aJava
c
lassthat
represenh
athh!uJ.
1'0
111akea
Lhread.
l1mkl\a
ThI\\ud.
Thread
Thread
voidjoinO
voidslartO
slatlcvoidsleepO
mainthread
anotherthread
started
by
thecode
A.
thread[lower-case
't")
isaseparatethreadofexecution.
Thatmeansaseparatecallslack.
Every
Javaapplication
starts
upamainthread-thethreadthatputsthe
mainOmethodonthebottomofthestack.TheJVM
is
responsibleforstartingthemainthread(andother
threads,asitchooses,
including
thegarbagecollection
thread).
As
aprogrammer,youcanwritecodetostart
otherthreadsofyourown.
490chapter
15
java.lang.Thread
class
Thread(capital
"I")
isaclassthat
represents
a
threadofexecution.
Ithasm
ethodsforstartinga
thread.joiningonethreadwith
another,andputtingathreadto
sleep.(Ithasmoremethods;these
are
justthecrucial
ODes
weneed
tousenow).
Whatdoes
it
ttteat1tohavetMorethatt
ot1ecallstack?
WithmorethanonecallSlack,yougetthe
appearance
ofhaving
multiple
thingshappenatthesametime.Inreality.onlyatrue
multiprocessorsystemcanactuallydomorethanonethingata
time,
but
with
Javathreads,
it
can
appear
thatyou'redoingseveral
thingssimultaneously.In
otherwords,executioncanmoveback
andforthbetweenstackssorapidlythatyoufeelasthoughallstacks
areexecutingatthesametime.Remember,java
is
justaprocess
runningonyourunderlyingOS.Sofirst,Java
itselfhas
tobe'the
currentlyexecutingprocess'ontheOS.ButonceJavagetsits
turntoexecute,exactly
what
doestheJVM
run?
Whichbytecodes
execute?Whateverison
thetopafthecurrently-runningstackl
Andin100milliseconds.
thecurrentlyexecutingcodemightswitch
toa
different
methodona
different
stack.
Oneofthethingsathreadmustdoiskeeptrackofwhichstatement
(ofwhichmethod)iscurrentlyexecutingonthethread'sstack.
It
mightlooksomethinglikethis:
networkingandthreads
o
TheJVMcallsthemalnOmethod.
publicstaticvoidmain(String
[l
args)(
mainthread
main()startsanewthread.Themain
threadistemporarilyfrozenwhilethenew
threadstartsrunning.
Runnabler
=
new
MyThreadJob()j~
Thread
t
=
new
Thread(~
YOl,t'1!
le;l'lI~hdt
t.
start
0;
-this...
~~.
.
c.si
Dogd::newDog()
j
d...
o.,.ellt...III
J
e
TheJVMswitchesbetweenthenew
thread(user
threadA)andtheoriginal
mainthread,untilboththreadscomplete.
t.startC)
mainO
mainthread
main
thread
userthreadA
x.goO
runO
user
threadA
youarehere.
491
launchingathread
Howtolaunchanewthread:
o
MakeaRunnableobject(thethread'sjob)
Runnable
threadJob
=
new
My~Jnnable()j
Runnableisaninterfaceyou'lllearnaboutonthenextpage.
You'llwriteaclassthatimplementstheRunnobleinterface,
and
thatclassiswhereyou'lldefinetheworkthatathread
willperform.Inotherwords,themethodthatwillberun
from
thethread'snewcallstack
e
MakeaThreadobject(theworker)and
give
it
aRunnable(thejob)
ThreadmyThread
=
newThread(threadJob)
j
PassthenewRunnableobjecttotheThreadconstructor.
Thistells
thenewThreadobjectwhichmethodtoputon
thebottomofthenewstack-theRunnable'srunOmethod.
Q
StarttheThread
myThread.start()j
NothinghappensuntilyoucalltheThread's
startOmethod.That'swhenyougofrom
having
justaThreadinstancetohavinganew
threadofexecution.Whenthenewthread
startsup.ittakestheRunnableobject's
runOmethodandputsitonthebottomof
thenewthread'sstack.
492chapter15
rul'10
networking
and
threads
Everyfhreadtteedsajobtodo.
AtMethodtoput
Ott
thettewthreadstack.
Runnah]e
is
to
a
Thread
what
ajoh
is
to
a
worker.
ARunnahle
is
the
johathread
is
supposed
to
run.
A
Runnah]e
holdsthe
method
that
goeson
the
bottom
of
thenew
thread'sstac"k:
ru.n().
AThreadobjectneeds
a
job.Ajobthethreadwillrunwhenthe
thread
is
started.Thatjobis
actually
thefirstmethodthatgoes
on
~.
ts
01\\'1
()I\e
the
newthread'sstack,anditmustalwaysbe
a
method
that
looks
~\
.
-\:.t.Yht.ede
11\
~lYI
i-tS
31'1
likethis:I"e1\""",,3
e\.II\
'10.
Y~O.{R.t"'t.\~ e~YG\ess
IL..A
I
y..,.b
It.
'10
00
',s.
y~'o
It.'"
:r
publicvoidrun(}(
"'~ ~t."'~
LI
-t.
'fld'1.)
II
codethatwill
be
run
by
thenewthread
il'l~ht.t
SO
l'IVt.
i-t.i"
,,"3
Lhty
,/0'"\..,\
~ ~"t:\,
Howdoesthethreadknowwhichmethodtoputatthebottomof
theslack?BecauseRunnabledefinesacontract.BecauseRunnable
isaninterface.Athread'sjobcanbedefined
in
any
classthat
implementstheRunnableinterface.Thethreadcaresonlythatyou
pass
theThreadconstructoranobjectofaclassthatimplements
Runnable.
WhenyoupassaRunnabletoaThreadconstructor,you'rereally
justgiving
the
Threadaway
to
gettoa
runt)
method.You'regiving
the
Threaditsjobtodo.
youarehere.
493
Runnableinterlace
fotttakeajobforyourthread,
itMpletMet1ttheRut1"ableiMterface
publicclusMyRunnable
~I..-nt:a
public
void
go()
doMore();
public
voiddoMOre()(
SYllItem.out.prll\tln("top
0'
thestack");
classThreadTetlter{
R
\:II
i"std"U
;"to
~e
I'C'O/
Pass-the
"ew,,<YIN
nis
-tellsthe
-l:.\-I,"~d
n
~d
t.O'I'ISb-l>l.t.o--.
'boB:.o
ok
~e
YltW
publicstatic
void
main(Strll\g[]&rgs){/'"
Ld.hod
to
y...
-t
0"
-the.
"'LLod
~t
wha~
"'
LL....,
J
s
-thetlY'S-t
",n;n
ta
k\"
OVlCY
'0/.,.
~
J
RunnablethreadJob
=
newMyRunnab1e();
st.∙
-l}
adwill
yUY\∙
ThreadmyThread
=_();
-the"ew"c
o
myThread
.start();
(
o
mainthread
newthread
Whatdoyouthinktheoutputwillbe
if
yourunthe
ThreadTesterclass?(we'llfindoutInafewpages)
494
chapter15
networking
and
threads
Thethreestatesofanewthread
Thread
t
=
newThread(r);
NEW
t.
start();
Threadt
=
newThread(r);
AThreadinstancehasbeen
createdbutnotstarted.
Inotherwords,thereis
a
Thread
object,
butno
thread
ofexecution.
RUNNABLE
Selected
to
run
t.start();
Whenyoustartthethread,it
movesintotherunnablestate.
Thismeansthethread
IS
ready
to
run
andjustwaitingforits
Big
Chancetobeselectedfor
execution.
At
thispoint,there
is
anew
call
stackforthisthread.
\
\
/
/
/
<,
RUNNING_
"
/
{
\"
"Call
I
S4ly~iu
thai:
to¥"
?"
yew..
Thisisthestateallthreadslust
after!To
beTheChosenOne.
TheCurrentlyRunningThread.
Onlythe
JVM
threadscheduler
canmakethatdecision.You
can
sometimes
influence
that
decision,butyoucannotforce
a
threadtomovefromrunnable
torunning.Intherunning
state,athread(andONLYthis
thread)hasanactivecallstack,
andthemethodonthe
top
of
theslackisexecuting.
Butthere'smore.Oncethethreadbecomes
runnable,
it
can
move
backandforthbetween
runnable,running,andanadditionalstate:
temporarilynotrunnable
(alsoknownas'blocked').
youare
here
~
495
thread
states
TypicalrunnableJrunningloop
Typically,athreadmovesbackand
forthbetweenrunnableandrunning,
as
the
JVM
threadschedulerselectsa
threadtorunandthenkicksitback
outsoanotherthreadgetsachance.
Athreadcanbemade
temporarilynot-runnable
RUNNABLERUNNING
~
~
Sent
bockto
runnable
soanother
threadcoo
haveachance
TIlethreadschedulercanmovea
runningthreadintoablockedstate,
foravariety
ofreasons.Forexample,
thethreadmightbeexecutingcode
toreadfromaSocketinputstream,
butthereisn'tanydatatoread.The
schedulerwillmovethethreadout
oftherunningstateuntilsomething
becomesavailable.Ortheexecuting
codemighthavetoldthethreadto
putitselftosleep(sleepO).Orthe
threadmightbewaitingbecauseit
triedtocalla
methodonanobject,
andthatobject
was
'locked',Inthat
case,thethreadcan'tcontinueuntil
theobject'slockisfreed
by
thethread
thathas
it.
Allofthoseconditions(andmore)
causeathreadtobecometemporarily
not-runnable,
496
chapter15
RUNNABLERUNNING
sIUfi...
~
waiti"9
.feN'
<ll'lOth&
th....
taa
to
ti...
ish,
....aib,,~
fat'
data
to
be
ilvClilablt
0'"
thtsh-til"'l
wilit,,~
fo...Cl"
objed;'s
lock...
fhefhreadScheduler
Thethreadschedulermakesallthedecisionsabout
whomovesfromrunnabletorunning.andaboutwhen
(andunderwhatcircumstances)athreadleavesthe
runningstate.Theschedulerdecideswhoruns,andfor
howlong,
andwherethethreadsgowhenthescheduler
decidestokickthemoutofthecurrently-runningstate.
You
can'tcontrolthescheduler.ThereisnoAPIfor
calling
methodsonthescheduler.Mostimportantly,
therearenoguaranteesaboutscheduling!(Therearea
few
almose-guarantees.buteventhosearealittle
fuzzy.)
Thebottomlineisthis:
donotbaseyourprogram
'$
rorrectness
Q1l
the
schedulerworking
in
a
particular
way!
Theschedulerimplementationsaredifferentfor
differentJVM's,
andevenrunningthesameprogram
onthesamemachinecangiveyoudifferentresults.
OneoftheworstmistakesnewJavaprogrammers
makeistotesttheirmulti-threadedprogramona
single
machine,andassumethethreadscheduler
will
alwaysworkthatway,regardlessofwheretheprogram
runs.
So
whatdoesthismeanforwrite-once-run-anywhere?
It
meansthattowriteplatform-independentJavacode,
yourmulti-threadedprogrammustworknomatter
how
thethreadschedulerbehaves.Thatmeansthatyoucan't
be
dependenton,forexample,theschedulermaking
sureallthethreadstakenice,perfectlyfairandequal
turns
attherunningstate.Althoughhighlyunlikely
today,
yourprogrammightenduprunningonaJVM
witha
schedulerthatsays,
~OK
threadfive,you'reup,
andas
far
asI'mconcerned,youcanstayhereuntil
you'redone,whenyourrun()methodcompletes."
Thesecrettoalmosteverythingis
sleep.
That's
right,
sleep.
Puttingathreadtosleep,evenforafew
milliseconds.forces
thecurrently-runningthreadto
leave
therunningstate,thusgivinganotherthreada
chancetorun.Thethread'ssleepOmethoddoescome
with
one
guarantee:asleepingthreadwill
not
become
thecurrently-runningthreadbeforethethelengthof
itssleeptimehasexpired.Forexample,
if
youtellyour
threadtosleepfortwoseconds(2,000milliseconds),
thatthreadcanneverbecometherunningthreadagain
until
sometime
after
thetwosecondshavepassed.
networkIng
and
threads
The"fhread
schedulermakesall
thedecisions
about
who
runs
and
who
doesn't.
lIe
usually
makesthethreads
take
turns,
nicely.
But
there's
noguarantee
about
that.
lIe
might
let
onethread
run
to
its
heart'scontent
whiletheother
threads'starve'.
youarehere
~
497
threadscheduling
Anexampleofhowunpredictablethe
schedulercanbe...
Runningthiscodeononemachine:
public
classMyRunnable
implements
Runnable
publicvoidrun()
qo();
publicvoidgo()
doMore();
publicvoiddOMOre()(
System.out.printin("top
0'
the
stack");
class
ThreadTestDrive{
publicstaticvoid
main(String[]args)(
RunnablethreadJob
=
newMyRunnable();
ThreadmyThread
=
newThread
(thraadJob);
myThread.start();
...
.
.
,.
.
'
..
498
chapter15
.
.
Producedthisoutput:
java
Th~eadTestDrive
back
inmain
top
0'
thestack
~(j.va T l- ~;::",adT·c~i:.DJ.--;_'.·'c
top
0'
thestack
backinmain
java
ThreadTestDrive
top
0'
thestack
backinmain
java
Th~eadTestnrive
top
0'
thestack
back
inmain
java
T h r e a dT e s ~ D r 1 v e
top
0'
thestack
back
inmain
java
T h r R a d TQs t D ~ ~ ~ ~
top
0'
thestack
backinmain
JavaThreadTestDr1ve
back
inmain
top
0'
thestack
Howdidweendupwithdifferentresults?
Sometimesitrunslikethis:
networkingandthreads
maIn
0
sta
rts
the
newthread
mainthread
Theschedulersends
themainthreadout
ofrunning
andback
to
runnable,
so
that
thenewthreadcan
run.
mainthread
Theschedulertets
thenewthread
run
to
completion,
printingout"top
0'
the
stack"
newthread
time
Thenewthreadgoes
away,because
its
runO
completed.Themain
threadonceagain
becomes
therunning
thread,andprints
'back
In
main"
time
youarehere.
499
socketconnecUons
:t1erelare~
Dumo
"C.UesU9nS
Q.:
I'veseenexamplesthatdon'tuseaseparate
RunnableImplementation,butInsteadJustmakea
subclassofThread
a
ndoverridetheThread'srunO
method.Thatway,you
call
theThread'sno--arg
constructorwhenyoumakethenewthread;
Thread
t
=
newThread();
1/
noRunnable
A:
Yes,that
Is
anotherwayofmakingyourown
thread,
butthinkaboutitfroman00perspective.
What'sthepurposeofsubclassing?Rememberthat
we'retalkingabout
twodifferentthingshere-the
Thread
andthe
thread'slob.
Froman
00
view,those
twoareveryseparateactivities,andbelonginseparate
classes.Theonlytimeyouwanttosubclass/extend
theThreadclass,Isifyouaremakinganewandmore
specifictypeofThread
.lnotherwords,ifyouthinkof
theThreadastheworker,don'textendtheThreadclass
unlessyouneedmorespecific
worker
behaviors.ButIf
allyouneedIsanew
lob
toberunbyaThread/worker,
thenImplementRunnable
In
aseparate,job-specific
(notworker-specific)class.
ThisisadesignIssueand
notaperformanceor
languageIssue.It'sperfectlylegaltosubclassThread
andoverridetherunOmethod,
butIt'srarelyagood
Idea.
Q.:
Canyou
reusea
Thread
object?
CanyougiveIt
anewJobtodoand
thenrestartItbycallingstartO
agaln7
A:
No.Onceathread'srunOmethodhascompleted,
thethreadcanneverberestarted.Infact,atthat
pointthethreadmovesIntoastatewehaven'ttalked
about-dead.Inthedeadstate,thethreadhas
finishedItsrunOmethodandcanneverberestarted.
TheThreadobject
mightstilibeontheheap,asa
livingobject
thatyoucancallothermethodson(If
appropriate),buttheThreadobjecthaspermanently
lostits'thread
ness'.Inotherwords,thereIsnolongera
separatecallstack,andtheThreadobjectIsnolonger
a
thread.
It'sJustanobject,atthatpoint,likeallother
objects.
But,therearedesignpatternsformakingapool
of
threadsthatyoucankeepusingtoperformdifferent
jobs.Butyou
don'tdoItbyrestartlng()adeadthread.
500
chapter15
•Athreadwith
a
lower-case
't'
is
a
separatethreadof
executioninJava.
•EverythreadInJavahas
its
owncallstack.
•A
Threadwithacapital
'T
isthejava.lang.Thread
class.
A
Threadobjectrepresentsathreadof
execution.
•AThreadneedsajobtodo.AThread'sjobisan
instanceofsomethingthatImplementstheRunnable
interface.
•
TheRunnableInterfacehasjustasinglemethod,runO.
Thisisthemethodthatgoesonthebottomofthenew
callstack.Inotherwords.
it
isthefirstmethod
to
runIn
thenewthread.
•Tolaunch
a
newthread,youneedaRunnable
to
pass
to
theThread'sconstructor.
•A
threadIsIntheNEWstatewhenyouhave
instantiatedaThreadobjectbuthavenotyetcalled
startO.
•Whenyoustartathread(bycallingtheThreadobject's
startOmethod),anewstackIscreated,withthe
Runnable's
runO
methodonthebottomofthestack.
ThethreadisnowintheRUNNABLEstate,waitingto
be
chosentorun.
•A
threadissaid
10
be
RUNNINGwhentheNM's
threadschedulerhasselecteditto
be
thecurrently-
runningthread.Onasingle-processormachine,there
can
be
onlyonecurrently-runningthread.
•
SometimesathreadcanbemovedfromtheRUNNING
state
to
aBLOCKED(temporarilynon-runnable)state.
Athreadmighl
be
blockedbecauseit'swaitingfordata
fromastream.orbecauseIthasgonetosleep,or
becauseItiswaitingforanobject'slock.
•ThreadschedulingIsnotguaranteedtoworkinany
particularway,soyoucannotbecertainthatthreads
wllltaketumsnicely.Youcanhelpinfluencetum-laking
byputtingyourthreadstosleepperiodically.
Putti.,g∙athreadtosleep
Oneofthebestwaystohelpyourthreadstaketurnsis
to
putthemtosleepperiodically.Allyouneedtodo
iscallthestaticsleepOmethod,passingitthesleep
duration,
in
milliseconds.
Forexample:
Thread.sleep(2000);
will
knockathreadoutof
the
nmningstate,and
keep
it
outoftherunnablestatefortwoseconds.
Thethread
can't
becometherunningthread
againuntilafteratleasttwosecondshavepassed.
A
bitunfortunately,thesleepmethodthrowsan
InterruptedException,
a
checkedexception,soall
callsto
sleepmustbewrappedinatry/catch(or
declared),Soasleepcallreallylookslikethis:
try(
Thread,sleep(2000);
catch(InterruptedExceptionex)(
ax.printStackTrace();
Yourthread
",;11
probably
never
beinterrupted[Tom
sleep;
theexceptionisinthe
API
tosupportathread
communicationmechanismthatalmostnobodyusesin
theReal
World.
But,youstill
have
toobeythehandle
or
declarelaw,soyou
need
to
getusedtowrappingyour
sleepOcallsin
a
try/catch.
Nowyouknow
thatyourthreadwon'twakeup
before
the
specifiedduration,butisitpossiblethatitwillwakeup
sometime
after
the'timer'
has
expired?Yesandno.
It
doesn't
matter,
really,becausewhen
the
threadwakes
up,
it
alwaysgoes
bcuk
totherusmable
stare!
Thethread
won'tautomaticallywakeupatthedesignatedtimeand
becomethecurrently-runningthread.When
a
thread
wakesup,thethreadisonceagainatthemercy
of
the
threadscheduler.
Now,
forapplicationsthatdon't
requireperfecttiming,
and
thathaveonly
a
fewthreads,
itmightappearasthoughthethreadwakesupand
resumesrunningrightonschedule(say,afterthe
2000
milliseconds).Butdon'tbetyourprogramonit.
networkingand
threads
Put
yourthreadtosleep
if
you
want
tohesure
that
otherthreads
get
a
chanceto
run.
"Whenthethreadwakes
up.
it
always
goesbac"k
totherunnah]e
state
and
waitS
forthethread
schedulertochoose
it
torun
again.
you
are
here
~
501
usingThread.sleep()
Usittgsleeptotttakeourprograttt
",orepredictable.
Rememberourearlierexamplethatkeptgivingusdifferent
resultseachtimeweranit?Lookbackand
study
thecode
andthesampleoutput.Sometimes
main
hadtowait
until
the
newthreadfinished(andprinted"topo'thestack"),while
othertimesthenewthreadwould
be
sentbacktorunnable
beforeit
was
finished,allowingthemaiothreadtocomeback
in
andprintout"backinmain",Howcanwe
fix
that?Stop
fora
momentandanswer
this
question:"Where
canyou
put
a
sleept)
call,tomakesurethat
"back
inmain"alwaysprints
before"top
0'
the
stack"?
We'll
waitwhile
you
workoutananswer(there's
more
than
oneanswerthatwouldwork).
Figureitout?
publicclassMyRunnableimplementsRunnable(
publicvoidrun()(
go();
Thi~
is
wh.rt.we.
WGl'It-a
l.or.siskt.
(Katy
0+
fYint.
st.at.~enh'
File
Ed~
WindowHelpSnoozeBunon
JavaThreadTestDrive
back
in
main
top
0'
thestack
.:iava
ThreadTestDrive
back
in
main
top
0'
thestack
javu
ThreadTestDriy~
back
in
main
top
0'
thestack
javaThreadTestDrive
backinmain
top
0'
thestack
javaThreadTestDrive
backinmain
top
0'
thestack
publicvoid
go()
Uy(
Thread••leep(2000);
catch(Ifttarrupt.eclExceptionex)(
ex.pr1ntStackTrace();
publicvoid
dOMOre()(
System.out.
prinUn
("top
0'
the
stack");
class
ThreadTestDrive(
publicstaticvoidmAin(String[]arqs)
Runnable
theJob-new
MyRunnable();
Thread
t:::
new
Thread(theJob);
t.
start();
Systam.out.println(~back
inmain");
}
502
chapter15
..
.
,
"
.J
.
,
"
,
.
networkingandthreads
Maki.,ga.,dsfarti.,g
two
threads
Threadshavenames.Youcangiveyourthreadsanameof
yourchoosing,oryoucanaccepttheirdefault
names.
Butthe
coolthingaboutnamesisthatyou
can
usethemtotellwhich
threadisrunning.Thefollowingexamplestartstwothreads.
Each
threadhasthesamejob:
run
inaloop.printingthe
currently-runningthread'snamewitheachiteration.
publicclassRunThreadsimplementsRunnable(
~\t i,..st;ll'tt.∙
publicstaticvoid
main(String[Jarqa)(.....
Ma\(t
O'f\t
RIl'l'ol"3
RunThreadsrunner'"
nitW
RunThreads();
Threadalpha
=
newThread(runner);
~ Mcl~
two
th
Threadbeta'"newThread(runner);
~
.
'r,edtb,
withtht
1,I>"t
R""Ylable(the
alpha.
setName
("Alphathread");
Scl"'eJob--...,eII
t:a
1k
...
~t
about
t.he
"-two
th..-t.ads
beta.88tName("Betathread");
~
andO?Ie
R"""\dblt.
In
a
+tvJ
ra~es).
alpha.
8
tart();
~
N
a",t.
the
tht"edds.
beta.start();
~
start
the
tht"t.clds.
LL
""-'A"
~is
\00f1
~t.h ~vtao
\fIi\\
YIlYl
V\~~-J
public
void
run(){.
L'
it.
1'0",1:
e.)l.h
tu"t.∙
P"r\Yl~'''~
'V
for(int
i
=
0;
i
<
25;
i++){
1
StringthreadName
K
Thread.currentThread()
.getName();
Syatam.out.println(threadName
+"
isrunning");
File
Ed ~
WindOW
H~p
C&ntaun
What
will
happe.,?
Wlll
thethreadstaketurns?Willyouseethethreadnames
alternating?Howoftenwilltheyswitch?Witheachiteration?
Afterfiveiterations?
Youalreadyknow
theanswer:
wedon'tknowlIt's
up
to
the
scheduler.Andon
your
as,
with
your
particular
JVM,
on
yourCPU,you
mightgetverydifferentresults.
Runningunder
asx
10.2
(Jaguar),
withfiveorfewer
iterations,
theAlphathreadrunstocompletion,then
theBetathreadrunstocompletion.Veryconsistent.Not
guaranteed.butveryconsistent.
Butwhenyou
uptheloopto25ormoreiterations,things
starttowobble.
TheAlphathreadmightnotgettocomplete
all25iterationsbeforetheschedulersendsitbackto
runnabletolettheBetathreadhaveachance.
Alphathreadisrunning
Alphathreadisrunning
Alphathreadisrunning
Betathreadisrunning
Alphathreadisrunning
Betathreadisrunning
Betathreadisrunning
Betathreadisrunning
Betathreadisrunning
Betathreadisrunning
Betathreadisrunning
Betathreadisrunning
Betathreadisrunning
Betathreadisrunning
Betathreadisrunning
Betathreadisrunning
Betathreadisrunning
Betathreadisrunning
Betathreadisrunning
Alphathreadisrunning
youarehere.503
aren'tthreadswonderful?
504
chapter15
UtM,yes.ThereISadarkside.
fhreadsca.,leadtoco.,curre.,cy'issues:
Concurrencyissuesleadtoraceconditions.Raceconditions
leadtodatacorruption.Datacorruptionleadstofear...you
knowtherest.
Itallcomesdownto
onepotentiallydeadlyscenario:twoor
morethreadshaveaccesstoasingleobject's
daia:
In
other
words,methodsexecutingontwodifferentstacksareboth
calling,say,gettersorsettersonasingleobjectontheheap.
It'sawhole'left-hand-doesn't-know-what-the-right-hand-
is-doing'thing.Twothreads,withouta
careintheworld,
hummingalongexecutingtheirmethods,eachthread
thinkingthatheistheOne-TrueThread.Theonlyone
thatmatters.Afterall,whenathreadisnotrunning,andin
runnable(orblocked)it'sessentiallyknockedunconscious.
Whenitbecomesthecurrently-runningthreadagain,itdoesn't
knowthatiteverslopped.
networkingandthreads
MarriageinTrouble.
Canthiscouplebesaved?
Next,on
8
veryspecialDr.SteveShow
[Transcriptfromepisode#42)
Welcometo
the
Dr.
Steve
show.
"RiYan
and
I
agreed
t.hat
neither
crus
will
overdraw
thecheckl.ngaccount.
So
theprocedure
1S,
whoever
wants
to
withdrawmoneymustcheckthe
balance
in
the
account
beiore
rna
k1ng
the
withdrawal.It
all
seemedso
simple.
But
suddenly
we'rebouncingchecks
and
gettinghitwithoverdraft.
fees
I
I
thoughtit
wasn't
possible,
I
thought
our
procedure
WBE
safe.
Butthen
this
happened:
Ryanneeded$50,so
he
checked
thebalance
in
the
account,
and
sawthat
it
WW3
$100.
No
problem.
So,
he
plans
to
withdraw
the
money.
But
first
he
faI1B
asleep
I
We've
gota
story
today
that'scenteredaroundthe
top
tworeasons
why
couples
split
up-financesandsleep.
Toctaor's
troubled
pair,
Ryan
and
Monica.,
share
a
bed
and
a.
bank
account.Butnot
for
long
if
we
can'tfindasolution.
The
problem?
The
classic'iiwopeople-one
bank
account"
th:1ng.
Here's
how
Monicadesoribedit
to
me:
Andthat'swhereI
come
in,
while
~'s
still
BEleep,
and
nowIwant
to
withdraw$100.Icheckthebalance,
and
it's
$100
(because!Wan'sst1llasleep
and
ha.sn'tyetmade
hiswithdrawal),
so
I
think,
no
problem.
SoImakethe
withdrawal,
and
agatn
no
problem.But
then
Ryanwakesup,
completes
h1s
withdrawal,
andwe'resuddenlyoverdrawn!
He
didn't
evenknowthathefellasleep,
so
he
just
wentaheadandcompleted
his
tra.nsaot1on
without
checking
thebalance
again.
You'vegot
to
helpus
Dr.
Steve
I"
Is
therea
solution?
.Are
they
doomed?Wecan'tstop
Ryan
from
fa.lllng
asleep,butcanwe
make
surethatMonicacan'tgether
hands
onthe
bank
accountuntilafterhewakesup?
Takea
momentand
tb.1n.k
aboutthatwhile
we
go
to
a.
commercialbreak.
youarehere.
505
RyanandMonicacode
TheRyattat1dMotticaproble'ltittcode
Thefollowingexampleshowswhatcanhappenwhen
two
threads
(Ryan
andMonica)sharea
single
object(thebank
account).
Thecodehastwoclasses,BankAccount,and
MonicaAndRyanJob.TheMonicaAndRyanjobclass
implementsRunnable,
andrepresentsthebehaviorthat
Ryan
andMonicabothhave--checkingthebalanceandmaking
withdrawals.Butofcourse,each
threadfullsasleep
inbetween
checkingthebalanceandactuallymakingthewithdrawal.
TheMonicaAndRyanJobclasshasaninstancevariableoftype
BankAccount.,thatrepresents
theirsharedaccount.
Thecodeworkslikethis:
BankAccount
intbalance
gelBalance()
withdrawO
Runnable
T
I
I
I
I
RyanAndMonlcaJob
BankAccountaccount
runO
makeWithdrawal0
•MakeoneInstanceofRyanAndMonlcaJob.
TheRyanAndMonicaJobclassistheRunnable(thejobtodo),
andsincebothMonicaandRyando
thesamething(check
balanceandwithdrawmoney),weneedonlyoneinstance.
•
RyanAndMonicaJobtheJob:::newRyanAndMonica.Job
0;
MaketwothreadswiththesameRunnable
(theRyanAndMonicaJobinstance)
Threadone:::newThread(theJob);
Threadtwo
=
newThread(theJob);
IntherunOmethod,do
exactlywhatRyanand
Monicawoulddo-check
thebalanceand,
if
there'senoughmoney,
makethewithdrawal.
Thisshouldprotect
againstoverdrawingthe
account.
•Nameandstartthethreads
one.setName(~Ryan"l
;
two.setN8IJle("Monica");
one.start();
two.start
0;
•Watchboththreadsexecutethe
runO
method
(checkthebalanceandmakeawithdrawal)
One
threadrepresentsRyan.theotherrepresentsMonica.
Boththreadscontinuallycheck
thebalanceandthenmakea
withdr<lwal.
butonlyifit'ssafe.!
if
(ACcount.get.BalanceO
>=
amount)(
try(
Thread.
sleep
(SOOl;
I
catch(InterruptedExceptionax)(ex.printStackTrace();)
508
chapter15
Except•••Ryanand
Monicaalwaysfall
asleep
~r
they
checkthebalancebut
beforetheyfinishthe
withdrawal.
publicvoidrun(){
for(intx
=
0;x
<
10;x++){
makeWithdrawl(10);
if(account.getBalance()
<
0){
System.out.println("OVerdrawn!");
networkingandthreads
TheRyat1at1dMOt1icaexalltple
classBankAccount{
L
tarts
ltIitha
privateintbalance
=
100;
~~
__
~
Tneattov.rI';s
'oa\aY\l.e
ok
fI
OO
.
publicintgetBalance()
returnbalance;
}
public
void
withdraw(intamount){
balance
=
balance-amount;
publicclassRyanAndMonicaJobimplementsRunnable{
privateBankAccountaccount
=
newBankAccount();
publicstaticvoidmain(String[]args){
RyanAndMonicaJob
theJob
=
newRyanAndMonicaJob();
~
frlsta.
Threadone
=
newThread(theJob);
~
r.t1ai:ethe
~"r.tldble
(-ob)
Threadtwo
=
newThread(theJob);
+--
Make
two.Lh
d
~
~I-eas
'.
one.setName("Ryan");
job.
nat'
~IVlr.g
eaththl-eadth
two.setName("Monica");
alloLir.t.
"'ear.sboththl-eads
will
b
e
~"'e
R"htldbl
e
one.start();
Ir.stahleval-iabl
e
ir.the
R
ealleSSl
h
!}
theOne
two.start();
"r.tldbl
e
tlass.
tn\'"eadloo\'s
t.nYO\l.~n
aridt.\'"∙le
s
IYlt.neyv.YlO
.",e+.h
od
'
t
ltIitneat.nit.e\'"ati
oYl'
AHe\'"
t.~~
to
makea1tI,t.nd\'"a
ltla
'DalaYlteoY\l.e
a~aiYl
to
see
I
ltIit.nd\'"altla\,'It.t.net.kst.ne
t.heattOv."t.isol/eV'dya
ltl".
ehetktheattov.Ylt.bala"t.e,aYldit
t.heYe~s
Ylot.
IS
}
e"ov.~h mOrle~,
wej\lSt.f\'"int.a
",essa~e.
I
t h e Y ~
t.e
.,..
Venov.h,ltIe
~o
to
sleef,t.henltIakev.?a"dt.OWIf
e
pr1;ratev01dmakeW1thdrawal(1ntamount){
~
't.hdv-altlal,'\lStlike
R'fan
did.
1f(account.getBalance()
>=
amount){
t.he
WI
J
System.out.println(Thread.currentThread().getName()+"isabouttowithdraw");
try{
System.out.println(Thread.currentThread().getName()+"isgoingtosleep");
Thread.sleep(500);
}catch(InterruptedExceptionex){ex.printStackTrace();}
System.out.println(Thread.currentThread().getName()+"wokeup.");
account.withdraw(amount);
System.out.println(Thread.currentThread().getName()+"completesthewithdrawl");
}
else{
System.out.println("Sorry,notenoughfor"+Thread.currentThread().getName(»;
We
p"i
ih
a
b"hlh
of
D>oihtstaL
L
se
h
l'
hi'
UhoIeh\;S
sowe
tar.
e
w
ae;sappehih!}asitl-"hS.
youarehere
~
507
!"CyananaMOniCaOUtput:
FlI&Edll
Window
HelpVI£ll
the
withdraw1
for
Monica
forMonica
for
Monica
forMonica
forMonica
,
.
508chapter
15
Ryanisabouttowithdraw
Ryanisgoingtosleep
Monicawokeup.
Monicacompletesthewithdrawl
Monicaisabouttowithdraw
Monicaisgoingtosleep
Ryanwokeup.
Ryancompletesthewithdrawl
Ryanisabouttowithdraw
Ryanisgoingtosleep
Monicawokeup.
Monicacompletesthewithdrawl
Monicaisabouttowithdraw
Monicaisgoingtosleep
Ryanwokeup.
Ryancompletesthewithdrawl
Ryanisabouttowithdraw
Ryanisgoingtosleep
Monicawokeup.
Monicacompletes
Sorry,notenough
Sorry,notenough
Sorry,notenough
Sorry,notenough
Sorry,notenough
R~'an
wokeup.
Ryancompletesthewithdrawl
Overdrawn'
Sorry,notenoughforRyan
Overdrawn!
Sorry,notenoughforRyan
Overdrawn!
Sorry,notenoughforRyan
Overdrawn!
ThemakeWithdrawalOmethod
alwayschecksthebalance
beforemakingawithdrawal,
butstiliweoverdrawthe
account.
Here'sonescenario:
Ryanchecksthebalance,seesthat
there'senoughmoney,andthenfalls
asleep.
Meanwhile,Monicacomesinandchecks
thebalance.She,too,
seesthat
there's
enoughmoney.ShehasnoIdeathat
Ryan
Is
goingtowake
up
andcompletea
withdrawal.
Monicafallsasleep.
Ryanwakesupandcompleteshis
withdrawal.
Monicawakesupandcompletesher
withdrawal.BigProblemlInbetweenthe
timewhenshecheckedthebalanceand
madethewithdrawal,Ryanwokeupand
pulledmoneyfromtheaccount.
Monica'scheckoftheaccount
was
notvalid,
because
Ryanhadalready
checkedand
was
stili
In
the
middleof
makinga
withdrawal.
Monicamustbestoppedfromgetting
IntotheaccountuntilRyanwakesupand
flnisheshistransaction.Andvice-versa.
Theyneedalockforaccountaccess!
networkingandthreads
Thelockworkslikethis:
~
There'salockassociatedwiththebonk
accounttransaction(checking
thebalance
andwithdrawingmoney).There'sonly
onekey,and
itstayswiththelockuntil
somebodywants
to
access
theaccount.
When
Ryanwantstoaccessthebank
account(tocheck
thebalanceandwithdraw
money),helocks
thelockandputsthekey
inhispocket.Nownobodyelsecanaccess
theaccount,sincethekeyisgone.
Ryankeeps
thekeyinhispocketuntilhe
finishes
thetrQl\SQctlon.Hehastheonly
key,soMonicacan'taccess
theaccount
(or
thecheckbook)untilRyanunlocksthe
accountandreturnsthekey.
Now,even
if
Ryanfallsasleepofterhe
checks
thebalance,he
has
aguarantee
thatthebalancewillbethesomewhenhe
wakesup,becausehe
keptthekeywhilehe
was
asleep!
f
f
Thebankaccount
transactionis
unlockedwhen
nobodyIsusing
theaccount.
WhenRyan
wantstoaccess
theaccount,he
securesthelock
andtakesthekey.
WhenRyanIs
finished,he
unlocksthelock
andreturnsthe
key.Nowthekey
isavailablefor
Monica(orRyan
again)toaccess
theaccount.
youarehere
~
509
usingsynchronized
Wet1eedthe
Itt
akeWithdrawal()
tttethod
torut1asotteatomicthit1Q.
Weneedtomakesurethatonceathreadentersthe
makeWithdrawal()method,itmust
be
allowed
to
finisbthemethod
beforeanyotherthread
can
enter.
In
otherwords,weneedtomakesurethatonceathreadhas
checkedtheaccountbalance,thatthreadhasaguaranteethatit
can
wakeupandfinishthewithdrawal
beforeanyotherthreadcancheck
the
accountbalance!
Usethesynchronizedkeywordtomodifyamethodsothatonly
onethreadata
time
canaccess
it
That'showyouprotectthebankaccountlYoudon'tputalockon
thebankaccountitself;youlockthemethodthatdoesthebanking
transaction.That
way.
onethreadgetstocompletethewhole
transaction,
starttofinish.even
if
thatthreadfallsasleepinthe
middleofthemethod
I
Soifyoudon'tlockthebackaccount,thenwhatexactly
is
locked?Is
it
themethod?TheRunnableobject?Thethreaditself?
We'lllookat
thatonthenextpage.
In
code,though,it's
quite
simple-justaddthesynchronizedmodifiertoyourmethod
declaration:
The
synchronized
keywordmeansthat
athreadneedsakey
inorder
to
accessthe
synchronizedcode.
Toprotectyour
data
(likethebankaccount),
synchronizethe
methods
thatacton
that
data.
private
synchronized
voidmakeWithdrawal(intamount){
if
(account.getBa1ance()
>=
amount){
Syetam.out.println(Thread.current'l'hreadO.q4ItNameO
+"
isabout
to
withdraw");
try(
System.out.println(Thread.currentThread()
.getName()
+
~
1sgoing
tosleepll);
Thread.s1eep(SOO);
}
eatch(InterruptedException
ex)
(e.x.printStackTraoeO;
I
System.out.println(Thread.ourr8ntThread().
gatName
0
+"
wob
up.");
aocount..withdraw(amount);
System.out.println(Thr8ad.currentThread0.qetNlUll80
+"
completesthewithdraw1"};
else(
System.out.print1n("Sorry,notenoughfor"
+
Thread.currentThread()
.getN~(»;
(Nou
~or
'f0'0lph'fsil.s-s.avvy
\"~ad~:'f~'
!he
t.onv~ntion
of
I&S;,,~
the
'oIcwl!
'at-.il.'
hcY~
does
1\0-1:
\"e.flut
the
whol~
s..bato.-il.
pard:jl.l~ t.hil\~.
ni"k
/'i~,
t\tJt
Eil\1Wl\,
whe"
'fou
ha\"
tl.e
'Hew-a
'ato.-it'i"
t.he
1.0JIU'j(t
0+
threadsortta"sal.i;iOt\1.
~t'(,
it's
Mt
OUR
~vtrltOl\.
l.fWE
\IItl"t
i....
t.haY~e,
'Wt'd
appl'f
t4t isc\'lhC'r~'s
Ul\l.crt<lif\t'fP\,,;l\l.ir1e
-to
fYttt'(...
lAt.heVCt"ytl.i"9relaW
to
t.hrc.alUJ
510chapter
15
networkingandthreads
EveryJavaobject
has
a
Iocl.
A
IocR
has
only
one
'key..
Most
of
thetiJtle,the
IocR
is
unlocked
and
nobody
cares.
But
if
an
ohject
has
synchronizedmethods,a
threadcanenter
one
of
the
synchronizedmethods
ONLY
if
the
"key
for
the
object's
Ioc"k
is
available.
In
otherwords.
only
if
another
thread
hasn't
already
grahbed
theone
"key.
Hey,thisobject's
takeMonevOmethodis
synchronized.Ineedto
get
thisobject'skeybeforeI
So
what
happenswhen
a
threadiscranking
throughitscallstack(startingwiththenm()
method)anditsuddenlyhitsasynchronized
method?
Thethread
recognizesthatitneeds
akeyforthatobjectbeforeitcanenterthe
method.
It
looksforthekey(this
is
all
handled
by
theJVM;there'snoAPTinjavaforaccessing
objectlocks),
and
if
thekeyisavailable.the
threadgrabs
thekeyandentersthemethod.
From
thatpointforward,thethreadhangson
to
thatkeylikethethread'slifedependson
it.
The
threadwon
't
giveupthekeyuntil
it
completesthesynchronizedmethod.
So
while
that
threadisholdingthekey,nootherthreads
can
enter
any
ofthatobject'ssynchronized
methods,becausetheonekeyforthatobject
won'tbeavailable.
zvery
objecthasalock.Mostofthetime,the
kisunlocked,
and
you
can
imagine
avirtual
.sittingwithit.Objectlockscomeintoplay
Iy
whentherearesynchronizedmethods.
\nenan
objecthasoneormoresynchronized
ethods,
athreadcanentera
syrn:hroniz.ed
-ethod
only
if
the
threadcan
get
the
key
iothe
J,ject'swckJ
e
locksarenotper
method,
they
are
per
object.
If
anobjecthastwo
-nch
ronizedmethods,itdoesnot
simplymeanthatyou
can't
havetwo
threads
entering
the
samemethod,
It
eansyoucan'thavetwothreadsentering
)ofthesynchronizedmethods.
Thinkaboutit.[fyouhavemultiple
methodsthatcanpotentiallyacton
an
object'sinstancevariables,
all
thosemethods
needtobeprotectedwithsynchronized.
Thegoalofsynchronizationistoprotect
criticaldata.Butremember,youdon'tlockthe
dataitself,
you
synchronizethemethodsthat
access
that
data.
Ushtgat1
objeet~
lock
youare
here.
511
synchronizationmatters
fhedreaded"LostUpdate
N
probleiM
Here'sanotherclassicconcurrencyproblem,thatcomesfromthedatabaseworld.It's
closely
relatedtotheRyanandMonicastory,butwe'llusethisexampletoillustrateafew
morepoints.
Thelostupdaterevolvesaroundoneprocess:
StepI:Getthebalanceintheaccount
inti
=
balance;
Step2:Add1tothatbalance
balance
=
i+1;
Thetricktoshowingthisistoforcethecomputertotaketwostepstocompletethechange
tothebalance.Intherealworld,you'ddothisparticularmoveinasinglestatement:
balance++;
Butbyforcing
it
into
two
steps,theproblemwithanon-atomicprocesswillbecomeclear.
So
imaginethatratherthanthetrivial"getthebalanceandthenaddItothecurrent
balance"steps,thetwo(ormore)stepsinthismethodaremuchmorecomplex,and
couldn'tbedoneinonestatement.
Inthe"LostUpdate"problem,wehavetwothreads,bothtryingtoincrementthebalance.
classTestSyncimplementsRunnable{
privateintbalance;
publicvoidrun()
for(inti
=
0;i
<
50;i++){
increment
0;
System.out.println("balanceis"+balance);
publicvoidincrement(){
inti
=
balance;
balance
=
i+
l;~ H ~ r~'s ih~
trlAtial
pari!
w.
additlQ/
1-.
~ Il'lt r ~""~ ll't
ih
I
I
J
1:0
w ha i ~ v ~ r
ih
I
~
oa
alll~
by
TIME
WEREAD
IT(
~
va
lA ~
o.f
balal'll~
was
AT
THE
ih ~
CURRE
AM-
I.
)ra
h ~r
ihalladdil'lQ
/1
h
1-.
"I
va
lA ~
IS
J
1:0
W
a~V~r
publicclassTestSyncTest{
publicstaticvoidmain(String[]args){
TestSyncjob
=
newTestSync();
Threada
=
newThread(job);
Threadb
=
newThread(job);
a.startO;
b.startO;
512chapter
15
networkingandthreads
LetJsrut1this
code...
ThreadArunsforawhile
Putthevalueofbalanceintovariable
i.
BalanceisO.so;isnowO.
Setthevalueofbalancetotheresultof
i
+
1.
NowbalanceIs1.
PutthevalueofbalanceIntovariable
i.
BalanceIs1,soIisnow1.
SetthevalueofbalancetotheresultofI
+
1.
NowbalanceIs2.
Welostthelastupdates
thatThreadAmadel
ThreadBhadpreViously
donea'read'ofthevalue
of
balance,andwhenB
wokeup,ItJustkeptgoing
asIfItnevermissedabeat.
Thread
A
runsagain,pickingupwhere.
it
left
off
PutthevalueofbalanceIntovariable
I.
BalanceIs3,soIisnow3.
SetthevalueofbalancetotheresultofI
+
1.
NowbalanceIs4.
PutthevalueofbalanceIntovariableI.
BalanceIs4,so
IIsnow4.
SetthevalueofbalancetotheresultofI
+
1.
Nowbalanceis5.
Thread
B
runsforawhile
Putthevalue
of
balanceintovariableI.
BalanceIs2,soiisnow2.
SetthevalueofbalancetotheresultofI
+
1.
NowbalanceIs3.
PutthevalueofbalanceIntovariable
i.
BalanceIs3,soIisnow3.
(nowthreadBissentbacktorunnebte,
before
It
setsthevalueofbalanceto4]
ThreadBrunsagain,andpicksupexactlywhere
it
leftoffl
SetthevalueofbalancetotheresultofI
+
1.
NowbalanceIs
~ ~
II
.
"·\\t~S
..
n__
ead
A
",ydat.ed
It.
to
1:),
blOt.
\'\0,",
B
ta...
e
bdl.\(
alia
~Ul'fea
0\'\
to!>
o.f
t.he
"fdat.e
A....
ade,
as
it
A's"'fdclU
IIt"'~
hcll1't\'\ea.
youarehere.513
synchronizing
methods
Maketheittcretttettt()tMethodatotttic.
Syttchrottize
it!
Synchronizingtheincrernenu)methodsolvesthe"Lost
Update"
problem,because
it
keepsthetwosteps
in
themethod
asoneunbreakableunit.
public
synchronizedvoidincrement(){
int
i-balance;
balance
=
i
+
1;
}
Q..:
SoundslikeIt'sagoodIdeatosynchronize
everything,Justtobethread-safe.
Onceathreadenters
themethod,wehave
tomakesurethatall
thestepsinthemethod
complete(asone
atomicprocess)before
anyotherthreadcan
enterthemethod.
J\:
Nope,it'snotagoodIdea.Synchronizationdoesn't
come
fOT
free.FIrst,asynchronizedmethodhasacertain
amountofoverhead.In
otherwords,whencodehitsa
synchronizedmethod,there'sgoingtobeaperformancehit
(althoughtypically,you'dnevernoticeIt)whilethematterof
HI
sthekeyavallable
7"
Isresolved.
Second,asynchronIzedmethodcanslowyourprogram
downbecausesynchronizationrestrictsconcurrency.In
otherwords,asynchronizedmethodforces
otherthreadsto
getinlineandwalt
theirturn.Thismightnotbeaproblem
Inyourcode,
butyouhavetoconsiderIt.
Third,andmostfrightening,synchronizedmethodscanlead
todeadlockl(Seepage516.)
A
goodruleofthumbIstosynchronizeonlythebare
minimumthatshouldbesynchronIzed.AndInfact,you
cansynchronizeatagranularitythat'sevensmallerthan
amethod.We
don'tuseitInthebook,butyoucanusethe
synchronizedkeywordtosynchronizeat
themorefine-
grainedlevelofoneormorestatements,ratherthanatthe
whole-methodlevel.
514
chapter15
networkingandthreads
•ThreadArunsforawhile
AttempttoentertheincrementOmethod.
Themethodissynchronized,so
getthekeyforthisobject
Putthevalueofbalanceintovariable
i.
Balanceis0,soiisnow0.
Setthevalueofbalancetotheresultofi+
1.
Nowbalanceis
1.
Returnthekey(itcompletedtheincrementOmethod).
Re-entertheincrementOmethodand
getthekey.
Putthevalueofbalanceintovariable
i.
Balanceis
1,
soiisnow
1.
[nowthread
A
issentbacktorunnable,butsince
it
hasnot
completedthesynchronizedmethod,Thread
A
keepsthekey]
•ThreadBisselectedtorun
,AttempttoentertheincrementOmethod.Themethodis
synchronized,soweneedtogetthekey.
Thekey
is
notavailable.
[nowthreadBissentinto
a
'objectlocknotavailablelounge]
•ThreadArunsagain,pickingupwhereitleftoff
~
(remember,itstillhasthekey)
.~
Setthevalueofbalancetotheresultofi+
1.
Nowbalanceis
2.
Returnthekey.
[nowthread
A
issentbacktorunnable,butsince
it
hascompletedtheincrementOmethod,thethread
does
NOTholdontothekey]
•ThreadBisselectedtorun
I
AttempttoentertheincrementOmethod.Themethodis
synchronized,soweneedtogetthekey.
Thistime,thekeyISavailable,getthekey.
Putthevalueofbalanceintovariable
i.
[continuestorun...]
you
arehere
~
515
thread
deadlock
Thedeadlysideofsyttchronizatiott
Becarefulwhenyouusesynchronizedcode,becausenothing
willbringyourprogramto
its
kneeslikethreaddeadlock.
Threaddeadlockhappenswhenyouhavetwothreads,bothof
whichareholding
a
keytheotherthreadwants.There'snoway
outofthisscenario,sothetwothreadswillsimplysitand
wait.
And
wait.
And
wait.
Ifyou'refamiliarwithdatabasesOrotherapplicationservers,
you
mightrecognizetheproblem;databasesoftenhavea
lockingmechanismsomewhatlikesynchronization.Buta
realtransactionmanagementsystemcansometimesdealwith
deadlock.Itmightassume,forexample,thatdeadlockmight
haveoccurredwhentwo
transactions
aretakingtoolongto
complete.ButunlikeJava,theapplicationservercandoa
"transactionrollback"thatreturnsthestateoftherolled-back
transactiontowhereit
was
beforethetransaction(theatomic
part)began.
Javahasnomechanismtohandledeadlock.
It
won'teven
know
deadlockoccurred.Soit'suptoyoutodesigncarefully.Ifyou
find
yourselfwritingmuchmultithreadedcode,youmight
wanttostudy
".Java
Threads"byScottOaksandHenryWong
fordesigntipsonavoidingdeadlock.Oneofthemostcommon
tipsistopayattentiontotheorderinwhich
YOUl'
threadsare
started.
Allittakesfor
deadlockaretwo
objectsandtwo
threads.
Asimpledeadlockscenario:
ThreadAcan'trununtil
itcangetthe
bar
key,
butBisholdingthe
bar
keyandBcan'trununtilIt
getsthe
too
keythaiAIs
holdingand...
ThreadAwakesup(stlll
holdingthe
(00
key)
andtriestoentera
synchronizedmethodon
objectbar,butcan'tget
thatkeybecauseBhas
It.Agoestothewaiting
1
lounge,untilthebarkeyIs
available
(it
neverwillbel)
too
ThreadBtriestoenter
asynchronizedmethod
ofobject
too,
butcan't
get
that
key(bacause
AhasIt).Bgoes
tothewaitinglounge.
untilthe
Ioo
keyis
available.Bkeepsthe
barkey.
ThreadBentersa
synchronizedmethod
ofobjectbar,andgets
thekey.
if
I
bar
"...
,-r
1
ThreadAgoesto
sleep,holdingthe
too
key.
ThreadAentersa
synchronizedmethod
ofobject
foo,
andgets
the
key."
I
faa
516
chapter15
-
•ThestaticThread.sleepf)methodforcesathreadtoleavethe
runningstateforatleastthedurationpassed
to
thesleepmethod.
Thread.sleep(200)putsathreadtosleepfor200milliseconds.
•ThesleepOmethodthrowsacheckedexception(InterruptedExceptionl,
soallcalls
to
sleept)must
be
wrappedinatry/catch.ordeclared.
•
YoucanusesleepOtohelpmakesureallthreadsgetachancetorun,
althoughthere'snoguaranteethatwhenathreadwakesupit'llgo
to
the
endoftherunnableline.Itmightforexample,gorightback
to
thefront.
Inmostcases,appropriately-timedsleepOcallsareallyouneed
to
keep
yourthreadsSWitchingnicely.
•
Youcannameathreadusingthe(yetanothersurprise)setNameO
method.Allthreadsgetadefaultname,butgivingthemanexplicl1name
canhelpyoukeeptrack
of
threads.especially
if
you'redebuggingwith
printstatements.
•Youcanhaveseriousproblemswiththreads
if
two
ormorethreadshave
accesstothesameobjectontheheap.
•Twoormorethreadsaccessingthesameobjectcanleadtodata
corruption
if
onethread,forexample,leavestherunningslatewhilestili
inthemiddleofmanipulatinganobject'scriticalstate.
•Tomakeyourobjectsthread-safe,decidewhichstatementsshould
be
treatedasoneatomicprocess.Inotherwords,decJdewhichmethods
mustrun
10
completionbeforeanotherthreadentersthesamemethod
onthesameobject.
•Usethekeyword
synchronized
tomodifyamethoddeclaration,
whenyouwanttopreventtwothreadsfromenteringthatmethod.
•
Everyobjecthasasinglelock,withasinglekeyforthatlock.Mostofthe
timewedon'tcareaboutthatlock;lockscomeintoplayonlywhenan
objecthassynchronizedmethods.
•Whenathreadattemptstoenterasynchronizedmethod,thethread
mustgetthekeyfortheobject(theobjectwhosemethodthethread
Istryingtorun).IfthekeyIsnotavailable(becauseanotherthread
alreadyhasit),thethreadgoesIntoakindofwaitinglounge.untilttrekey
becomesavailable.
•
EvenIfanobjeclhasmorethanonesynchronizedmethod,thereisstill
onlyonekey.Onceanythreadhasenteredasynchronizedmethodon
thatobject,nothreadcanenteranyothersynchronizedmethodonthe
sameobjectThisrestrictionletsyouprotectyourdatabysynchronizing
anymethodthatmanipulatesthedata.
networking
andthreads
youarehere
~
517
final
chatclient
NewanditltprovedSitltpleChafClienf
Waybacknearthebeginningofthischapter,webuilttheSimpleChatClientthatcould
send
outgoingmessagestotheserverbutcouldn'treceiveanything.Remember?That'showwe
gotontothiswholethreadtopicinthefirstplace,becauseweneededawaytodotwothings
at
once:sendmessages
to
theserver(interactingwiththeGUI)whilesimultaneouslyreading
incomingmessages
from
theserver,displayingtheminthescrollingtextarea.
importjava.io.*;
importjava.net.*;
importjava.util.*;
importjavax.swing.*;
importjava.awt.*;
importjava.awt.event.*;
publicclassSimpleChatClient
JTextAreaincoming;
JTextFieldoutgoing;
BufferedReaderreader;
PrintWriterwriter;
Socketsock;
publicstaticvoidmain(String[]args){
SimpleChatClientclient
=
newSimpleChatClient();
client.go
0;
publicvoidgo()
Yes,therereally
IS
an
B
end
to
thisthapter.
lottnotyet...
JFrameframenew
JFrame(~Ludicrously
SimpleChatClient");
JPanelmainPanel
=
newJPanel();
incoming
=
newJTextArea(lS,SO);
incoming.setLineWrap(true);
incoming.setwrapStyleWord(true);
incoming.setEditable(false);
JScrollPaneqScroller
=
newJScrollPane(incoming);
qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICALSCROLLBARALMAYS);
qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
outgoing
=
newJTextField(20);
JButtonsendButton
=
new
JButton(~Send");
sendButton.addActionListener(newSendButtonListener(»;
mainPanel.add(qScroller);
We're
startin~
ath
mainPanel.add(outgoing);/
lotSinliahew'nlewread,
.1dd(dB)
s.
J
Inner
t:
assas
maJ.nPane.asenutton;
,;heRlothnabl(-b)
+
setUpNetworking();
thl"ead.
Th
e
it
,o~ th~
s.
f'
el"eadsJobIS
l;O
l"ead1'rOft>thestl"vel"'s
SOlk~t
streaft>,
disrlayih~
any
11,~Oft>ih~ ft>essa~es
inthe
frame.getContentPane
0.
add(BorderLayout.CENTER,mainPanel);
Sll"o
In~
teXtarea.
frame.setSize(400,SOO);
frame.setVisible(true);
ii
closego
518
chapter15
networkingandthreads
privatevoidsetUpNetworking(){
tty{
sock
=
new
Socket("127.0.0.1
H
,
5000);
:J:nputStreamReaderstreamReillder
=
newInputStreamRaader(sock.getInputStream();
reader
~
newBufferedReader(streamReader);
writer
=
newPrintWriter(sock.getoutputStream();
tn∙t
Systam.out.prinUn("networkingestablished");
I•
~e
sot.Krt
to
~et.
e
'dYl'
\,lSil\~
catch(IOExceptionex)(
Wt.'rc
141
:{
strca".s.We
""crt.
al
yea
'1
cr
ax.prin
tStackTrAce();
alld
0Il-lf"
stY
to
strUi
to
1:.ht.
~
J
)t.M.
oJ:.YI't.
J
ea.",
tnt.
il\flot
sb-u'"
so
II
closesetUpNet:working
\,,,rt
f\CI'fl
we
'r(
,v.1;J
J
~Yc.ld
ea....
~et.
thatthe
r
I'L
he
~t.Y.
W\ts53¥S
",'r0W\
~
publicclassSendButtonListenerimplementsActionLietener
publicvoid
actionPerfo~(ActionEvent
ev){
try(
writer.prinUn(outgoing.getText(»;
writer.llush();
cateh(Exceptionex)(
ex.printStackTr8ce();
}
outgoing.setText("");
outgoing.requestFocus();
}
II
closeinner
cl~ss
lex.priilt:StaCJC'1'rac.
n;}
II
closeouterclass
youarehere.
519
chatservercode
IJ
_...
Readj-"a"e
Cade.
,fhereallyreallysltttpleChatServer
YoucanusethisservercodeforbothversionsoftheChatClient,Everypossible
disclaimereverdisclaimedisineffect
here.Tokeepthecodestrippeddowntothe
bareessentials,wetookoutalotofpartsthatyou'dneedtomakethisarealserver.
In
otherwords,itworks,butthereareatleastahundred
ways
tobreakit.
If
you
wantaReally
GoodSharpenYourPencilforafteryou'vefinishedthisbook,come
back
andmakethisservercodemorerobust.
AnotherpossibleSharpenYourPencil,thatyoucoulddorightnow,istoannotate
thiscodeyourself.You'llunderstanditmuchbetter
if
youworkoutwhat's
happeningthanifweexplainedittoyou.Thenagain,
this
is
Ready-bakecode,
soyoureallydon'thave
(0
understanditatall.It'sherejusttosupportthetwo
versions
oftheChatClient.
importjava.io.*;
importjava.net.*;
importjava.util.*;
publicclassVerySimpleChatServer
ArrayListclientOUtputStreams;
publicclaS8ClientBandlerimplementsRunnable(
BufferedReader
reader;
Soc:ketsock;
public:
ClientBandler(SocketclientSocket){
try(
sock
=
clientSocket;
InputStreamReaderisReader::newInputStreamReader(sock.getlnputStream());
reader::new
BufferedReader(isRl!!lader);
•catch(Exceptionex)(ex.printStackTrace();)
)II
closeconstructor
public
voidrun(){
Stringmessage;
try(
while«(message
=
reader.readLine(»
!a
null)
System.out.println("raad"
+
message);
tellEveryone(message);
•II
closewhile
catch(Excaptionex)(ex.printStackTr4l:e();)
)1/
closerun
II
closeinnerclass
520chapter
15
networtOngand
threads
publicstaticvoidmain(String[]args)
newVerySimpleChatServer().go();
publicvoidge()(
clientOutputSt.reams;;DewArrayList
0;
try(
ServerSocketserverSock;;newSarverSocket(5000);
wh.i.le(true)(
Socketclientsocltet
=
servarSoclt.aCC8pt();
Pr1.ntwrlterwriter""
new
PrintWriter(clientSoaket.qetoutputStream();
clientOutputst.relUD8.
add
(writer);
Thread
t
=
newThread(newClientHandler(clientsoOket»;
t.
start();
System.out.pr1.ntln("get
a
connection
H
)
i
catch(Exceptionex)(
ax.printStackTrace();
•
II
closego
publicvoid
tel~one(Str1.ng
message)
Iteratorit
=
cliantoutputStreama.iterator();
while(it.hasNaxt(»(
try(
PrintWriterwriter;;(Printwrlter)it.naxtO;
writer.println(message)i
writar.fluBh();
catch
(Exceptionex){
ex.printstacltTrace();
II
endwhile
II
closetellEveryooe
I
closeclass
youarehere.521
synchronlzaUon
questions
:t1erel~~
DumlJ
~uesti9ns
Q.:
Whataboutprotectingstatic
variablestate7
If
youhavestatic
methods
thatchangethestaticvariable
state,canyoustiliusesynchronization
7
A.:
YeslRememberthatstatic
methodsrunagainsttheclassand
not
againstanIndividualinstanceoftheclass.
Soyoumight
wonderwhoseobject'slock
wouldbeusedonastaticmethod?After
all,there
mightnoteven
be
anyinstances
ofthatclass.Fortunately,Justaseach
object
hasItsownlock-eachloaded
class
hasalock.ThatmeansthatIfyouhave
threeDogobjectsonyourheap,youhave
a
totaloffourDog-relatedlocks.Three
belongingtothethreeDogInstances,
andonebelongingtotheDogclassItself.
Whenyousynchronizeastatic
method,
Javausesthelockoftheclassitself.SoIf
yousynchronize
twostaticmethodsIna
singleclass,athreadwillneedtheclass
locktoenter
either
ofthemethods.
Q..:
What
are
threadprlorltlesll'Ye
heardthat's
a
wayyoucancontrol
scheduling.
A.:
Threadpriorities
might
help
youInfluencethescheduler,butthey
stilidon'tofferanyguarantee.Thread
prioritiesarenumericalvaluesthattell
thescheduler(IfItcares)
howImportanta
threadIstoyou.Ingeneral,thescheduler
willkickalowerprioritythread
outofthe
runningstateIfahigher
prioritythread
suddenlybecomes
runnable,
But...one
more
time,sayItwithmenow,"there
Isnoguarantee.»Werecommendthat
youuseprioritiesonlyifyouwantto
Influence
performance,
butnever,ever
relyonthemforprogramcorrectness.
522
chapter15
Q.:
Whydon'tyoujustsynchronize
all
thegettersandsettersfromthe
class
withthedatayou'retryingto
protect?Like,whycouldn'twehave
synchronlzedJustthecheckBalanceO
andwlthdrawOmethodsfromclass
BankAccount.Insteadofsynchronizing
themakeWlthdrawalOmethodfrom
theRunnable'sclass?
A:
Actua
lIy,
we
should
have
synchronizedthosemethods,toprevent
otherthreadsfromaccessingthose
methods
Inotherways.Wedidn'tbother,
becauseourexample
didn'thaveany
othercodeaccessingtheaccount.
Butsynchronizingthegetters
andsetters(orinthiscasethe
checkBalanceOandwlthdrawO)isn't
enough.Remember,the
pointof
synchronizationIstomake
a
speciflc
sectionofcode
workATOMICALLY.In
otherwords,It's
notJusttheindividual
methodswecareabout,It'smethods
thatrequire
morethan
one
stepto
completel
Thinkabout
lt.jf
wehadnot
synchronizedthemakeWlthdrawalO
method,Ryanwouldhavecheckedthe
balance(bycallingthesynchronized
checkBalanceOl,andthenImmediately
exitedthemethodandreturnedthekeyl
Ofcoursehewouldgrabthekeyagain,
afterhewakesup,sothathecan
call
thesynchronizedwithdrawOmethod,
butthisstillleavesus
withthesame
problemwehadbeforesynchronizationl
Ryancancheckthebalance,gotosleep,
andMonicacancomeinandalsocheck
thebalancebeforeRyanhasachanceto
wakesupandcompleteshiswithdrawal.
Sosynchronizingalltheaccessmethods
Is
probablyagoodIdea,toprevent
otherthreadsfrom
gettingin,butyou
stilineedtosynchronizethemethods
thathavestatementsthatmustexecute
asoneatomicunit.
CodeKitchen
CvberBeatBox
(Start)
(Stop)
(TempoUp)
(TempoDown)
(sendlt)
dancebeat
Andy:
groove
#2
Chris:
groove2revls&d
Nigel:dancebeat
This
is
the
last
version
ol
theBeatBox!
It
connectsto
a
simpleMusicServerso
that
youcan
send
andreceive
heat
patterns
witlt
othercUen
ts.
Thecode
is
really
long,
sotite
complete
listing
is
arluaUy
in
AppenJix
A.
networkingandthreads
youarehere.
523
exercise:CodeMagnets
publicclassTestThreads{
classAccum{
Code
Magnets
AworkingJavaprogramIsscrambleduponthefridge.Can
you
add
thecodesnippetsonthenextpagetotheempty
classesbelow,tomake
a
workingJavaprogramthatpro-
ducesthe
outputlisted?Someofthecurlybracesfellonthe
floorandtheywere
toosmalltopickup,sofeelfreetoaddas
manyofthoseasyouneedl
classThreadOne
classThreadTwo
BonusQuestion:
Whydoyouthinkweusedthe
modifiers
we
didIntheAccumclass?
524
chapter15
networking
and
threads
Code
Magnets,continued..
Threadone
~
newThread(tl)i
system.out.printlo(Utwou+a.getCount())i
}oatoh(InterruptedExceptiOnex){}
ThreadTwO
t2
newThreadTWO()i
returncounteicounter+=add:
publicstaticAccumgetAccurn(){
implementsRunnable(
}
catch(InterruptedExceptionex){}
:::-newTh
read(t2);
Accum.getAccum():Accuma
privatestaticAccurna
newAccurn()
i
privateintco
unter0:
a.updatecounter(l);
publicvoid
forti
t
nx=O:x
<
99.
I
X++)(
implementsRunnable(
publicint
getCount()(
a.updateCounter(lOOO)i
returna;
System.out.printl
O("one"+a
.getCount(»;
for(int
x=o;
x<98'two.start()i
,x++)(
publicstaticvoidmain(String
(I
args)(
publicvoidrunt)(
privateAccum(){}
ThreadOne
tl
=
newThreadO
ne():
youarehere
~
525
exercise
solutions
}
publicstaticAccurngetAccum(){
return
a;
publicvoidupdateCounter(intadd){
counter+=add;
Threadsfromtwodifferent
classes
areupdating
thesameobjectinathirdclass,becauseboth
threadsareaccessingasingleinstance
ofAccum.
Theline
ofcode:
privatestaticAccuma
=
new
Accum();createsa
staticinstanceofAccum(rememberstaticmeans
oneperclass),andtheprivateconstructorin
AccummeansthatnooneelseconmakeanAccum
object.Thesetwotechniques(privateconstructor
and
staticgettermethod)usedtogether,create
what's
knownasa'Singleton'-an00patternto
restrictthenumberofinstancesofanobject
thatcanexistinanapplication.(Usually,there's
justasingleinstanceofaSingleton-hencethe
name),butyoucanusethepatterntorestrictthe
instancecreationinwhatever
way
youchoose.)
/,~~
il
sUb/')i~".u
J
t.\ass
to.t.t........
newAccUDI();
}
}
pUblicclasaTestThreada{
pUblicstaticvoidmain(String[]args){
ThreadOnetl'"newThreadOne()j
ThreadTwot2'"newThreadTwo();
Threadone
~
newThread(tl);
Threadtwo
c
newThread(t2);
one.start();
two.start(),
classAccum{
privatestaticAccuma=:
privateintcounter=:
OJ
privateAccurn(){}
r--
to.
rri"~ ~~
}
publicintgetCount(){
returncounterj
}
}
classThreadOneimplementsRunnable{
Accuma
=:Accum.getAccum()j
publicvoidrun(){
for(intxeO;
x
<
98;
x++){
a.updateCounter(lOOO);
try{
Thread.sleep(50)j
}catch(InterruptedExceptionex){}
classThreadTwoimplementsRunnable{
Accum
a
=
Accum.getAccum()j
publicvoidrun(){
for(intx=:O;
x
<
99;
x++){
a.updateCounter(l)j
try{
Thread.sleep(50);
}catch(InterruptedExceptionex){}
}
System,out.println(~two
u+a.qetCount())j
}
}
}
system.out.println(Noneu+a.getCount())j
}
}
526
chapter15
•
networking
and
threads
Near-missattheAirlock
This
morning'smeetingwasfocusedonthecontrol
systems
fortheorbiter'sairlocks.
As
thefinalconstructionphaseswerenearingtheir
end,
thenumberof
spacewalks
was
scheduledtoincreasedramatically,andtrafficwashighbothinandoutoftheship's
airlocks."GoodmorningSarah",saidTom,"Your
timing
isperfect,we're
just
starting
thedetailed
design
review."
"As
youallknow",saidTom,"Eachairlock
is
outfittedwithspace-hardenedGUI
terminals,bothinsideand
out
Wheneverspacewalkers
are
enteringorexitingtheorbiter
theywillusethese
terminals
to
initiatetheairlocksequences."Sarahnodded,"Tomcan
youtelluswhatthemethodsequencesareforentryandexit?"Tomrose,and
floatedtothe
whiteboard.,"First,here'stheexitsequencemethod'spseudocode",Tomquicklywroteonthe
board
orbiterAirlockExitSequence()
verifyPortalStatus();
pressurizeAirlock();
openlnnerHatch();
confinnAirlockOccupied();
closelnnerHatch();
decompressAirlock();
openOuterHatch();
confirmAirlockVacated();
closeOuterHatch();
"Toensurethatthesequenceisnotinterrupted,wehavesynchronizedallofthe
methodscalledbytheorbiterAirlockExitSequence()method",Tomexplained."We'dhateto
seeareturningspacewalkerinadvertentlycatchabuddywithhisspacepantsdown!"
EveryonechuckledasTomerasedthewhiteboard,butsomethingdidn'tfeel
right
toSarahanditfinallyclickedasTombegan
towrite
theentrysequencepseudocodeonthe
whiteboard,"WaitaminuteTom!",
cried
Sarah.
''1
thinkwe'vegotabigflaw
in
theex.it
sequencedesign,let'sgobackandrevisitit,itcouldbe
critical!"
Why
didSarahstopthemeeting?Whatdidshesuspect?
youarehere
~
527
puzzleanswers
•
WhatdidSarah
know?
Sarah
realizedthat
in
ordertoensurethattheentireexit
sequencewouldrunwithoutinterruptionthe
orbi
terAi
rlockExi
tSequence()methodneededto
besynchronized.
As
thedesignstood,
it
wouldbepossible
forareturningspacewalkertointerrupttheExitSequencel
TheExitSequencethreadcouldn'tbeinterruptedinthe
middle
of
any
of
the
lower
level
methodcalls,
but
it
couldbe
interrupted
in
between
those
calls.
Sarah
knewthattheentire
sequenceshouldbe
runas
oneatomic
unit,
and
if
the
arbi
t
erAirlockExitSequence()
method
was
synchronized,it
couldnotbeinterruptedatanypoint.
528chapter
15
16
collectionsandgenerics
Data
structures
SortingisasnapinJava.
Youhaveallthetoolsforcollectingandmanipulating
yourdata
withouthavingtowriteyourownsortalgorithms(unlessyou'rereadingthisright
nowsittinginyourComputerScience101class,inwhich
case,trustus-youareSOgoingtobe
writing
sort
codewhiletherestofusJustcallamethodIntheJavaAPI).TheJavaCollections
Frameworkhasadatastructurethatshouldworkforvirtuallyanythingyou'lleverneed
todo.
Wanttokeepalistthatyoucaneasilykeepaddingto?Wanttofindsomethingbyname?Want
tocreatealistthatautomaticallytakesoutalltheduplicates?
Sort
yourco-workersbythe
numberoftimesthey'vestabbedyouintheback?Sortyourpetsbynumber
oftrickslearned?
It'sallhere...
thisisanewchapter
529
sortingalist
fracki"Q
SOt1g
popularity
0.,
yourjukebox
Congratulationsonyournewjob----managingtheautomated
jukeboxsystematLou'sDiner.There'sno
Java
insidethe
jukeboxitself,buteachtimesomeoneplaysasong,the
songdataisappendedtoasimpletextfile.
Your
jobistomanagethedatatotracksongpopularity,
generatereports,andmanipulatethe
playlists,
You'renot
writingtheentire
ap~ome
oftheothersoftwaredeveloper/
waitersareinvolvedas
well.
butyou'reresponsibleformanaging
andsortingthedatainside
thejava
app.
And
sinceLouhas
a
thing
againstdatabases,thisisstrictlyanin-memory
data
collection.
All
youget
is
thefilethejukeboxkeepsaddingto.Yourjob
is
totakeit
fromthere.
You'vealreadyfigured
outhowtoreadandparsethefile,andso
far
you'vebeenstoringthe
data
inanArrayList.
SongLlst.
txt
PinkMoon/NickDrake
Somersault/Zero7
Shiv&
Moon/PremJoshua
Circles/BT
DeepChannel/AfroCelts
Passenger/Headmix
Listen/Tahiti80
530
chapter16
Challenge#1
Sortthesongsinalphabeticalorder
Youhave
a
listofsongsinafile.whereeachline
representsonesong,andthetitle
and
artistare
separatedwithaforwardslash.
So
itshouldbesimple
toparse
theline,andputallthesongsin
an
ArrayList.
Yourbosscaresonly
aboutthesongtitles,sofornow
youcansimply
makealistthatjusthasthesongtitles.
Butyoucanseethatthelistisnotinalphabetical
order...whatcan
you
do?
Youknow
thatwithanArrayl.ist,theelementsare
keptintheorderinwhichtheywereinsertedintothe
list,
50
puttingtheminanArrayListwon'ttakecareof
alphabetizingthem,unless...maybethere'sa
sortj)
methodintheArrayListclass?
collectionswithgenerics
Here'swhatyouhavesofar;withoutthesort:
impo4tjava.util.*;
importjava.io.*;
pUblicclassJukeboxl
ArrayList<String>songList
:newArrayList<String>()
i
catch(Exceptionex)(
ex.printStackTrace();
public
static
voidmain
(String()args
1I
newJukeboxl().ge();
publicvoid
go()I
~
getSongs();
System.out.println(songList);
.1:
Y'tilO
thet'lle
il"d
Not.hi,,~
syet."lillhe....e..
J~oo ~a--
eat"
\il'le∙
voidgatSonqa()
t.a\\
-\:.he
ilod$of..~O
'"
try{
FilefilenewFile("SongList.txt
H
);
BufferedReaderreader
=
newBufferedReader(newFileReader(file»:
Stringline
=
null;
whiLe
«
line=reader,readLine()
!
=null)(
addSong(line);
The
tiddSon
Ci...
d
j
th1
"'eiJ..od
\\/orh.
r
(J...
-J..
Ln.
e
I/OthdpU
JIISf
likl!
i~1!
/.I"
~"t;
Ild$
both
th
tifl....--
yOk
b...
k
"i'l<lz.-
void
addSong(StrinqlineToParse)
I
pieCes
(MOu)
lotS'
I!
ill!tlnd
i1r-t.i:tJ
.tt
}itle
String(1tokens
=
lineToParse.split("/");
"\5
tht!
spliiO
"'eih;.
two
songList.add(tokens[Ol);
<:
%javaJukebox!
[PinkMoon,Somersault,
ShivaMoon,Circles,
DeepChannel,Passenger,
Listen}
youarehere.531
ArrayListAPI
~ut
theArrayListclassdoes
NOr
haveasartOtMethod!
Whenyoulookin
Arrayl.isr,
theredoesn'tseemtobeanymethodrelatedtosorting.
NaJking
uptheinheritancehierarchydidn'thelpeither-it'sclearthat
y()U
can't
call
a
sort
nethod
on
the
ArrayList.
•
-
.-
...
•...1•..,.,
AW..I.1a.aC~
.1UlI..
r---------------==:::::====--i
!IDt>nu
t.n.<llf
lhillUI
~
iIl£
spedIDI,
.........&
regu.......
(l...rlt.
IcgaJ..r:us.._,
at.
lA:ItlWl
..,.
~>es
fltJa>
!hi>
USl
all
~ ~
dcm<lll
I;
I
ftlW.1.a.
~
•
.L1&WRL
l!UIt,Ulor,
~7l.-f
••
~
-C;.
-::T~ A;ii'iVUi t
(Jiiii
2
Pli"tfOOii
sr
5:0)
~
i:i)
11
ern
+
lf ~ h It P:1/J av LS u n.ro m/J 1 n/l.S.O'docs/&pl/l n cl tx.h l ml
chapter16
~
TreeSet
Keepstheelementssortedandpreventsduplicates.
r
doseeacollectionclass
celled
TruSe.t...andthedocs
sCI>!
that
it
keepsyourdata
sorted.
r
wonder
if
r
shouldbe
usinga
TreeSetinste.adofan
ArrayList...
o
o
collections
with
generics
ArrayLisfis.!Q1theot1lycollectiot1
Although
ArrayList
istheoneyou'llusemostoften,
thereareothersforspecialoccasions.Someofthekey.
collectionclassesinclude:
D
't
'NcKY'f
C1nOl>t
b-'tl~
Of'
~ese oth~
Ol'Ies
t.o
\eClyY\
'\I
0
il'l-to
yiaht
"0...∙
We
~c
,1._
...
~e o~il~
a\iH:le
C1~'
..HashMap
Let's
youstoreandaccesselementsasnamelvaluepairs.
~
L1nkedLlst
Designedtogivebetterperformancewhenyouinsertordelete
elementsfromthemiddleofthecollection.
(In
practice,
an
ArrayUstisstillusuallywhatyouwant.)
~
HashSet
Preventsduplicatesinthecollection,andgivenanelement,can
findthatelement
in
thecollectionqulcldy.
~
L1nkedHashMap
LikearegularHashMap,exceptitcanremembertheorderin
whichelements(name/valuepairs)wereInserted,oritcanbe
configuredto
remember
theorder
In
whichelementswerelast
accessed.
youarehere
~
533
Collectlons.sortO
You
could
useafreeSet...
OryoucouldusetheColiectiotts.sortCltttethod
lava.utll.collections
publicstaticvoidcopy{Ustdestination.
List
source)
publicstaticUst
emptyUst()
publicstaticvoidflll(ListIIstToFill,ObjectobjToFillltWrth)
publicstaticInttrequency(Collectionc,Object
0)
publicstaticvoid
reverse{Ust
list)
publicstaticvoidrotate(Ust
list,
lntdistance)
publicstaticvoid
shuffle(Ust
list)
publicstatic
~
sOrt{L\st
listV
.
;~.
II".
OhiectoIdVal,ObjectnewVal)
public
staticboole
/I
many
more
met
.ij",,,,,,,...
!here
IS
asor!()Meihod
I-
- ~
1ft!heCollet-t;oftstlass.
I!
hkes
aLis!
and'A
nd1
'SlftterrayList
i"'ple_e...
i.s
!heLis!.t
+
....erate,
rrayLlst
ArrayLis!
IS-A
Lis!.Thanks
verloaded
!opolyMorphisM,
y~
tanpassa...
cklyascalling
~rayList
toaMe!hodd,
ntattheend.
to
ta
et
ared
'tneedtoput
Ice
List
A:
Yes,It'sslowertoinsertsomethinginanA
somewhere
other
thanattheend.Sousingthe
0
add(lndex,element)methoddoesn'tworkasqui
theadd(element)-whichputstheaddedeleme
Butmostofthe
timeyouuseArrayLists,youwon
somethingataspecificIndex.
lfyouputalltheStrings(thesongtitles)intoaTreeSetinsteadof
anArrayList,theStringswouldautomaticallylandintherightplace,
alphabetically
sorted.Wheneveryouprintedthelist,theelementswould
alwayscomeoutinalphabeticalorder.
Andthat'sgreatwhenyouneed
a
set
(we'll
talk
aboutsetsina
few
minutes)orwhen
youknowthat
the
listmust
au.vays
stay
sortedalphabetically.
Ontheotherhand,
if
youdon'tneedthe
listto
stay
sorted.TreeSetmightbemore
expensivethanyou
need-every
time
you
insertintoa
Treeset;
the
TreeSet
hasto
take
thetime
to
figure
outwherein
1M
tree
the
new
elementmust
go.
With
ArrayList,
insertscan
beblindinglyfastbecausethenewelement
justgoesinattheend.
Q:
ButyouCANadd
something
to
an
ArrayList
ataspecific
IndexInsteadofjustat
theend-there's
an
overloadedaddllmethod
thattakes
an
Int
along
withtheelementto
add
Sowouldn'fft
be
slowerthan
Inserting
atthe
e
Q:
Isee
there's
a
L1nkedllstclass,
so
wouldn'tthat
bebetterfor
doing
Inserts
somewhereInthemiddle1At
least
if
I
remembermyData
Structuresclassfrom
college...
A:
Yes,goodspot.TheLinkedLlst
can
bequickerwhenyouInsertor
removesomething
from
themiddle,butformostapplications,thedifference
between
middleinsertsIntoaLinkedllstandArrayListisusuallynotenough
tocare
aboutunlessyou'redealingwitha
huge
numberofelements.We'll
lookmoreatL1nkedLlstInafewminutes.
534
chapter16
collectlonswithgenerics
Addit1gColiectiot1s.sortUtotheJukeboxcode
importjava.util.*;
im
portjava.io.
T
;
publicclassJukeboxl
ArrayList<String>songList
=
newArrayList<String>();
publicstatic
voidma
i
n(String[]args)(
new
Jukebox1()
.go();
The
Collections.sortO
lllethod
sortsa
list
of
StriPgs
alphabetically.
publicvoid
got)
r
ger-Songs();1t.aVt.
CoI\et:b~
System.out.println(songList);
~ ~~~et\<'odl ~e"Y'f\,,~-\;.h~
Collections.sort(songList);\'
L
,"T"ne
~[t.ot>d ~,,,t.
,5<.
a~''''
\
J
I
System.out.println(songList);
~
'IS,,,
i\,,~'oebt.a\cJt"~t:'t'.
void
getsongs()
try(
File
lle
newFile("SongList.txt
H
);
BufferedReaderreader
=
newBufferedReader(newFileReader(file»;
Stringline-null;
while
((line-
reader
i
readt.Lne
t)
l
!='
null)(
addSong
(1
ine);
catch(Exceptionex)(
ex.printS
ackTrace();
void
addSong(StringlineToParse)(
tringl]tokens
=
lineToParse.split("/H);
songList.r.tdd(token.s[O]);
%javaJukeboxl
[PinkMoon,Somersault,ShivaMoon,Circles,Deep
Channel,Passenger,Listen)
(Circles,DeepChannel,Listen,Passenger,Pink
Moon,ShivaMoon,Somersault]
•
,
youarehere
~
535
sortingyourownobjects
Jutnowyou
MeedSOMQ
objects,
notjustshttple
Stri"Qs.
NowyourbosswantsactualSong
class
instancesinthe
list,
notjust
Strings,sothateachSongcanhavemoredata.Thenewjukebox
deviceoutputsmoreinformation,so
this
timethefile
will
have
four
pieces(tokens)insteadofjusttwo.
TheSongclassisreallysimple,withonlyoneinterestingfeature-
theoverriddentoStringOmethod.Remember,thetoString()
methodisdefined
in
classObject,soeveryclassinJavainheritsthe
method.AndsincethetaStringOmethodiscalledonanobject
whenit's
printed(System,out.println(anObject)),youshould
overrideittoprintsomethingmorereadablethanthedefault
uniqueidentifiercode.Whenyouprintalist.thetoStringO
methodwillbecalledoneachobject.
class
Song(
Stringtitle;
f
Stringartist;
Stringrating;
Stringbpmi
Song(Stringt,Stringa,Stringr,Stringb)(
title
=
t;
artist
='
a;The
va~i.ables
a.-t
all
sd.
i"
rating
=
r;
the
l.or\strl.ll.i«
wher>the
bpm
=
b
r"
I\ew
~,,~
is
l.~eated,
SongUstM0r2.
txt
PinkMoon/NickDrake/5/80
Somersault/Zero7/4/84
ShivaMoon/PremJoshua/6/120
Circles/BT/5/110
DeepChannel/AfroCelts/4/120
Passenger/Headmix/4/l00
Listen/Tahiti80/5/90
pUblicStringgetTitle()
returntitle;
publicStringgetArtist()
returnartist;
publicStringgetRating(}
returnrating;
publicStringgetBpm()
returnbpm;
publicStringtoString()
returntitle;
536chapter
16
import
java.util.*;
importjava.io.*;
collections
with
generics
ChangingtheJukeboxcodetouseSongs
insteadofStrings
Yourcodechangesonlyalittle-thefileI/Ocodeisthesame,
andtheparsingisthesame(String.splitf)).exceptthistime
therewillbe
Jour
tokensforeachsong/line,andallfourwillbe
usedtocreateanewSongobject.AndofcoursetheArrayList
willbe
oftype<Song>insteadof<String>.
L
A.rra'JL.ist
cJ
SoY\~
Chan~e ~
an
f\
J
'Stv:ln~.
objetts
Instead
publicclass
J UkebOX ~ ~
ArrayList<Song>songList
=
newArrayList<Song>();
public
staticvoidmain(String[]args)(
newJukebox3().go();
}
public
void
ge(){
getSongs();
Sy
stem.out.println(songList);
C
ollections.sort(songList);
Sys
tem.out.println(songList);
}
void
getSongs()
try{
FilefilenewFile{"SongList.txt
H
);
BufferedReaderreader
=
neviBufferedReader(newFileReader
(file));
Stringline
=
null;
wh
ile
«
Line>reader.readLine())
!
~ o
null)(
add
Song(line);
catch(Exceptionex)
ex
.printStackTrace();
vo
id
addSeng(StringlineTeParse){
String[]
tokens
=
lineToParse.split("/");
SongnextSonq
=
newSonq(tokens[O],tokens[l],tokens[2],tokens[3]);
songList.add(nextSong);
youarehere
~
537
Collections.s
0
rtO
It
WOt1~t
cotMpiIe!
Something'swrong...theCollectionsclassclearlyshowsthere'sa
sort/)method,thattakesaList.
ArrayListis-aList,becauseArrayList
implementstheListinterface,
so...it
should
work.
But
it
doesn't!
Thecompilersaysitcan'tfindasortmethodthattakesan
Arrayl.istc'Songo,somaybeit
doesn'tlikeanArrayl.istofSong
objects?Itdidn'tmindanArrayList<String>.sowhat'sthe
importantdifferencebetweenSongandString?What'sthe
differencethat'smakingthecompiler
fail?
%javacJukebox3.java
JukeboK3.java:15:cannotfindsymbol
symbolmethod
sort(java.util.ArrayList<Song»
location:classjava.util.Collections
Collections.sort(songList);
1
error
AndofcourseyOllprobablyalreadyasked
yourself,
"Whatwouldit
be
sorting
onr
How
wouldthesortmethodeven
know
whatmade
oneSonggreaterorlessthananotherSong?
Obviously
if
youwant
thesong's
title
to
be
thevaluethatdetermineshow
the
songsare
sorted,you'llneedsomewaytotellthesortmethodthatitneeds
tousethetitleandnot,say,
the
beatsper
minute.
We'llgetinto
aU
thatafewpagesfromnow,butfirst,let'sfindout
whythecompilerwon'tevenletuspassaSongArrayListtothe
sortt)method.
538
chapter16
collectionswithgenerics
WIDIhavenoideahowto
read
the
method
declaration
onthis.
It
says
that
sortO
takesa
List~T).
butwhatis
n
Andwhatisthatbigthing
beforethereturntype?
o
o
fhesortOtMethoddeclaratiot'
sort
public:
at.4t~
fUl.teDd:
eome:rllbl&<?auperT>";>Oid
.o~
HlStl
Sorts
the
specified
list
into
ascendingorder.according
to
the
nalJITal
ordering
of
itselements.
All
elements
in
the
list
mu.st
implement
the
Comparable
interface.
Furthermore.
allelements
in
thelist
must
be
mullllllJy
comparab~
(that
is,
el.cOIIlpareTo
I
82)
must
not
throw
a
ClaasC4st.E>l:c:eption
for
any
elements
&1
and
82
in
the
list).
Fromthe
API
docs(lookingup
the
java.util.Collections
class.and
scrollingtothe
sortt)
method),itlookslikethe
sortt)
method
is
declared...
strangely.
Or
at
leastdifferentfrom
anythingwe'veseensofar.
That'sbecausethesortOmethod(alongwithotherthingsinthewholecollectionframeworkin
Java)makesheavy
use
of
generics.
AnytimeyouseesomethingwithanglebracketsinJavasource
codeordocumentation,itmeansgenerics-afeatureaddedtoJava5.0.Soitlookslikewe'll
haveto
learnhowtointerpretthedocumentationbeforewecanfigureoutwhywewereableto
sortStringobjectsinan
Arrayl.ist,
butnotanArrayListofSongobjects.
youarehere
~
539
generictypes
&et1erics",eat1s",oretype...safety
We'lljustsayitright
here-virtuallyallofthecodeyouwritethatdeals
withgenericswillbecollection-relatedcode.
Althoughgenericscanbeused
inother
ways,
themainpointofgenericsistoletyouwritetype-safe
collections.
Inotherwords,codethatmakesthecompilerstopyou
fromputtingaDogintoalistofDucks.
Beforegenerics(which
meansbeforeJava5.0),thecompilercould
notcarelesswhatyouputintoacollection,becauseallcollection
implementationsweredeclaredtoholdtypeObject.Youcouldput
anything
inanyArrayList;
it
waslikeallArrayListsweredeclaredas
ArrayList<Object>.
ArrayList
~ ~ ~ ~
••••
AndcomeOUTasareferenceoftypeObject
wIthgenerics.youcan
createtype-safecollections
wheremoreprobleltlSare
caughtatcompile-time
inStead
of
runtil1le.
wIthoutgenerics.the
compilerwouldhappilylet
you
put
a
Pumplin
intoan
ArrayLiStthat
was
supposed
toholdonlyCatobjects.
ArrayList<Fish>
WITHgenerics
ObjectsgoINasareferenceto
onlyFishobjects
AndcomeoutasareferenceoftypeFish
540
chapter16
Learninggenerics
Ofthedozensofthingsyoucouldlearnaboutgenerics,thereare
reallyonlythreethatmattertomostprogrammers:
•Creatinginstancesofgenerifiedclasses(likeArrayList)
WhenyoumakeanArrayList,youhavetotellitthetype
ofobjectsyou'llallowinthelist,justasyoudowithplain
oldarrays.
•Declaringandassigningvariablesofgenerictypes
Howdoespolymorphismreallyworkwithgeneric
types?
If
youhaveanArrayList<Animal>reference
variable,canyouassignanArrayList<Dog>toit?What
aboutaList<Animal>reference?Canyouassignan
ArrayList<Animal>toit?You'llsee...
•Declaring(andinvoking)methodsthattakegenerictypes
If
youhaveamethodthattakesasaparameter,say,an
ArrayListofAnimalobjects,whatdoesthatreallymean?
CanyoualsopassitanArrayListofDogobjects?We'll
lookatsomesubtleandtrickypolymorphismissuesthat
areverydifferentfromthewayyouwritemethodsthat
takeplainoldarrays.
(Thisisactually
thesamepointas#2,butthatshowsyou
howimportantwethinkitis.)
Q.:
Butdon'tIalsoneedtolearnhowtocreatemyOWNgeneric
dasses?WhatifIwanttomakeaclasstypethatletspeople
instantiating
theclassdecidethetypeofthingsthatclasswilluse?
A.:
Youprobablywon'tdomuchofthat.Thinkaboutit-theAPI
designersmadeanentirelibrary
ofcollectionsclassescoveringmostof
thedatastructuresyou'dneed,andvirtuallythe
onlytypeofclassesthat
reallyneedtobegenericarecollectionclasses.Inotherwords,classes
designedtoholdotherelements,andyouwantprogrammersusingitto
specifywhat
typethoseelementsarewhentheydeclareandinstantiate
thecollectionclass.
Yes,itispossiblethatyoumightwantto
create
genericclasses,butthat's
theexception,sowewon'tcoverithere.(Butyou'llfigureit
outfromthe
thingswe
do
cover,anyway.)
collectionswithgenerics
newArrayList<Song>()
List<Song>songList
=
newArrayList<Song>()
voidfoo(List<Song>list)
x.foo(songList)
youarehere
~
541
genericclasses
UsinggenericCLASSES
SinceArrayListisourmost-usedgenerifiedtype,we'll
startbylookingatits
documentation.Theytwokeyareas
to
lookatinagenerifiedclassare:
1)
The
class
declaration
3)
The
method
declarationsthatletyouaddelements
UnderstandingArrayListdocumentation
(Or,what's
the
true
meaning
of"E"?)
publicclassArrayList<E>extendsAbstractList<E>
II
morecode
The"E"representsthetypeusedtocreateaninstance
ofArrayList.Whenyouseean"E"intheArrayList
documentation,youcandoamentalfind/replaceto
exchange
it
forwhatever<type>youusetoinstantiate
ArrayList.
So,newArrayList<Song>means
that"E"becomes"Song",
inany
methodorvariabledeclarationthatuses"E".
542chapter16
Thinl
of
"E"
asa
stand-in
for
"-thetype
of
elem.ent
youwant
this
collectiontohold
and
return."
(E
is
for
Elenent.)
-
-
implementsList<E>..,{
.:
Thet'tfe(the
lJal~
of
<f.»
bet.oMesthet'fVe
of
theList
il'ltel""kat.easwell.
collectionswithgenerics
Usit1QtypeparattteterswithArrayList
THIScode:
ArrayList<String>thisList
=
new
MeansArrayLlst:
.
..
{
publicboolean
addlE
0)
//more
code
Istreated
by
thecomplieras:
publicclass
ArrayList<Strinq>extendsAbstractList<Strinq>...{
publicboolean
add(Strinq
0)
//more
code
Inotherwords,the
~E~
isreplacedbythe
real
type(alsocalledthe
type
parameter)
thatyouusewhenyoucreatetheArrayl.ist,Andthat'swhytheadd
0
method
forArrayListwon'tletyouaddanythingexceptobjectsofareferencetypethat's
compatiblewith
thetypeof
~E".
So
if
youmakeanArrayList<:String>,theadd
0
methodsuddenlybecomesadd(String
0).
!fyoumaketheArrayListoftypeDog,
suddenlythe
addt)
methodbecomesadd(Dog
0).
Q:
Is"E"theonlythingyoucanputthere18ecausethedocsforsortused
"1'':'•••
A:
Youcanuseanythingthat'salegalJavaIdentifier.Thatmeansanythingthatyou
coulduse
foramethodorvariablenamewillworkasatypeparameter.Buttheconven-
tionIstouseasingleletter(sothat'swhatyoushoulduse),andafurtherconventionISto
use
MT"
unlessyou'respecIficallywrltlngacollectionclass,whereyou'duse
ME"
torepre-
sent
the"typeoftheElementthecollectionwillhold"
youarehere)543
genericmethods
Ageneric
class
meansthatthe
classdeclaration
includes
a
type
parameter.
A
generic
method
meansthatthemethoddeclaration
usesatype
parameterinitssignature,
You
canusetypeparametersinamethodinseveraldifferent
ways:
•Usinga
type
parameterdefinedIntheclassdeclaration
publicclassArrayList<E>extendsAbstractList<E>...(
publicboolean
addlE
0)
\/OII"~
"-../t-......"
~
fh
~E»
tllr~dy
b
tbl
d:fi"td
:~;tl~:r het.4~
it's
Whenyoudeclare
atype
parameterfortheclass,you
tht
lltlU.
cansimplyusethattypeanyplacethatyou'dusea
real
classorinterfacetype.Thetypedeclaredinthe
methodargumentisessentiallyreplacedwiththetype
youuse
whenyouinstantiatetheclass,
•Usinga
type
parameter
that
wasNOTdefinedIntheclassdeclaration
--
~
public<T
extends
Animal>voidt&keThing(ArrayList<T>list)
If
the
class
itselfdoesn'tuse
a
typeparameter,you
canstill
»&t
we
~
rr...."
~<T:>
be
specifyonefor
a
method,
by
declaring
it
ina
really
unusual
~rliel"
i"the...efh
~~
we
~1~hOA
(butavailable)
space-before
the
returntype,
Thismethodsays
od
dtlJdrd~
thatTcanbe"anytypeofAnimal",
544
chapter16
collections
with
generics
Wait...thatcan'tberight.
If
you
can
take
a
list
of
Animol,
why
don't
you
just
SAYthat?What'swrongwithjust
toke
ThIng{AtTayUst~
Animal;)
list)?
HereJswhereItgetsweird...
This:
public<T
extends
Animal>voidtakeThing(ArrayList<T>list)
IsNOT
the
sameas
this:
publicvoidtakeThing(ArrayList<Animal>list)
Both
arelegal,butthey're
diffmmtl
Thefirstone,where
<T
extendsAnimal>ispartofthemethod
declaration.meansthatanyArrayl.istdeclaredofatypethatis
Animal,
oroneofAnimal'ssubtypes(likeDogorCat),islegal.
So
youcouldinvokethetopmethodusinganArrayList<Dog>,
ArrayList<Cat>,
orArrayList<Animal>.
But...theoneonthebottom,wherethemethodargumentis
(Arr.tyList<Animal>list)
meansthat
only
anArr.tyList<Animal>
is
legal.Inotherwords,whilethefirstversiontakesanArrayl.isr
ofanytypethatisatypeof
Animal
(Animal,Dog,Cat,etc.),
thesecondversiontakes
Qnly
anArrayl.JstoftypeAnimal.Not
ArrayList<Dog>,orArrayList<Cat>butonlyArrayList<Animal>.
Andyes,itdoesappeartoviolatethepointofpolymorphism.
butitwillbecomeclearwhenwerevisitthisindetailattheend
ofthechapter.Fornow,rememberthatwe'reonlylookingat
thisbecausewe'restilltryingtofigureouthowto
sortO
that
SongList,andthatledusintolookingattheAPIforthesoru)
method,whichhadthisstrangegenerictypedeclaration.
Fornow,all
you
need
to
krww
is
thatthe
synt.ax
of
the
top
uersion
is
legal,
and
that
it
means
you
canpass
in
a
ArrayList
object
1'nstantiated
as
Animal
or
any
Animal
subtype.
Andnowbacktooursortt)method...
you
arehere.545
sortingaSong
Thisstilldoesn't
explainwhythe
soMmethod
failedonanArrayListofSongs
butworkedforanArrayListof
Strings...
Rememberwherewewere...
importjava.util.*;
importjava.io.*:
publicclassJukebox3(
ArrayList<Song>songList
=
newArrayList<Song>()i
pUblicstaticvoidmain{String{)args)(
new
Jukebox3{).go();
System.out.println(songList);
I
pUblicvoid
go()(
getSongs();
System.out.println(songList);
}
void
getSongs()
try(
FilefilenewFile("SongList.txt
H
);
BufferedReaderreader
=
newBufferedReader(newFileReader(file));
Stringline
~
null;
while((line=reader.readLine{»
!=
null)(
addSong{line);
I
catch(£xceptionex)(
ex.printStackTrace();
)
void
addSong(StringlineToParse)(
String!)tokens
=
lineToParse.split("/");
SongnextSong
=
newSong(tokens
[01,
tokens[l],tokans[2],tokens[3]);
songList.add(nextSong);
546
chapter16
collections
with
generics
Revisiti.,gthe
sortt)
tltethod
Sohereweare,trying
to
readthesortt)method
docs
tofind
out
why
it
was
OK
to
sorta
listofStrings,butnota
list
ofSongobjects.And
it
looksliketheanswer
is'''
L
L...
~ ~ OoVi i,;;;;;;
..
$(∙
:.1.-"
~"""lIHJ'/""""I_"I""/'''''
__1
':01
ThesortOmethodcantakeonlylists
ofComparableobjects.
SongisNOTasubtypeof
Comparable,soyoucannotsorto
thelist
of
Songs.
sort(List<T>list)
Yov.
c.dl'l
fau
i~
Of\ly
a
L.ist.
(.I:ir
slObtYfe
~
list,
[ikt:
AwayLlsV
t.hat
~
a
fara"'eW-iudt'ifc
thdt
"e'llUNis
Co""yarablt:".
publicstatic<TextendsComparable<?superT»void
----~---
J
~~
..«eth:spart.
to'r..
ow.
Bt.t
,f
y~
loa"
t..
it
j
lI.Si
"'tel
I'IS
thaithetypepara",c1:.tY
.f«
eo",parablc
"'t.jt
be
o-f
type
T
o'r
one
o-f
T's
st.pertyptsJ∙
At
least
notyet.•.
Urn...I
just
checkedthe
docs
for
String.andStringdoesn'tEXTEND
Comparable--itIMPLEMENTS
it.
CDmparableisan
Interlace.
Soit'snonsense
to
say
<T
extends
Comparable>,
publicfinalclaS9StringextendsObjectimplementsSerializable,
Comparable<String>,CharSequence
youarehere.547
thesortt)method
't1get1erics,"extet1ds
N
ttteat1S
"extet1ds
~
itttpletttet1ts
N
TheJavaengineershadtogiveyouawaytoputaconstraint
onaparameterizedtype,sothatyoucanrestrictitto,say,only
subclasses
ofAnimal.Butyoualsoneedtoconstrainatypeto
allowonlyclasses
thatimplementaparticularinterface.So
here'sasituationwhereweneedonekindofsyntaxtowork
forbothsituations-inheritanceandimplementation.Inother
words,thatworksforboth
extends
and
implements.
Andthewinningwordwas...
extends.
Butitreallymeans"is-a",
andworksregardlessofwhetherthetypeontherightisan
interfaceoraclass.
COMrarableisanin-ttr.fate,sothis
R~l...l...
y
reads,
"T
Ml.tStbeat'tr
e
t,hat
iMrleMentstheCOMrarablein-ttrfate.
~
publicstatic<TextendsComparable<?super
J'
Itdoesn'tMat-tt\'"whetherthe
thil'l~
onthe
ri~ht
is
at1ass
0\'"
il'l-tt\'"+ate...
'101#.
stillsa'l
"e~-ttnds".
Q.:
Whydidn'ttheyjustmakeanewkeyword,"is"?
A:
AddinganewkeywordtothelanguageisaREALLYbigdealbecause
itrisksbreakingJavacodeyou
wroteinanearlierversion.Thinkabout
it-youmightbeusingavariable"is"(whichwedouseinthisbooktorepre-
sent
inputstreams).Andsinceyou'renotallowedtousekeywordsasidenti-
fiersinyourcode,thatmeansanyearliercodethatusedthekeyword
before
itwasareservedword,wouldbreak.Sowheneverthere'sachanceforthe
Sunengineerstoreuseanexistingkeyword,as
theydidherewith"extends';
they'llusuallychoosethat.Butsometimesthey
don'thaveachoice...
Afew(veryfew)newkeywords
have
beenaddedtothelanguage,such
as
assert
inJava1.4and
enum
inJava5.0(welookatenumintheappen-
dix).Andthisdoesbreakpeople'scode,howeveryousometimeshavethe
optionofcompilingandrunninga
newer
versionofJavasothatitbehaves
as
thoughitwereanolderone.Youdothisbypassingaspecialflagtothe
compilerorJVMatthecommand-line,thatsays/Yeah,yeah,IKNOWthisis
.Java1.4,
butpleasepretendit'sreally1.3,becauseI'musingavariableinmy
codenamed
assert
thatIwrotebackwhenyouguyssaiditwouldOKI#$%':
(To
see
ifyouhaveaflagavailable,type
javac
(forthecompiler)or
java
(for
theJVM)atthecommand-line,
withoutanythingelseafterit,andyoushould
seealistofavailableoptions.You'lllearnmore
abouttheseflagsinthechap-
terondeployment.}
548
chapter16
In
generics,the"keyword
"extends"reallymeans
"is-a",
and
wor"ksfor
B01lI
classes
and
interfaces.
T»voidsort(List<T>list)
FittallywekttowwhatlwrottQ...
The
SOtt<l
class
tteedstohMplelMetttCOlMparable
WecanpasstheArrayList<Song>tothesortt)methodonly
if
the
SongclassimplementsComparable.since
that's
the
way
the
sortt)
method
was
declared.AquickcheckoftheAPIdocsshowsthe
Comparableinterface
is
reallysimple.
with
onlyonemethodto
implement
java.lang.Comparable
publicinterfaceCOIIIp&rahle<T>
int
compareTo(T
O)i
Andthemethoddocumentationfor
compare'Io()
says
Returns:
aneqativeinteger,zero,ora
positiveintegerasthisobject
1s1&88than,8qlUllto,orgreater
than
theSp8cl1iedobject.
It
lookslikethecompareToOmethod
will
becalledonone
Songobject,passingthatSongareference
to
adifferent
Song.
The
SongrunningthecompareToOmethodhasto
figure
out
if
theSongit
was
passedshouldbesortedhigher,
lower,
orthesameinthelist.
Your
bigjobnowistodecidewhatmakesonesonggreater
thananother,andthenimplementthecompareToOmethod
toreflectthat.
A
negativenumber
(any
negativenumber)
meanstheSongyouwerepassedisgreaterthantheSong
runningthemethod.Returning
a
positivenumbersays
thattheSongrunningthemethodisgreaterthantheSong
passed
to
thecompareToOmethod.Returningzeromeans
theSongsareequal(atleastforthepurposeofsorting...
it
doesn'tnecessarilymeanthey'rethesameobject).Youmight,
forexample.havetwoSongswiththesametitle.
(Whichbrings
upawholedifferentcanofwonnswe'Illook
atlater...)
collectionswithgenerics
Thebigquestion
is:
what
makesonesonglessthan,
equalto,orgreaterthan
anofhersong?
You
can'tImplementthe
ComparableInterfaceuntilyou
makethatdecision.
n
your
pencil-------,
WriteInyourideaandpseudocode(or
better,REAL
code)forImplementingthe
compareToOmethodInawaythatwill
sortf)the
SOl'\g
objects
by
title.
Hint:Ifyou'reontherighttrack,
it
should
takelessthan3lines
ofcodel
you
arehere
~
549
theComparableinterface
fhe"eYl,itltproved,cotltparable
SO"Q
class
IAsv.ally
t.~~se
,.,..;tt,h...
\lIt
't't
sfet l.f'ii~
thet'fYe
t1a-t
t~e
i
"le...
e"h,,~
dciss
tal>
be(.Oft\ra--ed
a~"'IJI,S+"
ThisecihS
that.
~,,~
ob
jed:.s
ta"
be
t.OMr
a
--
ed
-to
ot.hel"
~~
obje
t.b,
f~ t~e r~--fose
tJ
sorti~.
Comparable<Song>{
Stringa,Stringr,String
b)(
,---ThesoortO",dhod
~ds
a
So,,~
to
i.e-ya--e
T
of.)
.J..,.
-to
seehow
that
~~
t.o...
ya__
es
to
t~ Sol'l~
O'/'l
whiththe...
dhoa
was
,,,yoked.
publicintcompareTo(Songs){
returntitle.compareTo(s.getTitle(»;
Sonq(Stringt,
title=
t;
artist
=
a;
rating
=
r;
bpm
=
b;
)
Wedecided
we
wantto
son
by
title,soweimplementthecornpareTo()
methodtocomparethetitle
of
theSongpassedtothemethodagainst
thetitleofthesongonwhichthecompareToOmethod
was
invoked.
In
otherwords,thesongrunningthemethodhastodecidehow
its
titlecomparestothetitleofthemethodparameter.
Hmmrn...weknowthattheStringclassmustknowaboutalphabetical
order,because
the
sortj)
methodworkedonalistofStrings.Weknow
Stringhasa
compareTaOmethod.
80
whynotjust
call
it?That
way,
we
cansimplylet
onetitleStringcompareitselftoanother,andwedon't
have
to
writethecomparing/alphabetizingalgorithm!
class
Songimplements
StringtitIe;
Stringartist;
Stringrating;
String
bpm;
publicStringgetTitle()
returntitie;
publicStringgetArtist()
returnartist;
%javaJukebox3
publicStringgetRating()
returnrating:
(PinkMoon,Somersault,ShivaMoon,Circles,Deep
Channel,Passenger,Listen]
publicStringgetBpm(){
returnbpm;
[Circles,DeepChannel,Listen,Passenger,Pink
Moon,ShivaMoon,Somersault]
publicStringtoString()
returntitle;
)
550
chapter16
collectionswithgenerics
That'snotgoodenough.
Sometimes
r
want
ittosort
by
artist
insteadoftitle.
LookattheCollectionsclassAPIagain.There'sa
secondsortOmethod-andittakesaComparator.
Wecattsortthelist,
but...
There'sanewproblem-Louwantstwodifferentviewsofthesonglist,
one
by
songtitleandone
by
artist!
Butwhenyoumakeacollectionelement
comparable(byhaving
it
implementComparable),yougetonlyonechancetoimplementthe
compareToOmethod.Sowhatcanyoudo?
ThehorriblewaywouldbetouseaflagvariableintheSongclass,
andthendoan
if
testin
compare'Ior)
andgiveadifferentresult
dependingonwhethertheflagissettousetitleorartistforthe
comparison.
Butthat'sanawful
andbrittlesolution,andthere'ssomethingmuch
better.SomethingbuiltintotheAPIforjustthispurpose-whenyou
wantto
SOrt
thesamethinginmorethanone
way.
.
_-
CollectionsOava2PlatformSE5.0)
----
.
_.
~
flle:IIIUsers/kathyIPublic/docs/apl/lndex.hlml
0..
Google
J
--
s
Jellyvislon.Inc
Collections...formSE5.0)Caffelnated...dBrainDayBrandNoiseDIvaMarketing
»
static
8LngletoAKaP(Kkey,Vvalue)
,....
<X,V>
~<K.V>
Returns
animmutablemap,mapping
only
the
~
specifiedkey
to
the
specified
value.
:oJ
-
---
1
lllGtic
~(Li5t<T>
list)
-
~per
T»
,--
Sortsthe
specified
list
intoascendingorder,
sarlO
~~od
iso'Jev-\oad
ed
-to
void
according
to
the
1UJlUTalordering
of
its
elements.
\
llt;~
BOrt.(List<T>
list,
COlnD8f"lftor<?superT>
~
The.\\
d
acO"'yayat.o--∙
r>
v
c;nrte
~
.-
list
according
to
the
~.
r---
bke
SOft'et\oi,,,~
U
e
..
-
induced
by
me.
...
1--,'-
~ ~.
OIo't
~
-to
-<II
~I
\
Note
-to
se\:
,~~e
t.o--
t,nat
Un
tit/
w.av.t
aCotr-ya
Yd
~
ncl
o'I"dfYtntsanOJ
b~
WW'y~t
a
.wd
~
ttlt-oO
aM:.isl
,"s
)
L
-
youarehere.
551
theComparatorinterface
UshtgacustOtltCotltparafor
An
elementinalistcancompare
itself
toanotherof
itsowntype
in
onlyoneway.usingitscompareTo(}
method.But
a
Comparatorisexternaltotheelement
typeyou'recomparing-it'saseparateclass.
So
youcan
makeasmanyoftheseasyoulike!Waut
to
compare
songsby
artist?
Make
anArtis
tCompara
to
r.Sort
by
beats
perminute?MakeaBPMCornparator.
Then
all
youneedtodois
call
theoverloadedsortt)
methodthattakestheListandtheComparatorthat
will
helpthesortt)methodput
things
inorder.
ThesortOmethodthat
takesa
Comparator
will
use
the
Comparatorinstead
of
theelement's
own
compareTo(}
method,when
it
putstheelementsinorder.Inother
words,
if
yoursortt)methodgetsaComparator,itwon't
even
call
thecompareToOmethod
of
theelements
inthelist.Thesortf)method
will
insteadinvokethe
compareO
methodon
the
Comparator.
So,
therulesare:
~
Invokingtheone-argumentsort(L1st
0)
method
meansthelistelemenfscompareToOmethod
detennlnestheorder.SotheelementsInthelist
MUSTImplementtheComparableInterface.
~
Invokingsort(Llst
0,
Comparatorc)meansthe
listelemenfscompareToOmethodwillNOTbe
called,andtheComparatorscompare{)method
will
be
usedInstead.Thatmeanstheelements
InthelistdoNOTneedtoImplementthe
ComparableInterface.
Q.:
SodoesthismeanthatIfyouhaveaclassthat
doesn'tImplementComparable,andyoudon'thavethe
sourcecode,youcouldstiliputthethingsInorderby
creating
8
Comparator7
A:
That'sright.Theotheroption
(if
It'sposslble)wouldbe
tosubclasstheelementandmakethesubclassimplement
Comparable.
552chapter16
Java.util.Comparator
publicinterfaceComparator<T>
int
compare(TaI,T02);
If
you
passaeomparator
to
the
sortOmethod.thesortorder
is
determined
by
the
comparator
ratherthan
the
elements
own
compareToO
method.
Q.:
But
why
doesn't
~very
classImplli!mentComparable1
A:
Doyoureallybelievethat
everything
canbeordered?
IfyouhaveelementtypesthatJustdon'tlendthemselvesto
anykindofnaturalorderIng,thenyou'dbemisleadingother
programmersIfyouimplementComparable.Andyouaren't
takingahugerisk
by
notImplementingComparable,since
aprogrammercancompareanythinginanyway
thathe
choosesusinghisowncustomComparator.
collections
with
generics
UpdatiMQtheJukeboxtouseaCOlMparafor
Wedidthreenewthingsinthiscode:
1)
Createdaninner
class
thatimplementsComparator(andthusthe
rompare()
method
that
doestheworkpreviouslydoneby
romjJrue'Ib()).
2)
MadeaninstanceoftheComparatorinnerclass.
3)
Calledtheoverloaded
sortt)
method.givingitboththesong
list
andthe
instanceoftheComparatorinner
class.
Note:wealsoupdatedtheSongclasstcString()methodtoprintboththesong
titleandtheartist
(It
prints
title:
artist
regardlessofhowthelist
is
sorted.)
importjava.util.";
imporcjava.io.∙;
public
class
JukeboxS(
ArrayList<Song>songList
=
newArrayList<Song>();
publicstaticvoidmain(String[]args){
new
Jukebox5().go();
~
Make
a~ i~Ylt.t:~
the
ArtistCompareartistCompare::newArtistCompare();
C--y.lrat.m-
IMer
t.lau.
Collections.sort(songList,artisbCompare);
pUblic
void
got){
getSongs();
System.out.println(songList);
Collections.sort(songList);
System.out.println(songList);
System.out.println(SongListJ;
classArtistcompareimplementsComparator<Song>
publicintcampare(Songone,Song
twO)(
returnone.qatArtist().compareTo(two.g8tArtist
(»;
~
ni~
bet.OI'/I!1
i}
Sh-i",~
(tneartirt)
voidgetSongs(){
II
rIo
codehere
voidaddSong(StringlineToParse}{
II
parse
line
andaddcosonglist
Note:we'vemadesort-by-titlethedefaultsort.
by
keepingthecompareToOmethodInSongusethe
titles.Butanotherwaytodesignthiswouldbeto
Implementboth
thetitlesortingandartistsortingas
innerCom
pa
raterclasses,andnothaveSongImplement
Comparableatall.Thatmeanswe'dalwaysuse
the
two-
argversionofCollections.sortl).
youare
here
~
553
collectJonsexercise
import
publicclassSortMountains{
LinkedList
'-------
mtn
newLinkedList,()i
classNameCompare
{
publicintcOmpare(MouDtain
one,
Mountain
two)
{
return
}
classHeightCompare
{
pubLi.cintcompare(Mountainone,Mountaintwo)
{
return();
}
}
publicstaticvoidmain(String
[J
args){
new
SortMountain().go():
}
publicvoidgot){
mtn.add(newMountain(ULongs",14255»;
mtn.add(newMountain(UElbert",
14433»i
mtn.add(newMountain(nMarOOn
M
,
14156»i
mtn.add(newMountain(UCastle",14265»;
System.out.println(Uasentered:\n"
+
mtn);
NarneCornparenc
=
newNarneCompare();
System.out.println(ubynarne:\nn
+
mtn);
HeightCompare
he
=
newHeightCompare();
System.out.println(nbyheight:\nn
+
mtn)i
}
}
classMountain{
Output:
Reverse
Engineer
Assume
this
codeeXiStS
in
IISingle
!1le.Yourjoh
is
to
nil
in
the
hlankS
Sothe
the
program
will
create
the
output
shawn.
Note:answers
are
attheendof
thechapter,
}
}
}
554chapter16
{
{
FileEdHWIndowHelThlsOne'sFor8ob
%javaSortMountains
asentered:
[Longs14255,Elbert14433,Maroon14156,castle14265]
by
name:
lCastle
14265,Elbert14433,Longs14255,Maroon14156)
by
height:
[Elbert14433,
Castle
14265,Longs14255,Maroon14156]
~
your
penCil
fiTI-in-the-blanks
Foreachofthequestionsbelow,fillintheblank
withoneofthewordsfromthe"possibleanswers"
list,tocorrectlyanswerthequestion.Answersare
attheendofthechapter.
PossibleAnswers:
Comparator,
Comparable,
compareTo(),
compare(),
yes,
no
collectionswithgenerics
Giventhefollowingcompilablestatement:
Collections.sort(myArrayList);
1.WhatmusttheclassoftheobjectsstoredinmyArrayListimplement?
2.WhatmethodmusttheclassoftheobjectsstoredinmyArrayListimplement?_
3.
CantheclassoftheobjectsstoredinmyArrayListimplementboth
ComparatorANDComparable?
Giventhefollowingcompilablestatement:
Collections.sort(myArrayList,myCompare);
4.CantheclassoftheobjectsstoredinmyArrayListimplementComparable?
5.CantheclassoftheobjectsstoredinmyArrayListimplementComparator?
6.Must
theclassoftheobjectsstoredinmyArrayListimplementComparable?_
7.Must
theclassoftheobjectsstoredinmyArrayListimplementComparator?_
8.
WhatmusttheclassofthemyCompareobjectimplement?
9.
WhatmethodmusttheclassofthemyCompareobjectimplement?
youarehere
~
555
dealing
with
duplicates
Uh"'oh.
fhe
sortingallworks,butnow
we
haveduplicates...
Thesortingworksgreat,nowweknowhowtosononboth
title
(usingtheSongobject's
compareToOmethod)and
artist
(usingtheComparator'scompare
0
method).Butthere's
anewproblemwedidn'tnoticewithatestsampleofthejukeboxtextfile-the
sorted
list
containsduplicates.
It
appearsthatthedinerjukeboxjustkeepswriting
to
thefileregardlessofwhetherthe
same
songhasalreadybeenplayed(andthuswritten)tothetextfile.TheSongListMore.txt
jukeboxtextfileisacompleterecordofeverysongthat
was
played,andmightcontainthe
samesongmultipletimes.
SongllstMore.
txt
PinkMoon/NickDrake/5/80
Somersault/Zero7/4/84
ShivaMoon/PremJoshua/6/120
Circles/BT/5/110
DeepChannel/AfroCelts/4/120
Passenger/Headmix/4/100
Listen/Tahiti80/5/90
Listen/Tahiti80/5/90
Listen/Tahiti80/5/90
Clrcles/BT/5/110
556
chapter16
We
t1eed
aSet
it1stead
ofa
List
-
FromtheCollectionAPI,wefindthreemaininterfaces,
List,
Set,
and
Map.
ArrayList
isa
List,
but
it
looks
like
Set
is
exactlywhatweneed.
collectionswithgenerics
~
LIST∙
when
sequence
matters
Collectionsthatknowabout
Indexposfflon.
UstsknowwheresomethingisinthelistYou
canhavemorethanoneelementreferencing
thesameobjeel
~
SET∙
when
uniqueness
matters
Collectionsthat
donotaI/owduplicates.
Setsknowwhethersomethingisalreadyinthecollection.
Youcanneverhavemorethanoneelementreferencing
thesameobject(ormorethanoneelementreferencing
twoobjectsthatareconsideredequal-we'lIlookatwhat
objectequalitymeansinamoment).
~
MAp∙
when
finding
somethIng
bykey
matters
Collectionsthatuse
key-valuepairs.
Mapsknowthevalueassociatedwithagivenkey.You
canhavetwokeysthatreferencethesamevalue,butyou
cannothaveduplicatekeys.Althoughkeysaretypically
Stringnames(sothatyoucanmakename/valueproperty
lists,forexample),akeycan
be
anyobject.
List
Set
Map
youarehere
~
557
thecollections
API
TheCollectiot1API(partofit)
NoticethattheMapinterfacedoesn't
actuallyextendtheCollectioninterface,
butMapisstillconsideredpartofthe
"CollectionFramework"(alsoknown
as
the"Collection
APr).
So
Mapsare
stillcollections,eventhoughtheydon't
includejava.utilCollectionintheir
inheritancetree.
/'
Set
(Interface)
r.
,
,
,
"
,
,
,
,
,
"
,
,
,
,
"
List
(interface)
-r;
l\'"
I\
.
,
,
\
II
I,
,
\
II
I
I
,
\
,,
,
,
I
I
,
\
I,
I,
Collection
(interface)
I
II-
I
I
I
I
\
,
,
\
I
I
I
,
,
I
,
/'
."
,
,
,
,
r
,
,
I
,
I
,
I
I
,
,
SortedSet
(Interface)
(Note:thisisnotthecomplete
collectionAPI;thereareother
classesandinterfaces,but
thesearetheoneswecare
mostabout)
TreeSet
LinkedHashSetHashSetArrayList
LlnkedLlst
Vector
.--------KEy-------.
Ma~l
dOY\'+'
~'ll.u"d
'(\"00>\
jiIVel...
∙hl.Collet-!:.iOl'l,b..
+.
"thl'f)
ve
lV
II
tol'llidll"ld
to
b~ ~il..-t
of
the"
"tolled:.iOl'1
~\'"el
...
twetrk
i"
Java.
~o
a
Ma~
is
still
Ye{~ed
to
ell
a
tolled:.iol'\'
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
\
•
I
,
Map
I
(Interface)
-r;
1\'
..
.
,
I
.
,
,,
,
,
\
I
,
SortedMap
I\
,
\
r
,
(Interface)
I
,
,
,
,
I
,
I
I
,
.
/
'
/
/
extends
implements
implementation
class
interface
T
.T.
,
,
,
TreeMap
II
HashMap
"'-----.".
LinkedHashMap•
I
Hashtable
558
chapter16
collectionswithgenerics
UsingaHashSetinsteadofArrayList
WeaddedontotheJukeboxtoputthesongsinaHashSet.(Note:weleftoutsome
oftheJukeboxcode,butyoucancopyitfromearlierversions.Andtomakeiteasier
to
readtheoutput,wewentback
[Q
theearlierversionoftheSong'stoStringO
method,sothatitprintsonlythetitleinsteadoftitle
and
artist.)
import
j a v a.ut i l.~;
:mportjava.io.*;
ublicc
lassJukebox6{
ArrayList<Song>songList
=
newArrayList<Song>
(l;
~
II
mainmethodec.
~
public
voidgo()(
L
L.
A...
d
L:
+.
We
die!..'+.
t.ha)\~e ~d$ofI~(),
so
I+'
s1:.i1l
y"Vl
1;he
$O,,~
,"
a"--
y
LS
g e t S o n g s();~
System.out.println(songList);
Collection.sor(songList);
System.out.println(songList);
~~e
wet.__eaha"ew
l1asl-.Sct
V',wameW-iz.ed
t.D
hold
.so..~
AHe...
~\l.Ui",~
it.
into
a}lash&t.
a"a
Y'"i,,-tiYl~
tnt:
~a1~
(we
dia",'t
eallsor\:.O
a~a;n).
A~
te--
~iYl~
t.\-IeA----a'fLi!l
Ch'j
-title).
(A"dit.
lost.
ih
soV't.o...de...
",ne"
we
y"t
t.ne
listiYlto
a
\1as~t.1
blat.we'll
WcifY'I
a~t.
that
tm~
latey∙∙J
The
&f.
didr/
f.
help!!
We
still
haveall
ih~
dl.lplitaus!
System.out.println(songSBt);
HashSet<Song>songSet
=
newHashSet<Song>();
songSet.addA11(songList);
)
II
getSongs()andaddSong()methods
youarehere)
559
object
equality
Whattttakestwoobjectsequal?
First.wehavetoask-whatmakestwoSongreferences
duplicates?Theymustbeconsideredequal.Isitsimplytwo
referencestotheverysameobject,orisittwoseparateobjects
that
bothhavethesame
Lilli?
Thisbringsupakeyissue:
reference
equalityvs.
object
equality.
).Referenceequality
Tworeferences,oneobjectontheheap,
TworeferencestIlatrefertothesameobjecton
theheapareequal.Period.IfyoucallthehashCodeQmethodon
bothreferences.you'llgettilesameresultIfyoudon'toverridetile
hashCode()method,tiledefaultbehavior(remember,youinherited
thisfromclassObject)isthateachobjeclwillgelauniquenumber
(mostversionsofJavaassignahashcodebasedontheobjecfs
memoryaddressontheheap,sonotwoobjectswillhavethesame
hashcode).
Ifyouwanttoknowiftwo
references
arereallyreferring
to
thesame
object.usethe
==
operator.
which
(remember)comparesthebitsin
thevariables.Ifbothreferencespoint
to
thesameobject.thebitswill
be
Identical.
).Objectequality
Tworeferences,twoobjectsontheheap,but
theobjectsareconsidered
meaningfullyequivalent
IfyouwanttotreattwodifferentSongobjectsasequal(for
example
if
youdecidedthaItwoSongsarethesameif
they
have
matching
title
variables),youmustoverride
both
thehashCodeO
andequalsOmethodsinheritedfromclassObjecL
As
wesaidabove,ifyou
don
YoverridehashCodeO,thedefauh
behavior(fromObject)istogiveeachobjectauniquehashcode
value.SoyoumustoverridehashCodeOtobesurethattwo
equivalentobjectsreturntilesamehashcode.Butyoumustalso
overrideequalsOsothatifyoucallnon
either
object.passingin
theotherobject,alwaysreturns
tnn.
Iftwoobjectsfooandbarare
equal,foo.equa's(bar'mustbe
'rue,
andbothfooandbarmust
returnthesamevaluefrom
hashCode(J.
ForaSettotreat
twoobjectsasduplicates,you
mustoverridethehashCodeO
andequals()methodsinherited
fromclassObject,sothatyou
canmaketwodifferentobjects
beviewedasequal.
Song
if(faa--bar){
II
bothreferencesarereferring
II
tothesameobjectontheheap
Song
if(foo.equa18(bar)
&&
foo.bashCode()..bar.hashCode(»)
II
bothreferencesarereferringtoeithera
II
asingleobject,ortotwoobjectsthatareequal
560chapter
16
collectionswithgenerics
Howa
HashSetchecksforduplicates:hashCode()at'dequals()
WhenyouputanobjectintoaHashset,
it
usesthe
object'shashcodevaluetodeterminewheretoput
theobjectintheSet.Butitalsocomparestheobject's
hashcodetothehashcodeof
all
theotherobjectsin
the
Hash
Set,and
if
there'snomatchinghashcode,
theHashSetassumesthatthisnewobjectisnota
duplicate.
In
otherwords,
if
thehashcodesaredifferen
t,
the
HashSet
assumes
there'snowaytheobjects
can
be
equal!
Soyou
mustoverridehashCode
0
tomakesurethe
objectshavethe
same
value.
ButtwoobjectswiththesamehashCodeOmight
not
beequal(moreonthisonthenextpage).so
if
the
HashSetfindsamatchinghashcodefortwoobjects-
oneyou'reinsertingandonealreadyintheset-the
HashSet
will
thencallooeoftheobject'sequalsr)
methodsto
see
if
thesehashcode-matchedobjects
really
are
equal.
Andifthey'reequal,theHashSetknowsthatthe
objectyou'reattemptingtoaddisaduplicateof
something
in
the
Set,
sotheadddoesn'thappen.
You
don'tgetanexception,buttheHashSer'sadd
0
methodreturnsabooleantotellyou
(if
youcare)
whetherthenewobject
was
added.So
if
theaddO
methodreturns
false,
youknowthenewobject
wasa
duplicateofsomethingalreadyinthe
set,
eqUaJs(bar)
Yourhashcodes
are
thesome,butore
youREALLYequal?
Ineedtoknow
if
yourhashcode
values
arethe
same.
you
arehere
~
561
overridinghashCodeOandequalst)
TheSo.,gclass
with
overridde.,
hashCodeUa.,dequals()
Cornpe
r
eb
Le-cSonq>{
.t.h
t.
Btl,
is
aS-\:.vincy
publicbooleanequals
(ObjectaSong)(
The
qR~AT
neWSIS
a
-Jd,n
eQl>d\~O
L.
\la~e
ell'
O~t.Y""IO
\
Songs::(Song)aSong
i
el\'lei
S't.....
\,,~s
'II
to
doisaslt.one
returngetTitle().equals(s.getTitie())
il;;--'
",ct,hod.
,S:'
all
'H,
~~t.t.
ot.heY
~n~'~
∙btl,∙
title
it
Its
t.'\"<i
classSongimplements
Sex-iogtide;
String
artist;
St.ring
rating;
Stringbpm;
publicinthashCode()(
Sa...
edec'll
h~e
th
Sh'
returntitIe.hashCode()
~
hashCodd)...
dhod
e
IP\~ d,,~
hasa"
oV~idde"
l.dJli,,~
hdShCodeO
~"S~t~t'~"
jNtyeb..
n.
the:
res14H:.
of
and',\lId/SOare
l<..lil'l
fh:
SA
e∙
~
le
how
h~shCodeO
publicLrrtcompareTo(Songs)(
9ME
IlUit...
tevar-Ic'lbk
return
title.compareTo(s.getTitle(»);
Song(String
t,
String
a,
Stringr
,
St.ring
b)I
title
=
t;
artist
=a;
rating
=
r;
bpm
=
b;
p
ublicStringgetTitle()
return
t.itle;
publicStringgetArtist(J
returnartist.;
pUblicStringgetRacing()
retuxnrating;
publicStringgetBpm(){
r
turnbpm;
pub
licStringtoString(j
return
tit.le;
Now
it
wot"k.s!
No
dvplit.ates
when
wt.
fYi"f.
-i
-the
Itas~t.
BI.<-twe
did,,'
t
zallsortO
a~in,
andwhenwe
pllt
the
AyrayList
intot.heltashSd.,-the
Itas~d:
didn'+,
fr-e~ve
the
sort
~deY.
562
chapter16
collectionswithgenerics
O
tbere1EU"er\l?
0
umo
~uesfj9n8
Q:
Howcomehashcodescanbethesame
evenIfobjectsaren'tequal7
A..:
Hash5etsusehashcodestostoretheele-
mentsinawaythatmakesitmuchfasterto
access.
Ifyou
trytofindanobjectinanArrayListbygiving
theArrayListacopyoftheobject(asopposedto
an
indexvalue),theArrayListhastostartsearchIng
fromthebeginning,
lookingateachelementin
thelistto
see
ifitmatches.But
a
Hash5etcanfind
anobjectmuchmorequickly,becauseitusesthe
hashcodeasakindoflabelonthe"bucket''where
It
storedtheelement.SoIfyousay,"Iwantyou
tofindanobjectinthesetthat'sexactlylikethis
one...
"theHash5etgetsthehashcodevaluefrom
thecopyoftheSongyougiveit(say,
742),
and
thentheHashSet
says,MOh,
I
knowexactlywhere
theobjectwithhashcode
11742
isstored...:andit
goesrighttothe
#742
bucket.
Thisisn'tthewholestoryyougetinacomputer
scienceclass,
butit'senoughforyoutouseHash-
Setseffectively.Inreality,developing
a
goodhash-
codealgorithmisthesubjectofmanya
PhD
thesis,
andmorethanwewanttocover
In
thisbook.
The
pointIsthathashcodescanbethesame
withoutnecessarilyguaranteeingthattheobjects
areequal,becausethe-hashingalgorithm"usedIn
thehashCode()methodmighthappentoreturn
thesamevaluefor
multipleobjects.Andyes,that
meansthatmultipleobjectswould
all/and
in
the
samebucketIntheHashSet(becauseeachbucket
representsasinglehashcodevalue),butthat's
not
theendoftheworld.ItmightmeanthattheHash-
SetisJustalittlelessefficient
(or
thatit'sfilled
withanextremelylargenumberofelements),but
iftheHashSetfindsmorethanoneobjectinthe
samehashcodebucket,theHashSetwillsimply
usetheequalsOmethodtoseeIfthere's
a
perfect
match.Inotherwords,hashcodevaluesaresome-
timesusedtonarrowdownthesearch,buttofind
the
oneexactmatch,theHashSetstillhastotake
alltheobjectsinthatonebucket(thebucket
for
allobjectswiththesamehashcode)andthencall
equalsOon
themtoseeiftheobjectit'slookingfor
isInthatbucket.
you
arehere
~
563
TreeSetsandsorting
At1d
if
wewat1tthesettostay
-
sorted,we'vegotTreeSet
TreeSetissimilartoHashSetinthatitpreventsduplicates.Butitalso
keeps
thelistsorted.
It
works
justlikethe
sortt)
methodinthatifyoumakeaTreeSetusingtheset'sno-argconstructor,the
TreeSetuseseachobject'scompareToOmethodforthesort.Butyouhavetheoptionofpassing
a
ComparatortotheTreeSetconstructor,tohavetheTreeSetusethatinstead.Thedownsideto
TreeSetisthatifyoudon't
need
sorting,you'restillpayingfor
it
withasmallperformancehit.But
you'llprobablyfindthatthehitisalmostimpossibletonoticeformostapps.
importjava.util.*;
importjava.
io.*;
pu
blicclassJukeboxS{
ArrayList<Song>songList
i
ntval;
newAr
rayList<Song>();
publicstaticvoidmain(String[]args){
new
Jukebox8().go();
voidgetSongs(){
try{
F
ilefile
=
newFile("SongListMore.txt");
BufferedReaderreader
=
newBufferedReader(newFileReader(file»;
Stringline
=
null;
while(
(line=reader.readLine(»
!=
null){
addSong(line);
L'
Lad
~
\tashSet.
L'L-
T
YeeSe"IYlSU;
+.0
publicvoidgo(){
IYlstaYl-i,au;a
T
eSettOYlstylOt
I
Y
getSongs();
Ca\\iYl~
theYlo-a;?Y\heSoYlC?Jo'ojetts
System.out.println(songList);(
WleaYlS
the;)tWl:th~e ~OY
thesoYt;.
Collections.sort(songList);
t.OWIya
yeT
L_)
J'
aCo",yClYClW
Y
'
System.out.println(songList);
t.O"'\d
halleyClsselAIYI
TreeSet<Song>songSet
=
newTreeSet<Song>();
(We
songSet.addA11(songList);~
Syst.em,out.println(songSet);
~e
'al'l
aAdd
allthe
SOI'l~s
.froll\thel+ashSet
lAS l h~ ~d~
,110.
(Or
we
'olAld
have
added
the
SOI'l~S
Il'Id
1v1d"'1l1y
lASil'\~ sOI'\~et.add()
'lASt
thewaywe
added
SOI'l~S
t;,
the
Arra~Li s t.)
catch(Exceptionex){
ex.printStackTrace();
voidadd
Song(StringlineToParse){
String[]tokens
=
lineToParse.split("/");
Songnex
tSong
=
newSong(tokens[O],tokens[l],tokens[2],tokens[3]);
songL
ist.add(nextSong);
collections
with
generics
WhatyouMUSfkttowaboutfreeSet...
TreeSetlooks
easy,
butmakesureyoureallyunderstandwhatyouneedto
dotouse
it.
Wethought
it
wassoimportantthatwemadeitanexerciseso
you'd
have
tothinkaboutit.DoNOTturnthepageuntilyou'vedone
this.
Wemean
it.
V
your
pencil
Lookatthiscode.
ReadItcarefully,
then
answerthequestions
below.(Note:there
areno
syntaxerrors
Inthiscode.)
importjava.util.-;
publicclassTestTree{
public
static
voidmain(String[]
arqs)(
new
TestTree()
.go():
publicvoidgo(){
Bookbi
=
new
Book("BowcatsWork");
Book
b2
newBook("Remix
yourBody");
Bookb3
=
newBook("Finding
Emo");
TreeSet<Book>tree
=
newTreeSet<Book>();
tree.add(hl);
tree.
add(b2);
tree.add(1:13):
Systam.out.println(tree):
class
Book(
Stringtitle;
publicBook(String
t){
title
=
t;
1).WhatIstheresultwhenyoucompilethiscode?
2).
IfItcompiles,whatIstheresultwhenyouruntheTestTreeclass7
3).lfthereis
a
problem(eithercompile-timeorruntime)withthiscode,howwouldyou
fix
It7
you
arehere
~
565
howTreeSetssort
freeSetelettte.,tsMUSfbecotttparable
TreeSetcan'treadtheprogrammer'smindtofigureouthowthe
object'sshouldbesorted.YouhavetotelltheTreeSet
how.
TouseaTreeSet,oneofthese
thingsmustbetrue:
)-Theelementsin
thelistmustbeofatypethat
implementsComparable
TheBookclassontheprevious
pagedidn'timplementComparable,soit
wouldn'tworkatruntime.Thinkaboutit,the
poorTreeSet'ssolepurposeinlifeistokeep
yourelementssorted,andonceagain-ithad
noideahowtosortBookobjects!Itdoesn'tfail
atcompile-time,becausetheTreeSetaddO
methoddoesn'ttakeaComparabletype,The
TreeSetaddOmethodtakeswhatevertype
youusedwhenyoucreatedtheTreeSet.In
otherwords,ifyousaynewTreeSet<Book>O
theaddOmethodisessentiallyadd{Book).And
there'snorequirementthattheBookclass
implementComparable!Butitfailsatruntime
whenyouaddthesecondelementtotheset.
That'sthefirsttimethesettriestocalloneof
theobject'scompareToOmethodsand...can't.
OR
)-YouusetheTreeSet's
overloadedconstructor
thattakesaComparator
TreeSetworksalotlikethesortO
method-youhaveachoiceofusingthe
element'scompareToOmethod,assuming
theelementtypeimplementedthe
Comparableinterface,ORyoucanuse
acustomComparatorthatknowshow
tosorttheelementsintheset.Tousea
customComparator,youcalltheTreeSet
constructorthattakesaComparator.
566
chaptertfl
classBook
implementsComparable
Stringtitle;
publicBook(Stringt){
t
itle
=
t;
}
publicintcompareTo(Objectb)
Book
book
=
(Book)b;
return(title.compareTo(book.title»;
publicclassBookCompareimplementsComparator<Book>{
publicintcompare(Bookone,Booktwo){
return(one.title.compareTo(two.title»;
classTest{
publicvoidgo(){
Bo
okblnewBook("HowCatsWork");
Bookb2
=
newBook("RemixyourBody"};
Bookb3
=
newBook("FindingEmo");
BookComparebCompare
=
newBookCompare();
TreeSet<Book>tree
=
newTreeSet<Book>(bCompare);
tree.add(newBook("HowCatsWork");
tree.add(newBook("FindingEmo");
tree.add(newBook("RemixyourBody");
System.out.println(tree);
collections
with
generics
We~ve
See"
Listsand
Sets~
"OW
we~11
usea
Map
ListsandSetsaregreat,butsometimesaMap
is
thebestcollection(norCollection
withacapital
"Cn-rememberthatMapsarepart
of
Java
collections
buttheydon't
implementtheCollectioninterface).
Imagineyouwantacollectionthatactslikeapropertylist,whereyougiveitaname
anditgivesyoubackthevalueassociated
with
thatname.Althoughkeyswilloftenbe
Strings,they
canbeanyJavaobject(or,throughautoboxing,aprimitive).
Map
Mapexample
import
java.util.~;
pUblicclassTestMap
public
static
voidmain(String[args){
EachelementinaMapisactually
TWOobjects-a!!eyanda
value.
Youcanhaveduplicate
values,
but
NOTduplicatekeys.
BashMap<String,Integer>
scores
=
new
Ba.ahMap<String,
Integer>0;
scores.put
("Kathy"/
42);
A--
Use
Plot()
j'f>$~Cld
0+
ddO
r
P
t(
"B
t"
343)∙""""
-L
1_1.Cl
J
Clnd
now
o-t
l.Olor1e
scores.
U
er,,
11;WI<l.1
t.WO
ClrQIo""
b
(k
I)
t(
"Sk1"420)
J
en
~y,va~.
scores.pu
y
er,;
system.out.println(scores);
~
System.out.pr
i
n
t
Ln
(scores.
get
("Bert")l;
ThedO
1\1.
~""e~od
wkesakey,(ll<d
t'etuhlS
the
val~
(in
this
~S(:,
an
h"~9t\").
youarehere567
generictypes
Fit1all'tbacktoget1erics
Rememberearlierinthechapterwetalkedabouthowmethods
thattakeargumentswithgenerictypescanbe...
weird.
Andwe
meanweirdInthepolymorphicsense.
If
thingsstarttofeel
strange
here.just
keepgoing-Ittakesafewpagestoreallytell
thewholestory.
We'll
startwithareminder
on
how
array
arguments
work,
polymorphically,andthenlookatdoingthesamethingwith
genericlists.Thecodebelowcompilesandrunswithouterrors:
Here'showItworkswithregulararrays:
importjava.util.*;
Ifamethodargumentisanarray
ofAnimals,itwillalsotakean
arrayofanyAnimalsubtype.
Inotherwords,ifamethodis
declaredas:
void
loo(AnimalU
a){}
AssumingDogextendsAnimal,
youarefreetocallboth:
loo(anAnimalArray);
foo(aDogArraY)i
D~tlat'"e
,a"d
tl'"~t.e
a
D~
attay,
t.hatholds
0,.,1~
Do¥
(the
t.o",~il~t'"
wo,,'t.
Itt
yo...
"",-1:.
a
Cat.
i,.,),
publicvoid
got){
Animal[]animals
~
(newDog()
I
newCat(),new
Dog()};
Dog[]dogs:
(new
Dog(),
new
Dog(),
new
Dog()};~
takeAnimals(animals);
takeAnimals
(dogs);
<,CalltakeAr,i"'<llsO,
l.lSi,,~
boih
~
an-a'!t'lfes
41
at'"~lohe,.,ts,
..
pUblicclassTestGenericsl(
publicstaticvoidmain(String(]args)
newTestGenericsl().go();
publicvoidtakeAnimals(Animal{]
for
(Animala:animals)(
a.eat()
i
}»:.:
abstract
classAnima..l(
voideat{)(
System.out.printin("animaleating");
)
classDogextendsAnimal
void
bark()()
I
classCatextends
Animal
voidmeow(){}
568chapter
16
collections
with
generics
UsingpolYtMorphicargulMenfsat'dgenerics
So
wesawhowthewholethingworkedwitharrays,butwill
it
work
thesame
way
whenweswitchfroman
array
toan
ArrayList?
Sounds
reasonable,doesn'tit?
First,let's
try
itwithonlythe
AnimalArrayl.ist.
Wemadejusta
few
changestothego
0
method:
PassingInjustArrayList<Anlmal>
publicvoid
gel)
t
ArrayList<Animal>animals
=
newArrayList<Anima.l>()
j
animals.add(newDog());
animals.add
(newCat
(»);
~
Wehdve
t.o
add
Ol'\e
af.
d
ti....
e
sintetheyc's
animals.add(newDog());ShoYUkt
S'ft'Ul)(
like
thet"c
is
.for
drTay
lY~or..
takeAnimals(animals);
<--
Thisist.he
Sdmelode
~
•
.,j.
1,,,
.'e""cr'"
l'IO'N
{;.ncCllli...als"
v.)Ylelbl,
Yetm
t.o
illl
An-ayLisi
ilUwd
o-f
an-ely.
~ublic
void
takaAnimals(ArrayList<Animal>animals)(
for
(Animal
a:animals)(
a.eat();
I
Compliesand
runs
justfine
youarehere
~
569
polymorphismand
generics
~ut
will
it
work
with
ArrayList<~og)?
Becauseofpolymorphism.thecompilerletuspassaDog
array
toamethodwithanAnimalarrayargument.Noproblem.And
anArrayList<Animal>canbepassedtoamethodwithan
ArrayList<AnimaI>argument.
So
thebigquestionis,
will
the
ArrayList<Animal>argumentacceptanArrayList<Dog>?Ifitworks
witharrays,
shouldn'titworkheretoo?
PassinginjustArrayList<Dog>
publicvoidgo()(
ArrayL
ist<Animal>animalsnewArrayList"Animal>{);
anima
ls.add(newDog{));
anima
ls.add(new
Cat{));
animals.add{newDog{));
takeAnimals(animals);
~
Wk
.1hI
...-'now
1:
if
inc
w~ked.
.fine.
ArrayList<Dog>dogs
=
newArrayList<Dog>();
dogs.add
(newDog());
A1ak,
a
Doc
ltr'rayList.
d
d
L
dogs.add(newDog())
i
-J"
pill;
d
tOlAr1e
d~
ill.
takeAnimals(dogs);
~
Will
this
w
I.
.Lh
.1
Qt"1<;
now
1:
a~
we
thd~ed
.f...
o...
dl\
drYay
to
dll
A-r.-dyList?
public
void
takeAnimals(ArrayList<Animal>animals)(
for
(Animala:animals)(
a.
eat();
l
WhenwecompileIt:
%javaTestGenerics3
TestGenerics3.java:21:takeAnimals(java.util.
ArrayList<Animal»
in
TestGenerics3cannotbeappliedto
(java.util.ArrayList<Dog»
takeAnimals(dogs);
1error
570chapter16
It
lookedso
ri~ht,
bitt
wentso
\t,fr"on~
...
collectionswithgenerics
AndrmsupposedtobeOKwiththis?That
totallyscrews
my
animalsimulationwherethe
veterinaryprogramtakesalistofanytypeof
animal.so
that
a
dogkennelcansendalistofdogs,
and
a
catkennelcansend
a
listofcats...now
you
'resaying
I
can'tdothatif
I
usecollections
insteadofarrays?
Whatcouldhappet1
if
it
were
allowed...
Imaginethecompilerlet
yOIl
getawaywiththat,
It
letyoupassan
ArrayList<Dop
toamethoddeclared
as:
publ
i
cvoidtakeAnimals
(ArrayList<Animal>
animals)(
for
(Animala:animals)(
a.eat();
There'snothinginthatmethodthat
woks
harmful,right?
After
all,
thewholepointofpolymorphismisthatanythinganAnimalcan
do(inthiscase,theeatj)method),aDogcandoaswell.
So
what's
theproblemwithhavingthemethodcalleat()oneachoftheDog
references?
Nothing.
Nothingatall.
There'snothingwrongwith
that
code.Butimagine
thiscode
instead:
publicvoidtakeAnimals
(ArrayList<Animal>
animals)(
animals.add(newCat())
;.1
\J.kIIW.
LL
k
C
L∙
L
L
~
Ties..
e
Jl.\S"(.
s"(.1ol.a
<1"(.
ITl
wnCl"(.
M j~ht
be
a
D~-ol'lly
ArrClyList-
So
that'stheproblem.There'scertainlynothingwrong
with
addinga
Cat
to
anArrayList<An.imal>.
and
that'sthewholepointofhaving
an
ArrayList
ofasupertypelikeAnimal-sothatyoucanputalltypesof
animalsinasingleAnimalArrayl.ist.
But
if
you
passedaDogArrayl.ist-s-onemeanllOhold
ONLY
Dogs-
to
thismethodthattakesanAnimalArrayl.ist,thensuddenlyyou'd
endlipwithaCatintheDoglist.Thecompilerknowsthat
if
it
lets
youpass
aDog
ArrayListintothemethodlikethat,someonecould,
at
runtime,adda
Cat
toyourDog
list.So
instead.thecompilerjust
won'tletyoutakethe
risk.
If
youdeclareamethod
to
take
ArrayList<AnimaJ>itcan
take
ONLYan
ArrayLiskAnimal>,not
ArrayList<.Dog>orArrcryLi.rt<Cat>.
youarehere
~
571
arraysvs,ArrayUsls
publicvoidgot){
Dog[]dogs:{newDog(),newDog().newDog()}:
takaAnima1s(d~
publicvoid
takeAniJDals
(Animal
[1
animals)(
animals[0]
=
newcat();
~
W
~
pvt.
a
PI(W
Celt.
il'lto
d
D~ arra~.
The
tc,..pileyallowed
it,
beta\l1(
it
kl'lows
that
't01A
",i~ht.
have
passed
a
Cdt.
an"ely
cfr
Al'Iill'lal
arra't
to
the,..et.hod,
so
to
th~
to",pile\'"
it
was
possible
that.-Chis
was
O~.
Let'ssayyoudoaddaCattoanarraydeclaredasDog[l(anarraythat
was
passedintoamethodargumentdeclaredasAnimal[],whichisa
perfectlylegalassignmentforarrays).
Arraytypesarecheckedagainat
runtime,butcollectiontypechecks
...
happenonlywhenyoucompile
-
Waitaminute...
if
thisiswhytheywon'tIe.t
you
pass
aDogArrayListintoamethodthat
takesanAnimalArrayList-tostopyoufrom
possiblyputtingaCatinwhatwasactuallyaDoglist.
thenwhydoesitworkwith
arrays?
Don'tyouhave
thesameproblemwitharrayslCan'tyoustilladd
aCat
objecttoaDog[)
?
Itcompiles,butwhenwerunit:
Whew!
At.
leostthe
JVNlstopftd
it.
572chapter16
Wouldn'titbedreamy
if
therewere
a
waytostillusepolymorphiccollection
typesasmethodarguments,so
thatmy
veterinaryprogramcouldtake
Doglists
andCatIist$?That
way
I
couldloopthrough
thelistsandcalltheirimmunizeOmethod,
but
itwouldstillhavetobesafesothatyou
couldn'taddaCatin
totheDoglist.But
I
guessthat'sjustafantasy...
genericwildcards
Wildcardstotherescue
Itlooksunusual,butthere
is
awaytocreateamethodargumentthat
canacceptanArrayListofanyAnimalsubtype.Thesimplestwayis
to
useawildcard-addedtotheJavalanguageexplicitlyforthisreason.
Sonowyou'rewondering,"What'sthe
diffcrenc?
Don'tyouhave
thesameproblemasbefore?Themethodaboveisn'tdoing
anythingdangerous-a-callingamethodanyAnimalsubtypeis
guaranteedtohave-butcan'tsomeonestillchangethistoadda
Catto
the
animals
list,eventhoughit'sreallyanArrayLisL<DOg>?
Andsinceit'snotcheckedagainatruntime,how
is
this
any
differentfromdeclaring
it
withoutthewildcard?"
Andyou'dberightforwondering.Theanswer
is
NO.
Whenyou
use
thewildcard
<?>
inyourdeclaration,thecompilerwon'tlet
youdoanythingthataddstothelistl
publicvoidtakeAnirnals
(ArrayLiot<?
for/Animala:animals)(
a.eat
o.
extendsAnimal>
<..
animals)
I
Re....
e....
bey,
t.he
keywoyd
([I!')(.te~ds"
here
""ear..s
ei-chey
t'llUl'Ids
OR
-
∙I....
ple"'e"ts
dt~el'ldi,,~
0"
t.he
tyye.
~ i~
youwa"t.
to
take
al'lAttayList
ot
t'tfesthat
i",~le",el'lt
t.he
Pd:.
il'lUy~atel
yov.'
ddetlaye
it
as:
/tr-.,.ayList<?
~ul'lds
Pd:>
574chapter16
collectionswithgenerics
AlternatesyntaxfordoingthesalMething
Youprobablyrememberthatwhenwelookedatthe
sortf)
method,
itusedagenerictype,butwithanunusualformatwherethetype
parameterwasdeclaredbeforethereturntype.It'sjustadifferentway
ofdeclaringthetypeparameter,buttheresultsarethesame:
This:
public<T
extends
Animal>voidtakeThing(ArrayList<T>list)
Doesthesamethingasthis:
publicvoidtakeThing(ArrayList<?
extends
Animal>list)
D
:t1ere1lU"EH-?
0
UU}lJ
~uestI9ns
Q:
Iftheybothdothesamething,whywouldyouuse
oneovertheother?
A.:
Italldependsonwhetheryouwanttouse
"T"
some-
whereelse.Forexample,
whatifyouwantthemethodto
havetwo
arguments-bothofwhicharelistsofatypethat
extendAnimal?Inthatcase,it'smoreefficienttojustdeclare
thetypeparameteronce:
public<T
extends
Animal>voidtakeThing(ArrayList<T>one,ArrayList<T>two)
Insteadoftyping:
publicvoidtakeThing(ArrayList<?
extends
Animal>one,
ArrayList<?
extends
Animal>two)
youarehere
~
575
bethecomplier.exercise
BE
the
~omri1er,advan~eJ
YourjobIstoplaycomplieranddeterminewhichof
thesestatementswouldcompile.Butsomeofthls
codewasn'tcoveredinthechapter,soyouneedto
work
outtheanswersbasedonwhatyouDIDlearn,
applyingtherrules"tothesenewsituations.In
some
cases,youmighthavetoguess,butthe
pointistocomeupwithareasonableanswer
basedonwhatyouknowsofar.
(Note:assumethatthiscodeis
withinalegalclassand
method.)
Compiles?
[JArrayList<Doq>dogsl:newArrayList<Animal>()i
o
ArrayList<Animal>animalsl
=
newArrayList<DO<J>()
i
o
List<.Ani.mal>list
=
newArrayList<Anima.l>()
i
o
ArrayList<Dog>dogs
=
newArrayList<Doq>();
o
ArrayList<Animal>animals
=
dogsi
o
List<Dog>dogList:dogs
i
o
ArrayList<Object>objects
=
newArrayList<Object>();
o
List<Object>objList
=
objects;
o
ArrayList<Object>objs
=
newArrayList<oog>0;
576
chapter16
}
publicstaticvoidmain(String[)
newSortHountain().go():
collectlonswithgenerics
importjava.util.
*;
&lUfion
1;tl
the
~everge
publicclassSortMountains{
Engineer"
sh.arren
~reise,
LinkedList(Mountain>mtnnewLinkedList(Mountain>();
classNarneCompareImplementsComparator<Mountain>{
publiclntcompare(Mountainone,Mountaintwo){
returnone.name.compareTo(two.name):
}
classBeightCompareImplementsComparator<Mountain>{
publicintcompare(Mountainone,Mountaintwo){
return(two.
height-one.height);
~
."
'"~ ~,;.~"
I;,";,
args)(
D"\c!
'to\>
"of)l.t
"na"e;)")
;~ D~C~NDIN~.se~lIC>l.t?
"
}
publicvoidgo(){
mtn.add(newMountain(ULongs
U,
14255»:
mtn.add(newMountain(UElbert'",14433);
mtn.add(newMountain(UMaroon
u
,
14156»;
mtn.add(newMountain(UCastle
U
,
14265»:
System.out.print1n(Uasentered:\n'"
+
mtn);
NarneComparenc
=
newNarneCompare();
Collectlons.sort(mtn.
nc).
System.out.println(Ubyname:\n'"
+
mtn);
HeightComparehc
=
newHeightCompare()i
Collectlons.sort(mtn,
he);
Systern.out.prlnt1n(Ubyheight:\n
H
+
mtn);
}
}
::lassMountain{
String
name:
Int
height;
Mountaln(Stringn,
Int
h){
name
=
n;
height
=
hi
}
public
StringtoString(){
returnname
+....+
height;
}
Output:
FlIeEditWindowHel1l1lsOne'sFor8ob
'l;javaSortl'buntains
asentered:
[Longs
14255,Elbert
14433.
Maroon
14156,Castle
14265)
by
nan'e:
[Castle
14265,Elbert
14433,Longs
14255,Maroon
14156]
by
height:
(Elbert14433,Castle14265,Longs14255,
Maroon
14156)
youarehere.
577
f111-in-the-blanksolution
PossibleAnswers:
Comparator,
Comparable,
compareTo(
)J
compare(),
yes,
no
Giventhefollowingcompilablestatement:
Collections.sort(myArrayList);
L
Whatmustthe
class
oftheobjectsstaredinmyArrayListimplement?Comparable
2.Whatmethodmustthe
class
oftheobjectsstoredinmyArrayListimplement?compareTo()
3.
Canthe
classof
theobjectsstoredinmyArrayListimplementboth
ComparatorANDComparable?
yes
---"------
Giventhefollowingcornpilablestatement:
Collections.sort(myArrayList,myCompare)
i
4.
Canthe
classof
theobjectsstoredinmyArrayListimplementComparable?---'V'-e_S_
5.
CantheclassoftheobjectsstoredinmyArrayLis
t
implementCamparator?--'y'-e5_
6.Must
theclass
of
theobjectsstoredinmyArrayLis
t
implementComparable?
no
-------
7.
Mustthe
classof
theobjectsstoredinmyArrayListimplement
Compa
rat.orj',
---!..lnox-_
8.WhatmusttheclassofthemyCompareobjectimplement?
9.What
methodmusttheclassofthemyCompareobjectimplement?
578
chapter16
Comporator
comparee)
collectionswith
generics
Compiles?
[JArrayList<oog>dogsl
=
newArrayList<AnimAl>();
o
ArrayList<Animal>
anim&ld:::
newArrayList<Doq>();
)if
List<Animal>list:::newArrayList<Anima.l>()
j
o
ArrayList<Dog>dogs:::newArrayList<Doq>();
o
ArrayList<Animal>animals
=
dogs;
J!I
List<Dog>dogList
=
dogs;
~ArraYList<Object>
objects
=
newArrayList<Object>();
~
List<Object>ObjList
=
objects;
o
ArrayList<Object>objs
=
newArrayList<Dog>();
youarehere
~
579
17
package,jarsanddeployment
ReleaseYourCode
It'stimetoletgo.
Youwroteyourcode.Youtestedyourcode.Yourefinedyourcode.
Youtoldeveryoneyouknow
thatifyouneversawalineofcodeagain,that'dbefine.Butinthe
end,you'vecreatedaworkofart.The
thingactuallyrunslButnowwhat?
How
doyougiveItto
end
users?
What
exactlydoyougivetoendusers?Whatifyoudon'tevenknowwhoyourend
usersare?Inthesefinal
twochapters,we'llexplorehowtoorganize,package,anddeployyour
Javacode.We'lllookatlocal,semi-local,andremotedeploymentoptionsIncludingexecutable
jars,JavaWebStart,
RMI,andServlets.lnthischapter,we'llspendmostofourtimeonorganizing
andpackagingyour
code-thingsyou'llneedtoknowregardlessofyourultimatedeployment
choice.Inthefinalchapter,we'llfinish
withoneofthecoolestthingsyoucandoInJava.Relax.
ReleasingyourcodeIsnotsayinggoodbye.There'salwaysmaintenance...
thisIsa
new
chapter
581
Java
deployment
Peployi"Qyourapplieatio"
Whatexactly
is
aJavaapplication?
In
otherwords,
onceyou'redonewithdevelopment,whatisitthatyou
deliver?Chancesare,
yourend-usersdon'thaveasystem
identicaltoyours.Moreimportantly,they
don'thaveyour
application.Sonowit'stimeto
getyourprograminshape
fordeploymentintoTheOutsideWorld.
In
this
chapter,
we'lllookatlocaldeployments,
includingExecutableJars
andthepart-local/'part-remotetechnologycalledjavaWeb
Start.Inthe
nextchapter,we'lllookatthemoreremote
deploymentoptions,includingRMIandServlets,
Deploymentoptions
Executable
Jar
A
Javaprogram
is
a
bunch
of
classes.That's
the
output
of
yourdevelopment.
Thereal'f,Uestion
is
what
todowiththose
classes
whenyou'redone.
100%LocalCombination100%
Remote
@
Remote
TheentireJavaapplicationrunsona
serversystem,withtheclientaccessing
thesystemthroughsomenon-Java
means,probablyawebbrowser.
CD
Local
Theentireapplicationrunsonthe
end-user'scomputer,asastand-alone,
probablyGU!,program,deployedas
an
executableJAR(we'lllookatJAR
inafewpages.)
I1i'\
~
Combination
of
localandremote
Theapplicationisdistributedwitha
clientportionrunningon
theuser's
localsystem,connectedtoaserver
whereotherpartsoftheapplication
arerunning.
Whataretheadvantagesand
disadvantagesofdeliveringyour
Javaprogram
asa
local,stand-
aloneapplicationrunningon
theend-user'scomputer?
Whataretheadvantagesand
disadvantagesofdeliveringyour
Javaprogramasweb-based
systemwheretheuserInteracts
withaweb
browser,andthe
Javacoderunsasservletsonthe
server?
Butbeforewereallygetintothewholedeploymentthing,
let'stakeastepback
andlookatwhatbappenswhenyou've
finished
programmingyourappandyousimplywanttopull
outtheclassfilestogivethemtoanend-user.What'sreally
inthat
working
directory?
682
chapter17
package,jarsanddeployment
ItMagittethisscettario...
Bob'shappilyatworkonthefinalpiecesofhiscoolnew
Java
program.Afterweeksofbeinginthe"I'mjust-
one-compile-away"
mode,thistimehe'sreally
done.Theprogram
isa
fairlysophisticated
CUI
app.butsincethebulkofitisSwing
code.he'smadeonlynineclassesofhis
own.
Atlast,it'stimetodelivertheprogramtothe
client.He
figures
all
hehastodo
is
copythe
nine
classfiles.
sincetheclientalreadyhas
theJava
API
installed.He
starts
bydoingan
1s
onthedirectorywhereallhisfilesare...
e
o
o
Whoa!Somethingstrangehashappened.Insteadof18
files
(ninesourcecodefilesandninecompiled
class
files),hesees
31
files,manyofwhichhaveverystrange
names
like:
Account$FileListen
er.
class
Chart$SaveListener.class
and
on
itgoes.Hehadcompletelyforgotten
that
thecompiler
has
togenerate
class
files
for
allthoseinner
class
CUI
eventlisteners
hemade.andthat'swhatallthestrangely-
namedclassesare.
Now
he
has
tocarefullyextractall
the
class
filesheneeds.
If
heleavesevenoneofthem
OUI,
hisprogramwon'twork.Butit's
tricky
sincehe
doesn'twanttoaccidentallysendtheclient
oneofhis
source
codefiles,yeteverything
is
inthesamedirectoryinonebigmess.
youarehere
~
583
organizingyourclasses
Separatesourcecodeat'dclassfiles
Asingledirectory
with
a
pileofsourcecodeand
class
filesisa
mess.
Itturnsout,
Bob
shouldhavebeenorganizinghisfiles
fromthebeginning,keepingthesource
codeandcompiled
codeseparate.
In
otherwords,makingsurehiscompiled
class
filesdidn'tlandinthesamedirectory
as
hissourcecode.
1M
key
is
acombinationofdirectury
stTudure
organizatUm
and
the
-d
compiler
option.
Therearedozensof
ways
youcanorganizeyourfiles,andyour
company
mighthaveaspecific
way
they
want
youtodoit.We
recommendanorganizationalschemethat'sbecomealmost
standard.
though.
Withthisscheme,youcreateaprojectdirectory,
andinside
thatyoucreateadirectorycalledsourceandadirectorycalled
classes.
Youstart
by
savingyoursourcecode(javafiles)into
thesourcedirectory.
Thenthetrick
is
tocompileyourcode
in
suchawaythattheoutput(the.classfiles)endsupinthe
classes
directory.
Andthere'sanice
compilerflag,
-d,
thatletsyoudothat.
But
r
thoughtIdidn'thave
achoice
aboutputtingthecloss
files
inwiththesource
files.
Whenyou
compile,
theyjust
go
there.sowhat
doI
do?
Compilingwiththe
-d
(directory)flag
MyApp.Java
MyApp.class
(~It1h-ii,,~
noU:
c~cr'tl:.hi~
in
-lhis
lhapicr
il1.l_Uthiltt},e
tUh"c..
t
~kin~
dil"Clky(i.e.the
~.~)
ij
in
'f()l.J.r
dilSSf'il!:.h.
If
'10<>
havee....
pl,t'fJy
sd:.
ildaSSf'.1th
tl\~;t"(ln"'tl\t
vill",able.
be
tcr-bin
that
it
tor.t.ai"s
the",")
~cd
MyProject/classes
%j
avaMinirlOlI
~Ol.lr
pr03r-<I",frOlol
tht
tldues'
di'rtltory.
Runningyour
code
%cd
Mypr~je~t/s~urce
%javac-d../classes
)'\
tells
-tht
lo"'pi/tr
to
lot.tht
lo"'piled
lode
(llats.
~,
)
.to
th".oFi
es
t;.,
t
tla1S.ts:
di~ettory
ab
Ohedired:A'ry
lop
clnd
bellk
dow"
a6
'i('
I.
:JG
n1'ro",Ole
lLlrrent
w(l\"k;l'I~
dil'tttory.
Byusingthe-dflag,
you
gettodecidewhich
directory
the
compiledcodelandsin,ratherthanacceptingthedefaultof
/r
class
fileslandinginthesamedirectoryasthesourcecode.
r
TocompilealltheJavafilesinthesourcedirectory,use:
til
YOWl'....
ai"O
roo..
htt't•
OIl"
%javac
-d../c1asses
*.
java
::~;~:oo o'o
'\.
lno100
1
AL
L
oto\O•
~.
iavatompies"'.'"
..J
t:
Ll.
lUOJOIO
SOLl~t'
-tiles;
illVI'
"""010\
t\ort"tfl+'
dirtt~
584chapter
17
package,jarsanddeployment
PutyourJava
itt
aJAR
-
manifesLtxt
no
SO\O..
tt.
toOt
Cja~d)
in
the
"JAR
MyApp.dass
CIflPl.Jar
manifesLtxt
Run
theJar
tool
to
create
aJARfile
thatcontainseverythingintheclasses
directory
I
plus
the
manifest.
Createa
manifest.
txt
file
that
states
which
class
hasthe
malnO
method
Make
Q
text
filenamedmanifest.txtthathasa
one
line:
Makesureallofyourclassfilesarein
theclassesdirectory
We'regoingtorefinethisinafewpages,
but
fornow.keepall
yourclass
filessittinginthe
directorynamed'classes'.
dO\'l'
t
,,~t
t\lt.t.lass
Main-Class:
MyApp
0(-
ontht",d
Press
thereturn
key
aftertypingtheMain-
Classline,oryourmanifestmaynotwork
correctly.
Put
themanifest
file
intothe
"closses"
directory.
%cdMiniProject/class8s
'jar-cvmf.manifest.txtappl.jar*.class
OR
'jar-cvmfmanifest.txtappl.jarMyApp.class
MakinganexecutableJAR
AJARfileisaJavaARchive.It'sbasedonthepkzipfileformat,anditletsyoubundle
all
yourclassessothatinsteadofpresentingyourclientwith28classfiles,youhand
overjustasingleJARfile.lfyou'refamiliarwiththetarcommandonUNIX,you'll
recognize
thejartoolcommands.(Note:whenwesayJARinallcaps,we'rereferring
to
thearchive
jilt.
Whenweuselowercase,we'rereferringtothe
ja-r
tool
youuseto
createJARfiles.)
Thequestionis,whatdoestheclientMwiththeJAR?Howdoyougetitto
run?
YoumaketheJAR
executable.
An
executableJARmeanstheend-userdoesn'thavetopulltheclassfilesoutbefore
runningtheprogram.Theusercanruntheappwhiletheclassfilesarestillinthe
JAR.Thetrickistocreatea
manifest
file,thatgoesintheJARandholdsinformation
aboutthefilesintheJAR.TomakeaJARexecutable.themanifestmusttelltheJVM
whuh.
class
hasthe
main()method!
•
•
•
youarehere)
585
executableJAR
100%Local
Combination
100%
Remote
Most
100%
localJava
arrs
aredeployedas
executableJARfiles.
RUt1t1it1g(executi.,g)theJAR
JaVli(thejVM)iscapableofloadingaclassfromaJAR,andcalling
themain()methodofthatclass.Infact,theentireapplicationcan
stay
intheJAROncetheball
is
rolling(i.e.,themain()method
startsrunning),theJVMdoesn'tcare
where
yourclassescome
from,aslongasitcanfindthem.AndoneoftheplacesthejVM
looksiswithinanyJARtilesintheclasspath.
U
itcan
see
aJAR,the
JVM
will
look
inth3tJARwhenitneedstofindandloadaclass.
0
:
~(:':r-':"-':_:~..,.::l"'l
.'.~ -"
appl.jar
r
l
Dependingonhowyouroperatingsystem
is
configured,you
mightevenbeabletosimplydouble-click
theJARfiletolaunch
it.ThisworksonmostflavorsofWindows,
andMacOSX.You
canusuallymakethis
happenbyselectingtheJARandtelling
theOSto"Openwith...
~
(orwhatevertheequivalentisonyour
operatingsystem).
Youcan'tputyourclassfliesIntosomearbitrary
directoryandJAR
themupthatway.But
If
yourclasses
belongtopackages,youcanJAR
uptheentirepackage
directorystructure.Infact,you
must.
We'llexplainallthison
thenextpage,soyoucanrelax.
Q:
Why
can't
I
Just
JARupanentiredirectory?
A.:
TheJVMlooksinsidetheJARandexpectstofind
what
It
needs
rightthere.
Itwon'tgodiggingIntoother
directories,unlesstheclassIspartofapackage,andeven
then
theJVMlooksonlyInthedirectoriesthatmatchthe
packagestatement7
----------
Dffin~~estiQns
Q:
Whatdid
you
jU5t
say?
A:
586
chapter17
package,jarsanddeployment
Putyourclasses
itt
packages!
Soyou'vewrittensomenicelyreusableclassfiles,andyou've
postedtheminyourinternaldevelopmentlibraryforother
prognmmerstouse.Whilebaskingintheglowofhaving
justdeliveredsomeofthe(inyourhumbleopinion)best
examples
of00everconceived.yougetaphonecall.A
frantic
one.Twoofyourclasseshavethesamenameas
theclassesFredjustdeliveredtothelibrary.Andallhellis
breakinglooseoutthere,asnamingcollisionsandambiguities
bringdevelopmenttoitsknees.
Andallbecauseyoudidn'tusepackages!Well,youdiduse
packages,in
thesenseofusingclassesintheJavaAPIthatare,
ofcourse,inpackages.Butyoudidn'tputyourownclasses
intopackages,andintheRealWorld,that'sReallyBad.
We'regoingtomodifytheorganizationalstructurefromthe
previouspages.justalittle,toputclassesintoapackage.and
toJARtheentirepackage.Payverycloseattention
to
the
subtleandpickydetails.Eventhetiniestdeviationcanstop
yourcodefromcompilingand/orrunning.
Packagesprevettf
class
ttattte
co"fllcts
PackagestnJcture
of
the
J
QVQ
APIfor:
java.
text
NumberFormat
java.ut
i
I.ArrayList
java.awt.fJowLayout
java.awt.event.ActionEvent
java.net.Sock
et
ActionEvent
Whatdoestklspicturelookliketo
you?
Doesn't
Itlook
Q
wholelotlike
adirectory
hlercrc.hyi
java
text~et
•/
a~
NumberFormat
uti!/'"
I'"
Socket
:~':I t ~
event
~:'~::
\
AnayUslFlowlayout
Althoughpackagesaren'tjustforpreventingnamecollisions,
that'sakeyfeature.Youmightwriteaclass
namedCustomer
andaclassnamedAccountandaclassnamedShoppingCan.
Andwhatdoyouknow,halfofalldevelopersworkingin
enterprisee-comrnercehaveprobablywrittenclasseswith
thosenames.Inan
00world,that'sjustdangerous.
If
partof
thepointof00istowritereusablecomponents,developers
needtobeabletopiecetogethercomponentsfroma
variety
ofsources,andbuildsomethingnewoutofthem.
Your
componentshave
to
beableto'playwellwithothers',
includingthoseyoudidn'twriteorevenknowabout,
Remember
way
backinchapter6whenwediscussedhow
apackage
nameislikethefullnameofaclass,technically
knownasthe
fully-qualifiedname.
ClassArrayListisreally
java.utiLArrayList,
]Buttonisreally
javax.swingJButton,
and
Socketisreally
java.
net.
Socket.
Noticethattwoofthoseclasses,
ArrayList
andSocket,bothhave
java
astheir"firstname".
In
otherwords.thefirstpanoftheirfully-qualifiednames
is"java".Thinkofahierarchywhenyouthinkofpackage
structures,
andorganizeyourclassesaccordingly.
youarehere
~
587
packagenarnlnq
PrevettfittgpackagettalMecottflicts
Puttingyourclassinapackagereducesthechancesofnaming
conflicts
with
otherclasses,butwhat'stostoptwoprogrammers
fromcomingupwithidentical
pa~kage
names?Inotherwords,
what'sto
stoptwoprogrammers,eachwithaclassnamedAccount,
from
puttingtheclassinapackagenamedshopping.customers?
Bothclasses,in
thatcase,would
still
havethesamename:
shopping.customers.Acwunt
Sunstronglysuggestsapackagenamingconventionthatgreatly
reducesthatrisk-prependeveryclasswithyourreversedomain
name.Remember,domainnamesareguaranteedtobeunique.
TWodifferent
guxs
canbenamedBartholomewSimpson,butrwo
differentdomainscannotbenameddoh.com.
Reversedomainpackagenames
588chapter17
pachgescan
prevent
name
confhcts.
butonly
if
you
choosea
raclagename
that's
gtlaranteed
to
he
unicrue,
The
hest
way
to
do
that
is
to
preface
your
pachges
with
your
reverse
domain
name.
com.headfirstbooks.Book
~f'
e
pallc.j~(
J\o}",c\..
t..\6~
,..6""
package,jars
and
deployment
You
_~!i.t
putaclass
intoadirectory
structurethatmatches
thepackagehierarchy.
LorI""
l'\l.N......
U,\_.'"
.-
~ ct'-t4,.
6<:1
.a~ dl
do'l
6-1
.tlp
com
heacfflrstjava
PackageExerclse.Java
lOUOl
lOUOl
IOIO\C-o ~le
lOlOlD)
010101
11)\01111
\Ol~lal0
I~OI(1U1.0
•
PackageExerclse.class
seapackagename
'reusingcom.headflrstjavaasour
pie.
TheclassnameisPackageExercise,
sethe
fully-qualifiednameoftheclassisnow:
.
headfirstjavQ.PackageExercise.
Q
packagestatementin
your
class
bethefirststatementinthesource
file,aboveanyimport
statements.
There
weonlyonepackagestatementpersource
file,
soallclassesIn
Q
SOlJrce
tilemust
-thesamepackage.Thatincludesinner
es,ofcourse.
importjavax.swing.*i
publicclassPackageExercise{
II
life-alteringcodehere
SetUp
amatchingdirectorystructure
:-snotenoughto
say
yourclassisinapackage,
lerely
puttingapackagestatementin
code.Your
classisn't
truly
inapackage
-jl
youputtheclassinamatchingdirectory
ture.So,
if
thefully-qualifiedclassname
.om.headfirstjava.PackageE
xercise,you
put
thePackageExercisesourcecodeina
torynamedneadflrstjaVQ,which
must
bein
..'re
ctorynamedcom.
:-.possible
tocompilewithoutdoingthat,but
us-it'snotworththeotherproblems
'
IIhave.Keepyoursourcecodeinadirectory
turethatmatchesthepackagestructure,
.you'llavoid
0
tonofpainfulheadachesdown
-road.
_put
your
classin
apackage:
Setupamatchingdirectorystructurefor
boththesourceandclassestrees.
youarehere.
589
compileandrun
with
packages
Cotttpilittg
at'd
ruttttinQ
with
packages
Whenyourclassisinapackage,it'salittletrickiertocompileand
run.Themainissue
is
that
both
thecompilerand]VMhavetobe
capableof
f
ndingyourclassand
all
oftheotherclassesituses.
For
theclassesinthecoreAPI,that'sneveraproblem.Javaalways
knowswhere
its
ownstuffis.Butforyourclasses,thesolution
ofcompilingfrom
thesamedirectorywherethesourcefilesare
simplywon'twork(oratleastnot
reliably).
Weguanotee,though,
that
if
youfollowthestructurewedescribeonthispage,you'llbe
successful.
There
are
otherwaystodoit,butthisistheonewe've
foundthemostreliable
andtheeasiesttostick
to.
Compilingwiththe
-d
(directory)flag
sta'"
tht
~yt.f diytt~'t!
Do
NO!
~dJ
Oo...m
%cdMyProject/source
~
il\J
tht.
dirtt,1:.t*-y
...,h~t
tht.
jd~il
tIlt
IS,
cam/beadfirstjava/*.java
to...piles
ev(;'ry/'(
.file'
1.∙.
SOlorte.
\Ava>
'I'
UlIS
d,ret.U>ry
.r:
%javac-d../classes
%javac-d../01a8s8s
.>
urJs
tAeloto.pHer
it>
t
t.h
.to",piled
lode
(tlau
ll:s)e
'~it>
.the
tI~
dirtt.ky,
~he
rillhi
patkd
e
sfr~
Yes.
it
k_~
Tocompileallthejavafilesinthecom.headfirstjava
package,use:
Runningyourcode
com
com
%cdMyProject/classes
%javacam.headfirstjava.PackaqeExeroise
headf1f$f/8
heacffl
IOIlOl.
10
no
J'
0110
00110
00101
PackagaExercl8&.class
PackageExe~S8~ava
590
chapter17
package,jarsanddeployment
fhe...dflagiseve"coolertha"wesaid
PackageExercrse.java
A:
Onceyourclassisina
package,youcan'tcall
itbyits
'short'name.You
MUST
specify,
at
thecommand-line,thefully-
qualifiednameoftheclasswhose
mainO
methodyouwanttorun.
Butsince
thefully-qualifiedname
Includes
the
package
structure,
Javainsists
thattheclassbeina
matching
directory
structure.Soif
atthecommand-lineyousay:
%java
com.foo.Book
theJVM
will
lookinitscurrent
directory(andthe
rest
of
Its
classpath),
for
adirectory
named
"corn:
It
will
notlookfor
a
class
namedBoole.untilIthas
found
a
directorynomed
"com"
with
a
directory
Inside
named
ufoo':
OnIy
thenwilltheJVMacceptthatits
foundthecorrectBookclass.Ifit
findsaBookclass
anywhereelse,
itassumestheclassisn'tinthe
rightstructure,evenifitislThe
JVM
won'tforexample,lookback
up
thedirectorytreetosaY,"Oh,1
cansee
thataboveusisadirectory
namedcom,sothismustbethe
rightpackage..."
~:
ItriedtocdIntothe
directorywheremymainclass
was,butnowtheJVMsaysItcan't
findmyc1asslButIt's
rightTHERE
In
thecurrentdirectoryl
com
Compilingwiththe
-d
£lagiswonderfulbecausenotonlydoes
it
letyousendyourcompiledclassfilesintoadirectoryotherthan
theonewherethesourcefileis,butitalsoknowstopllttheclass
intothe
correctdirectorystructureforthepackagetheclassisin.
Butitgetsevenbetter!
Let'ssaythatyouhavea
nice
directorystructureallsetupforyour
sourcecode.Butyouhaven'tset
upa
matchingdirectorystructure
foryourclassesdirectory.Nota
problem!
Compiling
with
-d
tellsthecompilertonot
just
put
yourclassesinto
correctdirectorytree,butto
'ld
thedirectories
if
theydon't
The
-d
flagtellsthecomplier,
"PuttheclassintoItspackage
directorystructure,usingthe
classspecKledafterthe
-d
as
therootdirectory.But...
If
the
directoriesaren'tthere,create
themfirstandthenputtheclass
Intherightplace!"
youarehere
~
591
JARsandpackages
Makit1gat1executableJARwithpackages
Whenyourclass
is
inapackage,thepackagedirectorystructure
mustbeinsidetheJAR!Youcan't
justpopyourclassesinthe
JARthewaywedidpre-packages.Andyoumustbe
surethatyou
don'tinclude
any
otherdirectoriesaboveyourpackage.The
firstdirectoryofyourpackage(usuallycom)mustbethefirst
directorywithintheJAR!
If
youweretoaccidentallyincludethe
directory
above
thepackage(e.g.the"classes"directory),theJAR
wouldn'tworkcorrectly.
Makinganexecutable,JAR
•
Make
sureallofyourclassfilesare
within
thecorrectpackagestructure,
under
theclassesdirectory.
toll0'
10UII'
IhelldtIn:tfM•....∙∙
~ll:
",0\
•Createamanifest.txtfilethatstates
whichclasshasthemainOmethod,
and
be
sureto
use
thefully-qualified
class
namel
Make
0
text
filenamedmanifest.txtthathasa
singleline:
Main-Class:com.headfirstjava.PackaqaExercise
∙,u
manl1ast.lxt
Put
themanifesttileintotheclassesdirectory
_I
RuntheJartooltocreateaJARfile
thatcontainsthepackagedirectories
plus
themanifest
Theonly
thing
youneedtoincludeis
the'com'
directory,and
theentirepackage(and
all
classes)
t.~
is
~t,
I
willgointo
theJAR.
AI\
'1~ ~"~...oAI1 ~d
"Iou
II
t.0fP'
o,y
tot
V'"
I'..
t.
1
'Sed
MyProject/claasea
.t
~et.
tvt,......
f\:),i\l,~
'"
I.
pcdcEx.jor........
•
%jar-cvm£manifest.txtpackEx.jar
com
-
PaclalgeExerclM.dua
592
chapter17
package,jarsanddeployment
Sowhere
did
thetMat1ifestfilego?
'.
-'
com
~
_I
headflrstjavl
McrA./NF
I
%
jar
jarcommandsforlistingandextracting
G)
List
thecontentsofaJAR
Why
don'twelookinsidetheJARandfindout?Fromthe
command-line,
thejartoolcandomorethanjustcreateandruna
JARYoucanextractthecontentsofaJAR(justlike'unzipping'or
'unrarring').
Imagineyou'veputthepackExjarintoadirectorynamedSkyler;
MANIFEST.MF
@
Extractthecontentsof
Q
JAR(l.e.unJar)
%
cdSkyler
%
jar
-xf
packEx.jar
MANIFEST.MF
IO\Ul
LOlib'
~
\I
t:l
00\
1~
00\01
PackageExerclse.c1ass
META-INF
standsfor'meta
information'.The
jartoolcreates
theMETA-INFdirectoryas
wellas
theMANIFEST.MFfile.
Tt
also
takes
the
contentsof
your
manifest
file,
and
puts
it
into
theMANIFEST.MFfile.So,
your
manifest
file
doesn'tgointo
the
JAR,but
the
contents
ofit
are
putinto
the'real'
manifest
(MANIFEST.MF).
youarehere
~
593
organizingyourclasses
COWl
1CIUO
lOUO'J'
•U•
_lO
..,
..
Foot.class
manlfesttxt
COWl
Foof.java
Giventhepackage/directorystructureInthis
picture,figure
outwhatyoushouldtype
at
the
command-line
tocompile,ru
n,
createa
JAR,
and
executea
JAR.
Assumewe'reusingthestandard
where
thepackagedIrectorystructure
starts
just
below
source
and
classes
.In
otherwords,the
source
and
classes
directoriesarenotpartofthepackage.
Compile:
%cd
source
%javac_
Run:
%cd_
%java_
C~Qte
QJAR
%cd_
,-----------------
ExecuteaJAR
'cd_
%_---------------
Bonusquestion:What'swrongwith
the
packagename?
594
chapter
17
•
Q.:
WhathappensIfyou
try
to
runanuec:utable
JAR.
and
theend-userdoesn'thaveJava
Installed?
A:
Nothingwillrun,since
withoutaJVM,Javacodecan't
run.Theend-user
musthaveJava
Installed.
Q:
How
can
I
g@t
Java
installedontheend-user's
machine?
Ideally,youcancreateacustom
Installer
anddistributeItalong
withyourapplication.Several
companies
offerInstallerpro-
gramsrangingfromsimpleto
extremely
powerlu
I.
AnInstaIler
programcould,forexample,
de-
tectwhetherornottheend-user
hasan
approproprlateversion
ofJavaInstalled,andIfnot,
InstallandconflgureJavabefore
Installingyour
application.
Instalishleld,lnstaIlAnywhere,
and
DeployDlrectorallofferJava
Installersolutions.
Anothercoolthingaboutsome
oftheInstallerprograms
Is
that
youcanevenmakeadeploy-
mentCD-ROMthatIncludes
installers
forallmajorJava
platforms,so...
oneCDtorule
themall.
If
theuser'srunningon
Solarls,
forexample,the
Solarls
verslonofJavaisinstalied.On
Windows,
theWindows,ver-
sl
on,etc.Ifyouhavethebudget,
thisisbyfar
theeasiestwayfor
yourend-userstogettheright
versionofJavaInstalledand
conflgured.
package,jarsanddeployment
•
Organizeyourprojectsothatyoursourcecodeandclassfilesarenotin
thesamedirectory.
•A
standardorganizationstructure
is
tocreatea
project
directory,andthen
puta
source
directoryanda
classes
directoryinsidetheprojectdirectory.
•Organizingyourclassesintopackagespreventsnamingcollisions
with
otherclasses.ifyouprependyourreversedomainnameontothefrontof
aclass
name.
To
putaclassinapackage,putapackagestatementatthetopofthe
sourcecodefile,beforeanyimportstatements:
pac:kagecom.
wi
cJcedlysmart;
•Tobeinapackage,aclassmust
be
ina
directorystructurethetexactly
matches
the
packagestructure.
Foraclass,com.wlckedlysmarlFoo.
theFooclassmustbeinadirectorynamed
wickedlysmart.
which
Isina
directorynamed
com.
•Tomakeyourcompiled
dass
landinthecorrectpackagedirectory
structureunderthe
classes
directory,usethe
-d
compilerflag:
%
cdsource
%
javac
-d../
clauesaom/wicJcedlysmart/l1'oo.java
•Torunyourcode,
cd
totheclassesdirectory,andgivethefully-quallfied
nameofyourclass:
..cdclasses
%
javacom.wickedlyamart.l1'oo
•YoucanbundleyourclassesintoJAR(JavaARchive)flies.JARisbased
onthepkzipfonnal.
•YoucanmakeanexecutableJARfilebyputtingamanifestIntotheJAR
thatstates
which
classhasthemalnOmethod.Tocreateamanifestfile,
makeatextfilewithanentrylikethefollowing(forexample):
Main-Class:com.wicJcedlysmart.FOO
•BesureyouhitthereturnkeyattertypingtheMain-elassline,oryour
manifestfilemaynotwork.
•TocreateaJARfile.
type:
jar
-cvfm
manifest.
txt
MyJar.jarcom
•Theentirepackagedirectorystructure(and
only
thedirectoriesmatching
thepackage)mustbeImmediatelyInsidetheJARfile.
•TorunanexecutableJARfile,
type:
java-jar
MyJar.
jar
youare
here.
595
wouldn't
it
be
dreamy...
596
chapler17
WithJavaWebStart(JWS),yourapplication
is
launchedforthe
firsttimefromaWebbrowser(getit?WebStarf)butitrunsasa
stand-aloneapplication(well,
almost),
withouttheconstraintsofthe
browser.Andonceit'sdownloadedtotheend-user'smachine(which
happensthefirsttimethe
user
accessesthebrowserlinkthatstarts
thedownload),
it
stays
there.
JavaWeb
Startis,amongotherthings,asmallJavaprogramthatlives
on
theclientmachineandworksmuchlikeabrowserplug-in(the
way,say,AdobeAcrobatReaderopenswhenyourbrowsergetsa.pdf
file).ThisJavaprogramiscalledtheJavaWebStart'helperapp',
and
its
keypurposeistomanagethedownloading,updating,and
launching(executing)of
yOUT
JWS
apps,
WhenJWSdownloadsyourapplication(anexecutableJAR),it
invokes
themain
0
methodforyourapp.Afterthat,theend-usercan
launchyourapplicationdirectoryfromtheJWShelperappwithout
havingtogo
backthroughtheWebpagelink.
Butthat'snotthebestpart.TheamazingthingaboutJWSisits
abilityto
detectwhenevenasmallpartofapplication(say,asingle
classfile)has
changedontheserver,and-withoutanyend-user
intervention-downloadandintegratetheupdatedcode.
There'sstillanissue,ofcourse,likehowdoestheend-usergetJava
andjavaWebStart?Theyneedboth-Javatoruntheapp,andJava
WebStan(asmallJavaapplicationitself)tohandleretrievingand
launchingtheapp.Buteven
tluu
hasbeensolved.Youcansetthings
upsothatifyourend-usersdon'thaveJWS.theycandownload
itfrom
Sun.And
if
theydohaveJWS,buttheirversionofJavais
out-of-date(becauseyou'vespecifiedin
yourJWSappthatyou
needaspecificversionofJava),theJava2StandardEditioncan
be
downloadedtotheend-usermachine.
Best
ofall,it'ssimpletouse.YoucanserveupaJWSappmuchlike
any
othertypeofWebresourcesuchasaplainoldHTMLpageora
JPEGimage.YousetupaWeb(HTML)pagewithalinktoyourJWS
application,
andyou'reinbusiness.
Intheend,yourJWSapplicationisn'tmuchmorethanan
executableJAR
thatend-userscandownloadfromtheWeb.
JavaWebStart
End-users
launchaJava
Web
Start
appby
clicling
ona
lin1
in
aWeb
page.
But
oncethe
apr
downloads.
it
runs
outside
thebrowser,
just
like
any
other
stand-alone
Java
application.
In
fact,
a
Java
Web
Start
app
is
just
an
executableJARthat's
distributed
overtheWeb.
package,jarsanddeployment
100%
Remote
Web
Start
---
Executable
Jar
100%Local
youarehere
~
597
Java
WebStart
How.JavaWebStartworks
G)
Theclient
clicks
on
a
Web
page
link
toyour
JWS
application
(0
.jnlpfile).
TheWebpagelink
<a
href="MyApp.
jnlp">Clic:k</a>
Web
br-o'NSt"r
-giveme
MyApp.jnlp"
®
TheWebserver(HTTP)getsthe
.requestandsendsbacka.Jnlpfile
(thisIs
NOT
the
JAR).
The.jnlpfileisanXMLdocumentthat
statesthenameoftheapplication's
executableJARfile,
Java
Web
Start(asmall'helperapp'
ontheclient)isstartedup
by
the
browser.TheJWShelperapp
reads
the.jnlpfile,andaskstheserverfor
the
MyApp.jar
file.
@
TheWebserver'serves'upthe
requested.jar
file.
Java
Web
Startgets
theJARand
startstheoppUcation
by
callingthe
specifiedmalnOmethod(justlikean
executableJAR).
Nexttimetheuserwantstorunthisopp.he
can
opentheJavaWebStartapplicationand
from
therelaunchyourapp.withoutevenbeingonline.
598
chapter17
-givemeMyApp.jar"
--
package,jarsanddeployment
The.j"lpfile
TomakeaJavaWebStartapp,youneedtoJnlp(JavaNetwork
LaunchProtocol)filethatdescribesyourapplication.Thisisthe
filetheJWSappreadsandusestofindyourJARandlaunchthe
app(bycallingtheJAR'smain
0
method),Ajnlpfileisasimple,
XML
documentthathasseveraldifferentthingsyoucanputin,.
~ -t~e
'yoat:
butasaminimum,
it
shouldlooklikethis:
~
ye
~o~ s~et.l l~e seY"e~ ·
,-tal"'s'II
~ L~~
'ISO'f\'ye
v51'f\~
,G10a
se
:\:,a.n-
s'\-
:t
so
'lie10
<?:xmlversion="l.O"encoding="ut£-B"?>
\~e
(.0
e
y'fle
S
\ot.a\~OS
I\"
yOV'
'lie
J
'II~eye'f~\Ii
-tnlsO'f\o'J'y
"\1,1.0.0..
-tn\S
'fIO~\G
,.f'
e
-\:.tS-\:."'V'~L
.1,
ado
ytsS
L
Lsey"e
Y
,
v'
eY
~\oo~va","
ev
'fIe
v
"
r
-t~e
\oc.
a
S
oy\
o'J'Y
· l ~~:;o.\~ s
...
a..t-(.o'"
<J'nlpspec="0.21.0"
s-tayt,a~~
/1,.rIl'fl,'fIIi.
"~-t-\:.r
sO'l'
codebase=''http://l27.0.0.1/~kathy''
t∙
~th
..L\
tio'f\otthejtllf
~ ile
rt:la'ovee
hre£="MyApp.jnlp">
~
ThiSIS"he
~a
I
showSthatMyAyyjnlyis
todebase..
T~,'s e14d':Yd~
ttor'f
otthewebseYller,not
allailableItl"heYOO"lye
tlesteditlso",eothey
diYet~'f-
<information>
<title>kathyApp</title>
<vendor>WickedlySmart</vendor>
<homepaqehre£="index.html"/>
<description>HeadFirstWebStartdemo</description>
<iconhre£="kathys.qi£"/>
.n1
ya
",withollt
<o£fline-allowed/>
>/.
This",eanSthelOSertanYl/in'f0l/il'"
r.
ottl'
e
~.
ted
~
theinternet.
-t
helOSer
I ~
\n,
</in£ormation>
~t:~::;~~e a\Atomatit -l/ifdahn~
teahyewontwork.
<resources>
ThissaysthatYOI/il'"al'l'needslIel'"sion
1.3
<j2seversion="l.3+"/>
~
otJalla,oY
~reate\".
<jarhre£="MyApp.jar"/>
~
n
e
tlatl'le
0+
t:
/
oiher
JAo,.
eXef∙l<tah/
e
JAo/
y;
<resources>"
1";
es
as
w
/I
1.L
1.".
010tI'Iip'hih
ever.SOlltld
d.
e•<;nat:
hold
.I.
ave
s
an
I tI'I a ~ e s
llSed
b
Outer(.asses
0\'"
Y
YOll\"
apr.
<application-descmain-class="HelloWebStart"/>
</jnlp>
~
ThisislikethetI'IainfestMain-Classent\"'1'"itsays
whithzlassinthe
JAR
hasthellIairDllIethod.
youare
here.599
deploying
with
JWS
Stepsformakinganddeploying
aJavaWebStartapp
Make
anexecutable
JAR
foryourapplication.
0
MyApp.Jar
~
Write
a.Jnlpfile.
MyApp.jnlp
®
PlaceyourJARand.jnlp
filesonyour
Web
server.
@)
Addanewmime
type
toyour
Webserver.
application/x-java-jnlp-nle
Thiscausestheservertosendthe.jnlpfilewiththe
correctheader,sothatwhenthebrowserreceives
theJnlpfileitknowswhatit
is
andknowsto
start
the
JWS
helperapp.
~
.....
I~
.....
~--:
MyJWSApp.hbnl
600
chapler17
Create
Q
Web
page
withalink
toyour.jnlpfile
<HTML>
<BODY>
<8
href='~App2.jnlpH>Launch
My
Application</a>
<
I
BODY>
</HTML>
package,jarsanddeployment,
,
.
LOO
I
katthesequence
ofeventsbelow,and2.
p
acethemintheorderInwhichthey
occurIna
JWSapplication.
3.
5,
4.
7.
6.
theJWShelper
appinvokes
theJAR's
malnO
method
er
requestsa.jnlpfile
fromtheWeb
server
theWebserversends
tiJe
to
thebrowser
__
-~--:::;':::-;;;-v
!heWebserversendsaJAR
\heWebbrowserstartsuplileto!heJWShelperapp
theJWShelperapp
userdicksaWebpageItn
WhentheJWSgetstheJAR,itinvokesthe
mainOmethod(specifiedinthe.jnlpfile).
•
•
•
•
•
•
•
,--BULlO
POINTS-
JavaWebStarttechnologyletsyoudeploya
stand-aloneclientapplicationfromtheWeb.
Java
WebStartincludesa'helperapp'thatmust
beinstalledontheclient(alongwithJava).
AJavaWebStart(JWS)apphastwopieces:
anexecutableJAR
and
a.jnlpfile.
A
.jnlpfileisasimple
XML
documentthat
describesyourJWSapplication.
It
includes
tagsforspecifyingthenameandlocationofthe
JAR,andthenameoftheclasswiththemainO
method.
Whenabrowsergetsa.jnlpfilefromtheserver
(becausetheuserclickedonalinktothe.jnlp
file),thebrowserstartsuptheJWShelperapp.
TheJWShelperappreadsthe.jnlpfileand
requeststheexecutableJARfromtheWeb
server.
Appletscan'tliveoutsideofaWebbrowser.Anappletis
downloadedfromtheWebaspart
ofaWebpageratherthan
simplyfromaWebpage.Inotherwords,tothebrowser,theapplet
IsJustlikea
JPEG
oranyotherresource.Thebrowseruseseithera
Javaplug-Inorthebrowser'sownbuilt-InJava(farlesscommon
today)toruntheapplet.Applets
don'thavethesamelevelof
functionalityforthingssuchasautomaticupdating,andtheymust
alwaysbelaunchedfromthebrowser.With
JWSapplications,once
they'redownloadedfromtheWeb,theuserdoesn'tevenhaveto
beusIngabrowsertorelaunchtheapplicationlocally.Instead,
theusercanstartupthe
JWShelperapp,anduse
Itto
launchthe
already-downloadedapplicationagain.
dlim~estJons
Q.:
HowIsJavaWebStart
dl~rent
fromanapplet1
A:
Q..:
Whatarethesecurityrestrictions
of
JWS1
A:
JWSappshaveseverallimitationsIncludingbeing
restrictedfromreadingandwritingto
theuser'sharddrive.But...
JWShasItsown
API
with
a
specialopenandsavedialogboxso
that,
withtheuser'spermission,your
app
cansaveandreadIts
ownfliesInaspeclaI,restrictedareaoftheuser'sdrive.
youarehere
~
601
exercise:TrueorFalse
Weexploredpackaging,deployment,andJWS
inthischapter.Yourjobistodecide
whether
eachofthefollowingstatementsistrueorfalse.
1.TheJavacompilerhasaflag,
-d,
thatletsyoudecidewhereyour.classfilesshouldgo.
2.AJARisa
standarddirectorywhereyour.classfilesshouldreside.
3.
WhencreatingaJavaArchiveyoumustcreateafilecalledjar.mf.
4.
ThesupportingfileinaJavaArchivedeclareswhichclasshasthemain()method.
5.JARfilesmustbeunzippedbeforethe
jVM
canusetheclassesinside.
6.Atthe
commandline,JavaArchivesareinvokedusingthe-archflag.
7.Packagestructuresaremeaningfullyrepresentedusinghierarchies.
8.Usingyourcompany'sdomain
nameisnotrecommendedwhennamingpackages.
9.Differentclasseswithinasourcefilecanbelongtodifferentpackages.
10.
Whencompilingclassesinapackage,the-pflagishighlyrecommended.
11.
Whencompilingclassesinapackage,thefullnamemustmirrorthedirectorytree.
12.Judicioususe
ofthe
-d
flagcanhelptoassurethattherearenotyposinyourclasstree.
13.Extracting
aJARwithpackageswillcreateadirectorycalledmeta-info
14.Extracting
aJARwithpackageswillcreatea
file
calledmanifest.mf.
15.
TheJWShelperapp
always
runs
in
conjunctionwithabrowser.
16.JWSapplicationsrequirea.nlp(NetworkLaunchProtocol)filetoworkproperly.
17.AJWS'smain
methodisspecifiedinitsJARfile.
602
chapter17
~U1Il1Ilar)'-Or~ss
7-.0
package,jars
and
deployment
Anythinginthebook
Isfairgameforthis
onel
Aaoss
Down
6.Won'ttravel
26.Mineisunique
1.
Pushywidgets16.Who'sallowed
30.
110
cleanup
9.Don'tsplitme
27.
GUl'starget
2.
__ofmydesire
19.
Efficiencyexpert
31.
MUll-nap
10.
Release-able
29.Javateam
3.'Abandoned'moniker
20.
Earlyexit
34.Trigmethod
11.Gotthe
key
30.
Factory
4.Achunk21.Commonwrapper
36.
Encapsmethod
12.VOgang
32.Forawhile
5.Mathnottrlg
23.
Yesorno
38.
JNLPformat
15.Flatten
33.Atomic
It
8
6.
Be
brave
24.Javajackets
39.
VB'sfinal
17.
Encapsulatedreturner
35.Goodasnew
7.Arrangewell
26.Notbehavior
40.
Javabranch
18.Shipthisone
37.
Pairsevent
8.
Swingslang
28.
Socket'ssuite
21.MakeItso
41.WheredoIstart
11.I/O
canals
22.I/Osieve
42
Alittlefirewall
13.Organized
release
25.Diskleaf
14.Notforaninstance
youarehere
~
603
exercisesolutions
,
.
2.
3.
4.
5.
6.
7.
theWebserversendsa.jnlp
file
10
thebrowser
'
the
Web
browserstartsup
theJWShelperapp
\\he
NJS
helperapprequests
\lheJARfl\e
I
theWebserversendsaJAR
I
L
li/e
10
the
JWShelperapp
I
theJWShelperappInvokes
I
the
JAR'smal
nO
method
True
False
False
True
False
False
True
False
False
False
True
True
True
True
False
False
False
1.TheJavacompilerhasaflag,-d,thatletsyoudecidewhereyour.classfilesshouldgo.
2.AJARisa
standarddirectorywhereyour.classfilesshouJdreside.
3.
WhencreatingaJavaArchiveyoumustcreateafilecalledjar.mf,
4.Thesupportingfile
in
aJavaArchivedeclareswhichclasshasthemainOmethod.
5.JARfilesmustbeunzippedbeforethejVMcanusetheclassesinside.
6.At
thecommandline,JavaArchivesareinvokedusingthe-archflag.
7.Package
structuresaremeaningfullyrepresentedusinghierarchies.
8.Using
yourcompany'sdomainnameisnotrecommendedwhennamingpackages.
9.Differentclasseswithina
sourcefilecanbelongtodifferentpackages.
10.
Whencompilingclassesinapackage,the-pflag
is
highlyrecommended.
II.Whencompilingclassesinapackage.thefullnamemustmirrorthedirectorytree.
12.
Judicioususeofthe
-d
flagcanhelptoassurethattherearenotyposinyourtree.
13.Extracting
aJARwithpackageswillcreateadirectorycalledmeta-inf,
14.
ExtractingaJARwithpackageswillcreatea
file
calledmanifestmf.
15.TheJWShelperapp
always
runsinconjunctionwithabrowser.
16.]WS
applicationsrequirea.nlp(NetworkLaunchProtocol)filetoworkproperly.
17.
A]WS'smainmethod
is
specifiedinitsJARfile.
604
chapter17
~UtIltIlary-Or~55
t.
O
youarehere
~
605
18
remotedeployment
with
RMI
Distributed
Computing
Beingremotedoesn'thavetobeabadthing.
Sure,things
areeasieT
when
all
thepartsofyourapplicationareinoneplace,inoneheap,withoneJVMtorulethemall.But
that's
notalwayspossible.Ordesirable.WhatIfyourapplicationhandlespowerfulcomputations,
buttheend-usersareonawimpylittleJava-enableddevice?What
if
yourappneedsdata
fromadatabase,
butforsecurityreasons,onlycodeonyourservercanaccessthedatabase?
ImagIneabige-commerceback-end,
thathastorunwithinatransaction-managementsystem?
Sometimes,
partofyourapp
must
runonaserver,whileanotherpart(usuallyaclient)must
runona
different
machine.Inthischapter,we'lllearntouseJava'samazinglysImpleRemote
MethodInvocation(RMI)technology.We'llalsotakeaquickpeekatServlets,EnterpriseJava
Beans
(EJB),andJInl,andlookatthewaysInwhIchEJBand
J
Inl
depend
onRMI.We'llendthe
bookbywritingoneofthecoolestthingsyoucanmakeInJava,a
universalservicebrowser.
thisisanewchapter
807
how
many
heaps?
100%Local
..
RMlapp
Combination
MethodcallsarealwaysbetweeK
twoobjects
OK
thesattteheap.
Sofarinthisbook,everymethodwe'veinvokedhasbeenon
anobject
runninginthesamevirtualmachineasthecaller.
In
otherwords,thecallingobjectandthecallee(theobject
we'reinvoking
themethodon)liveonthesameheap.
classFoo{
voidgo()
Barb
=
new
Bar();
b.doStuff()
j
publicstaticvoidmain(String[]args)(
Faa
f
=
newFoa()j
f
.go();
Inthecodeabove,weknowthattheFooinstance
referencedby
fandtheBarobjectreferencedbybare
bothonthesameheap,runbythesameJVM.Remember,
the
jVM
isresponsibleforstuffingbitsintothereference
variable
thatrepresent
how
to
get
toanobjecton
the
heap.
TheJVMalwaysknowswhereeachobjectis,andhow
La
get
to
it.ButtheJVMCanknowaboutreferencesononly
its
own
heap!Youcan't,forexample,haveaJVMrunning
ononemachineknowingabouttheheapspaceofaJVM
runningona
different
machine.Infact,aJVMrunningon
onemachinecan'tknowanythingaboutadifferentjVM
runningonthe
same
machine.
It
makesnodifference
if
theJVMsareonthesameordifferentphysicalmachines;
itmattersonlythatthetwoJVMsare,well,twodifferent
invocations
ofthe
JVM.
608chapter18
Inmostapplications,whenoneobject
callsamethodonanother,bothobjects
areonthesameheap.Inotherwords,
both
arerunningwithinthesameJVM.
remotedeployment
with
RMI
Whatifyouwattttoittvoke8'MethodOtt
attobjectrutttthtgOtt
another
tH8chitte?
JVM
I
Big
__'--'-
~
r---'
CJ~r.=a~~~..::::15
L-''---
I
CJ
l-J
C-.l
L-J
L..J
L--o;
'I--"
l..
\l∙
U
Little
Imaginetwocomputers...
Weknowhowtogetinformationfromonemachinetoanother-
withSocketsandI/O.WeopenaSocketconnectiontoanother
machine,andgetanOurputfitreamandwritesomedatatoit.
Butwhatifweactuallywantto
callamethod
onsomethingrunning
inanothermachine...another
JVM?
Of
coursewecouldalwaysbuild
ourownprotocol,andwhenyousenddatatoaServerSocketthe
servercouldparseit,figureoutwhatyoumeant,dothework,and
sendbacktheresultonanotherstream.Whatapaia,though.Think
howmuchniceritwould
be
tojustgetareferencetotheobjecton
~ ~t.1
lovtS
theothermachine,andcallamethod.
yO-.lC"hl,
~I..
...
~n
'b\C)
t.o
t....I»'t.
n
"V'
~ t.O\t.~abo'f\S~
......
~
Big
has
something
Little
wants.
C~ute-l0~er.
Little
wantstosendsomedatatoBig,so
thatBig
can
do
the
heavy
~ruting.
Little
wants
simply
tocallamethod...
doubledoCalcUsingDatahase(CalcNumbersnumbers)
andgetLacktheresult.
Buthowcan
Little
getarelerence
to
anobjectonBig?
youarehere'
609
twoobjects,twoheaps
ObjectAIrut,.1i.,g
0.,
Little,wa.,tstocall
atttethod
0.,
Object
~
ru.,.,it1gOt1Jig.
Thequestionis,howdowegetanobjectononemachine
(whichmeansadifferentheap/]VM)tocallamethodon
anothermachine?
doCalcUsi
ngDatabase.O
~ ~ ~
returnvalue
~
- - ~
e-..
,,~ -
.-
......
'-
..
-.11_'--
,
-,
Jutyoucan'tdothat.
Well,
notdirectlyanyway.Youcan'tgetareferenceto
something
onanotherheap.
If
yousay:
Dog
d
=
???
Whatever
d
isreferencingmustbeinthesameheapspace
as
thecoderunningthestatement,
Butimagineyouwant
to
designsomethingthatwilluse
Sockets
and
I/O
tocommunicateyourintention(amethod
invocationonanobjectrunningonanothermachine),yet
still
feel
as
thoughyouweremaking
a
localmethodcall.
In
otherwords.youwanttocauseamethodinvocationona
remoteobject(i.e.,anobjectinaheapsomewhereelse)
J
but
withcodethatletsyou
pretend
thatyou'reinvokingamethod
onalocalobject.Theeaseofaplainoldeverydaymethod
call,butthepowerofremotemethodinvocation.That'sour
goal.
That'swhatRM1(RemoteMethodInvocation)givesyou!
Butlet's
stepbackandimaginehowyouwoulddesignR.i\1I
if
youweredoingityourself.Understandingwhatyou'dhaveto
buildyourselfwillhelpyoulearnhowRMlworks.
610
chapter18
Adesignforremotemethodcalls
Createfourthings:server,client,
serverhelper,clienthelper
•Createclientandserverapps.Theserverappisthe
remoteservicethathasanobjectwiththemethod
thattheclientwantstoinvoke.
remotedeploymentwithRMI
Clientheap
Serverheap
Createclientandserver'helpers'.
They'llhandle
011
thelow-levelnetworkingandI/Odetailssoyourclient
ondservicecanpretendlikethey'rein
thesameheap.
youarehere>611
clientandserverhelpers
fheroleofthe'helpers"
The'helpers'aretheobjectsthatactuallydothecommunicating.
Theymake
it
possiblefortheclientto
ad
asthoughitscallinga
methodonalocalobject.Infact,it
is.
Theclientcallsamethodon
theclienthelper,
as
if
theclienthelperweretheactualservice.The
client
helper
is
a
frrorj
fortheRealThing.
Inotherwords,theclientobject
thinks
it'scallingamethodon
theremoteservice,becausetheclienthelperis
pretending
tobe
theserviceobjeel.
Pretending
to
be
the
thing
with
the
met/wd
the
client
wants
10
call!
Buttheclienthelperisn'treallytheremoteservice.Althoughthe
clienthelper
ruts
likeit(becauseithasthesamemethodthatthe
serviceisadvertising),theclienthelperdoesn'thaveanyofthe
actualmethodlogictheclientisexpecting.Instead,theclient
helpercontactstheserver,transfersinformationaboutthemethod
call(e.g.,nameofthemethod,arguments,etc.),andwaitsfora
returnfromtheserver.
Ontheserverside,
theservicehelperreceivestherequestfrom
theclient
helper(throughaSocketconnection),unpacksthe
informationaboutthecall,andtheninvokesthe
real
methodon
the
real
serviceobject.
So
totheserviceobject,thecallislocal.It's
comingfromtheservicehelper,notaremoteclient.
Theservicehelpergetsthereturnvaluefromtheservice.packsit
up,
andshipsitback(overaSocket'soutputstream)totheclient
helper.
Theclienthelperunpackstheinformationandreturnsthe
valuetotheclientobject.
612chapter18
Yourclientobject
gets
to
act
llke
it'smakingremote
methodcalls.
But
what
it'sr!!llY
doing
is
calling
methods
on
a
heap-local
'proxYobject
that
handles
all
the
low-level
details
of
Sockets
and
streams.
Serverheap
remotedeployment
with
RMI
Howthemethodcallhappens
•ClientobjectcallsdoBigThingOontheclienthelperobject
Se~r
heap
•Clienthelperpackagesupinformationaboutthecall
(arguments,methodname,
etc.)andships
it
overthe
networktotheservicehelper.
Client
heap
I
"client
wonts
tocallamethod"
Serverheap
•Servicehelperunpackstheinformationfromtheclienthelper,
findsoutwhichmethodtocall(andonwhich
object)and
invokes
therealmethodontherealserviceob]ect.
-
-
Client
heap
I
"clientwantstocoliamethod"
youarehere
~
613
RMIhelperobjects
JavaRMIgives
you
thecliet1tat1d
servicehelperobjects!
InJava,
RMJ
buildstheclientandservicehelper
objectsforyou,anditevenknowshowtomakethe
clienthelperlookliketheRealService.Inother
words.RMIknowshowtogivetheclienthelper
objectthesamemethodsyouwanttocallonthe
remoteservice.
Plus,RMIprovidesall
theruntimeinfrastructureto
makeitwork,includingalookupservicesothatthe
clientcanfindandgettheclienthelper(theproxy
fortheRealService).
WithRMI.you
don'twrite
any
ofthenetworking
orI/Ocodeyourself.Theclientgetstocallremote
methods(i.e.theonestheRealServicehas)just
likenormalmethodcallsonobjectsrunninginthe
client'sown10ca1JVM.
Almost.
ThereisonedifferencebetweenRMIcallsandlocal
(normal)methodcalls.Rememberthateventhough
totheclientitlookslikethemethod
call
is
local,
theclienthelpersendsthemethodcallacrossthe
network.SothereisnetworkingandI/O.Andwhat
doweknowaboutnetworkingandI/Omethods?
They'rerisky!
Theythrowexceptionsallovertheplace.
So,
theclientdoeshavetoacknowledgetherisk.The
clienthastoacknowledgethatwhenitcallsaremote
method.eventhoughtotheclientit'sjustalocal
call
totheproxy/helperobject,thecall
ultimaJely
involves
Sockets
andstreams.Theclient'soriginal
call
is
local,
butthepro"]'turnsitintoa
remote
call.Aremotecall
JUSt
meansamethodthat'sinvokedonanobjecton
another
JVM.
HQ11J
theinformationaboutthatcall
getstransferredfromoneJVMtoanotherdepends
ontheprotocolusedbythehelperobjects.
WithRMI.youhavea
choiceofprotocols:JRMPor
IIOP,JRMPisRMJ's'native'protocol,theonemade
justforJava-ta-Javaremotecalls.
nop,
ontheother
hand.istheprotocolforCORBA(CommonObject
RequestBrokerArchitecture),andletsyoumake
remotecallsonthingswhicharen'tnecessarilyJava
objects.CORBAisusually
much
morepainfulthan
RMI,because
if
you
don'thaveJavaonbothends,
there'sanawfullotoftranslationandconversionthat
hastohappen.
Butthankfully,allwecareaboutisJava-to-Java,so
we'restickingwithplainold.remarkably
easy
RMl.
InRMI,theclienthelperis
a'stub'
andtheserverhelperisa'skeleton'.
614
chapter18
Client
heap
..
Serverheap
MakingtheRemoteService
Thisisanoverviewofthefivestepsformakingtheremote
service(thatrunsontheserver).Don'tworry,eachstep
is
explainedindetailoverthenextfewpages.
Stepone:
MakeaRemoteInterface
Theremoteinterfacedefinesthemethods
thataclientcancallremotely.It'swhat
theclient
will
useasthepolymorphicclass
type
foryourservice.BoththeStuband
actualservicewillimplementthis!
Step
two:
MakeaRemoteImplementation
ThisistheclassthatdoestheRealWork.
It
hastherealimplementationofthe
remotemethodsdefinedintheremote
interface.It'stheobjectthattheclient
~~~~~~.
remotedeployment
with
RMI
Server
D!!
Stepthree:
Generatethe
stubs
and
skeletonsusingrmic
Thesearetheclientandserver'helpers'.
You
don'thavetocreatetheseclassesorever
lookatthesourcecodethatgeneratesthem.
It'sallhandledautomaticallywhen
you
runthe
rmic
toolthatships
with
yourJava
development
kit,
MyRemotelmpl_Stub.class
101101-
Jtl
1...10'
e"
II
bOt.HI
001Ol
Stepfour:
StarttheRMI
registry
(rmiregistry)
The
nniregistry
is
J
i
ke
the
wh
i
te
pagesofa
phonebook.It'swheretheusergoesto
gel
the
proxy
(theclientstubv'helperobject).
MyRemotelmpLSkel.class
Stepfive:
Starttheremoteservice
Youhave
to
gettheserviceobjectupandrunning.
Yourservice
implementationclassinstantiatesan
instanceoftheserviceandregistersitwiththeRMI
registry.
Registeringitmakestheserviceavailablefor
clients.
you
arehere.
615
aremoteinterface
DeclarethatallmethodsthrowaRemoteException
Theremoteinterfaceistheonetheclientusesasthepolymorphictype
fortheservice.Inotherwords,theclientinvokesmethodsonsomething
thatimplementstheremoteinterface.Thatsomethingisthestub,of
course,andsincethestubisdoingnetworkingandI/O,allkindsofBad
Thingscanhappen.Theclienthastoacknowledgetherisksbyhandling
ordeclaringtheremoteexceptions.
If
themethodsinaninterface
declareexceptions,anycodecallingmethodsonareferenceofthattype
(theinterfacetype)musthandleordeclaretheexceptions.
t,
~
..'
av,H'",i
importjava.
rmi.
*;
~ th~ R~",oh
'"n;c;Y
ate'S,,,
J'
Stepone:MakeaRemoteInterface
Extendjava.rmLRemote
Remoteisa'marker'interface,whichmeansithasnomethods.
It
has
special
meaningforRMI,though,soyoumustfollowthisrule.Notice
thatwesay'extends'here.Oneinterfaceisallowedto
extend
another
interface.
publicinterfaceMyRemote
publicinterfaceMyRemoteextendsRemote{
publicStringsayHello()throws
}
MyRemote.java
BesureargumentsandreturnvaluesareprimitivesorSerializable
Argumentsandreturnvaluesofaremotemethodmustbeeitherprimitive
orSerializable,Thinkaboutit.Anyargumenttoaremotemethodhasto
be
packagedupandshippedacrossthenetwork,andthat'sdonethrough
Serialization.Samethingwithreturnvalues.Ifyouuseprimitives,Strings,
andthemajorityoftypesintheAPI(includingarraysandcollections),
you'll
befine.Ifyouarepassingaroundyourowntypes,justbesurethat
youmakeyourclassesimplementSerializable.
publicsayHello()throwsRemoteException;
"'-This
r-et;...rn
vc1/~e
is
~onna
beshirred
over
~he
wire
+\'"0'"
theserve\"batk
to
the
~"ent,
soit
lrIl.tSt
beSe\"ializable.
Thats
how
ar~s
and
\"et~rn
valf.tt:s
ad:;
ratka~ed ~r
andSent,
J
remotedeploymentwithRMI
MyRemotelmpl.java
Steptwo:MakeaRemoteImplementation
•ImplementtheRemoteinterface
Yourservicehastoimplementtheremoteinterface-theone
withthemethodsyourclientisgoingtocall.
publicclassMyRemoteImplextendsUnicastRemoteObject
publicStringsayHello()
{~
return"Serversays,'Hey''';
Th~ t~n-riler
will
n-akeSlArethat
}rIA
lieIn-r1en-el'lteoallthen-ethods
//morecodeinclass
t~.om
theintel-fate
'/OIA
ir..r1er..el'lt.Il'I
}IStase,theresol'llyOhe.
1
~
.......";i_
--
-0
{
•ExtendUnicastRemoteObject
Inordertoworkasaremoteserviceobject,yourobjectneedssome
functionalityrelatedto'beingremote'.Thesimplestwayistoextend
UnicastRemoteObject(fromthejava.rmi.serverpackage)andletthat
class(yoursuperclass)dotheworkforyou.
publicclassMyRemoteImpl
implementsMyRemote{
•Writeano-argconstructorthatdeclaresaRemoteException
Yournewsuperclass,UnicastRemoteObject,hasonelittleproblem-its
constructorthrows
a
RemoteException.Theonlywaytodealwiththisis
to
declareaconstructorforyourremoteimplementation,justsothatyou
havea
placetodeclaretheRemoteException.Remember,whenaclassis
instantiated,itssuperclass
constructorisalwayscalled.Ifyoursuperclass
constructorthrowsanexception,youhavenochoicebuttodeclarethat
L
thO'l'l
y'ourconstructoralsothrowsanexception.
,/o\A
dOl'l'thalle
to
yv-".
al'l~
I:i
~
-1
t
toY-
Y
oIAJV-S"l'Ie..
~
P
ublicU.rRemoteImpl()
the
t.01'lS
rv.t.,
~hat
"OIArslAfert.lass
6"6:t
wa"
to
det.are
"I
L,
t.~trv.t.tor
throwsal'leuefvOTI.
•RegistertheservicewiththeRMIregistry
Nowthatyou'vegotaremoteservice,youhavetomake
it
availableto
remoteclients.Youdothisbyinstantiatingitandputting
it
intotheRMI
registry(which
mustberunningorthislineofcodefails).Whenyou
register
theimplementationobject,theRMIsystemactuallyputsthe
stub
in
theregistry,sincethat'swhattheclientreallyneeds.Registeryourservice
using
thestaticrebind()methodofthejava.rmi.Namingclass..
M",e(thatt.I\el'tstal'
~t
try(
q\ve
~o\Ar serv.lt.et~ ~\str~)
al'd
re~\ster
It
Remoteservice
=
newRemoteI1();
~\otnit.R~IIl'Ire~\:t:;.
W'hel'l
~o\A
b.\"dthethe
wltne.t.
RMI
swayst.heserv,u
o'r
~
.,-servit.e
obJe~_,
LhestlAb\l'the
re~istr~·
'---'"stlAbal'dflA';>"
youarehere.
617
Stepthree:generatestubsandskeletons
G)
Runrmicontheremoteimplementationclass
(notthe
remote:Interface)
Therrnictool,thatcomeswiththejavasoftware
development
kit,
takes
aserviceimplementationand
creates
two
newclasses.thestubandtheskeleton.
It
usesanamingconventionthat
is
thenameof
yourremoteimplementation,witheither_Stubor
_Skeletonaddedtotheend.Thereareotheroptions
with
rmic,includingnotgeneratingskeletons,
seeingwhat
the
sourcecodefortheseclasseslooked
like,andevenusingllOPastheprotocol.Theway
we'redoingithereisthewayyou'llusuallydo
it.
Theclasseswilllandinthecurrentdirectory(i.e.
whateveryou
didacdto).Remember,
rmic
must
beabletoseeyourimplementationclass,soyou'll
probably
runrmicfromthedirectorywhereyour
remoteimplementationis.(We'redeliberatelynot
usingpackageshere,tomake
it
simpler.IntheReal
World,
you'll
needtoaccountforpackagedirectory
structuresandfully-qualifiednames).
Stepfour:runrmiregistry
MyRemotelmpl_Stub.class
lClnO).
10liOI
o
U6
001\0
OO~
0)
MyRemotelmpCSkel.class
(1)
Bringupa
terminaland
start
the
rmlre:gistry.
Be
sureyoustartitfromadirectorythat
has
access
to
yourclasses.Thesimplestwayistostartitfrom
your'classes'directory.
Stepfive:starttheservice
CD
Bring
up
anotherterminal
and
start
yourservice
Thismightbefromamain
0
methodinyourremote
implementation
class.
orfrom
a
separatelauncher
class.
Inthissimpleexample.weputthestartercodeinthe
implementationclass,inamainmethodthatinstantiates
theobjectandregistersitwith
RMl
registry.
618
chapter18
remotedeploymentwithRMI
Completecodefortheserverside
TheRemoteinterface:
TheRemoteservice(theimplementation):
publicMyReIDoteImpl()throwsRemoteException{
I
<c>
publicstaticvoidmain(String[]args)(
try(
MyRemoteservice
=
new
MyR8moteImpl();~
Naming.rebind("RemoteHella
H
I
service);
catch
(Exceptionex){
~
M.ikethert....
oU
ob∙
t
I,I
ex.printStacltTrace();
'r"'irt4ish-y'd∙
1.,
:Je~"1.~e"
b"'d
it
to
-the
J
_I"~
Ult
S'td{;H':.
N∙
b
J\d"'t
yOIA
l-
e
9;su
..-
it:.
lA"d.
t...
'''?,.....
ei"dO.The
"ted
to
look
it.
"d∙
1.,
t"r
r~
he
1I<1"'etliel'lts
'011/1
--r
tr.
Ule
r""
re9'shy
youarehere
~
619
gettingthestub
Howdoestheclientgetthe
stub~?
Theclienthascogetthestubobject,sincethat'sthethingthe
clientwillcall
methodson.Andthat'swheretheRMIregistry
comesin.
Theclientdoesa'lookup',likegoingtothewhitepages
ofaphonebook,andessentially
says,
"Here'saname,andI'dlike
thestubthatgoeswiththatname."
loolcllpO
is
a
statit
l\'ltihod
o-t
the
Na",i~
tlass
\t
~Remote)
Naming.lookup("rmi://127.0.0.1/Remote
l'
~
\'1011
hil'lt
to
t..ut
it.
to
tht
'f0\l.'"
host.l\il",e
0'"
/P
i"u...t
ate,siYllet.he
loolc'-r
addytsS
~oes
heye
...ethod
ret.'-Yl'I$
t'ffe
Objett..
Bello");
•Clientdoes
Q
lookupon
the
RMIregistry
Naminq.lookup("rm1://127.0.0.1/Ramot:8Bello");
•RMI
registry
returnsthestubobject
(asthereturnvalueofthelookupmethod)andRMI
deserializes
thestub
automatically,
YouMUSThave
thestubclass(thatrmicgeneratedforyou)onthe
clientor
thestubwon'tbedeserialized,
•ClientInvokes
Q
methodon
the
stub,
as
thoughthestubIStherealservice
620
chapter18
Server
remotedeploymentwith
RMI
Howdoestheclientgetthestubclass?
Nowwegettotheinterestingquestion.Somehow,someway,the
clientmusthavethestubclass(thatyougeneratedearlierusing
rmic)at
thetimetheclientdoesthelookup,orelsethestubwon't
bedeserialized
ontheclientandthewholethingblowsup.Ina
simplesystem,youcansimplyhand-deliverthestubclassto
the
client.
There'samuchcoolerway,though,althoughit'sbeyondthe
scopeofthisbook.Butjustincaseyou'reinterested,thecooler
wayiscalled"dynamicclassdownloading".Withdynamicclass
downloading,a
stubobject(orreallyanySerializedobject)is
'stamped'withaURLthattellstheRMIsystemontheclient
wheretofindtheclassfileforthatobject.Then,intheprocessof
deserializinganobject,ifRMIcan'tfindtheclasslocally,ituses
thatURLtodoanHTTPGettoretrievetheclassfile.Soyou'd
needasimpleWebservertoserveupclassfiles,andyou'dalso
needtochangesomesecurityparametersontheclient.Thereare
afewothertrickyissueswithdynamicclassdownloading,butthat's
theoverview.
Completeclientcode
I
~
The
Na...
ih
9dass
(.f.
..*.
<
re...ire3istr
look
c:
~ 01n 9
the
importJava.rnu..,
J'ava.
Y
lop)IS'nthe
∙r...,
patkage
publicclassMyRemoteClient{
publicstaticvoidmain(String[]args)
newMyRemoteClient().go();
J.
tht
V't~ is ty~
as
~'/Y t
publicvoidgo()
\t
t.o.,.,e
s
Ol/.t
't
~ « ~ t t
thtt.as
r:
O'oy:.t.t,
sodon
try{
\I-
MyRemoteservice
=
(MyRemote)
Naming.lookup(~rmi://127.0.0.1/Remote
Hello");
Strings
=
service.sayHello();
Y
d
1-.
7'\
L-
010nee"Ule
IP
address
a
c1
t.he"artie
~ed
VI
It
orhosw...e
VI
I
L'
d
LhestV'vit.t
System.out.println(s);\
~ Vld
V'CUly\
~
catch(Exceptionex){
It
looks
jlAStlikea
I
ex.printStackTrace();
tall!
(E'lt.teptit
1
9
'"
~ r
old
"'cthod
Re...
oteE'lt.t ept io ~ 1AS
at
now/edsethe
youarehere;621
RMI
classfiles
JesureeachlMachhtehastheclass
files
it
"eeds.
Thetopthreethingsprogrammersdowrongwith
RMI
are:
1)
Forgettostartrmiregistrybeforestartingremoteservice
(whenyouregister
theserviceusing
Nammg.rebindt),
the
nniregistrymustberunning!)
2)Forgettomake
argumentsandreturntypesserializable
(you
won'tknowuntilruntime;thisisnotsomethingthe
compilerwilldetect.)
3)
Forgettogivethestubclasstotheclient.
lQt~OI
l~
H.I)
I
6110
OGt
L~
"'".t
MyR9mote.class
MyRemotelmpLStub.class
SeYVer"eeds
boththestub
a..
aSkeld:.o"
dasses,as
""ell
astheseYviua.-t:I
the
l"C"'otL
i"u,-tau.
It.
MeaS
the
st.Lt'otlass
~t.alAU
rC"'-t'"bcr,
the
st.",bis
s",bst.i+'"iea
to\"
the
veal
service,wh(l\thevealw-vice
is
bOWla
+.0
the
RMI....
c5isttY∙
MyRemotelmpl,class
MyRemotelmpl_Skel.class
10UIn-
10UO'
o
110
0CI110
00\01
MyRemotelmpLStub.class
llUJln,
lIilUO""l
o
UCI
O<Il1G1
0(111011
lOU01.,
to
HoO
1.
~
1\
I)
~~l
10
UtOl
,gclient
Cllentclass
Do,,'
t
+cn-5tt,
tilt
zhe..
+'
uses
the
i"te~~att
to
tall
Methods
<»>
the
st.",b.Tnt
clie"t
JVM
"eeasthe
si",b
tla~,b~
thetliO'lt"eveY
rete",s
to
the
shbclass
i.-
toae.
Tbetlit"t.
always
v.sestheve...
o{:e
i"ktate,
as
thou5h
the
l"t"'ote
iPlttrk.lte
WERE.
t.he
atb.al
yC"'oU:
objttt.
622
chapter
18
remotedeployment
with
RMI
1.
~n
yoor
penCil
W:~$J~
Look
at
the
sequenceofeventsbelow,and2.
placethemintheorderinwhichthey
occur
in
aJavaRMIapplication.
3.
6.
s.
4.
7.
ate
service
(remote
implementation)isinstantiated
onthestub
TheclIent
doesalooku
the
RMI
Registry
The
clientgetsIheslub
from
-The--SlU-b-se-n-;ds-:th~e::--:m::e:;\h;;:od~
Ihe
RMI
regIstry
call
to
the
serverThediem
invokes
8'm
TheRMIregistryIssta
,----IUUR
POINTS ~
•An
objectononeheapcannotgetanormalJava
reference
10
anobjectonadifferentheap(whichmeans
runningonadifferent
NM)
•JavaRemoteMethodInvocation(RMI)makes
it
seem
like
you'recalting
a
methodon
a
remoteobject
(l.e.
anobject
in
a
differentJVM),butyouaren't
•When
a
clientcallsamethodonaremoteobject,the
clientisreallycallingamethodona
proxy
oftheremote
object.Theproxy
is
calleda'stub'.
•A
stubis
a
clienthelperobjectthattakescareofthelow-
levelnetworkingdetails(sockets,streams,serialization,
etc)
bypackagingandsendingmethodcallstothe
server.
•Tobuildaremoteservice(inotherwords,
an
objectthat
a
remoteclientcanultimatelycallmethodson),youmust
startwitharemoteInterface.
•A
remoteInlerfacemustextendthejava.rml.Remote
Interface.andallmethodsmustdeclare
RemoteException.
•
YourremoteserviceimplementsyourremoteInterface.
•
YourremoteserviceshouldextendUnicastRemoleObject.
(Technicallythereareother
ways
10
createaremoteob-
ject,
but
extendingUnicaslRemoteObjectisthesimplest).
•Yourremoteservice
class
musthave
a
constructor,
andtheconstructormustdeclare
a
RemoleException
(becausethe
superclass
constructordeclaresone).
•Yourremoteservicemustbeinstantiated,andtheobject
registered
with
theRMIregistry.
•Toregister
a
remoteservice,usethestatic
Naming.rebind('ServiceName",
servicelnstance);
•TheRMIregistrymust
be
runningonthesamemachine
astheremoteservice,beforeyou
try
10
registeraremote
objectwiththe
RMI
registry.
•Theclientlooksupyourremote
serviceusingthe
static
Naming.lookup{'rmi:/IMyHostNameJServiceName");
•Almost
everythingrelated
to
RMIcanthrowa
RemoteException(checkedbythecompiler).This
IncludesregisteringorlookingupaserviceIntherelgstry,
anda/lremotemethodcallsfromtheclienttothestub.
youarehere.
623
usesforRMI
Yeah,
but
whoreally
uses
RMI?
Iuseit
forseriousB-to-B,
e-commerceback-
ends,runningonJ2EE
technology.
I
624
chapter18
remotedeployment
with
RMI
100%Local
Combination
100%Remote
What
about
Servlets1
ServletsareJavaprogramsthatrunon(andwith)an
HTfP
webserver.Whenadientusesa
webbrowserto
interactwithawebpage,arequest
is
sentbacktothewebserver.
If
therequest
needsthehelpofaJavaservler,thewebserverruns(orcalls,iftheservlet
is
alreadyrunning)
theservletcode.Servletcodeissimplycodethatrunsontheserver,todoworkasaresultof
whatevertheclientrequests(forexample,saveinformationtoatextfileordatabaseonthe
server).Ifyou'refamiliarwith
eGl
scriptswritteninPerl,youknowexactlywhatwe'retalking
about.Webdevelopersuse
CGJ
scriptsorservletstodoeverythingfromsendinguser-submitted
infotoadatabase,to
runningaweb-site'sdiscussionboard.
AndevenseroletscanuseRMI/
By
far,themostcommonuseof
J2EE
technologyistomixservletsandEJBstogether,where
servlets
aretheclientoftheEJB.Andinthatcase,
theserulet
is
usingRJ1IlItotalktotheEJBs.
(Althoughthe
way
youuseRM1withEJBisa
little
differentfromtheprocesswejustlookedat.)
WebBrowser
(client)
-clientrequestsRegisterServlet"
1
Clientfillsoutaregistrationformand
clicks
'submit',
TheHTTPserver(i.e.webserver)getstherequest,seesthat
it'sforaservlet,andsendstherequesttothe
servlet,
WebServer
Servlet(Javacode)runs,addsdatatothedatabase,
composesawebpage(withcustominfo)andsendsitbackto
theclientwhereit∙displaysinthebrowser.
WebServer
................
WebBrowser
(client)
"clientrequestsRegister5ervlet"
"heresaconfirmationpage"
........
conflnn.html
youarehere.
625
verysimple
servlet
Stepformakingandrunningaservlet
G)
Find
out
whereyourservletsneedtobeplaced.
Fortheseexamples,we'llassumethatyoualreadyhaveawebserver
upandrunning,andthatit'salreadyconfiguredtosupport
servlets,
Themostimportantthingistofindoutexactlywhereyourservlet
classfileshavetobe
placedinorderforyourserverto'see'them.
If
youhaveawebsitehostedbyan
ISP,
thehostingservicecantellyou
wheretoputyourservlets.justasthey'lltellyouwheretoplaceyour
eGI
scripts.
WebSel"Ver
®
Gettheservlets.jarandadd
It
toyourc10sspath
Servletsaren'tpart
of
thestandardJavalibraries;youneed
theservletsclassespackagedintotheservlets.jarfile.Youcan
downloadtheservletsclassesfromjava.sun.com,oryoucanget
themfromyourJava-enabledwebserver(likeApacheTomcat,at
theapache.orgsite).Withouttheseclasses,youwon'tbeableto
compileyourservlets.
servlals.Jar
®
Write
aservletcloss
byextending
HttpServlet
AservletisjustaJavaclassthatextendsHttpServlet(fromthe
javax.servlet.httppackage).Thereareothertypesofservlersyou
canmake,butmostofthetimewecareonlyaboutHttpServlet.
publicclassMyServletAextendsHtt:pServlet{...}
UUOt;
16
U~
I
o
U0
Cl611C1
Ql)lOI
MyServletA.cJass
~
MyPage,html
@
WrIteanHTML
page
thatinvokesyourservlet
Whentheuserclicksalinkthatreferencesyourservlet,theweb
serverwillfindtheservletandinvoketheappropriatemethod
dependingontheHITPcommand(GET,POST.etc.)
<ahref="aervlets/MyServletA">Thisisthemostamazingservlet.</a>
~-.
Web
Server
~.
\"
~l
1-,"
~
-.JI'
"
'--
-.':
'I,
:1∙.∙.",.:',--
,I•.
I;;,-:::-,'
@
MakeyourservletandHTML
page
Qvallableto
your
server
Thisiscompletelydependentonyourwebserver(andmorespecifi-
cally,onwhich
version
ofJavaServletsthatyou'reusing).YourISP
maysimplytellyouto
dropitintoa"Servlets"directoryonyour
website.But
if
you'reusing,say,thelatestversionofTomcat.you'll
havea
lotmoreworktodotogettheservlet(andwebpage)into
therightlocation.(Wejusthappentohaveabookonthistoo.)
626
chapter18
servletsand
JSP
•
ServletsareJavaclassesthatrunentirelyon
(and/orwithin)anHTIP(web)server.
•
Servletsareusefulforrunningcodeonthe
serverasaresultofclientinteractionwitha
webpage.Forexample,ifaclientsubmits
informationinawebpageform,theservletcan
processtheinformation,addittoadatabase,
andsendbackacustomized,confirmation
responsepage.
•
Tocompileaservlet,youneedtheservlet
packageswhichareintheservlets.jarfile.The
servletclassesarenotpartoftheJavastandard
libraries,soyouneedtodownloadtheservlets.
jarfromjava.sun.comorgetthemfromaservlet-
capablewebserver.(Note:theServletlibrary
isincludedwiththeJava2EnterpriseEdition
(J2EE))
•
Torunaservlet,youmusthaveawebserver
capableofrunningservlets,suchastheTomcat
serverfromapache.org.
•
Yourservletmustbeplacedinalocationthat's
specifictoyourparticularwebserver,soyou'll
needtofindthatoutbeforeyoutrytorunyour
servlets.IfyouhaveawebsitehostedbyanISP
thatsupportsservlets,theISPwilltellyouwhich
directorytoplaceyourservletsin.
•
AtypicalservletextendsHttpServletand
overridesoneormoreservletmethods,suchas
doGetOordoPostO.
•
Thewebserverstartstheservletandcallsthe
appropriatemethod(doGetO,etc.)basedonthe
client'srequest.
•
Theservletcansendbackaresponsebygetting
aPrintWriteroutputstreamfromtheresponse
parameterofthedoGetOmethod.
•
Theservlet'writes'outanHTMLpage,complete
withtags).
628
chapter18
D
therel&rH?"
ume
~uestl9ns
Q.:
What'saJSP,andhowdoesitrelatetoservlets7
A:
JSPstandsforJavaServerPages.Intheend,thewebserver
turnsaJSPintoaservlet,butthedifferencebetweenaservletand
aJSPis
whatYOU(thedeveloper)actuallycreate.Withaservlet,
youwriteaJava
class
thatcontains
HTML
intheoutputstatements
(ifyou'resendingbackanHTMLpagetotheclient).Butwitha
JSP,it'stheopposite-youwritean
HTML
pagethatcontains
Java
code!
Thisgives
youtheabilitytohavedynamicwebpageswhereyou
writethepageasanormalHTMLpage,exceptyouembedJava
code(andothertagsthat"trigger"Javacodeatruntime)that
getsprocessedatruntime.Inotherwords,partofthepageis
customizedatruntimewhentheJavacoderuns.
The
mainbenefitofJSPoverregularservletsisthatit'sjustalot
easiertowritetheHTMLpartofaservletasaJSPpagethanto
writeHTMLinthetorturousprintoutstatementsintheservlet's
response.
ImagineareasonablycomplexHTMLpage,andnow
imagineformattingitwithinprintlnstatements.Yikes!
But
formanyapplications,itisn'tnecessarytouseJSPsbecause
theservletdoesn'tneedtosendadynamicresponse,orthe
HTMLissimpleenoughnottobesuchabigpain.And,thereare
still
manywebserversouttherethatsupportservletsbutdonot
supportJSPs,soyou'restuck.
AnotherbenefitofJSPsisthatyoucanseparatetheworkby
havingtheJavadeveloperswritetheservletsandthewebpage
developerswritetheJSPs.That'sthepromisedbenefit,anyway.
Inreality,there'sstillaJava
learningcurve(andataglearning
curve)foranyonewritingaJSP,sotothinkthatanHTMLwebpage
designercanbangoutJSPsisnotrealistic.Well,notwithouttools.
Butthat'sthegoodnews-authoringtoolsarestartingtoappear,
thathelpwebpagedesignerscreateJSPswithoutwritingthe
codefromscratch.
Q.:
Isthisallyou'regonnasayaboutservlets?Aftersucha
huge
thingonRMI7
A:
Yes.RMIispartoftheJavalanguage,andalltheclassesfor
RMIareinthestandardlibraries.ServletsandJSPsare
not
partof
theJavalanguage;they'reconsidered
standardextensions.
You
canrunRMIonany
modernJVM,butServletsandJSPsrequirea
properlyconfiguredwebserverwithaservlet"container':Thisis
ourwayofsaying,"it'sbeyondthescopeofthisbook."Butyoucan
read
muchmoreinthelovely
HeadFirstServlets
&
JSp'
JustforfUt1,
lets
tMakethePhrase-O-Matic
workasaservlet
Nowthatwetoldyouthatwewon't
say
any
moreaboutservlets,
we
can't
resistservletizing(yes,we
am
verbify
it)
thePhrase--O-Maticfromchapter
1.
A
servlet
isstilljustJava.AndJavacode
cancallJavacodefromotherclasses.
Soaservletisfreeto
call
amethodon
thePhrase-O-Matic.Allyouhavetodo
is
dropthePhrase-O-Maticclassinto
thesamedirectoryasyourservlet,
and
you'reinbusiness.(ThePhrase-O-
Matie
codeisonthenextpage).
importjava.io.*;
importjavax.servlet.-;
importjavax.servlet.http.*;
remotedeploymentwith
RMI
Try
my
newweb-enabled
phrase-o-maticandyou'll
beaslicktalkerjustlike
thebossorthose
guys
in
marketing.
publicclassKathyServletextendsBttpServlet{
publicvoid
doGet
(HttpServletRequestrequest,BttpServletResponseresponse)
throwsServletException,IOException
Stringtitle
=
"PhraseOMatichasgeneratedthefollowingphras8.
H
;
response.setcontentType("text/html");
PrintWriterout
=
respons8.getWriter();
I
-l.
t4\\
",~od1
QI'\
out.printl.n(\\<HTML><HEAD><'l'ITLE>");
r:
r
\/OUI(
SfY"'~
td\'l
I
\1'
II
~
~ee.
T
I
tho
t4u
'fleve
U
1\'1;)
out.println("PhraseOmatio
H
);
ano1:.hey
t.\a~
\'I
I!>()
'~cKi
cJ
the
ou
t
.println("</TITLEX/HEAD><BOD'l>");
t,\\e
s-laBt.
",a\t.eP'nya.!>l'"
..,.t,
a
e}
out.println("<B1>"
+
title
+
"</81>");
P~ya1(OMdt iC.
tlau
(()f'I
thene
Y
~
out.prlntln("<P>"
+
Phr&seOMatic.makePhrass());
out.println(~<Pxa
href=\"KathyServlet\">makeanotherphrase</a></p>H);
out.println
("</BODY></BTML>");
out.close();
you
are
here
~
629
Phrase-O-Maticcode
Phrase-O-Maticcode,servlet-friet1dly
Thisisaslightlydifferentversionfromthecodeinchapterone.Inthe
original,werantheentirethinginamainOmethod,andwehadtorerun
theprogrameachtimetogenerateanewphraseatthecommand-line.Inthis
version,
thecodesimplyreturnsaString(withthephrase)whenyouinvoke
thestaticmakePhrase
0
method.Thatway,youcancallthemethodfromany
othercodeandgetbackaStringwiththerandomly-composedphrase.
Please
notethattheselongString[]arrayassignmentsareavictimofword-
processinghere-don'ttypeinthehyphens!Justkeepontypingandletyour
codeeditordothewrapping.Andwhateveryoudo,don'thitthereturnkeyin
themiddleofaString(i.e.somethingbetweendoublequotes).
publicclassPhraseOMatic{
publicstaticStringmakePhrase()
II
makethreesetsofwordstochoosefrom
String[]wordListOne
=
{"24/7","multi-Tier","30,OOOfoot","B-to-B","win-win","front-
end","web-based","pervasive","smart","six-sigma","critical-path","dynamic"};
String[]wordListTwo
=
{"empowered","sticky","valued-added","oriented","centric",
"distributed","clustered","branded","outside-the-box","positioned","networked","fo-
cused","leveraged","aligned","targeted","shared","cooperative","accelerated"};
String[]wordListThree
=
{"process","tippingpoint","solution","architecture",
"corecompetency","strategy","mindshare","portal","space","vision","paradigm","mis-
sion"};
II
findouthowmanywordsareineachlist
intoneLength
=
wordListOne.length;
inttwoLength
=
wordListTwo.length;
intthreeLengthwordListThree.length;
II
generate
intrandl
intrand2
intrand3
=
three
(int)
(int)
(int)
randomnumbers,topullrandomwordsfromeachlist
(Math.randomO
*
oneLength);
(Math.randomO
*
twoLength);
(Math.randomO
*
threeLength);
II
nowbuildaphrase
Stringphrase
=
wordListOne[randl]
+""
+wordListTwo[rand2]
+""+
wordListThree[rand3];
II
nowreturnit
return("Whatweneedisa"
+
phrase);
630
chapter18
RMIisgreatforwritingandrunningremoteservices.But
you
wouldn'trunsomethinglike
an
AmazonoreBayonRMI
alone.
For
a
large,deadlyserious,enterpriseapplication,you
needsomethingmore.Youneedsomethingthat
can
handle
transactions,heavyconcurrencyissues(likeagazillion
peoplearehittingyourserveratoncetobuythoseorganic
dogkibbles),security(notjustanyoneshouldhityour
payrolldatabase),
anddatamanagement.Forthat,youneed
an
enterpriseapplil;atUmserver.
Injava,thatmeansajava
2
EnterpriseEdition02EE)server.
AJ2EEserverincludesbothawebserverandanEnterprise
JavaBeans(EJB)server,
so
thatyou
can
deployanapplication
thatincludesbothservletsandEJBs.Likeservlets,EJEis
way
beyondthescopeofthisbook,andthere'snowayto
show"justalittle"EJE
examplewithcode,butwe
wiU
take
aquicklookathowitworks.
(Foramuchmoredetailed
treatmentofEJE,we
canrecommend
thelivelyHeadFirst
EJB
certificationstudyguide.)
remotedeployment
with
RMI
An
EJB
serveraddsabunch
of
services
that
you
don't
get
with
straight
RMI.
Things
like
transactions,
security.
concurrency.database
management.
and
networ"king.
An
EJB
server
steps
into
the
middle
of
anRMIcall
and
layers
in
all
of
theservices.
EJ'B
server:.-_---\-,--
.-
.....
'.
Thisisonlyasmall
paM
oftheE,JBpicture.!
youarehere
~
831
alittleJInI
Forourfinaltrick...alittleJini
Welovejini.Wethink]iniisprettymuchthebestthinginJava.IfE]B
is
RMI
onsteroids(withabunchofmanagers),JiniisRMIwith
wings.
PureJava
bliss.
LiketheEJBmaterial,wecan'tgetintoanyoftheJinidetailshere,but
if
you
knowRMI,
you'rethree-quartersofthe
way
there.Intermsoftechnology,
anyway,
Intermsof
mindset,
it'stimetomakeabigleap.No,it'stimeto
fl>'.
JiniusesRMI(althoughotherprotocolscanbeinvolved),butgivesyouafew
keyfeaturesincluding:
Adaptive
discovery
Self-healingnetworks
With
RMT,
remember,theclienthastoknowthe
nameandlocationoftheremoteservice.The
clientcodeforthelookupincludestheIPaddressor
hostnarneoftheremoteservice(becausethat'swhere
theRMIregistryisrunning)
and
thelogicalnamethe
service
was
registeredunder.
Butwithjini,theclienthastoknowonlyonething:
the
interfaceimplemented
by
the
service!
Tha
t
's
it.
Sohowdoyoufindthings?Thetrickrevolvesaroundjinilookup
services.
jini
lookupservicesarefarmorepowerfuJandflexiblethan
theRMIregistry.Foronething,jinilookupservicesannouncethemselvestothe
network,
automatically.
Whenalookupservicecomesonline,
it
sendsamessage(usingIP
multicast)
outtothenetworksaying,"I'mhere,ifanyone'sinterested."
Butthat'snot
all.
Let'ssayyou(aclient)comeonline
after
thelookupservicehasalready
announceditself,
you
cansendamessagetotheentirenetworksaying,"Arethereany
lookupservicesoutthere?"
Exceptthatyou'renotreallyinterestedinthelookupserviceitself-you'reinterestedin
theservicesthatare
registered
withthelookupservice.ThingslikeRMIremoteservices,
otherserializablejavaobjects,andevendevicessuchasprinters,cameras,andcoffee-
makers.
Andhere'swhereitgetsevenmorefun:whenaservicecomesonline,itwill
dynamically
discover(and
register
itselfwith)anyJinilookupservicesonthenetwork.Whenthe
serviceregisterswiththelookupservice,theservicesendsaserializedobjecttobeplaced
in
thelookupservice.Thatserializedobjectcanbeastubtoan
RMT
remoteservice,a
driverfora
networkeddevice,oreventhewholeserviceitselfthat(onceyougetitfrom
thelookupservice)runslocallyonyourmachine.Andinsteadofregisteringby
name,
the
serviceregistersbythe
interfacei:
implements.
Onceyou(theclient)haveareferencetoalookupservice,youcan
say
tothatlookup
service,"Hey,doyouhaveanythingthatimplementsScienuficf'alculator?"Atthatpoint,
thelookupservicewillcheck
its
listofregisteredinterfaces.andassumingitfindsa
match,saysback
to
you,"YesI
do
havesomethingthatimplementsthatinterface.Here's
theserializedobjecttheScientificCalculatorserviceregistered
with
me."
632
chapter
18
remotedeployment
with
RMI
Adaptivediscoveryi"actio"
@)
Jinilookupserviceislaunchedsomewhere
on
thenetwork,and
announcesitselfusingIPmulticast.
•
machIneonthenetwork
somewhere
...
An
already-runningJiniserviceon
anothermachineaskstoberegistered
with
thisnewly-announcedlookup
service.
It
registersbycapability,
ratherthanbyname.
In
otherwords,
itregisters
as
theserviceinterlaceit
implements.Itsends
a
serializedobject
tobeplacedinthelookupservice.
machineonthe
network
somewhere...
anothermachineonthenetwork
Register
meossomething
thatimplements
ScientificCaJculator.Here's
a
serialized
object
thatrepresents
myservice.Send
itto
anybody
whoasks...
anothermachineonthenetwork
youarehere.633
adaptivediscoveryinJini
Adaptivediscovery
itt
actio",co"thtued...
anothermachineonthenetwork
®
Aclientonthenetworkwants
something
thatimplementsthe
ScientificColculatorinterface.Ithas
noideawhere(or
if)thatthingexists,
so
itasksthelookupservice.
machineonthenetwork
somewhere
...
anothermachine
on
thenetwork
@
Thelookupserviceresponds,sinceitdoeshavesomething
registeredasaScientificCalculatorinterface.
machineonthenetwork
somewhere
...
634
chapter
18
anothermachineonthenetwork
remotedeploymentwithRMI
A
JiniServicehasaskedtoregisterwiththelookupservice.Thelookup
serviceresponds
witha"leese".Thenewly-registeredservicemustkeep
renewing
thelease,orthelookupserviceassumestheservicehasgone
offline.Thelookupservicewantsalwaystopresentanaccuratepicture
to
therestofthenetworkaboutwhichservicesareavailable.
Self...healit1Qt1etwork
it1
actio"
e
machineonthenetwork
somewhere..,
anothermachine
on
thenetwork
anothermachineon
thenetwork
®
Theservicegoesoffline(somebodyshutsitdown),soitfailsto
renew
itsleasewiththelookupservice.Thelookupservicedropsit.
machineonthenetwork
somewhere
...
anothermachineonthenetwork
youarehere
~
635
universalserviceproject
FhtalProject:theUt1iversalServicebrowser
We'regoingtomakesomethingthatisn'tjini-enabled,butquiteeasilycouldbe.
Itwillgiveyou
theflavorandfeelingofJini,butusingstraightRMI.Infactthe
maindifferencebetweenourapplicationandaJiniapplicationishowtheserviceis
discovered.Insteadofthe
Jinilookupservice,whichautomaticallyannouncesitselfand
livesanywhereonthenetwork,we'reusingtheRMIregistrywhichmustbeonthesame
machineastheremoteservice,andwhichdoesnotannounceitselfautomatically.
Andinstead
ofourserviceregisteringitselfautomaticallywiththelookupservice,
we
havetoregisteritintheRMlregistry(usingNaming.rebind()).
Butoncetheclienthasfoundtheservicein
theRMIregistry,therestoftheapplication
is
almostidenticaltothewaywe'ddoitinJini.(Themainthingmissing
is
thekasethat
wouldletushaveaself-healingnetworkifanyoftheservices
go
down.)
Theuniversalservicebrowser
is
likeaspecializedwebbrowser,exceptinsteadofHTML
pages,
theservicebrowserdownloadsanddisplaysinteractiveJavaGUIsthatwe're
calling
uniuersalservices.
RMIBrowser
Choosea
~Ite
k'f'ol'l\
the
listTheRMI
TC"'oU:
W"\IiU
has
a
~~\IiteList.O
...cthod-th.it
~N:Js
batK
this
list.
o-t
SCT\litcs.
WheJI+.hc
\!Sa'
~Ieth
OYIC,
-the
tl,
eJI
t.asks
.f
0\'"
the
ad;\oIG1
scrvitc
cDil.eRolli,,~
Da'l0fneWccK
J
e+.tJ
to
be
~t
batlt.
~'f'0ft\
the
RMI
yt"'oU:
W"\/itc.
636
chapter18
How
it
works:
CIientstartsupand
doesalookupon
the
RMI
registryfor
theservicecalled
"Service.Server",and
getsbackthestub.
ServiceBrowser
(client)
remotedeploymentwithRMI
Server
ClientcallsgetServiceListOonthestub.TheServiceServer
returnsanarrayofservices
ServIceBrowser
(client)-
"getServiceListO∙
-
"OK,
here'sanarrayofservices"
•Clientdisplaysthelistofservicesina
GUI
ServiceBrowser
(client)
Server
~==
Server
youarehere.631
universalservicebrowser
Howitworks,continued...
•
Userselectsfromthelist,soclientcallstheget5erviceO
methodon
theremoteservice.Theremoteservicereturnsa
serialized
objectthatisanactualservicethatwillruninside
theclientbrowser.
'getService(selectedSl/ct
'OK,here's
theservice-
Server
•ClientcallsthegetGuiPanelOontheserializedserviceobjectit
justgotfromtheremoteservice.TheGUIforthatserviceis
displayedinside
thebrowser,andtheusercaninteractwithit
locally.Atthispoint,wedon'tneedtheremoteserviceunless/until
theuserdecidestoselectanotherservice.
ServiceBrowser
(client)
638
chapter18
remotedeployment
with
RMI
Theclassesandinterfaces:
interfaceServlce.ServerImplementsRemote
AregularoldRMIremoteinterlacefortheremoteservice(the
remoteservicehasthemethodforgettingtheservicelistand
returninga
selectedservice).
Servlc9Server
gelServicesUslO
gelServlceO
•classServlceServerImplImplements5ervlceServer
TheactualRMIremoteservice(extendsUnicastRemoteObject).
Itsjobistoinstantiateandstorea/ltheservices(thethings
thatwillbeshippedtotheclient),andregistertheserveritself
(ServiceServerImpJ)withtheRMIregistry.
ServlceServerlmpl
gelServicesListO
gelServiceO
3'classServlceBrowser
Theclient.
It
buildsaverysimpleGUI,doesalookupintheRMI
registrytogettheService5erverstub,thencallsaremotemethodon
it
togetthelistofservicestodisplayintheGUIlist.
ServlceBrowser
mainO
MlnlMuslcServlce
gelGulPanelO
S&lVlce
~
"
.
'
..
.
,
.
,
.
.
"I"
,
.
.
,II
,
,
.
,
,
.
,
,
.
,
,
.
,,
.
,,
.
,
,
.
/I....
getGuiPaneJO
..
r------....
.
.
.
.
.
.
.
.
.
:DiceServlce
....gelGulPanelO
.
,
,
.
.
,
,
,
DayOfTheWeekServlce
gelGuiPanelO
class
Dic£5erviceimplementsService
Gotdice?Ifnot,butyouneedsome,usethisservicetorollanywhere
from
1
to
6
virtualdice.foryou.
class
MlnlMusicServiceimplementsService
Rememberthatfabulouslittle'musicvideo'programfromthefirst
GUICodeKitchen?We'veturneditintoaservice,andyou
can
playit
r----'-----~
overandoverandove.runtilyourroommatesfinallyleave.
InterfaceService
Thisisthe
key
toeverything.Thisverysimpleinterfacehas
just
one
method,getGuiPanelO.Every
servicethotgetsshippedovertothe
clientmustimplementthisinterface.Thisiswhatmakesthewholething
UNIVERSAL!
By
implementingthisinterface,aservicecancomeover
eventhough
theclienthas
noideo
whattheactualclass(orclasses)
arethatmakeupthatservice.
All
theclientknowsisthatwhatever
comesover,itimplementstheServiceinterface,soitMUSThovea
getGuiPanelOmethod.
Theclientgetsaserializedobjectasaresultofcalling
getService(selectedSvc)ontheService5erverstub,andalltheclient
saysto
thatobjectis,
"r
don'tknowwhoorwhatyouare,but
IDO
knowthatyouimplementtheServiceinterface,soIknowIcancall
getGuiPanelOonyou.AndsincegetGuiPanelO
returnsaJPanel,rlljust
slapitintothebrowserGUIandstartinteractingwithitl
•classDayOfTheWukSuviu
ImplementsSuvlce
WereyoubornonaFriday?Typeinyourbirthdayandfindout.
youarehere.639
universalservicecode
interfaceServiceServer(theremoteinterface)
importjava.rmi.*;
publicinterfaceServiceServerextendsRemote(
Object[]getServiceList()throwsRemoteException;
ServicegetService(ObjectserviceKey)throwsRemoteException;
publicinterfaceServiceextendsSerializable{
publicJPanelgetGuiPanel();
640chapter
18
remotedeploymentwith
RN
assServiceServerlmpl(theremoteImplementation)
java.rm.i.*;
java.util.*;
java.
rm.i.
server.•;\
RM\
'l"'f\tl'l\tn~bOt'l
A
\"\O'I'",a
publicclassServiceServerImpl
extends
UnicastRemoteObjectimplementsServiceServer
BashMapserviceList;
publicServiceServerImpl()throwsRemoteException
I
setUpServices();
.'bal
iu
tht
ad:.u.al)
~1
..
d.D'r
i~
taIled,
'~I
.
M~itS~:r.il{,t.,
dt..
V/'h(.Yt
the
t..
CDit.tStY~iU)
M,nI
private
voidsetUpServices()(._"\
~e.YV~t.es
...
nIV(;,'~
serviceList
=
new
BashMap();
service.List.put("DiceRollingService",
new
DiceService();
servlceList.put
("Day
oftheWeekService"
I
newDayOfTheWHkService());
serviceLlst.put("VisualMusicService",newMiniMusicService());
.u
~
L\..6
KyVit.e.~
(the.
at~~I\..K"""1
MaKe.
V'"
tt\olc.'"
''''1v>
v>c.
r
o'oy:tb)
a~
flo'
sh"',,,~
I\il....
e
(-to'!"
~as\olMa~J
WItha
the.
'KC'/).
publicObject£]getServiceList(){
Client.t.alts
.1,..
S
tern
t
.
tl('"
te")
"UlJSIn
oraet-
f.o
Q....L/•
.L
f'
ys..ou.
~rl.n.
nanr6ltlO;
display
in
the
bro
;)Cl:
a
Ib~
O't
s~viles
f.o
returnservJ..ceLJ..st.keySet(),toArray();
~
d
r
wsa-
(s.o
t.he
lI.S~
tan
~1.1.
)
h
iln
array
o-t
f.
e
Ob'
t
e...
l;
oneWe
~
il'lSiae)
by
"'d
kin
9
a!:rrd
~:f
.(eva.
th~h
ii:
has
S&-il'l~s
j..
the
lf~lhN!ap.
We
,'Y
JlI.St
the
i(EYS
t.h~f.
a"e
I
f.
J
W<»It
lCha
~n ~lt."~1
C'-•
LAn
eLl;
he
diePlt
asks
.for
;1
b.-..
~.,.v'te
objai
l;
y
l.dJlln~
gef.StrvileO.
public
staticvoidmain
(Strinq[]arqa){
tty{
Naminq.rebind("ServiceServer",newServic:eServerImpl(»:
catch(Exception
ex)(
ex,printStackTraoe();
}
Syst&m.out.println("Ramotesarviceisrunning");
youarehere.
64
ServlceBrowsercode
classServlceBrowser(theclient)
import
java.awt.∙i
importjavax.
swing.
*
i
~rt
java.rmi.*i
import
java.awt.event.*;
publicclassSarviceBrowsar
JPanelmainPanel;
JComboBoxserviceList;
ServlceServer
server;
publicvoidbuildGUI()(
JFrameframe
=
new
JFrame(~RMI
Browser
H
);
mainPanel
D
newJPanel();
frame.geteontentPane().
add
(BorderLayout.CEN'rEll,mainPanel);
.~
lQOku.\,'
-e'nis
Method
o~s -e'n~\~~iteL.irtO.
~j.ot[]
••
~i~~.M;:dd:'~:~::::~~t;~\_ ~
servlceList
=
newJCombo80x(services);
JCorr-bo~
(the
\~~.n~
cJ
eat'n
thi~
',,,
theoYTd'1'
Mav-e
disylcl'1cl\'le
Sh,~
fr8llMi.getcontentpane().
add
(BorderLayout.NOR'l'B,serviceList);
serviceList.addActionListener(new
MyListL1stener(»;
frame.setSize(SOO,500);
frama.setVisible(true);
642
chapter18
remotedeploymentwith
RMI
Object[]getServicesList(){
Objectobj
=
null;
Object[]services
=
null;
try{
obj
=
Naming.lookup(~rmi://127.0.0.1/ServiceServer");
)
catch(Exceptionex){
ex.printStackTrace();
}
~
server
=
(ServiceServer)obj;
CastthestlAb
to
th
so
thatwetalltalle
~".o~e
illtertatetype
~e
ervlteListO
Oil
it'
try{
services
=
server.getServiceList();
~
__
catch(Exceptionex){
ex.printStackTrace();
returnservices;
~d:.set'viteLis ·W ~ives
lAStheat't'ay
0+
Objetts,
-ChatwedisplayintheJCoMboBo'/C.tOt'HielASet'
to
seletttt'OI'l\.
}
classMyListListenerimplementsActionListener{
publicvoidactionPerformed(ActionEventev){
publicstaticvoidmain(String[]args)
newServiceBrowser().buildGUI();
youarehere.643
DiceServicecode
classDiceService(auniversalservice,implementsService)
eee
lUIllflD'Vrltt
Dlullolll"9_.
-
- ~
fT.1Wl
'=
SH
-
JLabellabel;
JComboBoxnumOfDice;
publicJPanelgetGuiPanel()(
JPanelpanel
=
newJPanel();
JButtonbutton
=
newJButton("Roll'em!");
String[]choices
=
{"I","2","3","4",
"5
H
};
numOfDice
=
newJComboBox(ohoices);
label
=
newJLabel("dicevalueshere");
button.addActionListener(newRol1EmListener(»;
panel.
add
(numOfDice);
ftt:r'th.
panel.
add
(button);
St:r:i:i
f..t:
C»Il'",POl"idl'r
t
",tthod!
nt:",eihod
0+
tht:
panel.
add
(label);
thil
S~i~t:
:
a~e--;_
v'e
07It:
t.hedibrt's901\1Id
~II
whtrl
returnpanel;.....
a
t∙.1'
SZ}t
ua
andloaded.
y
rAJ,
u"
do
whdie
l\
In
tne
~t:u:jlliPa"eJO
eihodI
vty
y04l.
JPal'u~"
$(I
itbioi/as
tht:
at.t.:~1
d"
J
as
II~n~ ~s
you
retur"a
-
Ilt-ro,~
'-JUt.
publicclassRollEmListenarimplementsActionListener{
publiC!voidaotionPerfo:rmed(ActionEvent
ev){
/I
roll
the
dice
StringdiceOutput
="";
Stringselection
=
(String)numOfDice.get5electedItem():
intnumOfDiceToRoll
=
Integer.parselnt(selection);
for(inti
=
0;
i
<
numOfDiceToRoll;i++)(
int
r
=
(int)
((Math.
random()
*
6)
+
1);
diceoutput
+=(""
+
r);
publicclassDiceServiceimplementsService(
importjavax.swing.∙;
importjava.awt.event.*;
importjava.io.*;
)
label.setText(diceOUtput);
~arpen
your
penCil
ThinkaboutwaystoimprovetheDiceService.One
suggestion:usingwhatyoulearnedInthe
GUIchapters,
makethedice9raphicaI.
Usearectangle,anddrawthe
appropriatenumberof
circlesoneachone,correspondIng
totherollforthatparticulardie.
1---1
•
•
644
chapter18
remotedeploymentwithRMI
classMlnlMusicService(auniversalservice,implementsService)
1'i.~.o.!~6~ ~= ~"'~-~ ~ ==;:~
~w...
.............
import
j
avax.sound.
midi...;
importjava.io.*;
importjavax.sving.*;
illlport
java.art.*;
illlport
java.awt.event.*;
publicclauMiniMusicServiceimplementsService{
I
/'t..\\
°rt
-n...
~.,.\iLt,~
",rt
h06
.
L__
6
MyDrawPanelmyPanel;
r
In<..
d'sola'ol
il
D~~
a"
does's
'\
I.
lot
(..,httr(
t.h
,h·a\Oli,,~ ~'f"'I'tu.a\\~
publicJPanelgetGuiPanel()(
e
ta~lt.S
..,tIl
C\l~
JPanelmainPanEll
=
newJPanel();
thC
"'~\.edJ
myPanel
=
newMyDrawPanel();
~
ya,".
JButtonplayltButton
=
newJButton("Playit
N
);
playItButton.addActionLiatener(ne.PlayItLlstener());
mainPanel.lldd(myPanel);
mainPanel.lldd(playItButton);
returnmainPanel;
publio
class
PlayItListenerimplementsActionLiatener
publievoid
actionPerfo~(ActionEvent
ev)(
try(
Sequencersequencer
=
MidiSystam.qetSequencer();
sequencer.open();
sequencer.addControllerEventLiatener(myPanel,newlnt[](127»);
Sequenceseq
=
newsequence(Sequence.
PPQ,4);
Tracktrack
=
s&q.creataTrack();
for(lnt
i
=
0;
i
<
100;
i+=
4){
lntrNum
=
(int)
«(Math.random()
*
50)
+
1);
if(rNum<39)(
II
sonowonlydoit
if
num<38(15\ofthe
time)
track.add(makeEvent(144,l,rNum,lOO,l»);
track.add(makeEvent(116,l,121,O,i));
track.add(makeEvent(128,l,rNum,lOO,1
+
2»;
)
II
endloop
sequencer.aetSequence(seq);
sequencer.start();
sequencer.setTampoInBPM(220);
catch
(Exceptionex)(ax.printstackTrace();}
}1/
closeactionperfor=ed
)II
closeinnerclass
youarehere.
645
MiniMuslcServlcecode
classMiniMusicService,continued••.
publicMidiEventmakeEvent(intcomel,intchan,intone,inttwo,inttick){
MidiEventevent
=
null;
try(
ShortMessagea
=
newShortMessage();
a.setMessage(comel,chan,one,two);
event
=
newMidiEvent(a,tick);
}catch(Exceptione){}
returnevent;
classMyDrawPanelextendsJPanelimplementsControllerEventListener
II
onlyifwegotaneventdowewanttopaint
booleanmag
=
false;
publicvoidcontrolChange(ShortMessageevent){
msg
=
true;
repaint
0;
publicDimensiongetPreferredSize()
returnnewDimension(300,300);
publicvoidpaintComponent(Graphicsg){
if(msg){
Graphics2Dg2
=
(Graphics2D)g;
intr
=
(int)(Math.random()
*
250);
intgr
=
(int)(Math.random()
*
250);
intb
=
(int)(Math.random()
*
250);
g.setColor(newColor(r,gr,b»;
intht
=
(int)«Math.random()
*
120)
+
10);
intwidth
=
(int)«Math.random()
*
120)
+
10);
=
(int)«Math.randomO
*
40)
+
10);
(int)«Math.random()
*
40)
+
10);
intx
inty
=
g.fillRect(x,y,ht,width);
mag
=
false;
}II
close
if
}II
closemethod
}II
closeinnerclass
II
closeclass
remotedeployment
with
RMI
classDayOfTheWeekService(auniversalservice,ImplementsService)
importjavax.swing.-;
importjava.awt.event.∙;
importjava.awt.*;
importjava.lo.∙;
importjava.util.*;
importjava.text.•:
publicclassDayOfTheWeekServicElimplementsService(
,.e9:"............
D.rroln......
s-w..
~
-..,....
~ I
...
0.,
IF
.~ ~..,
....jlOOI
I
JLabeloutput:Labe1;
JComboBox
month;
JTextFleldday;
J'l'extFieldyear;
public.
JPanelqetGuiPanel()(
JPanelpanel""newJPanel();
JButtonbutton""new
JButton(~Do
it!");
button.addAetionListener(newDoltListener(»;
outputLabel.""new.JLabel
("date
appearllhe.ra");
DateFormatsymbolsdataStuff
=
newDateFonaatsymbols();
month
=
newJComboBox(dateStuff.g8tMOnthll{»;
day""newJTextField(8);
year;:newJ'l'extField(8):
JPanelinputpanel;:newJPanel(newGriciLayout(3,2));
inputPane1.add(newJLabel("Month");
inputpanel.add(month);
inputPanel.add(newJLabel("Day"));
inputPanel.add(day);
inputPanel.add{newJLabel("Year"»;
inputPanel.ac1d(year);
panel.add(inputpanel):
panel.add(button);
panel.add(outputLabel);
returnpanel;
publicclassDoItLlstenerimplementsA.ctionLilltener
J
O\l
"etd
Cl....
e....i"dev
publicvoidaotionPerformed(ActionEvent
&V)(
R
~O"
to
t'hayUY
10
-\:.t:'1
~~t.t,,~""o'r\t.~
intmonthNum
==
month.getselectedIndexO;;
h
"",,'olY
a",dd
6
H
t.
ho""
e"'lY,
lntdayNum•Integer.paraeInt(day.qatTextO);
n\
~e
is
t\'~"'t\~ ~\;~\ass-
Aho.
the
intyearNum::Integer.parselnt(year.getTaxt());\)
11
u.st.
it.
lASt>
the
Ca
IoU
1
tt.i~'1
a
fott.ern
Calendar
0•
Calendar.qetInst&nce();
et.4
\tDa~f~t\~d\"~,,t
",,-l:.,
c•set(Calendar.MONTH
J
monthN\DJl):
f
~""'f ~
t,nt
dw
t"'''''
f
c.set(Calendar.DAY_OF_MONTH
I
dayNum);
CIf
c.set(Calendar.YEAR,yearNum):
Datedate::c.qetTime();
StringdayOfWeelt;:(newSimplaDataFor:JUt
("EEEE
N
))•
format
(date):
outputLabel.setText(dayOfW&elt);
youarehere
~
647
theend...
sortof
Congratulations!
You
made
it
totheend.
Of
course,there'sstilithe
two
appendices.
AndtheIndex.
Andthenthere'sthe
web
site•••
There'snoescape,really.
648
hapter18
*
AppendixA:
Final
Code
Kitchen
*
Chris:groove2revised
NIgel:dance
beat
FinaLLy,
the
completeversion
01
theBeatBox!
It
connects
to
asimpleMusicServersothat
you
can
sendandreceive
beat
patternswithotherclients.
thisisanewappendix
649
finalBeatBoxcode
FinalBeatBoxclientprogram
MostofthiscodeisthesameasthecodefromtheCodeKitchensintheprevious
chapters,sowedon'tannotatethewholethingagain.Thenewpartsinclude:
GUI-twonewcomponentsareaddedforthetextareathatdisplaysincoming
messages(actuallyascrollinglist)andthetextfield.
NETWORKING-justliketheSimpleChatClientinthischapter,theBeatBoxnow
connectstotheserverandgetsaninputandoutputstream.
THREADS-again,justliketheSimpleChatClient,westarta'reader'classthat
keepslookingforincomingmessagesfromtheserver.Butinsteadofjusttext,the
messagescominginincludeTWOobjects:theStringmessageandtheserialized
ArrayList(thethingthatholdsthestateofallthecheckboxes.)
importjava.awt.*;
importjavax.swing.*;
importjava.io.*;
importjavax.sound.midi.*;
importjava.util.*;
importjava.awt.event.*;
importjava.net.*;
importjavax.swing.event.*;
publicclassBeatBoxFinal
JFrametheFrame;
JPanelmainPanel;
JListincomingList;
JTextFielduserMessage;
ArrayList<JCheckBox>checkboxList;
intnextNum;
Vector<String>listVector
=
newVector<String>();
StringuserName;
ObjectOUtputStreamout;
ObjectInputStreamin;
HashMap<String,boolean[]>otherSeqsMapnewHashMap<String,boolean[]>();
Sequencersequencer;
Sequencesequence;
SequencemySequence
=
null;
Tracktrack;
String[]instrumentNames
=
{~Bass
Drum",
~Closed
Hi-Hat",
~Open
Hi-Hat","Acoustic
Snare",
~Crash
Cymbal",
~Hand
Clap",
~High
Tom",
~ H i
Bongo",
~Maracas",~Whistle",
~Low
Conga",
~Cowbell",~Vibraslap",~Low-mid
Tom",
~High
Aqogo",
~Open
HiConga");
int[]instruments
=
{35,42,46,38,49,39,50,60,70,72,64,56,58,47,67,63);
650appendixA
appendixAFinalCodeKitchen
staticvoidmain(String[]args)(
BeatBoxFinal().startUp(args[O]);
II
args[O]isyouruserID/screenname
fI\
l.f
\J 0~ V-
stv-eeYlYla",e∙
""-----AdO.a
t..o",....
aYlo-liYle
a v-~ ~",e Yl1;.
ov-
I
c
I'
01
'ava0eatBo'l-f=iYlalthef=lash
...'/.cl....
y
e∙
ID
j[}
public
new
publicvoidstartup(Stringname){
userName
=
name;
II
openconnectiontotheserver
try(
Socketsock
=
newSocket("l27.0.0.l",4242);
out
=
newObjectOutputStream(sock.getOUtputStream(»;
in
=
newObjectInputStream(sock.getInputStream(»;
Threadremote
=
newThread(newRemoteReader(»;
remote.start
0;
catch(Exceptionex)(
System.out.println("couldn'tconnect-you'llhavetoplayalone.");
}
setupMidi
0;
buildGUI();
II
closestartUp
publicvoidbuildGUI()
~lA.1
tode,
Ylot h iYl~
Yle-."hev-e
theFrame
=
newJFrame("CyberBeatBox");
BorderLayoutlayout
=
newBorderLayout();
JPanelbackground
=
newJPanel(layout);
background.setBorder(BorderFactory.createEmptyBorder(10,10,10,10»;
checkboxList
=
newArrayList<JCheckBox>();
Box
buttonBox
=
newBox(BoxLayout.Y_AXIS);
JButtonstart
=
newJButton("Start");
start.addActionListener(newMyStartListener(»;
buttonBox.add(start);
JButtonstop
=
newJButton("Stop");
stop.addActionListener(newMyStopListener(»;
buttonBox.add(stop);
JButtonupTempo
=
newJButton("TempoUp");
upTempo.addActionListener(newMyUpTempoListener(»;
buttonBox.add(upTempo);
JButtondownTempo
=
newJButton("TempoDown");
downTempo.addActionListener(newMyDownTempoListener(»;
buttonBox.add(downTempo);
JButtonsendlt
=
newJButton("sendIt");
sendlt.addActionListener(newMySendListener(»;
buttonBox.add(sendIt);
userMessage
=
newJTextField();
youarehere
~
651
finalBeatBoxcode
buttonBox.add(userMessage):
Box
namaBox::;
new
Box
(BoxLayout.'i_AXIS)
i
for(int
i
=
0;
i
<
16;
i++){
nameBox.
aeld(naw
Label
(i.nst%UmentNames
[i]»;
background..
add
(Bord.erLayout.EAST,
buttonBox)
i
background..add(Bord.erLayou
t.
WEST,
nameBox);
theFrame.
qetContentpane().
add.(background);
GridLayoutgrid'"newGridLayout(16,16);
grid.aetVgap
(1);
grid.setHqap(2):
mainPanel'"
new
.Ji'anel
(grid):
background.add
(BorderLayout.CENTER,
UlA1nPanel);
for(inti'"0;
i
<
256;i++)(
JCheckBoxc'"newJCheck.Box();
c.setse1ected(false);
checkboxList.add.(c);
DIlU.nPanel.add.
(c);
II
end
loop
theFrAmQ.aetBounds(50,50,300,300);
theFrAmQ.pack();
theFrame.setVisible(true);
II
closebuildGUI
publicvoid.setUpMidi()
try(
sequencer
IS
MidiSystem.getSequencer()
i
sequencer.open();
sequence
IS
newsequence(Saquence.PPQ,4);
track'"sequance.areateTrack();
sequencer.setTempolnBPM(120);
catch(Exceptione)(e.printstackTrace();)
II
closesetUpMldi
652
appendix.
A
appendixAFinalCodeKitchen
for(inti
=
0;i<16;i++){
II
becausethisslotshouldbeemptyinthetrack
trackList
=
newArrayList<Integer>();
publicvoidbuildTrackAndStart(){
ArrayList<Integer>trackList
=
null;
sequence.deleteTrack(track);
track
=
sequence.createTrack();
II
thiswillholdtheinstrumentsforeach
hthet..het.k'ooi-t
S
'0
'fIo\k i\'\~ thY"o~
t
t
to
a\'\
?J",M
0kO,t.kSJteloYlO
.,..aYYMi~~,chl/~ Yl t
koY"
.o.
L
to
«jtt"flt
l
C
\'\0
",okiYl~
the.
1~ 1r;,.
ACTL.:'!oSi"
i\'\stv-",,,,e\'\t
~.
•o\e1'o,b",tIt
IS ~ )<
L
oY"el/iol.lS
.et,,\1..
0"',
L
Y"eteY"
"IP,
T\oils'SyY"
'r.
t.hay"eY"s,so
L'
a ~aiYl.
.theyyel/lOI.lS
LLL
f'"'\\
ei-y\aYlo"IOYl
'fIoS
1\'\•
to
~e"
"fie
-t
for(intj
=
0;j<16;j++){
Code~l tt..he\'lS
JCheckBoxjc
=
(JCheckBox)checkboxList.get(j+(16*i»;
if(jc.isSelected(»(
intkey
=
instruments[i];
trackList.add(newInteger(key»;
else{
trackList.add(null);
}
}II
closeinnerloop
makeTracks{trackList);
}II
closeouterloop
track.add(makeEvent{192,9,1,0,15»;
II-
sowealwaysgotofull16beats
try{
sequencer.setSequence(sequence);
sequencer.setLoopCount(sequencer.LOOP_CONTINUOUSLY);
sequencer.start();
sequencer.setTempolnBPM{120);
}catch(Exceptione){e.printStackTrace();}
}II
closemethod
publicclassMyStartListenerimplementsActionListener
publicvoidactionPerformed(ActionEventa){
buildTrackAndStart();
}II
closeactionPerformed
II
closeinnerclass
publicclassMyStopListenerimplementsActionListener
publicvoidactionPerformed(ActionEventa)(
sequencer.stop();
}II
closeactionPerformed
II
closeinnerclass
publicclassMyUpTempoListenerimplementsActionListener
publicvoidactionPerformed(ActionEventa){
floattempoFactor
=
sequencer.getTempoFactor();
sequencer.setTempoFactor«float)(tempoFactor*1.03»;
}II
closeactionPerformed
II
closeinnerclass
youarehere.653
finalBeatBoxcode
publicclassMyDownTempoListener
~lements
ActionListener
publicvoidactionPerformed(ActionEventa){
fioattempoFactor
=
sequencer.getTempoFactor();
sequencer.setTempoFactor«fioat)(tempoFactor
*
.97»;
publicclassMySendListenerimplementsActionListener(
publicvoidactionPerformed(ActionEventa){
II
makeanarraylistofjusttheSTATEofthecheckboxes
boolean[]checkboxState
=
newboolean[256];
for(inti
=
0;i
<
256;i++){
JCheckBox
check
=
(JCheckBox)
if(check.isSelected(»{
checkboxState[i]
=
true;
}
}II
closeloop
StringmessageToSend
=
null;
try{
out.writeObject(userName+nextNum+++"."+userMessage.getText(»;
out.writeObject(checkboxState);
catch(Exceptionex){
System.out.println("Sorrydude.Couldnotsendittotheserver.");
}
userMessage.setText("");
}II
closeactionPerformed
II
closeinnerclass
publicclassMyListSelectionListenerimplementsListSelectionListener
publicvoidvalueChanged(ListSelectionEventle){
if(!le.getValueIsAdjusting(»{
Stringselected
=
(String)incomingList.getselectedValue();
if(selected
!=
null)(
II
nowgotothemap,andchangethesequence
boolean[]selectedState
=
(boolean[])otherSeqsMap.get(selected);
changeSequence(selectedState);
sequencer.stop();
buildTrackAndStart();
}
II
closevalueChanged
II
closeinnerclass
654appendixA
appendixAFinalCodeKitchen
publicclassRemoteReaderimplementsRunnable{
boolean[]checkboxState=null;
StringnameToShow=null;
Objectobj=null;
publicvoid
rune){
try{
while«obj=in.readObject(»!=null){
System.out.println("gotanobjectfrom
System.out.println(obj.getClass(»;
StringnameToShow=(String)obj;
checkboxState=(boolean[])in.readObject();
otherSeqsMap.put(nameToShow,checkboxState);
listVector.add(nameToShow);
incomingList.setListData(listVector);
}IIclosewhile
catch(Exceptionex){ex.printStackTrace();}
IIcloserun
IIcloseinnerclass
W~~II
a
~esS4
(deseriaJi~) {h~
t:
ill,lIIe
read
~~ssage
alld.L
e1110
ob
ietL(
thetkb.
,;he
Arra
c:
rsthe
the
JL~~
stau
val lAe sf~
Ids+,
0+
Boo/
ea
ll
.JC
to~p
.L
I'l
tidd∙.L
J
IS
a
1;111
U
Ohen,;.
Add'
I,;1;0
0+
the!:;ts
pthil'l.9:
'lOlA
k
1
11
9
to
a
JList
fashioned
A
data!Vetto
:~p
a
Vettor
JList
to
rrayLisi)a;
't.
an
oJd_
.for
wh
t
lAse
thai.
Ve~k
hen
t~ 1J
th
publicclassMyPlayMineListenerimplementsActionListener{
a
to
display'.Lasit's
SOIA
e
publicvoidactionPerformed(ActionEventa){
III
,;h~
lisi..
r t~
if(mySequence!=null){
sequence=mySequence;
II
restoretomyoriginal
All
the
MIDI
shHis
~uttl~
theSaMeasit
wasintheyYe'JiolAS'Jet-Slon.
This
Ift~thod
is
tailed
h
t
sO lft ethin~
.ft-Olftth
I'
i
~
he
lASerseletts
checkboxSta~,n~
the
patter:;;.fhe/NI'j1hf;[)/ATE.LY
eone..eyseletted.
checkboxList.get(i);
}
}IIcloseactionPerformed
IIcloseinnerclass
}
IIcloseloop
II
closechangeSequence
publicvoidchangeSequence(boolean[]
for(inti=0;i
<
256;i++){
JCheckBoxcheck=(JCheckBox)
if
(checkboxState[i]){
check.setSelected(true);
else{
check.setSelected(false);
publicvoidmakeTracks(ArrayListlist)
Iteratorit=list.iterator();
for(inti=0;i
<
16;i++){
Integernum=(Integer)it.next();
if(num!=null){
intnumKey=num.intValue();
track.add(makeEvent(144,9,numKey,100,i»;
track.add(makeEvent(128,9,numKey,100,i+1»;
}
}II
closeloop
II
closemakeTracks()
you
are
here.
655
._-
---------
finalBeatBoxcode
publicMidiEventmakeEvent(intcomd,intchan,intone,inttwo,inttick){
MidiEventevent
=
null;
try{
ShortMessagea
=
newShortMessage();
a.setMessage(comd,chan,one,two);
event
=
newMidiEvent(a,tick);
}catch(Exceptione}{}
\i~e
thelast
~e'f"si()'l\·
returnevent;
Not\\'''~
"eVl∙
J~t
}II
closernakeEvent
}II
closeclass
~yourpenCii
Whataresomeofthewaysyoucanimprovethisprogram?
Hereareafewideastogetyoustarted:
1)Onceyouselectapattern,whatevercurrentpatternwasplayingis
blown
away.Ifthatwasanewpatternyouwereworkingon(oramodificationof
anotherone),you'reoutofluck.Youmightwanttopopupadialogboxthat
askstheuserifhe'dliketosavethecurrentpattern.
2)Ifyoufailtotypeinacommand-lineargument,you
justgetanexception
whenyourunit!Putsomethinginthemainmethod
thatcheckstoseeif
you'vepassedinacommand-lineargument.Iftheuserdoesn'tsupplyone,
eitherpickadefaultor
printoutamessagethatsaystheyneedtorunit
again,
butthistimewithanargumentfortheirscreenname.
3)It
mightbenicetohaveafeaturewhereyoucanclickabuttonandit
willgeneratearandompatternforyou.Youmighthitononeyoureallylike.
Betteryet,haveanotherfeature
thatletsyou
load
inexisting'foundation'
patterns,likeoneforjazz,rock,reggae,etc.
thattheusercanaddto.
YoucanfindexistingpatternsontheHeadFirstJavawebstart.
656appendixA
appendixAFinalCodeKitchen
FinalBeatBoxserverprogram
MostofthiscodeisidenticaltotheSimpleChatServerwemadeinthe
NetworkingandThreadschapter.Theonlydifference,infact,isthatthisserver
receives,andthenre-sends,twoserializedobjectsinsteadofaplainString
(althoughoneoftheserializedobjectshappensto
be
aString).
importjava.io.*;
importjava.net.*;
importjava.util.*;
publicclassMusicServer
ArrayList<ObjectOutputStream>clientOutputStreams;
publicstaticvoidmain(String[]args){
new
MusicServer().go();
publicclassClientHandlerimplementsRunnable{
ObjectlnputStreamin;
SocketclientSocket;
publicClientHandler(Socketsocket)(
try{
clientSocket
=
socket;
in
=
newObjectlnputStream(clientSocket.getlnputStream(»;
catch(Exceptionex)(ex.printStackTrace();}
}II
closeconstructor
publicvoidrun{}{
Object02
=
null;
Object01
=
null;
try{
while((01
=
in.readObject(»
!=
null)(
02
=
in.readObject();
System.out.println("readtwoobjects");
tellEveryone(01,02);
II
closewhile
catch(Exceptionex)(ex.printStackTrace();}
II
closerun
II
closeinnerclass
youarehere
~
657
finalBeatBoxcode
publicvoid
qo(){
clientOutputStreams
=
newArrayList<ObjectOutputStream>();
try{
ServerSocketserverSock
=
newServerSocket(4242);
while(true){
SocketclientSocket
=
serverSock.accept();
ObjectOutputStreamout
=
newObjectOutputStream(clientSocket.qetOutputStream(»
clientOutputStreams.add(out);
Threadt
=
newThread(newClientHandler(clientSocket»;
t.start();
System.out.println("qotaconnection");
}
}catch(Exceptionex){
ex.printStackTrace();
}
II
closego
publicvoidtellEveryone(Objectone,Objecttwo)
Iteratorit
=
clientOutputStreams.iterator();
while(it.hasNext(»{
try{
ObjectOutputStreamout
=
(ObjectOutputStream)it.next();
out.writeObject(one);
out.writeObject(two);
}catch(Exceptionex){ex.printStackTrace();}
II
closetellEveryone
}II
closeclass
658
appendix
A
AppendixB
TheTopTenTopicsthatalmostmadeitintotheRealBook...
Wecoveredalotofground,andyou'realmostfinishedwiththisbook.We'llmissyou,butbefore
weletyougo,wewouldn'tfeelrightaboutsendingyououtIntoJavaLand
withoutalittlemore
preparation.Wecan'tpossibly
fiteverythingyou'llneedtoknowIntothisrelativelysmallappendix.
Actually,we
did
originallyIncludeeverythingyouneedtoknowaboutJava(notalreadycoveredby
theotherchapters),byreducingthetype
pointsizeto.00003.Itall
fit,
butnobodycouldreadIt.So,
wethrewmostofitaway,butkeptthebestbitsforthisTopTenappendix.
Thisreally
Is
theendofthebook.ExceptfortheIndex(amust-read
I).
thisisa
newappendix
659
bit
manipulation
We'llusethefollowingexampleforthenextthreeoperators:
TheShiftOperators
Theseoperatorstakeasingleintegerprimitiveandshift(or
slide)allofitsbitsinonedirectionoranother.
If
youwant
todustoffyourbinarymathskills,youmightrealizethat
shiftingbits
left
effectively
multiplies
anumberbyapowerof
two,andshiftingbits
right
effectively
divides
anumberbya
poweroftwo.
#10BitManipulation
Whydoyoucare?
We'vetalkedaboutthefactthatthereare8bitsinabyte,
16bitsinashort,andsoon.Youmighthaveoccasionto
turnindividualbitsonoroff.Forinstanceyoumightfind
yourselfwritingcodeforyournewJavaenabledtoaster,
andrealizethatduetoseverememorylimitations,certain
toastersettingsarecontrolledatthebitlevel.Foreasier
reading,we'reshowingonlythelast8bitsinthecomments
ratherthanthefull32foranint).
int
x
=
-11;
II
bits
are
11110101
BitwiseNOTOperator:...
Thisoperator'flipsallthebits'ofaprimitive.
Thenextthreeoperatorscomparetwoprimitivesonabit
bybitbasis,andreturnaresultbasedoncomparingthese
bits.We'llusethefollowingexampleforthenextthree
operators:
II
bits
are
00000110
II
bits
are
00001010
RightShiftOperator:
»
Thisoperatorshiftsallofanumber'sbitsrightbyacertain
number,andfillsallofthebitsontheleftsidewithwhatever
theoriginalleftmostbitwas.Thesignbitdoes
not
change:
Ok,ok,we'vebeenputtingitoff,hereistheworld's
shortestexplanationofstoringnegativenumbers,and
two'scomplement.
Remember,theleftmostbitofaninteger
numberiscalledthe
sign
bit.
Anegativeintegernumberin
Java
always
hasitssignbitturned
on
(i.e.setto
1).
Apositive
integernumber
alwayshasitssignbitturned
011(0).
Java
usesthe
two'scomplement
formulatostorenegativenumbers.
Tochangeanumber'ssignusingtwo'scomplement,flipall
thebits,thenadd1(withabyte,forexample,thatwould
meanadding00000001totheflippedvalue).
bits
are
00001010
II
bits
are
now11110101
II
x
=
-x;
int
x
=
10;
int
x
=
10;
int
y
=
6;
BitwiseANDOperator:&
Thisoperatorreturnsavaluewhosebitsareturnedononly
if
both
originalbitsareturnedon:
int
a
=
x
«y;
II
bits
are
00000010
int
y
=
x
»2;
II
bits
are
11111101
UnsignedRightShiftOperator:
»>
JustliketherightshiftoperatorBUTitALWAYSfillsthe
leftmostbitswithzeros.Thesignbit
might
change:
BitwiseOROperator:
Thisoperatorreturnsavaluewhosebitsareturnedononly
if
either
oftheoriginalbitsareturnedon:
int
y
=
x»>
2;
II
bits
are
00111101
int
a
=
x
I
y;
II
bits
are
00001110
BitwiseXOR(exclusiveOR)Operator:
A
Thisoperatorreturnsavaluewhosebitsareturnedononly
if
exactlyone
oftheoriginalbitsareturnedon:
LeftShiftOperator:
«
Justliketheunsignedrightshiftoperator,butintheother
direction;therightmostbitsarefilledwithzeros.Thesignbit
might
change.
int
y
=
x
«2;
II
bits
are
11010100
int
a
=
x
A
y;
II
bits
are
00001100
660
appendixB
#9Immutability
Whydoyou
eare
thatStrlt1i!..
are1"''Mutable?
WhenyourJavaprogramsstart
to
getbig.you'll
inevitably
end
up
withlotsandlotsofStringobjects.
Forsecuritypurposes,andforthesakeof
conserving
memory(rememberyourJavaprogramscanrunon
teenyJava-enabledcellphones),Stringsinjavaare
immutable.What
this
meansisthatwhenyousay:
Strings
=
"0";
for(intx::
1;
x
<
10;
x++)(
8
=
S
+
Xi
)
What'sactuallyhappeningisthatyou'recreatingten
Stringobjects(withvalues
"0","01","012",
through
"0123456789").
Intheend
s
isreferringtotheString
withthevalue
"0123456789",
butatthispointthere
are
ten
Stringsinexistence
I
WheneveryoumakeanewString,theJVMputsit
intoaspecialpartofmemorycalledthe'StringPool'
(soundsrefreshingdoesn'tit.?).
If
thereisalready
a
StringintheStringPoolwiththesamevalue,the
JVM
doesn'tcreateaduplicate,itsimplyrefersyour
referencevariabletotheexistingentry.TheJVMcan
getawaywiththisbecauseStringsareimmutable;one
referencevariablecan'tchangeaString'svalueout
fromunderanotherreferencevariablereferringto
thesameString.
TheotherissuewiththeStringpoolisthatthe
GarbageCollector
doesn't
go
there.
Soinourexample.
unlessbycoincidenceyoulaterhappentomakea
Stringcalled
"01234",
forinstance,thefirstnine
Stringscreatedinour
forloop
willjustsitaround
wastingmemory.
Howdoesthissavememory?
Well,
if
you'renotcareful,
it
dcesn't!
But
if
youun-
derstandhowStringimmutabilityworks,thanyou
cansometimestakeadvantageofittosavememory.
If
youhave
to
doalotofStringmanipulations(like
concatenations,etc.),however,
thereisanotherclass
StringBuilder,
bettersuitedforthatpurpose.We'll
talk
moreaboutStringBuilderinafewpages.
appendixBTopTenReference
WhydoyoucarethatWra2!.ersare
It"",utable?
In
theMathchapterwetalkedaboutthetwomain
uses
ofthewrapperclasses:
•
Wrapping
a
primitivesoitcanpretendtobean
object.
•Using
thestaticutilitymethods(forexample,
Integer.parseln
t()).
It'simportanttorememberthatwhenyoucreatea
wrapperobjectlike:
IntegeriWrap::newInteger(42);
That's
it
forthatwrapperobject.
Its
value
will
always
be42.
Thereis
no
setter
methodfora
wrapper
object.
Youcan,ofcourse,refer
iWrap
toa
different
wrapper
object,butthenyou'llhave
two
objects.Onceyou
createawrapperobject,there'snowaytochange
the
value
ofthatobjectl
Rosesorered..
Strln'
Violetsoreblue
.11S
ar.'mmutobf,.
e,
'NfDppe,saretoo.
youarehere
~
661
assertions
#8Assertions
Wehaven'ttalkedmuchabouthowtodebugyourJava
programwhileyou'redevelopingit.Webelievethat
youshouldlearnjavaatthecommandline,aswe've
beendoingthroughoutthebook.Onceyou'reaJava
pro,
if
youdecidetousean
IDE*,
youmighthave
otherdebuggingtoolstouse.
In
theold
days,
when
ajavaprogrammerwantedtodebughercode,she'd
stickabunchofSystem.out.println()statements
throughouttheprogram,printingcurrentvariable
values,
and"Igothere"messages,tosee
if
theflow
control
was
workingproperly.(Theready-bakecode
in
chapter
6
leftsomedebugging'print'statements
inthecode.)Then,once
the
program
was
working
correctly,
she'dgothroughandtakeaUthoseSystem.
out.println()statementsbackoutagain.
It
was
tediousanderrorprone.ButasofJava
1.4
(and
5.0),
debugginggotawholeloteasier.Theanswer?
Assertions
Assertionsarelike
Systern.out.println()
statements
onsteroids.Addthemtoyourcode
as
youwould
addprintlnstatements.Thejava
5.0
compiler
assumesyou'llbecompilingsourcefilesthatare
5.0
compatible,
so
asofJava
5.0,
compilingwithassertions
is
enabledbydefault.
At
runtime,
if
youdonothing,theassertstatements
youaddedtoyourcodewillbeignoredby
the
JVM,
and
won't
slowdownyourprogram.But
if
youtellthe
JVM
to
enable
yourassertions,theywillhelpyoudo
yourdebugging,withoutchanging
a
lineofcode
I
Somefolkshavecomplainedabouthaving
to
leave
assert
statementsintheirproductioncode,but
leavingthem
incan
bereallyvaluablewhenyour
code
is
alreadydeployedinthefield.!fyourclient
ishavingtrouble,youcaninstructtheclienttorun
theprogramwithassertionsenabled,andhavethe
clientsendyoutheoutput.
If
theassertionswere
strippedoutofyourdeployedcode,you'dnever
have
thatoption.Andthereisalmostnodownside;
whenassertionsarenotenabled,theyarecompletely
ignoredbythejVM,
so
there'snoperformancehitto
worry
about.
662
appsnuix
B
HowtomakeAssertionswork
Addassertionstatementstoyourcodewhereveryou
believe
thatsomething
mustbe
true.
Forinstance:
assert(height>0);
II
iftrue,programcontinuesnormally
II
iffalse,throw
an
AssertionError
You
can
addalittlemoreinformationtothestack
tracebysaying:
assert
(height>0):"height
="
+
height
+"
weight
="
+
weight;
Theexpressionafterthecolon
can
beanylegal
Javaexpression
that
resolves
to
anon-nullvalue.
But
whateveryoudo.don't
create
assertions
that
cJumge
an
objed'sstale!
If
youdo,enablingassertionsatruntime
mightchangehowyourprogramperforms.
Compilingandrunningwith
Assertions
Tocompilewilhassertions:
javacTestDriveGame.java
(Noticethatnocommandlineoptionswere
necessary.)
To
run
withassertions:
java-eaTestDriveGame
'"IDE
SlaDW
forIntegratedDevelopmentEnvironment
andincludestoolssuchasEclipse,Borland'sjbuilder,or
theopensourceNetBeans(netbeans.org).
appendixB
TopTenReference
#7BlockScope
Inchapter9,wetalkedabouthowlocalvariables
liveonlyas
longasthemethodinwhichthey're
declaredstaysonthestack.Butsomevariablescan
haveeven
shorter
lifespans.Insideofmethods,we
oftencreate
blocks
ofcode.We'vebeendoingthis
allalong,
butwehaven'texplicitlytalkedintermsof
blocks.
Typically,blocksofcodeoccurwithinmethods,
andareboundedbycurlybraces{}.Somecommon
examplesofcodeblocksthatyou'llrecognizeinclude
loops
(jar,
while)
andconditionalexpressions(like
if
statements).
+,nodb\ot.\I.
Let'slookatanexample:s-tarl.
~
-tne
,.,e
voiddoStuff()
{~
J
t.o
thee"tiYe",ethod
,
/_lotalvayiablestofe"
Lnt;x
=
0;
~
~ ~
1
f
blotka"d
'1
is
for(int
y
=
0;
y
<
5;
y++)
{ ~be~i\'l\'li\'l~'
a
OY
r
I"
stofed
t.o
0\'11'1
the
0\"
oof∙
x
=
x
+
y;
~
...,
LI
y..
a"d
\I
aye
bothi\'lst°fe
1'0
fYOD
e"',
I
H-
e\'lQ
o.f
the
torloop
blotk
Inthepreviousexample,
y
wasablockvariable,
declaredinsideablock,and
y
wentoutofscopeas
soonastheforloopended.Yourjavaprogramswill
be
moredebuggableandexpandableifyouuselocal
variables
insteadofinstancevariables,andblock
variablesinsteadoflocalvariables,wheneverpossible.
Thecompilerwillmakesurethatyoudon'ttrytouse
avariable
that'sgoneoutofscope,soyoudon'thave
toworry
aboutruntimemeltdowns.
youarehere•
663
linked
invocations
#6LinkedInvocations
Whileyoudidseealittleofthisinthisbook,wetriedtokeepoursyntaxascleanand
readableaspossible.Thereare,however,manylegalshortcutsinJava,thatyou'llnodoubt
beexposedto,especiallyifyouhavetoreadalotcodeyoudidn'twrite.Oneofthemore
commonconstructsyouwillencounterisknownas
linkedinvocations.
Forexample:
StringBuffersb
=
newStringBuffer("spring");
sb
=
sb.delete(3,6).insert(2,"umme").deleteCharAt(l);
System.out.println("sb
="
+sb);
II
resultissb
=
summer
Whatintheworldishappeninginthesecondlineofcode?Admittedly,thisisacontrived
example,butyouneedtolearnhowtodecipherthese.
1-
Workfromlefttoright.
2-
Findtheresultoftheleftmostmethodcall,inthiscasesb.delete(3,6).Ifyou
lookupStringBufferintheAPIdocs,you'llseethatthedelete()methodreturnsa
StringBufferobject.
Theresultofrunningthedelete()methodisaStringBufferobject
withthevalue"spr".
3-
Thenextleftmostmethod(insert())iscalledonthenewlycreatedStringBuffer
object"spr".Theresultofthatmethodcall(theinsert()method),is
also
aStringBuffer
object(althoughitdoesn'thavetobethesametypeasthepreviousmethodreturn),andso
itgoes,
thereturnedobjectisusedtocallthenextmethodtotheright.Intheory,youcan
linkasmanymethodsasyouwantinasinglestatement(althoughit'sraretoseemorethan
threelinkedmethodsinasinglestatement).Withoutlinking,thesecondlineofcodefrom
abovewouldbemorereadable,andlooksomethinglikethis:
sbsb.delete(3,6);
sbsb.insert(2,"umme");
sbsb.deleteCharAt(l);
Buthere'samorecommon,andusefulexample,thatyousawususing,butwethought
we'dpointitoutagainhere.Thisisforwhenyourmain
0
methodneedstoinvokean
instancemethodofthemainclass,butyoudon'tneedtokeepa
reference
totheinstanceof
theclass.Inotherwords,themain
0
needstocreatetheinstance
only
sothatmain
0
can
invokeoneoftheinstance's
methods.
class
Faa{
publicstaticvoidmain(String[]args)[
()
LL
we
do,,'
t.ea-e
a b ~ t.
new
Faa().
go();
~
we'fJa"t.
+.0
t.all
~o
,0,",,,.1
't.bot.heY
ass i~l'I il'l~
L
r.:
il'ls-tal'lt.e,sowel.\Ol'l
I'
"t,he
rOO
r.:
~,.
t.t.
+.0
aye-teyel'lt.e∙
voidgo()
t.hel'Iew
rOO0
~e
II
here'swhatweREALLYwant...
}
664
appendixB
appendixB
Top
TenReference
#5AnonymousandStaticNestedClasses
NestedclassescomeInmanyflavors
In
theGUlevent-handlingsectionofthebook,westartedusinginner(nested)classesasa
solutionfor
implementinglistenerinterfaces.That'sthemostcommon,practical,andread-
ableform
ofaninnerclass-wheretheclassissimplynestedwithinthecurlybracesofanother
enclosing
class.
Andremember,itmeansyouneedaninstanceoftheouterclassinordertoget
aninstanceoftheinner
class,
becausetheinnerclass
is
a
member
oftheouter/enclosingclass.
But
thereareotherkindsofinnerclassesincluding
static
and
arwnymous.
We'renotgoing
intothedetailshere,butwedon'twantyoutobethrownbystrangesyntaxwhenyousee
it
in
sorneone's
code.Becauseoutofvirtuallyanythingyou
can
dowiththeJavalanguage,perhaps
nothingproducesmorebizarre-lookingcodethananonymousinnerclasses.Butwe'llstartwith
somethingsimpler--staticnestedclasses.
Staticnestedclasses
Youalreadyknowwhatstatic
means-s-something
tiedtotheclass,not
aparticular
instance.
A
staticnestedclasslooksjustlikethenon-staticclassesweusedforeventlisteners,exceptthey're
markedwiththekeyword
static.
publicclass
FooOuter(
classBarlnner
void
saylt(){
System.out.printin("methodofastaticinnerclass");
)
}
classTest(
publicstaticvoid
faa.
sayIt();
StaticnestedclassesaremorelikereguJarnon-nestedclassesinthattheydon'tenjoyaspecialrelation-
shipwithanenclosingouterobject.Butbecausestaticnestedclassesarestillconsidereda
memberoi
theenclosing/outerclass,theystillgetaccesstoanyprivatemembersoftheouterclass...but
only
the
onesthatarealsostatu.
Sincethestaticnestedclassisn'tconnectedtoaninstanceoftheouterclass,it
doesn'thaveanyspecialwaytoaccessthenon-static(instance)variablesandmethods.
youarehere
~
665
whenarraysaren'tenough
#5AnonymousandStaticNestedClasses,continued
ThediHereneebetweennestedandInner
AnyJavaclassthat'sdefinedwithinthescopeofanotherclassisknownasa
rI£SU:d
class.
It
doesn'tmatter
if
it'sanonymous,
static.
normal,whatever.
If
it'sinsideanotherclass,it's
technicallyconsidereda
nested
class.But
non-statu
nestedclassesareoftenreferredtoas
inner
classes,whichiswhatwecalledthemearlierinthebook.Thebottomline:
all
innerclassesare
nestedclasses,butnot
all
nestedclassesareinnerclasses.
Anonymousinnerclasses
Imagineyou'rewritingsomeGUIcode,andsuddenlyrealizethatyouneedaninstance
ofaclass
thatimplementsActionListener.Butyourealizeyoudon't
have
aninstanceofan
Actionl.istener,
Thenyourealizethatyoualsoneverwrotea
class
forthatlistener.Youhavetwo
choicesat
thatpoint:
1)
Writeaninnerclassinyourcode,the
way
wedidinourGUIcode,andtheninstantiateit
andpassthatinstanceintothebutton'seventregistration(addActionListenerO)method.
OR
2)
Createan
anonymous
innerclassandinstantiate
it,
rightthere.just-in-time.Litera11y
right
where
YlJU
are
atthe
pmntyou
need
the
listener
or,jed.
That'sright,youcreatetheclassandthe
instancein.theplace
whereyou'dnormallybesupplyingjusttheinstance.Thinkaboutthatfor
a
moment-itmeansyoupasstheentire
cla.sswhere
you'dnormallypassonlyan
instance
intoa
methodargumentl
}
666
appendix8
access
levelsappendixB
TopTenReference
#4AccessLevelsandAccessModifiers(WhoSeesWhat)
Javahasfouraccesslevelsandthreeaccessmodifiers.Thereareonlythreemodifiersbecause
thedefault(whatyougetwhenyoudon'tuseanyaccessmodifier)isoneofthefour
accesslevels.
AccessLevels
(inorderofhowrestrictivetheyare,fromleasttomostrestrictive)
public
~
rlAblit....eansanycedeanywheretanaUesstheflAblit
th in~
(by
thin~'
we....eantlass,I/ariable,....ethod,tonstrlAttor,eUJ.
protected"''-:---
froutudworksjlAs
t
likedetalAlt(todeinthesa....e
fatka~e
hasauess),
EXCEPT
it
alsoallowsslAbtiassesolAtsidethe
fatka~e
toinherittheyrotetud
thin~.
default
~
detalAltaUess....eansthatonlycedewithinthesa....e
fatka~e
as
the
tlasswiththedetalAlt
thin~
tal'laUessthedetalAlt
th in~.
private
~
fril/ate....eansthatol'llytodewithil'lthesamedasstal'laUesstheyril/ate
thin~.
Keefil'lmil'lditmeansfril/autothetlass,notfril/atetotheobjett.One
D~
tal'lseeal'lother
D~
objett'sfril/aushU,blAtaCattan'tseea
D~'s
yril/aus.
Accessmodifiers
public
protected
private
Mostofthetimeyou'lluseonlypublicandprivateaccesslevels.
public
Usepublicforclasses,constants(staticfinalvariables),andmethodsthatyou're
exposingtoothercode(forexamplegettersandsetters)andmostconstructors.
private
Useprivateforvirtuallyallinstancevariables,andformethodsthatyoudon'twant
outsidecodetocall(inotherwords,methodsusedbythepublicmethodsofyourclass).
Butalthoughyoumightnotusetheothertwo(protectedanddefault),youstillneedto
knowwhattheydobecauseyou'llseetheminothercode.
youarehere
~
667
when
arrays
aren'tenough
#4AccessLevelsandAccessModifiers,cont.
defaultandprotected
default
Bothprotectedanddefaultaccesslevelsaretiedtopackages.Defaultaccessissimple-it
meansthatonlycode
within
the
samepackage
canaccesscode
with
defaultaccess.Soa
defaultclass,forexample(whichmeansaclassthatisn'texplicitlydeclaredas
puhlil:)
can
be
accessedbyonlyclasseswithinthesamepackageasthedefaultclass.
Butwhat
doesitreallymeanto
MUSS
aclass?Codethatdoesnothaveaccesstoaclassis
notallowedtoeven
think
abouttheclass.Andbythink,wemean
use
theclassincode.
Forexample,
if
youdon'thaveaccess
to
aclass,becauseofaccessrestriction,youaren't
allowedtoinstantiatetheclassorevendeclareitasatypeforavariable,argument,or
returnvalue.Yousimplycan'ttypeitintoyourcodeat
all!
!fyoudo,thecompilerwill
complain.
Thinkabouttheimplications-adefaultclasswithpublicmethodsmeansthepublic
methodsaren'treallypublicatall.Youcan'taccessamethod
if
youcan't
see
theclass.
Whywouldanyonewanttorestrictaccessto
codewithinthesamepackage?Typically,
packages
aredesignedasagroupofclassesthatworktogetherasarelatedset.
So
itmight
makesensethatclasseswithinthesamepackageneedtoaccessoneanother'scode,while
asapackage,onlyasmall
numberofclassesandmethodsareexposedtotheoutside
world(i.e.
codeoutsidethatpackage).
OK,that'sdefault.It's
simple-ifsomethinghasdefaultaccess(which,remember,means
noexplicitaccess
rnodifierl),
onlycodewithinthesamepackageasthedefault
thing
(class,variable,method,innerclass)canaccessthat
thing.
Thenwhat's
proucudfor?
protected
Protectedaccessisalmostidenticaltodefaultaccess,withoneexception:itallowssub-
classesto
inherit
theprotectedthing,
eveniJthosesubclassesare
()UtsUU
the
pad1.ageof
the
super--
class
they
extend:
That'sit.That's
all
protectedbuysyou-theabilitytoletyoursubclasses
beoutside
yoursuperclasspackage,yetstill
inherit
piecesoftheclass,includingmethods
andconstructors.
Many
developersfindverylittlereasontouseprotected,butitisusedinsomedesigns,
andsomedayyoumightfindittobeexactlywhat
you
need.Oneoftheinterestingthings
aboutprotectedisthat-unliketheotheraccesslevels-protectedaccessappliesonlyto
inheritance.
If
asubclass-outside-the-packagehasa
nference
toaninstanceofthesuperc1ass
(thesuperclassthathas,say,aprotectedmethod),thesubclasscan'taccessthepro-
tected
methodusingthatsuperclassreferencelTheonlywaythesubclasscanaccessthat
method
is
by
inheritingit.
Inotherwords,thesubclass-outside-the-packagedoesn'thave
access
totheprotectedmethod.itjust
has
themethod,throughinheritance.
668
appendixB
Stringand
StringBuffer
appendixB
TopTenReference
#3StringandStringBufferlStringBuilderMethods
TwoofthemostcommonlyusedclassesintheJavaAPIareStringandStringBuffer(rememberfrom
#9afewpagesback,Stringsareimmutable,soaStringBuffer/StringBuildercanbealotmorefficient
ifyo
u'remanipulatingaString).
As
ofJava5.0youshouldusetheStringBuilderclassinsteadof
StringBuffer,
unlessyourStringmanipulationsneedtobethread-safe,whichisnotcommon.Here'sa
briefoverviewofthekeymethodsintheseclasses:
BothStringandStringBuffer/StringBuilderclasseshave:
charcharAt(intindex);
intIength
t):
Stringsubstring(intstart,intend);
Stringto.String():
ToconcatenateStrings:
Stringconcat(string);
Stringappend(String);
//
whatcharisatacertainposition
//howlongisthis
//
getapartofthis
//what's
theStringvalueofthis
//for
theStringclass
//
forStringBuffer
&
StringBuilder
TheStringclasshas:
Stringreplace(charold,charnew);
Stringsubstring(intbegin,intend);
char[]toCharArrayO;
StringtoLowerCase();
String
toUpperCaseO;
Stringtrim();
StringvalueOf(char[])
StringvalueOf(inti)
//
replacealloccurencesofachar
//getaportionofaString
//converttoanarrayofchars
//convertallcharacterstolowercase
//convertall
characterstouppercase
//removewhitespace
fromtheends
//makeaStringoutofachararray
//
makeaStringoutofaprimitive
//
otherprimitivesaresupportedaswell
TheStringBuffer&StringBuilderclasseshave:
StringBxxxxdelete(intstart,intend);//deleteaportion
StringBxxxxinsert(intoffset,anyprimitiveorachar[]);//insertsomething
StringBxxxxreplace(intstart,intend,Strings);//replacethispartwiththisString
Stringlsxxxxreverser)://reversetheSBfromfronttoback
voidsetCharAt(intindex,charch);//replaceagivencharacter
Note:StringBxxxxreferstoeither
StringBufferorStringBuilder,
asappropriate.
youarehere.
669
whenarraysaren'tenough
#2MultidimensionalArrays
Inmostlanguages,
if
you
create,
say,
a4
x
2two-dimensionalarray,youwouldvisualize
a
rectangle,
4
elementsby
2
elements,with
a
totalof
8
elements.ButinJava,such
an
array
wouldactuallybe
5
arrays
linkedtogether!
In
java,atwodimensional
array
issimply
anarra)'
ofarrays.
(A
three
dimensionalarray
is
an
array
ofarraysofarrays,butwe'llleavethatfor
youtoplay
with.)
Here'showit
works
i.nt]](]a2d
=
newint[4](2];
The
JVM
creates
an
arraywith
4
elements.
Each.
of
thesefourelementsisactuallyareference
variablereferringtoa(newlycreated),intarraywith
2
elements.
int[J(]
intarrayobject
(int[][D
Workingwithmultidimensionalarrays
-Toaccessthesecondelementinthethirdarray:intx
=
a2d[2)[1)
i
II
remember,0based!
-Tomakeaone-dimensionalreferencetooneofthesub-arrays:int
[J
copy
=
a2d[1
J;
-Short-cutinitializationofa2x3array:
intlJI)x
=(
l
2,3,4},
I7,8,9}};
-Tomake
a2d
array
withirregulardimensions:
int(J
[J
y
=
newint(2)[);
II
makesonlythefirstarray,withalengthof2
y[Ol
newint(3J;
II
makesthefirstsub-array3elementsinlength
y(l]
=
newint
15J;
II
makesthesecondsub-array5elements
in
length
670
appendixB
enumerationsappendixBTopTenReference
Andthenumberonetopicthatdidn'tquitemakeitin...
#1Enumerations(alsocalledEnumeratedTypesorEnums)
We'vetalkedaboutconstantsthataredefinedintheAPI,forinstance,
JFrame.EXIT_ON_CLOSE.
Youcanalsocreateyourownconstantsby
markingavariable
staticfinal.
Butsometimesyou'llwanttocreateaset
ofconstantvaluestorepresentthe
only
validvaluesforavariable.Thissetof
validvaluesiscommonlyreferredtoasan
enumeration.
BeforeJava5.0you
couldonlydoahalf-bakedjobofcreatinganenumerationinJava.
As
ofJava
5.0you
cancreatefullfledgedenumerationsthatwillbetheenvyofallyour
pre:Java5.0-usingfriends.
Who'sintheband?
Let'ssaythatyou'recreatingawebsiteforyourfavoriteband,andyouwantto
makesurethatallofthecommentsaredirectedtoaparticularbandmember.
Theoldwaytofakean"enum":
publicstaticfinalintJERRY
=
1;
publicstaticfinalintBOBBY
=
2;
publicstaticfinalint
PHIL
=
3;
II
laterinthecode
We'reh.
Lh
L
b
Lh
L"
~ °flll~
;;a;;
y;;
e;;'l'WIewe
~ot
here
if(selectedBandMember
==
JERRY){"
s
dettedBalldMe
l'Wlber"hasavalidval"t.!
II
doJERRYrelatedstuff
ThegoodnewsaboutthistechniqueisthatitDOESmakethecodeeasierto
read.Theothergoodnewsisthatyoucan'teverchangethevalueofthefake
enumsyou'vecreated;JERRYwillalwaysbe
1.
Thebadnewsisthatthere's
noeasyorgoodwaytomakesurethatthevalueofselectedBandMember
willalwaysbe1,2,or3.
If
somehardtofindpieceofcodesets
selectedBandMemberequalto812,it'sprettylikelyyourcodewillbreak...
youarehere
~
671
A
new,official"enum":
MembersifName
=
Members.PHIL;
switch(ifName){
caseJERRY:System.out.print("makeitsing");
casePHIL:System.out.print("godeep");
caseBOBBY:System.out.println("Cassidy!");
whenarraysaren'tenough
#1Enumerations,cont.
ThesamesituationusingagenuineJava5.0enum.Whilethisisaverybasic
enumeration,mostenumerationsusually
are
thissimple.
~
publicenumMembers{JERRY,BOBBY,PHIL};
public
Yourenumextendsjava.lang.Enum
Whenyoucreateanenum,you'recreatinganewclass,and
you'reimplicitlyextending
java.
lang.Enum.
Youcandeclareanenumasitsownstandaloneclass,initsown
sourcefile,orasamemberofanotherclass.
Using"if"and"switch"withEnums
Usingtheenumwejustcreated,wecanperformbranchesinourcodeusingeither
theiforswi
tch
statement.Alsonoticethatwecancompareenuminstancesusing
either
==
orthe.equals()method.Usually
==
isconsideredbetterstyle.
______
Assi~r.ir.~
ar.er.1mI
yal~
to
avariable,
Membersn
=
Members.BOBBY;
~
if(n.equals(Members.JERRY))System.out.println("Jerrrry!");
I.
r,el
0'("""",
if(n
==
Members.BOBBY)System.out.println("RatDog");
"--- ~ o -\:)l J t"'e $ e'"
D
""$
,"",,-\:,ed,
"Rat
~
672
appendix8
enumerations
#1Enumerations,completed
appendixBTopTenReference
Areallytricked-outversionofasimilarenum
Youcanaddabunchofthingstoyourenumlikeaconstructor,methods.
variables,
and
somethingcalledaconstant-specificclassbody.They're
notcommon,butyoumightrunintothem:
L
sstO
il'\
-\:p
publicclassHfjEnum(
ay~"",el'\1:.~a
L.\
________nils
is
a~\Il.~
oeda....
td
~
o'Wl∙
enumNames(
~
__
L.'•_
~~_.~e ~Q'I\S
th
$O-t.llleo
JERRi'("lead
guitar){
publicString
sings(){
~
Tkesea....ee
ok'
daubodies".
return"plaintively";};/
"~Ylt.-s?etl
It
o.-th
}J
Think
~
t.he'"as
O"t:rt"IO.ln~
e
o
LL
od
(iYl
-thIS
t,4St
BOBBY
("rhythmguitar")(publicString
s
i
nqs()
I
\)asit
eYl.........
n.n
roO.
return"hoarsely";)
the
"S'IYI~O)l
""et.hcxl),
iot
S,,\~
IS
),t.llleo
0"
alIayid'ole...
ith
aYlen--
PHIL
("bass");
I
r
J~RRY ~
BOBBY∙
lIa
v.t
o-t
privateStringinstrument;
Names(Stringinstrument)(
this.instrument
=
instrument;
)
publicStringgetlnstrument{)
returnthis.instrument;
)
publicStringsings()(
return"occasionally";
~~--
Thisis
-thetr>lAM'S
toYlShvttm-.
It.
ruYlS
OWIU
+t*'
e6th
detla....ed
eYllAM
I/al~
(iYl
t.his
~
it.....
"'W\.\
t.hree
tiMes)o
publicstaticvoidmain(String[]args)
(0___________
for(Namesn:
Names.values(»)(
~
System.aut.print<n);
System.out.prin~(",
instrument:
"+
n.getlnstrument<)):
System.aut.println(",sings:"
+
n.sings());
%javaHfjEnum
JERRY,instrument:leadguitar,sings:plaintively
BOBBY,instrument:rhythmguitar,sings:hoarsely
PHIL,instrument:bass,sings:occasionally
%
Not.itt
thatthe
ba.sit
Usi,,~())
""et.hod
is
oYlly
lJlled
wheYl
the
e"w.-
I/al~
has
110tOPl.Sta7lt-
speti.fit
tlas.s
body.
you
arehere.
673
when
arrays
aren'tenough
CaptainBytegaveEnsignSmiththefollowingprogramminginstructionstoprocessthecritical
navigationalcodes:
ALongTripHome
CaptainByteoftheFlatlandstarship"Traverser"hadreceivedanurgent,TopSecrettransmission
fromheadquarters.Themessagecontained30heavilyencryptednavigationalcodesthatthe
Traverserwouldneedtosuccessfullyplotacoursehomethroughenemysectors.Theenemy
Hackarians,fromaneighboringgalaxy,haddevisedadevilishcode-scramblingraythatwascapable
ofcreatingbogusobjectsontheheapoftheTraverser'sonlynavigationalcomputer.
In
addition,thealienraycouldaltervalidreferencevariablessothattheyreferredtothese
bogusobjects.TheonlydefensetheTraversercrew
had
againstthisevilHackarianraywas
torunaninlineviruscheckerwhichcouldbeimbeddedintotheTraverser'sstate
ofthe
art
Java1.4code.
"Putthe
first
fivecodesinanarrayof
type
ParsecKey.Putthelast25codes
in
afiveby
fi
ve,two
dimensional
array
oftypeQuadmntKey.PassthesetwoarraysintotheplolCourseOmethodofthe
publicfinalclassShipblavigation.Oncethecourseobjectisreturnedruntheinlineviruschecker
againstalltheprogramsreferencevariablesandthenruntheNavSimprogramandbringmethe
results
."
AfewminuteslaterEnsignSmithreturnedwiththeNavSimoutput."NavSimoutputreadyfor
review,sir",declaredEnsignSmith."Fine",repliedtheCaptain."Pleasereviewyourwork"."Yes
sir!",respondedtheEnsign,"FirstIdeclaredandconstructedanarray
oftypeParsecKeywiththe
followingcode;ParsecKey
0
p
=
newParsecKey[5];,next1declaredandconstructedanarray
oftypeQuadrantKeywiththefollowingcode:QuadrantKey
00
q
=
newQuadrantKey[5][5];.
Next,Iloadedthefirst5codesintotheParsecKeyarrayusinga
'for'loop,andthenIloadedthelast
25codesintotheQuadrantkey,arrayusingnested
'for'{oops,
Next,Irantheviruscheckeragainst
all32referencevariables,IfortheParsecKeyarray,and5foritselements,IfortheQuadrantKey
array.and25foritselements.Oncetheviruscheckreturnedwithnovirusesdetected,Iranthe
NavSim
programandre-ranthe
virus
checker,justtobesafe...Sir!"
CaptainBytegavetheEnsignacool,longstareandsaidcalmly,"Ensign,youareconfinedto
quartersforendangeringthesafety
oftbisship,Idon'twanttoseeyourfaceonthisbridgeagain
until
you
haveproperlylearned
your
Java!LieutenantBoolean,takeoverfortheEnsignanddothis
jobcorrectly!"
WhydidthecaptainconfinetheEnsigntohisquarters?
674
appendixB
A
LongTrip
Home
CaptainByteknewthatinJava,multidimensionalarraysareactu-
allyarraysof
arrays.
ThefivebyfiveQuadrantKey
array
'g',would
actually
needatotalof31referencevariablesto
be
able
to
access
all
ofitscomponents:
I-referencevariable
for'q'
5-referencevariablesforq[0)-q[4
J
25-referencevariablesforq[0][0]-q
[4][4]
Theensignhadforgottenthereferencevariablesforthefiveone
dimensionalarraysembeddedinthe'q'array.
Any
ofthosefive
referencevariablescouldhave
beencorruptedbytheHackarian
ray,
andtheensign'stestwouldneverrevealtheproblem.
youarehere
~
675
This
isn't
goodbye
Bringyourbrainoverto
wickedlysmart.com
Автор
JRzayev
Документ
Категория
Информатика
Просмотров
2 933
Размер файла
34 780 Кб
Теги
edition, head, first, 2nd, java
1/--страниц
Пожаловаться на содержимое документа