12.07.2015 Views

OsmWv

OsmWv

OsmWv

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Table of Contents (summary)Introxxi1 Breaking the Surface: a quick dip 12 A Trip to Objectville: yes, there will be objects 273 Know Your Variables: primitives and references 494 How Objects Behave: object state affects method behavior 715 Extra-Strength Methods: flow control, operations, and more 956 Using the Java Library: so you don’t have to write it all yourself 1257 Better Living in Objectville: planning for the future 1658 Serious Polymorphism: exploiting abstract classes and interfaces 1979 Life and Death of an Object: constructors and memory management 23510 Numbers Matter: math, formatting, wrappers, and statics 27311 Risky Behavior: exception handling 31512 A Very Graphic Story: intro to GUI, event handling, and inner classes 35313 Work on Your Swing: layout managers and components 39914 Saving Objects: serialization and I/O 42915 Make a Connection: networking sockets and multithreading 47116 Data Structures: collections and generics 52917 Release Your Code: packaging and deployment 58118 Distributed Computing: RMI with a dash of servlets, EJB, and Jini 607A Appendix A: Final code kitchen 649B Appendix B: Top Ten Things that didn’t make it into the rest of the book 659Index 677Table of Contents (the full version)iIntroYour brain on Java. Who is this book for?What your brain is thinkingMetacognitionBend your brain into submissionWhat you need for this bookTechnical editorsAcknowledgementsxxiixxiiixxvxxviixxviiixxxxxxiix


1Breakingthe SurfaceJava takes you to new places. Method Party()0 aload_01 invokespecial#1 4 returnCompiledbytecodeVirtualMachinesYou BetShoot MeThe way Java works 2Code structure in Java 7Anatomy of a class 8The main() method 9Looping 11Conditional branching (if tests) 13Coding the “99 bottles of beer” app 14Phrase-o-matic 16Fireside chat: compiler vs. JVM 18Exercises and puzzles 202ATrip to ObjectvilleI was told there would be objects. Chair Wars (Brad the OO guy vs. Larry the procedural guy) 28Inheritance (an introduction) 31Overriding methods (an introduction) 32What’s in a class? (methods, instance variables) 34Making your first object 36Using main() 38Guessing Game code 39Exercises and puzzles 42x


3KnowYour VariablesVariables come in two flavors: primitive and reference. fidoDog reference24sizeintDog objectDeclaring a variable (Java cares about type) 50Primitive types (“I’d like a double with extra foam, please”) 51Java keywords 53Reference variables (remote control to an object) 54Object declaration and assignment 55Objects on the garbage-collectible heap 57Arrays (a first look) 59Exercises and puzzles 634How ObjectsBehaveState affects behavior, behavior affects state. pass-by-value meanspass-by-copy00000111Xcopy of x00000111ZMethods use object state (bark different) 73Method arguments and return types 74Pass-by-value (the variable is always copied) 77Getters and Setters 79Encapsulation (do it or risk humiliation) 80Using references in an array 83Exercises and puzzles 88intintfoo.go(x); void go(int z){ }xi


5Extra-StrengthWe’re gonna build theSink a Dot Com game MethodsLet’s put some muscle in our methods. Building the Sink a Dot Com game 96Starting with the Simple Dot Com game (a simpler version) 98Writing prepcode (pseudocode for the game) 100Test code for Simple Dot Com 102Coding the Simple Dot Com game 103Final code for Simple Dot Com 106Generating random numbers with Math.random() 111Ready-bake code for getting user input from the command-line 112Looping with for loops 114Casting primitives from a large size to a smaller size 117Converting a String to an int with Integer.parseInt() 117Exercises and puzzles 1186Usingthe Java LibraryJava ships with hundreds of pre-built classes. - Julia, 31, hand modelAnalying the bug in the Simple Dot Com Game 126ArrayList (taking advantage of the Java API) 132Fixing the DotCom class code 138Building the real game (Sink a Dot Com) 140Prepcode for the real game 144Code for the real game 146boolean expressions 151Using the library (Java API) 154Using packages (import statements, fully-qualified names) 155Using the HTML API docs and reference books 158Exercises and puzzles 161xii


xivdDuckDuck9Lifeobjectobject‘d’ is assigned a new Duck object, leaving theoriginal (first) Duck object abandoned. Thatfirst Duck is toast..Static variablesare shared byall instances ofa class.kid instance onestatic variable:iceCream10Numbersand Death of an ObjectObjects are born and objects die. When someone callsthe go() method, thisDuck is abandoned. Hisonly reference has beenreprogrammed for adifferent Duck.kid instance twoHeapMatterDo the Math. instance variables:one per instancestatic variables:one per classThe stack and the heap, where objects and variables live 236Methods on the stack 237Where local variables live 238Where instance variables live 239The miracle of object creation 240Constructors (the code that runs when you say new) 241Initializing the state of a new Duck 243Overloaded constructors 247Superclass constructors (constructor chaining) 250Invoking overloaded constructors using this() 256Life of an object 258Garbage Collection (and making objects eligible) 260Exercises and puzzles 266Math class (do you really need an instance of it?) 274static methods 275static variables 277Constants (static final variables) 282Math methods (random(), round(), abs(), etc.) 286Wrapper classes (Integer, Boolean, Character, etc.) 287Autoboxing 289Number formatting 294Date formatting and manipulation 301Static imports 307Exercises and puzzles 310


13Workon your SwingSwing is easy. Components inthe east andwest get theirpreferred width.Things in thenorth andsouth get theirpreferred height.The center getswhatever’s left.Swing Components 400Layout Managers (they control size and placement) 401Three Layout Managers (border, flow, box) 403BorderLayout (cares about five regions) 404FlowLayout (cares about the order and preferred size) 408BoxLayout (like flow, but can stack components vertically) 411JTextField (for single-line user input) 413JTextArea (for multi-line, scrolling text) 414JCheckBox (is it selected?) 416JList (a scrollable, selectable list) 417Code Kitchen (The Big One - building the BeatBox chat client) 418Exercises and puzzles 42414Saving ObjectsObjects can be flattened and inflated. xviAny questions?serializeddeserializedSaving object state 431Writing a serialized object to a file 432Java input and output streams (connections and chains) 433Object serialization 434Implementing the Serializable interface 437Using transient variables 439Deserializing an object 441Writing to a text file 447java.io.File 452Reading from a text file 454Splitting a String into tokens with split() 458CodeKitchen 462Exercises and puzzles 466


Socket connectionto port 5000on the server at196.164.1.103Client15MakeSocket connectionback to the clientat 196.164.1.100,port 4242a ConnectionConnect with the outside world. ServerChat program overview 473Connecting, sending, and receiving 474Network sockets 475TCP ports 476Reading data from a socket (using BufferedReader) 478Writing data to a socket (using PrintWriter) 479Writing the Daily Advice Client program 480Writing a simple server 483Daily Advice Server code 484Writing a chat client 486Multiple call stacks 490Launching a new thread (make it, start it) 492The Runnable interface (the thread’s job) 494Three states of a new Thread object (new, runnable, running) 495The runnable-running loop 496Thread scheduler (it’s his decision, not yours) 497Putting a thread to sleep 501Making and starting two threads 503Concurrency issues: can this couple be saved? 505The Ryan and Monica concurrency problem, in code 506Locking to make things atomic 510Every object has a lock 511The dreaded “Lost Update” problem 512Synchronized methods (using a lock) 514Deadlock! 516Multithreaded ChatClient code 518Ready-bake SimpleChatServer 520Exercises and puzzles 524xvii


16DataStructuresSorting is a snap in Java. ListSetclasses0 1 2 3Map “Ball” “Ball1” “Ball2” “Fish” “Fish” “Car”17ReleaseYour CodeCollections 533Sorting an ArrayList with Collections.sort() 534Generics and type-safety 540Sorting things that implement the Comparable interface 547Sorting things with a custom Comparator 552The collection API—lists, sets, and maps 557Avoiding duplicates with HashSet 559Overriding hashCode() and equals() 560HashMap 567Using wildcards for polymorphism 574Exercises and puzzles 576It’s time to let go. JWSxviiiMyApp.jarcomfooMyApp.jar10110110 110 10 11 0001 10001 01MyApp.classWeb ServerLorperiureeuguetat veroconseeuguero-MyApp.jnlp MyApp.jarDeployment options 582Keep your source code and class files separate 584Making an executable JAR (Java ARchives) 585Running an executable JAR 586Put your classes in a package! 587Packages must have a matching directory structure 589Compiling and running with packages 590Compiling with -d 591Making an executable JAR (with packages) 592Java Web Start (JWS) for deployment from the web 597How to make and deploy a JWS application 600Exercises and puzzles 601


18DistributedComputingBeing remote doesn’t have to be a bad thing. ClientClient objectRMI STUBClient helperRMI SKELETONService helperServerService objectJava Remote Method Invocation (RMI), hands-on, very detailed 614Servlets (a quick look) 625Enterprise JavaBeans (EJB), a very quick look 631Jini, the best trick of all 632Building the really cool universal service browser 636The End 648AAppendixAThe final Code Kitchen project. BeatBoxFinal (client code) 650MusicServer (server code) 657 BAppendixBThe Top Ten Things that didn’t make it into the book. Top Ten List 660iIndex677xix


how to use thOIS bookIntroIY\ -this stl.bOf\I 'Wt. .lYlS'Ht:Y -the bl>Yl\i,,~,~tiOf\:'So, whY DID \:h


how to use this bookWho is this book for?Ifyou can answer "yes" to all of these:E!)" Have you done some programming?®®Do you want to learn Java?Do you prefer stimulating dinner partyconversation to dry, dull, technicallectures?this book is for you.This is NOT a referencebook. Head First Java is abook designed for 'earning,not an encyclopedia ofJava facts.Who should probably back away frotH this book?If you can answer "yes" to anyone of these:Is your programming background limitedto HTML only, with no scripting languageexperience?(If you've done anything with looping, or if/thenlogic , you'll do fine with this book, but HTMLtagging alone might not be enough.)®Are you a kick-butt C++ programmerlooking for a reference book?®Are you afraid to try something different?Would you rather have a root canal thanmix stripes with plaid? Do you believethan a technical book can't be serious Ifthere's a picture of a duck in the memorymanagement section?Ithis book is not for you .xxiiintro


the intraWe k.,ow what you"re thittkhtg."How can this be a seriousJava programming book?""What's with all the graphics?""Can I actually learn it this way?""Do I smell pizza?"A.,d we kt10w what your brain is thittkittg.Your brain craves novelty. It's always searching, scanning, waitingforsomething unusual. It was built that way,and it helps you stay alive.Today, you're less likely to be a tiger snack. But your brain's stilllooking. Youjust never know.So what does your brain do with all the routine, ordinary, normalthings you encounter? Everything it can to stop them frominterfering with the brain's realjotr-recording things that matter. Itdoesn't bother saving the boring things; they never make it past the"this is obviously not important" filter.How does your brain know what's important? Suppose you're out fora day hike and a tigerjumps in front ofyou , what happens inside yourhead?Neurons fire. Emotions crank up. ChemicalssuWAnd that's how your brain knows ...This must be Importantl Don't forget ItIBut imagine you're at home, or in a library. It's a safe, warm, tiger-freezone. You're studying. Getting ready for an exam. Or trying to learnsome tough technical topic your boss thinks will take a week, ten daysat the most,Just one problem. Your brain's trying to do you a big favor. It'strying to make sure that this obviou.sly non-important contentdoesn't clutter up scarce resources. Resources that are betterspent storing the really bigthings. Like tigers. Like the danger offire. Like how you should never again snowboard in shorts.And there's no simple way to tell your brain, "Hey brain, thankyou very much, but no matter how dull this book is. and howlittle I'm registering on the emotional richter scale right now, Ireally do want you to keep this stuffaround.hyou are he re ~xxiII


how to use this bookWe tlUn1 of a"!lead Fll'St Java" reader as a learner.-So whatdoes It take to learn something? First, you have to get It, then make sureyou don't forgetll It's not about pushing facts Into your head. Based on thelatest research In cognltJve science, neurobiology, and educatJonal psychology,learning takes a lot more than text on a page. We know what turns your brain on.Soma of the Head First learning principles:Make It visual. Images are far more memorable than wordsalone, and make learning much more effective (Up to 89%Improvement in recall and transfer studies).It also makesthings more understandable. Put the words withinor near the graphics they relate to, rather than on thebottom or on another page, and learners will be up to twiceas likely to solve problems related to the content.RMI"'(loo~~iteIt re4l1y SlJcks to ~


the introMetacogtlitiott: thittkittg about thittki"Q.Ifyou really want to learn, and you want to learn more quickly and more deeply,pay attention to how you pay attention. Think about how you think, Learn howyou learn.Most of us did not take courses on metacognition or learning theory when we weregrowing up. We were expected to learn, but rarely taught to learn.But we assume that ifyou're holding this book, you want to learnJava. And youprobably don't want to spend a lot of time.To get the most from this book, or any book or learning experience, takeresponsibility for your brain. Your brain 00 thai content.The trick is to get your brain to see the new material you're learningas Really Important. Crucial to your well-being. As important asa tiger. Otherwise, you're in for a constant battle, with your braindoing its best to keep tile new content from sticking.o oSo Just how DO you get your brain to treat Java like Itwas a hungry tiger?There's the slow, tedious way,or the faster, more effective way. Theslow way is about sheer repetition. You obviously know that you areable to learn and remember even the dullest of topics, ifyou keep poundingon the same thing. With enough repetition, your brain says, "This doesn'tfeelimportant to him, but he keeps looking at the same thing overand over and over, soI suppose it must be."The faster way is to do anything that increases brain activity, especially different typesof brain activity. The things on the previous page are a big part of the solution,and they're all things that have been proven to help your brain work in your favor.For example, studies show that putting words within the pictures they describe (asopposed to somewhere else in the page, like a caption or in the body text) causesyour brain to try to makes sense of how the words and picture relate, and thiscauses more neurons to fire. More neurons firing = more chances for your brainto get that this is something worth paying attention to, and possibly recording.A conversational style helps because people tend to pay more attention when theyperceive that they're in a conversation, since they're expected to follow along andhold up their end. The amazing thing is, your brain doesn't necessarily carethatthe "conversation" is between you and a book! On the other hand, if the writingstyle is formal and dry, your brain perceives it the same way you experience beinglectured to while sitting in a roomful of passive attendees. No need to stay awake.But pictures and conversational style arejust the beginning.you are here ~xxv


how to use this bookHere"s what WE did:We used pidures, because your brain is tuned for visuals, not text As fur as yourbrain's concerned, a picture really ssworth 1024 words. And when text and pictureswork together, we embedded the text in the pictures because your brain worksmore effectively when the text is wiihin the thing the text refers to, as opposed to ina caption or buried in the text somewhere.We used repetitUm, saying the same thing in different waysand with different mediatypes, and multiplesenses, to increase the chance that the content gets coded codedinto more than one area ofyour brain.We used concepts and pictures in ~ways because your brain is tuned fornovelty, and we used pictures and ideas with at least SO'1M emf>tional content, becauseyour brain is tuned to pay attention to thebiochemlstry ofemotions. That whichcauses you to feel something is more likely to be remembered. even ifthat feeling isnothing more than a little humor; SU1"f1rise, or interest.We used a personalized, conversational style, because your brain is tuned to pay moreattention when it believes you 're in a conversation than ifit thinks you're passivelylistening to a presentation. Your brain does this even when you're reading.We included more than 50~ , because your brain is tuned to learn andremember more when you do things than when you readabout things. And wemade the exercises challenging-yet-do-able, because that's what most pet1J/.e prefer.We used multiple learning styles, because youmight prefer step-by-step procedures,while someone else wants to understand the big picture first, while someone elsejust wants to see a code example. But regardless ofyour own learning preference,everyone benefits from seeing the same content represented in multiple ways.We include content for both ridesofyourbrain; because the more ofyour brain youengage, the more likely you are to learn and remember, and the longer you canstay focused. Since working one side of the brain often means giving the other sidea chance to rest, you can be more productive at learning for a longer period oftime.And we included storie: and exercises that present J'TUWe than one point ofview,because your brain is tuned to learn more deeply when it's forced to makeevaluations andjudgements.We included chaIknges, with exercises, and byasking qrustions that don't always havea straight answer, because your brain is tuned to learn and remember when it hasto work at something (just as you can't get your body in shape by watching peopleat the gym). But we did our best to make sure that when you're working hard, it'son the right things: That you'renotspending oneexITa denLfrile processing a hard-tounderstandexample, or parsing difficult,jargon-Iaden, or extremely terse text.We used an 80/20 approach. We assume that ifyou 're going for a PhD in java,this won't be your only book. So we don't talk about everything. Just the stuffyou'llactually use.~8\"Barlle"xxviIntra


Herels what YOU ca., do to be.,d yourbrah1 i"to subltdssiot1.So, we did our part. The rest is up to you . These tips are astarting point; Listen to your brain and figure out what worksfor you and what doesn't. Try new things.the intralki. -this OUt dhd sf.itk 'tOh yOlJ.'r l'"e+l'"id9tt"ak . I. _ - - _ . _ - - - - - - - - - - -~ -----------------------------------------------------------•~ . Slow down. The more you understand,the less you have to memorize.Don'tjust 'read. Stop and think. When thebook asks you a question, don'tjust skip tothe answer. Imagine that someone really isasking the question. The more deeply youforce your brain to think, the better chanceyou have of learning and remembering.Do the exercises. Write your own notes.We put them in, but ifwe did them for you,that would be like having someone elsedo your workouts for you. And don'tjustlookat the exercises. Use a pencil. There'splenty of evidence that physical activitywhile learning can increase the learning.Read the "There are No Dumb Questions"That means all of them. They're notoptional side-bars-they're part of the corecontentl Sometimes the questions are moreuseful than the answers.Drink water. Lots of It.Your brain works best in a nice bath of fluid.Dehydration (which can happen before youever feel thirsty) decreases cognitive function.•Talk about It. Out loud.Speaking activates a different part ofthe brain. Ifyou're trying to understandsomething, or increase your chance ofremembering it later, say it out loud. Betterstill, try to explain it out loud to someoneelse . You'll learn more quickly, and you mightuncover ideas you hadn't known were therewhen you were reading about it.Listen to your brain.Pay attention to whether your brain is gettingoverloaded. Ifyou find yourself starting to skimthe surface or forget what you just read, it'stime for a break. Once you go past a certainpoint, you won't learn faster by trying to shovemore in, and you might even hurt the process.Don't do all your reading In one place.Stand-up, stretch, move around. changechairs, change rooms. It'll help your brainfeelsomething, and keeps your learning frombeing too connected to a particular place.Make this the last thing you read beforebed. Or at least the last challengIng thing.Part of the learning (especially the transferto long-term memory) happens afleryou putthe book down. Your brain needs time onits own, to do more processing. Ifyou put insomething new during that processing-time,some of what you just learned will be lost.• Feel somethlnglYour brain needs to know that this mauers. Getinvolved with the stories. Make up your 0\\>11captions for the photos. Groaning over a badjoke is still better than feeling nothing at all... Type and run the code.Type and run the code examples. Then youcan experiment with changing and improvingthe code (or breaking it, which is sometimesthe best way to figure alit what's reallyhappening). For long examples or Ready-bakecode, you can download the source files fromheadfirstjava.cornyou are here.xxvII


how to use this bookWhat you heed for this book:You do not need any other development tool. such as an IntegratedDevelopment Environment (IDE). We strongly recommend that you notuse anything but a-basic text editor until you complete this book (andespecially not until after chapter 16). An IDE can protect you from some ofthe details that really matter. so you're much bener off learning from thecommand-line and then. once you really understand what's happening.move to a tool that automates some of the process.SmlNG UP JAVA------------------,• If you don't already have a 1.5 orgreater Java 2 Standard Edition SDK (SoftwareDevelopment Kit), you need it. Ifyou're on Linux, Windows, or Solaris, you can gellt for freefrom java.sun.com (Sun's websile forJava developers). It usually takes nomore than two clicksfrom the main page togelto the J2SE downloads page. Get the latest non-beta version posted.The SDK includes everything you need tocompile and run Java.Ifyou're running Mac OS X10.4. the Java SDK isalready installed. It's partof OS X, and youdon't have todoanything else. Ifyou're on an earlier version of OS X. you have an earlierversion ofJava that will wor1< for95% ofthe code in this book.Note: This book is based on Java 1.5, but forstunningly unclear mar1


the introLast...tMinute thhtgs you need to know:This is a learning experience, not a reference book. We deliberatelystripped out everything that might get in the way of lmrningwhatever itis we're working on at that point in the book. And the first time through,you need to begin at the beginning, because the book makes assumptionsabout what you've already seen and Learned.We use simple UML.-IIke diagrams.Ifwe'd used pureUML, you'd be seeing something that looks like Java , butwith syntax that'sjust plain 1UTfYflf;. So we use a simplified version ofUMLthat doesn't conflict with Java syntax. Ifyou don't already know UML. youwon't have to worry about leamingJava and UML at the same time.We don't worry about organizing and packaging your owncode until the end of the book.In this book, you can get on with the business of learningJava , withoutstressing over some of the organizational or administrative details ofdeveLopingJava programs. You will, in the real world, need to know-anduse--these details, so we cover them in depth. But we save them for the endof the book (chapter 17). Relax while you ease intoJava, gently.sizeDogbarkQeatOchaseCatQ-The end-of-chapter exercises are mandatory; puzzles areoptional. Answers for both are at the end of each chapter.One thing you need to know about the puzzles-tmy're puxxles. As in Logicpuzzles, brain teasers, crossword puzzles, etc. The exercises are here to help}'ou practice what you've learned, and you should do them all. The puzzlesare a different story, and some of them are quite challenging in a puzzleway. These puzzles are meant for pualets, and you probably already know ifyou are one. Ifyou're not sure, we suggest you give some of them a try, butwhatever happens, don't be discouraged ifyou can't solve a puzzle or if yousimply can't be bothered to take the time to work them out.The 'Sharpen Your Pencil' exercises don't have answers.Not printed in the book, anyway. For some of them, there isno rightanswer, and for the others, part of the learning experience for the Sharpenactivities is for you to decide if and when your answers are right, (Some ofour suggested answers are available on wickedlysman.com)The code examples are as lean as possibleIt's frustrating to wade through 200 lines of code looking for the two linesyou need to understand. Most examples in this book are shown within thesmallest possible context, so that the part you're trying to learn is clear andsimple. So don't expect the code to be robust, or even complete. That'sJour assignment for after you finish the book. The book examples arewritten specifically for learning, and aren't alwaysfully-functional.you are here ~xxix


tech editing: Jessica and Valentinfecht-tical Editors"Credit goes to all, but mistakes are the sale reponsibility of theauthor...", Does anyone really believe that? See the two people onthis page? If you find technical problems, it's probably theirfaulL : )Vjj\el'lt,i,,'s ·beJess works at Hewlett-Packard on the Self­Healing Services Team. She has a Bachelor'sin Computer Engineering from VillanovaUniversity, has her SCPJ 1.4 and SCWCDcertifications, and is literally months awayfrom receiving her Masters in SoftwareEngineering at Drexel University (whewl)When she's not working, studying ormotoring in her MINI Cooper S,jess canbe found fighting her cat for yam as shecompletes her latest knitting or crochetproject (anybody want a hat?) She isoriginally from Salt Lake City, Utah (no,she's not Mormon... yes, you were toogoing to ask) and is currently living nearPhiladelphia with her husband. Mendra, andtwo cats: Chai and Sake.You can catch her moderating technicalforums acjavaranch.com.Valentin Valentin Creuaz has a Masters degreein Information and Computer Science fromthe Swiss Federal Institute ofTechnology inLausanne (EPFL). He has worked as a softwareengineer with SRI International (Menlo Park,CA) and as a principal engineer in the SoftwareEngineering Laboratory of EPFL.Valentin is the co-founder and CTO ofCondrisTechnologies, a company specializing in thedevelopment ofsoftware architecture solutions.His research and development interestsinclude aspect-oriented technologies, designand architectural patterns, web services, andsoftware architecture. Besides taking care ofhis wife. gardening, reading. and doing somesport, Valentin moderates the SCBCD andSCDJWS forums atJavaranch.com. He holdsthe SCJP, SCjD, SCBCD, scwco, and SCD]WScertifications. He has also bad the opporruniryto serve as a co-author for Whizlabs SCBCDExam Simulator.(We're still in shock from seeing him in a tie.)XXXintra


t\'"~ditOther people to b~e:•41 O'Reilly:Our biggest thanks to Mike Loukides at O'Reilly, for taking achance on this, and helping to shape the Head First concept intoa book (and series) . As this second edition goes to print thereare now five Head First books, and he's been with us all the way.To Tim O'Reilly, for his willingness 10 launch into somethingcompletely new and different. Thanks to the clever Kyle Hart forfiguring out how Head First fits into the world, and for launchingthe series. Finally, to Edie Freedman for designing the Head First"emphasize the head" cover.Our intrepidbeta testers and reviewer team:Our top honors and thanks go to the director ofourjavaranchtech review team.johannes deJong. This is your fifth time aroundwith us on a Head First book, and we're thrilled you're still speakingto us, Jeff Cumps is on his third book with us now and relentlessabout finding areas where we needed to be more clear or correct.Corey McGlone, you rock. And we think you give the clearestexplanations on javaranch, You'll probably notice we stole one ortwo of them. Jason Menard saved our technical butts on morethan a few details, and Thomas Paul, as always, g-ave us expertfeedback and found the subtleJava issues the rest of us missed.Jane Griscti has herJava chops (and knows a thing or two about",-riting) and it was great to have her helping on the new editionalong with long-timejavarancher Barry Gaunt:\farilyn de Queiroz gave us excellent help on both editions of thebook. ChrisJones,Jobn Nyquist, James Cubeta, Terri Cubeta,and Ira Becker gave us a ton of help on the first edition.Special thanks to a few of the Head Firsters who've been helpingus from the beginning: Angelo Celeste, Mikalai Zaikin, andThomas Duff (twduff.corn). And thanks to our terrific agent, DavidRoge1berg ofStudioB (but seriously, what about the movie rights?)$OfrIe ~ 0".... Java!')I.~t....t .... !vi~e ....s...the intrayou are here ~xxxi


" still more acknowledgementsJust whet1 you thought there wouldt1't be at1YtMore ackt1owledgetMet1ts*.MoreJava technicalexperts woo helped out on thefirst edition (in pseudo-random order):Emiko Hori, Michael Taupitz, Mike Gallihugh, Manish Hatwalne,James Chegwidden,Shweta Mathur, Mohamed Mazahim,John Paverd,Joseph Bih, Skulrat Patanavanich,Sunil Palicha, Suddhasatwa Ghosh, Ramki Srinivasan, Alfred Raouf, Angelo Celeste,Mikalai Zaikin,John Zoetebier,Jim Pleger, Barry Gaunt, and Mark Dielen.The first edition puzzle team:Dirk Schreckmann, Mary 'JavaCross Champion" Leners, RodneyJ. Woodruff, Gavin Bong,and Jason Menard.Javaranch is lucky to have you all helping out.Other co-conspirators to thank:Paul Wheaton, thejavaranch Trail Boss for supporting thousands ofJava learners.Solveig Haugland, mistress ofJ2EE and author of "Dating Design Patterns".Authors Don Smith and Tom Negrino (backupbrain.com), for helping us navigate thetech book world.Our Head First partners in crime, Eric Freeman and Beth Freeman (authors ofHead FirstDesign Patterns), for giving us the Bawls" to finish this on time.Sherry Dorris, for the things that really matter.Brave Early Adoptersofthe Head Firstseries:Joe Litton, Ross P. Goldberg, Dominic Da Silva, honestpuck, Danny Bromberg, StephenLepp, Elton Hughes, Eric Christensen, Vulinh Nguyen, Mark Rau, Abdulhaf, NathanOliphant, Michael Bradly, Alex Darrow, Michael Fischer, Sarah Nottingham, Tim Allen,Bob Thomas, and Mike Bibby (the first)."The large number of acknOWledgements is because we're testing the theory that everyone mentioned ina book acknowledgement will bUy at least one copy, probably more, what with relatives and everyth ing. Ifyou'd like to be in the acknowledgement of our next book, and you have a large family, write to us.xxxiiintro


1 dive in A Quick DipBreaking the SurfaceCome on, the water'sgreat! We'll dive right in andwrite some code, then compile andrun it. We're talking syntax, loopingand branching, and a look at whatmakes J alia so cool. You'll becoding in no time.Java takes you to new places. From its humble release to the public as the(wimpy) version 1.02,Java seduced programmers with Its friendly syntax, object-orlented features,memory management, and best of aU-the promise of portability.The lure of wrlte-once/runanywhereIsjust too strong. A devoted followlnq exploded, as programmers fought against bugs,limitations, and, on yeah, the fact that it was dog slow. But that was ages ago. If you're just starting inJava,you're lucky. Some of us had to walk five miles in the snow, uphill both ways (barefoot), toget even the most trivial applet to work.more powerful Javaof today. .....".--..•.But you, why,yov get to ride the sleeker, faster. muchthis is a new chapter 1


the way Java worksfhe Way Java WorksThe goal Is to write one application (in thisexample, an interactive party Invitation) and haveIt work on whatever device your friends have.source code (orthe Interactiveparty hwltaUon. ----..Method Pany()Oalo;l


dive In A Quick DipWhat you'll do in Jav~You'll type a source code file, compile It using theJavac complier, then run the complied bytecodeon a .Java virtual machine.java.awl·;r:.pon java.awtevenL·;:tass Party (pc.;b!ic void bu~dlnvlte() (Fl3me r=IlllW FtameO;Labell =new LabellParty atTlm's1;B tton b=new ButIoI'I('You ber) ;Button C=te« Button("Shool me'):Panel p=new PanelO;p.addO):} II more code here...)SourceoType your source code.Saveas:Party.JavaMethod Party()oaload_O1Invokespedal #1 4 returnMethod void bu lidInviteOonew #23 dup4 Invokespec1al #J Output(code)Complied code: Party.dassPartY at Tim's1VirtualMachlttUoRun the program bystarting the JavaVirtualMachine (JVM) with theParty.doss file. The JVMtranslates the bytecodeinto something theunderlying platformunderstands, and runsyour program.(NoU: U,is is ~ ....e.l"t to be d h-kial... '101


Avery brief history of Java~ 3500I!~ 3000'!lIlI 2500"acS 2000lill~>.,CII 1500..G).z:. 1000.51ft 500G)1ft1ft0lIlIUJava 1.02250 classes500 classesJava 2(wnloKs 1.2 .. t~)Java 5.0(wrsloKs 1.5 attd up)Slow.A little faster.2300dasses3500 classes~>«l~'0~.s01:cCute name and logo.Fun to use. Lots ofbugs. Applets arethe Big Thing.More capable, friendlier.Becoming verypopultJr.Better GUI code.Much faster.Can (sometimes) run atnative speeds. Serious,powerful. Comes in threeflavors: Micro Edition (J2ME),Standard Edition (J2SE) andEnterprise Edition (J2EE).Becomes the langutlge ofchola for new enterprise(especially web-based) andmobile applications.More power, ~/e,todevelop with.Besides adding more than athousand additional classes,Java 5.0 (known as"Tiger"')added major changes tothe language itself, makingit easier (at least in theory)for programmers and givingit new features that werepopular in other languages.....'-2 a.IIIs: o~


dive In A Quick DipLook how easy Itis towrite Java.Try to guess what each line of code Is doinq.;(answersare on the next page),.int size = 27;String name = UFido";Dog rnyDog = new Dog(name, size);x = size - 5jif (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);String nurn = US";int Z = Integar.parselnt(nurn);-:.....-y {readTheFila(UrnyFile.txt H ) ;}catch(FileNotFoundException ex) {syetem.out.print(UFile not found.");}Q..: I see Java 2 and Java 5.0, but was there a Java 3-.d 41 And why Is It Java 5.0 but not Java 2.07: The joys of marketing...when the version of Javaed from 1.1 to 1.2, the changes to Java were sornatic that the marketers decided we needed a whole"name:so they started calling It Java 2, even thoughactual version of Java was 1.2. But versions 1.3 and 1.4ftfe still considered Java 2. There never was a Java 3 or~_ Be9inning with Java version 1.5,the marketers decidedonce again that the changes were so dramatic that anew name was needed (and most developers agreed), sothey looked at the options.The next number In the namesequence woul d be ·3: but caIIing Java 1.5Java 3 seemedmore confusing, so they decided to name It Java 5.0 tomatch the "5~ in version "l.S~So, the original Java was versions 1.02 (the first officialrelease) through 1.1 were just"Java" Versions 1,2,1.3, and1.4 were "Java 2~ And beginning with version 1.5,Java iscalled "Java 5.0~ But you'll also see it called "Java 5· (withoutthe ",0") and "Tiger" (its original code-name). We have noidea what will happen with the next release...you are here ~ 5


.'why Java Is coolpen your pencil answerslook how easy ItIs towrite Java.Don't wotryabout whetheryou understand any ofthis yetiEverything here Is explained in great detall!n the book, mostwithin the first 40 pages).If Java resembles a language you'veused in the past, some of th is will be simple. If not, don't worryabout it. We'llget there...int size::; 27;String name = #FidoHjDog myDog ::; new Dog (name, size);x = size - 5;if (x < 15) myDog .bark(8);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.'while (x > 3) {}myDog.play( l ;intl] numList = {2,4,6,8};System.out.print(HHello R ) ;System.out.print(HDogl U + name);String num ::; US";fnt z = Integer.parselnt(num);try {}catch(FileNotFoundException ex) {System.out.print(HFile not found.");}try to do ~i~ ...~ybc ~ thi~ 'IlI('l"t try~ isJ,'t ~.lI'.Ued to ~ ..~ ~ tot file IIolMCll "..yFile.bi· (ar .Ii. lust TRy' 1;0 ~e.ld ~ fild..lIS! be the erod of ~ "I:.h~ to try", sor ~lOC.U 'f'" te


dive In A Quick DipCode structure i., JavaWhat goes in asource file?A source code file (with the .javaextension) holds one classdefinition.The class represents a pieceof your program, although a verytiny application might needjusta single class. The class must gowithin a pair of curly braces.public class Dog {classPut a class in a source file.Put methods in a class.Put statements In a method.What goes in aclass?A class has one or more methods.In the Dog class, the bark methodwill hold instructions for how theDog should bark. Your methodsmust be declared inside a class(in other words, within the curlybraces ofthe class).public class Dog {void bark () {tttefho~What goes In amethod?Within the curly braces ofamethod, write your instructionsfor how that method should beperformed. Method code is basicallya set of statements, and fornow you can think of a methodkind of like a function or procedure.public class Dogvoid bark () {s tatementl ;statement2 ;}sfafetttet1fsyou are here • 7l


a Java classAttafottty of aclassWhen thejVM starts running, it looks for the class you give it at the commandline. Then it starts looking for a specially-Written method that looksexactly like:public static void main (String() argsl (II your code goes hereNext, theJVM runs everything between the curly braces { }ofyour mainmethod. EveryJava application has to have at least one class. and at leastone main method (not one main per class;just one main per 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


dive In A Quick DipWriti"Q aclass with amainInJava, everything goes in a class. You'll type your source code file (with a.java extension), then compile it into a new class file (with a .class extension).When you run your program, you're really running a class.Running a program means telling theJava VIrtual Machine (JVM) to "Load theHello class, then start executing its main () method. Keep running 'til all thecode in main is finished."In chapter 2. we go deeper into the whole class thing, but for now, all you need tothink is, how cUJ 1 writeJava code $0 that itwill run1 And it all begins with mainf).The mamO method is where your program starts running.No matter how big your program is (in other words, no matter how many classesyour program uses), there's got to be a mainO method to get the ball rolling.MyFlrstApp.Java4t-~~...,,\~t''''''-MyFlratApp.claupublic class MyFirst.Aflp (public static void main (strinq[] arqs)Systall.out.priJ)t1n("I Ma!H);System.out.println ('''l.'be World") ;)o SaveMyFirstApp. javao Compilejavac MyFirstApp.javaE)Run~%j ava MyFirstAppI Rule!The Worldyou are here ~ 9


statements, looping, branchingWhat ca., you say I., the",al., ",ethod1Once you 're inside main (or any method), the funbegins. You can say all the normal things that you sayin most programming languages to make the computerdo something.Your code can tell theJVM to:o do solttethi.,gStatements:declaratlons, assignments.method calls.etc,int x ~ 3;String name = ~Dirk";x = x * 17;System .ouc .print("x is " + x);double d = Math.random();II this is a commente do solttethlttQ agal., and agal"Loops: (or and whilewhile (x > 12)x = )( - 1;for (int x ee 0; x < 10; x = x + 1) (System.out.print("x is now II + x);e do solttethlttQ uttder this CO.,dltlonBranching: If/else testsif (x == 10) 1System.out.print("x mUSt be 10");else {System.out.print("x isn't lOll);if «x < 3) & (name.equals("Dirk ll » ) )System.out.println(~Gently ");System.out.print("this line runs no matter what ll ) ;SyntaxFun.. Eachstatement must end in asemicolon.x=x+1;.. A single-line comment beginswith two forward slashes.x = 22;II this line disturbs me.. Most white space doesn't maner.x.. Variables are declared with aname and a type (you'll learn aboutall the Java types In chapter 3).int weight;Iitype: int, name:3weight.. Classes and methods must bedeflned within a pair of curly braces.public void go ( ) (II amazing code here}10 chapter 1


dive In A Quick Dipwhile (more Balls == true) {}keepJugg/ing() ;.»Loopit1g a.,d loopi.,g at'd...Java has three standard Looping constructs: uihile;do-iahile, and for. You'll get the full loop scoop laterin the book, but not for awhile, so let's do whi~fornow.The syntax (not to mention logic) is so simpleyou're probably asleep already. As long as somecondition is true, you do everything inside theloop block. The loop block is bounded by a pair ofcurly braces, so whatever you want to repeat needsto be inside that block.The key to a loop is the conditionaltest. lnJava, aconditional test is an expression that results in aboolean vaJue-in other words, something that iseither true orfalse.lfyou say something like , "While i.aCnamlnTMTubis true; keep scooping", you have a clear booleantest. There either is ice cream in the cub or thereisn't. But if you were to say. "While Bob keepscooping", you don't have a real test, To makethat work, you'd have to change it to somethinglike. "While Bob is snoring... ~ or "While Bob is notwearing plaid..."ShMple boolean testsYou can do a simple boolean test by checkingthe value ofa variable, using a comparison operatorincluding:< (less than)> (greater than)= (equality) (yes, that's two equals signs)Notice the difference between the assignmentoperator (a singleequals sign) and the equalsoperator (two equals signs). Lots of programmersaccidentally type • when they want -. (But notyou.)iot x ~ 4; II assign 4 to xwhile (x > 3) {II loop code will run becauseII x is greater than 3x = x-I; II or we'd loop foreverinc z = 27; IIwhile (z =~ 17)II loop code will not run becauseII z is not equal to 17you are here ~ 11


Java basicsQ: Whydoes everything haveto be In a dass7A: ~ava is an object-oriented(00) language. It's not Iiketheold days when you had steamdrivencompliers and wrote onemonolithic source file with a pileof procedures. In chapter 2 you'lllearn that a class Is a blueprint foran object, and that nearly everythingin Java Is an object.Q: Do I have to put a main Inevery class Iwrite1A: Nope .A Java prog rammight use dozens of classes (evenhundreds), but you might onlyhave one with a maIn methodtheone that starts the programrunning.You might wrIte testclasses, though, that have mainmethods for testing your otherclasses,Q: In my other language Icando a boolean test on an Integer.InJava, can Isay something like:int x .. 1;while (J&:) (A: No.A boolean and anintegerare not compatible types InJava.Since the result of a conditionaltest must be a boolean, theonly varIable you can directly test(without using a comparison operator)Is a boolean. For example,you can say:boolean isBot • true;while (llIHot) ( )Exall1ple of awhile looppublic class Loopy {public static void main (String[] args) (int x .. 1;System.out.println("Before the Loop");while (x < 4) {)System.out.println("In the loop");System.out.prlntln("Value of x is " + x);x = x + 1;System.out.println("This is after the loop");% java LoopyBefore the LoopIn the loopVa.lue ot x is 1In the loopVa.lue of x i8 2In th8 loopValue of x is 3This is aft.r the loop,------ BULLD POI~ ----------,• Statements end ina semicolon;• Code blocks are defined byapair of cu~y braces { }• Declare an int variable with a name and atype: Intx;••The assignment operator Isone equals sign =The equals operator uses two equals signs ==• Awhile loop runs everything within itsblock (defined by cu~ybraces) as long as the conditional test Is true.• If the conditional test isfa1S8, the while loop code block won'trun, and execution will move down to the code Immediatelyefterthe loop block.• Put a boolean test Inside parentheses:while (x = 4) ( }12 chapter 1


dive In A Quick DipConditlo"al bra"chl"QJava, an iftest is basically the same as the boolean test in a'leloop - except instead ofsaying, ~UJhile there's still beer.,",u']] say, ~ifthere's still beer.,"cLa s s IfTest (public static void main (String[) args) {int x = 3;if (x == 3)System.out.println("x must be 3 H ) ;System.out.println("This runs no matter what");, java If'restJI: must be 3This runs no matter whatThe code above executes the line that prints "x must be 3" onlyifthe condition (x is equal to 3) is true. Regardless ofwhetherit's true, though, the line that prints, "This runs no matter what"~ill run. So depending on the value of x; either one statementor two will print out.But we can add an else to the condition, so that we cansay something like, "Iftbere's still beer, keep coding, else(otherwise) get more beer, and then continue on..."::lass IfTest2 {public static void main (String!) a rqs ) (int x = 2;if (x == 3)System.out.println("x must be 3 H ) ;else (System.out.println("x is NOT JH);System.out.println("This runs no matter what");Glv~n the output:% javaDooBeeDooBeeDooBeeDoFJIIln th~ missing code:public class DooBee {public static void main (StringO args) I}intx=l;while (x


serious Java appCoding aSerious fushtessApplicatfottLet's put all your"new Java skills to good use withsomething practical. We need a class with a mains); an intand a String variable. a whik loop, and an iftest. A littlemore polish, and you'll be building that business backendin no time. But beJoreyou look at the code on thispage, think for a moment about how youwould code thatclassic children's favorite, "99 bottles ofbeer."pUblic class BeerSong (public static void main (String[) args) (int beerNum 99;String word ~ "bottles";while (beerNum > 0) Iif (beerNum == 1) (word - "bottle H ; II s i ngul a r , as in ONE bottle .System.out.println(beerNum + " H + word + " of beer on the wall H ) ;System.out.println(beerNum + " H + word + " of beer.");System.out.println("Take one down. H ) ;System.out .println("Pass it around. ") ;beerNum = beerNum - 1;if (beerNum > 0) (System.out .println(beerNum + " H + word + " of beer on che wall H ) ;else (System.out.println("No more bottles of beer on the wall H ) ;) II end elsef II end while loop) II end main methodII en~ classThere's stili one little flaw In ourcode. It complies and runs. but theoutput Isn't 100% perfect. See Ifyou can spot the flaw, and fix It.14 chapter 1


dive In A Quick DipBob's alarm clock rings at 8:30 Monday morning, just like every other weekday.But Bob had a wildweekend, and reaches for the SNOOZE button.And that's when the action starts, and the Java-enabled appliancescome to life.First, the alarm clock sends a message to the coffee maker* "Hey, the geek'ssleeping in again, delay the coffee 12 minutes."The coffee maker sends a message to the Motorola'>'toaster, "Hold the toast, Bob's snoozing."( -The alarm clock then sends a message to Bob'sNokia Navigator cell phone, "Call Bob's 9o'clock and tell him we're running a little late."Finally, the alarm clock sends a message toSam's (Sam is the dog) wireless collar, with the too-familiar signal thatmeans, "Get the paper, but don't expect a walk."A few minutes later, the alarm goes off again. And again Bobhits SNOOZE and the appliances start chattering. Finally,the alarm rings a third time. But just as Bob reaches for thesnooze button, the clock sends the "jump and bark" signal to Sam'scollar. Shocked to full consciousness, Bob rises, grateful that hisJavaskills and a Little trip to Radio Sbackn< have enhanced the dailyroutines of his life.His toast is toasted.His coffee steams.His paper awaits.Just another wonderful morning in TheJava--ErUlbled HOMSB.You can have aJava~enabledhome. Stick with a sensible solution using Java,Ethernet, andJini technology. Beware of imitations using other so-called "plugand play" (which actually means "plug and play with it for the next three daystrying to get it to work") or "portable" platforms. Bob 's sister Berry Died one ofthose others, and the results were, well, not very appealing, or safe.Bit of a shame about her dog, too...Could this story be true? Yes and no.While there are versions of Java running in devicesIncluding PDAs, cell phones (especiallycell phones), pagers, rings, smart cards,and more -you might not find a Javatoaster or dog collar.But even jf you can'tfind a Java-enabled version of your favorite gadget. you can stili run it as if it were aJava device by controlling it through some other Interface (say, your laptop) that isrunnIng Java.This Is known as the Jini surrogate architecture. Y~ you con have thatgeek dream home.·IPmulticastIf you're gonna be all picky about protocolyou are her e ~ 15


let's write a programTry my newphrase-a-matic andyou'll be a slick talkerjust like the boss orthose guys in marketing.public class PhraseQlatic (public static void main (String(l args) {/ / iliaD thNt sets ofwords tochoose from. leW yoar own!String[] wordListOne ::: {"24/7"/'multi­Tiar","30,OOO foot", "B-to-B" , "win-win" , "frontend", "web- based" , "pervasive", "smart", "sixsigma","cri tical-path" , "dynamic"} jStrinq[] wordListTwo ::: I "empowered", "sticky","value-added.", "oriented", "centric", "distributed","clustered", "branded", "outaide-the-box", ''positioned'',"networked", "f ocused" / "leveraged", "aligned","targeted", "shared" / "cooperative", "accelerated"};OK, so the beer song wasn't reallya seriousbusiness application. Still need somethingpractical to show the boss? Check out thePhrase-O-Matlc code.Strinq[] wordListThree = {"process", "tippingpoint","solution", "architecture", "core competency","strategy", "mindshare", "portal" , "apace" / "vision",'~adigm",~ssion"};O/ / find out!low many word. aN In ...d11btiot one.Lenqth '" wordListOne .length;int twoLength '" wordListTwo.length;int threeLength =wordListThree.lenqthj/ / generate .... random numbersint randl :lII (int) (Math.random() '" ooeLenqth) jint rand2 ::: (int) (Math .randomO • twoLength);int rand3 '" (int) (Math.randa:n() " threeLength);//now build a pllrueString phrase'" wordListOne [randl] + " " +wordListTwo[rand2] + " " + wordListTbree[rand3] ;/ / print oat the phra..Sys.tem.out.println("What we need is a " + phrase);}16 ch apter 1


Phrase...O...Matlclow Itworks,In a nutshell, the program makes three lists ofwords, then randomly picks one wordfrom each of the three lists; and prints out the result, Don't worry ifyou don't underm.ndexactly what's happening in each line. For gosh sakes, you've got the whole book~d ofyou, so relax. This isjust a quick look from a 30,000 foot outside-the-boxa.rgeted leveraged paradigm.dive In A Quick Dipi. The first step is to create three String arrays - the containers that will hold all the-..ords. Declaring and creating an array is easy; here's a small one:bch word is in quotes (as all good Strings must be) and separated by commas.• For each ofthe three lists (arrays), the goal is to pick a random word, so we haveknow how many words are in each list, If there are 14 words in a list, then we needrandom number between 0 and 13 (Java arrays are zero-based, so the first word is atition 0, the second word position I, and the last word is position 13 in a 14-element~') . Quite handily, ajava array is more than happy to tell you its length. Youjustto ask. In the pets array, we'd say.sat z =: pets. length;z would now hold the value 3.what we needhere Is a •••pervasive targetedprocess,. We need three rand~m numbers.Java ships out-of-the-box, off-the-shelf, shrinkpped,and core competent with a set ofmath methods (for now, think of them asctions). The random () method returns a random number between 0 and not-'te-l , so we have to multiply it by the number of elements (the array length) in thewe're using. We have to force the result to be an integer (no decimals allowed!) soput in a cast (you'll get the details in chapter 4). It's the same as ifwe had any floatpointnumber that we wanted to convert to an integer.~t z • (int) 24.6;ow we get to build the phrase, by picking a word from each ofthe three lists,smooshing them together (also inserting spaces between words). We use the ,,+nrator, which concatenaus (we prefer the more technical'S1TU>OShes') the String objectsether. To get an element from an array, you give the array the index number (posi-- n) ofthe thing you want using:SUinq s '" pet. [0l : / / s is now the String "FiOO".... + " " + "is a dog"; / / • is now "Fido ill a dog"dynamic outsidethe-boxtipplngpointsmart distributedcore competency24/1 empoweredmindshare30,000 fool win-winvisionstx-slqrna networkedportal5. Finally, we print the phrase to the command-line and... voilaI Wen in marketing.you are here ~ 17


the complier and the JVMFireside Chats~Ton1gb.t's Talk: Thecompllerand~e JVM battle overthe question."Who'smore lmportaJlU"!he Java Vlrtual MachineWhat, are you kidding? HELLO. I amJava.I'm the guy who actually makes a programrun. The compilerjust gives you a file. That'sit. Just a file. You can print it out and use itfor wall paper, kindling, lining the bird cagewhateuer, but the file doesn't do anything unlessI'm there La run it.And that's another thing. the compiler hasno sense of humor. Then again. if ycm had tospend all day checking nit-picky little syntaxviolations...I'm not saying you're, like, complmly useless.But really, what is it that you do? Seriously. Ihave no idea. A programmer couldjust writebytecode by hand, and I'd take it. You mightbe out ofajob soon, buddy.(I rest my case on the humor thing.) But youstill didn't answer my question, what doyouactually do?The ComplierI don't appreciate that tone.Excuse me, but without me, what exactlywould you run? There's a TMSonJava wasdesigned to use a bytecode compiler, for yourinformation. IfJava were a purely interpretedlanguage, where-s-at runtime-s-the virtualmachine had to translate straight-from-a-texteditorsource code, a java program wouldrun at a ludicrously glacial pace. java's had achallenging enough time convincing peoplethat it's finally fast and powerful enough formostjobs.Excuse me, but that's quite an ignorant (notto mention arrogant) perspective. While itis true that-tJuoretically--you can run anyproperly formatted bytecode even if it didn'tcome out of a Java compiler, in practice that'sabsurd. A programmer writing bytecode byhand is like doing your word processing bywriting raw postscript. And I would appreciateit ifyou would not refer to me as "buddy."18 chapter 1


The Java Virtual MachineBut some still get through! I can throw Class­CastExceptions and sometimes I get peopletrying to put the wrong type of thing in anarray that was declared to hold somethingelse, and-OK. Sure. But what about security? Look at allthe security stuff I do , and you're like, what,checking for semicolons? Oooohhh big securityrisk ! Thank goodness for youlWhatever. I have to do that same stuff too,though, just to make sure nobody snuck inafter you and changed the bytecode beforerunning it.Oh, you can count on it. Buddy.The Compilerdive In A Quick DipRemember thatJava is a strongly-typed language,and that means I can't allow variablesto hold data ofthe wrong type. This is acrucial safety feature, and I'm able to stop thevast majority ofviolations before they ever getto you. And I also-Excuse me, but I wasn't done. And yes, thereare some datatype exceptions that can emergeat runtime, but some of those have to beallowed to support one ofJava's other importantfeatures--dynamic binding. At runtime,aJava program can include new objects thatweren't even known to the original programmer,so I have to allow a certain amount offlexibility. But myjob is to stop anything thatwould never-could never-succeed at runtime.Usually I can tell when something won 'twork, for example, ifa programmer accidentallytried to use a Button object as a Socketconnection, I would detect that and thusprotect him from causing harm at runtime.Excuse me, but I am the first line ofdefense,as they say. The datatype violations I previouslydescribed could wreak havoc in a programifthey were allowed to manifest. I am alsothe one who prevents access violations, suchas code trying to invoke a private method, orchange a method that - for security reasons- must never be changed. I stop people fromtouching code they're not meant to see,including code trying to access another class'critical data. It would take hours, perhaps dayseven, to describe the significance of my work.Of course, but as I indicated previously, if Ididn't prevent what amounts to perhaps 99%of the potential problems, you would grind toa halt. And it looks like we're out of time, sowe'll have to revisit this in a later chat.you a re here ~ 19•


exercise: Code MagnetsCode MagnetsA working Java program is all scrambled upon the fridge. Can you rearrange the codesnippets to make a working Java programthat produces the output listed below?Some of the curly braces fell on the floorand they were too small to pick up, so feelfree to add as many of those as you need!if ( JC


dive In A Quick Dip"BE the oomrilerEach ofthe JIlVll files on this pagerepresents 11 complete source file.Your job is to pIa}' cotJ1Piler anddetermine whether each ofthesefiles will cottlPile. If-theywon'tcottlPile. howwoald you l"lX them?Bpublic static void main(String [] args)int x = 5;while ( x > 1 )x = x-I;if ( x < 3) {System.out.println(~small X~)iA~_ass Exerciselb {public static void main(String [) args)int x '" Iiwhile ( x < 10if ( x > 3) (systam.out.println(~bigX")icclass Exerciselb {int x • 5;while ( x > 1 )x = x - Iiif ( x < 3) (System.out.println(~smallx~);you are here ~ 21


puzzle: crosswordJa~Cr~sst.Olet's give your right brain somethIng to do.It'syour standardcrossword, but almost allof the solution words are from chapter 1.Justto keep you awake, we alsothrew in a few(non-Java) words from the high-tech world.4 SII ~1 2 J8 -9 10 ~I-2-f- ~ I-- 134 5 6If-'---l..-- - - - ~18 9Across4. Command-line invoker6. Back again?8. Can't go both ways9. Acronym for your laptop'S power12. number variabletype13. Acronymfor achip14. SaysomethIng18. Quite a crew of characters19. Announcea new class or method21. What'sa prompt good for?I-20 -L- '--bLDown2111. Not an integer (or__your boat)2. Come back empty-handed3. Open house5. 'ThIngs' holders7. Until attitudes improve10. Sourcecode consumer11 . Can't pin it down13. Dept.of LANJockeys1S. Shockingmodifier16. Justgona haveone17. How to get things done20. Bytecode consumer\22 chapter 1


dive In A Quick DipA short Java program is listed below. One block of the programis missing. Your challenge is to match the candidate block ofcode (on the left),with the output that you'd see if the blockwere inserted. Not all the lines of output will be used, and someof the lines of output might be used more than once. Draw linesconnecting the candidate blocks of code with their matchingcommand-line output.(The answers are at the end of the chapter).class Test {public static void main (String [)int x 0;int y = 0;while x < 5 )args)System.out.print(x + "" + y +" ");x = x + 1;candidates:Possible output:00 11 21 32 42lJ. 21 32 42 5300 11 23 36 41002 14 25 36 41you are here ~ 23


puzzle: Pool PuzzleP~l puzzleYourjob is to take code snippets from thepool and place them into the blanklines in the code.You may not use thesame snippet more than once,andyou won't need to use all the snippets.Your goal is to make a cia5S thatwill compile and run and produce theoutput listed. Don't be fooled-this one'sharder than it looks.class PoolPu2zleOne {public static void main(String (I arga) {int x = OJwhile ( ) {if ( x < 1 ) {}if ( ) {Output }if ( x 1 ) {%java PoolPuzzleOnea noiseannoysan oyster}if ) {}System.out.println("");}}Note: Each snippetfrom the pool can beused only oncel24 chapter 1


e Magnets:__~ss Shuftlel {~~lic static void main(String (J args) {int x = 3;....nile (x > 0) {Aclass Exercise1b {}dive In A Quick Dippublic static void main(String I] arqs) {int x = 1;while ( x < 10 )x=x+l;if ( x > 3) {System.out.println("big x")jThis will compile and run (no output), butwithout Q line added to the program, itwould run forever inan infinite 'while' loop!}if (x > 2) {Systern.out.print(Ua")i}x = x - IjSystem.out.print("-");if (x == 2) {systern.out.print(Nb e")j}if (x == 1), {Systern.out.print("d")jx = x - Ij}class Foo {public static void main(String I] args) {int x = s;while ( x > 1 )x = x - IiB if ( x < 3) {system.out.println("small x");This file won't compile without 0} class d~c1Qratlon, and don't forget) the matching curly brace!j a v a Shuffle!a-b c - dclass Exerciss1b {public static void main(String Uargs) {int x = Sjwhile ( x > 1x .. x - 1;C if ( x < 3)System.out.println(~smallX·]i}The 'while' loop code must be insidea method. It can't just behanging out inside the class.you are here ~ 25


puzzle answersclass PoolPuzzleOne {public static void main(String (] args) {int x == 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;• sfF IV PJ A V A 'L 0 0 p U,,- -R W.E-I B-IS B A INIt 'V'"-1:R C H A D lA N T 0 A I- - -Y L M R It t's y s ir E 8 L.M a u T P R r N TT A I A~- - - - ~A I L B M189S T R I N G D E C L A R eI R E Tf--f--C~J H'---- - -V 011 C 0 M M A N Dclass Tesc Ipublic scat:ic void main (Scring [ 1 args) (i n c l< ~ 0;i nc y - 0;wh i Ie ( x < 5 l (}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);"""slble output:-}}X = X + 1;}' y j ava PoolPuzzlcOneCt noiseanno~'san o ~'s te r.I.f I Y < 5 )II - X + 1,UIy


2 classes and objectsA Trip to ObjectvilleWe’re going toObjectville! We’releaving this dusty ol’procedural town for good.I’ll send you a postcard.I was told there would be objects. this is a new chapter 27


once upon a time in ObjectvilleChair Wars(or How Objects Can Change Your Life) Othe spec the chairIn Larry’s cube rotate(shapeNum) {// make the shape rotate 360º}playSound(shapeNum) {// use shapeNum to lookup which// AIF sound to play, and play it}At Brad’s laptop at the cafe }}}28 chapter 2


classes and objectsLarry thought he’d nailed it. He could almost feel the rolledsteel of the Aeron beneath his...But wait! There’s been a spec change. There will be an amoeba shapeon the screen, with the others.When the user clicks on theamoeba, it will rotate like theothers, and play a .hif sound filewhatgotaddedtothespecBack in Larry’s cube 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} At Brad’s laptop at the beach Amoebarotate() {// code to rotate an amoeba}playSound() {// code to play the new// .hif file for an amoeba}you are here429


once upon a time in ObjectvilleLarry snuck in just moments ahead of Brad. 1) determine the rectangle that surrounds the shape2) calculate the center of that rectangle, and rotate the shape around that point. Ameoba rotation point in Larryand Brad’s version:Whatthespecconvenientlyforgot to mentionWhere the ameba rotationpoint should be:Back in Larry’s cube 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}30 chapter 2At Brad’s laptop on his lawnchair at the Telluride Bluegrass Festival Amoebaint xPointint yPointrotate() {// code to rotate an amoeba// using amoeba’s x and y}playSound() {// code to play the new// .hif file for an amoeba}


classes and objectsSo, Brad the OO guy got the chair, right? What Larry wanted(figured the chair would impress her)Squarerotate()playSound()Circlerotate()playSound()Trianglerotate()playSound()Amoebarotate()playSound()1Ilookedatwhatallfourclasseshaveincommon.2They’reShapes,andtheyallrotateandplaySound. SoIabstractedoutthecommon features and put them into anew class called Shape.You can read this as, “Square inherits from Shape”,“Circle inherits from Shape”, and so on. I removedrotate() and playSound() from the other shapes, so nowthere’s only one copy to maintain.The Shape class is called the superclass of the other fourclasses. The other four are the subclasses of Shape. Thesubclasses inherit the methods of the superclass. In otherwords, if the Shape class has the functionality, then thesubclasses automatically get that same functionality.Shaperotate()playSound()superclassShaperotate()playSound()subclassesThen I linked the otherfour shape classes tothe new Shape class,in a relationship calledinheritance.Square Circle TriangleAmoeba3you are here431


once upon a time in ObjectvilleWhat about the Amoeba rotate()? Override NowAsk MeHowsubclasses(more specific)superclass(more abstract)Shaperotate()playSound()Square Circle TriangleAmoebarotate()// amoeba-specific// rotate codeplaySound()// amoeba-specific// sound code{{{{4I made the Amoeba class overridethe rotate() and playSound()methods of the superclass Shape.ImadetheAmoebaclassoverridetherotate()methodofthesuperclass Shape.Overriding just means that asubclass redefines one of itsinherited methods when it needsto change or extend the behaviorof that method.Overridingjustmeansthatasubclass redefines one of itsinherited methods when it needsto change or extend the behaviorof that method.Overriding methods I know how a Shape issupposed to behave. Yourjob is to tell me what todo, and my job is to make it happen.Don’t you worry your little programmerhead about how I do it.I can takecare of myself.I know how an Amoebais supposed to rotateand play a sound.32 chapter 2


classes and objectsThe suspense is killing me.Who got the chair? What do you like about OO?“It helps me design in a more natural way. Thingshave a way of evolving.”-Joy, 27, software architect“Not messing around with code I’ve alreadytested, just to add a new feature.”-Brad, 32, programmer“I like that the data and the methods that operateon that data are together in one class.”-Josh, 22, beer drinker“Reusing code in other applications. When I writea new class, I can make it flexible enough to beused in something new, later.”-Chris, 39, project manager “I can’t believe Chris just said that. He hasn’twritten a line of code in 5 years.”-Daryl, 44, works for Chrismetacognitive tip“Besides the chair?”-Amy, 34, programmerIf you’re stuck on an exercise, try talking aboutit out loud. Speaking (and hearing) activatesa different part of your brain. Although itworks best if you have another person todiscuss it with, pets work too. That’s howour dog learned polymorphism.you are here433


thinking about objectsWhen you design a class, think about the objects thatwill be created from that class type. Think about: things the object knows things the object doesShoppingCartcartContentsknowsButtonlabelcolorknowsAlarmalarmTimealarmModeknowsaddToCart()removeFromCart()checkOut()doessetColor()setLabel()dePress()unDepress()doessetAlarmTime()getAlarmTime()setAlarm()isAlarmSet()snooze()doesThings an object knows about itself are called instance variablesThings an object can do are called methodsinstancevariables(state)methods(behavior)titleartistSongsetTitle()setArtist()play()knowsdoes Think of instance as another way of saying object. Sharpen your pencil 34 chapter 2


classes and objectsWhat’s the difference betweena class and an object?A class is not an object.(but it’s used to construct them) JVMclassLook at it this way... you are here435


making objectsMaking your first object TestDrive Bungee BungeeTestDrive TestDrive class Dog {}1 Write your classint size;String breed;String name;instance variablesa methodvoid bark() {System.out.println(“Ruff! Ruff!”);}DOGsizebreednamebark()just a main method(we’re gonna put codein it in the next step)2The Dot Operator (.) Write a tester (TestDrive) classclass DogTestDrive {public static void main (String[] args) {// Dog test code goes here}}dotoperator3In your tester, make an object and accessthe object’s variables and methodsclass DogTestDrive {public static void main (String[] args) {Dog d = new Dog();d.size = 40;d.bark();}}make a Dog objectuse the dot operator (.)to set the size of the Dogand to call its bark() methodIf you already have some OO savvy,you’ll know we’re not using encapsulation.We’ll get there in chapter 4.36 chapter 2


classes and objectsMaking and testing Movie objectsclass 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;}}Sharpen your pencilMOVIEtitlegenreratingplayIt() object 1object 2object 3titlegenreratingtitlegenreratingtitlegenreratingyou are here437


get the heck out of mainQuick! Get out of main! The two uses of main:38 chapter 2 to test your real class to launch/start your Java application The Guessing Game GuessGame.class Player.class GameLauncher.class GameLaunchermain(String[] args)GuessGamep1p2p3startGame()numberguess()Playermakes aGuessGameobject andtells it tostartGameinstancevariablesforthe threeplayersthe numberthis playerguessedmethod formaking aguess


classes and objectspublic 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;GuessGame has three instancevariables for the three Playerobjectscreate three Player objects andassign them to the three Playerinstance variablesdeclare three variables to hold thethree guesses the Players makeboolean 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) {declare three variables to hold a true orfalse based on the player’s answercall each player’s guess() methodSystem.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 loopmake a ‘target’ number that theplayers have to guessget each player’s guess (the result of theirguess() method running) by accessing thenumber variable of each playercheck each player’s guess to see if it matchesthe 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)} 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 classotherwise, stay in the loop and ask theplayers for another guess.you are here439


Guessing GameRunning the Guessing Gamepublic class Player {int number = 0; // where the guess goes}public void guess() {number = (int) (Math.random() * 10);System.out.println(“I’m guessing “+ number);}public class GameLauncher {public static void main (String[] args) {GuessGame game = new GuessGame();game.startGame();}}Java takes out theGarbage File Edit Window Help Explode%java GameLauncherI’m thinking of a number between 0 and 9...Number to guess is 7I’m guessing 1I’m guessing 9I’m guessing 9Player one guessed 1Player two guessed 9Player three guessed 9Players will have to try again.Number to guess is 7I’m guessing 3I’m guessing 0I’m guessing 9Player one guessed 3Player two guessed 0Player three guessed 9Players will have to try again.Number to guess is 7I’m guessing 7I’m guessing 5I’m guessing 0Player one guessed 7Player two guessed 5Player three guessed 0We have a winner!Player one got it right? truePlayer two got it right? falsePlayer three got it right? falseGame is over.40 chapter 2


classes and objectsthere are noDumb Questions random() public static public static final random() Math Make it StickßßßßßßßßßßBULLET POINTS Object-oriented programming lets you extenda program without having to touch previouslytested,working code.All Java code is defined in a class.A class describes how to make an object ofthat class type. A class is like a blueprint.An object can take care of itself; you don’thave to know or care how the object does it.An object knows things and does things.Things an object knows about itself are calledinstance variables. They represent the stateof an object.Things an object does are called methods.They represent the behavior of an object.When you create a class, you may also wantto create a separate test class which you’lluse to create objects of your new class type.A class can inherit instance variables andmethods from a more abstract superclass.At runtime, a Java program is nothing morethan objects ‘talking’ to other objects.you are here441


exercise: Be the Compiler Each of the Java files on this pagerepresents a complete source file.Your job is to play compiler anddetermine whether each ofthese files will compile.If they won’t compile,how would you fix them,and if they do compile,what would be their output?Aclass 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();Bclass 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 (t.canRecord == true) {t.recordTape();}}}if (d.canRecord == true) {d.recordDVD();}42 chapter 2


if (d.snare == true) { d.playSnare();boolean topHat = true;boolean snare = true;classes and objectsDrumKit d = new DrumKit();void playSnare() {}System.out.println(“bang bang ba-bang”);public static void main(String [] args) {}d.playSnare();d.snare = false;class DrumKitTestDrive {d.playTopHat();class DrumKit {void playTopHat () {File Edit Window Help Dance% java DrumKitTestDrivebang bang ba-bangding ding da-ding}System.out.println(“ding ding da-ding”);you are here443


puzzle: Pool PuzzlePool Puzzle File Edit Window Help Implode%java EchoTestDrivehelloooo...helloooo...helloooo...helloooo...10 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... “);}} 44 chapter 2


classes and objectsWho am I? I am compiled from a .java file.classMy instance variable values canbe different from my buddy’svalues.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.you are here445


exercise solutionsCode Magnets: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();}File Edit Window Help Dance% java DrumKitTestDrivebang bang ba-bangding ding da-ding46 chapter 2ABBe the Compiler: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 !


classes and objects 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( ) {}Pool PuzzleSystem.out.println(“helloooo... “); I am compiled from a .java file.My instance variable values can bedifferent 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 objectinstances.My state can change.I declare methods.I can change at runtime.classobjectclassobject, methodclass, objectinstance variableobject, classmethod, instance variableobjectclassobject, instance variableclassobject, instance variableNote: 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.File Edit Window Help Assimilate%java EchoTestDrivehelloooo...helloooo...helloooo...helloooo...10you are here447


3 primitives and referencesKnow Your VariablesVariables come in two flavors: primitive and reference. So far you'veused variables In two places-as object state (instance variables), and as local variables(variables declared within a method). Later, we'll use variables as arguments (values sent to amethod by the calling code), and as return types (values sent back to the caller of the method).You've seen variables declared as simpie prjmIUve integer vaIues (type inc). You've seenvariables declared as something more complex like a String or an array. But there's gotta bemore to life than integers, Strings, and arrays.What If you have a PetOwner object with a Doginstance variable? Or a Car with an Engine? In this chapter we'll unwrap the mysteries of Javatypes and look at what you can declare as a variable, what you can pur In a variable, and what youcan do with a variable. And we'll finally see what life Is truly like on the garbage-collectible heap.this Is a new chapter 49


declaring a variablePeclarittg avariableJava cares about type. It won't let you dosomething bizarre and dangerous like stuff aGiraffe reference into a Rabbit variable-whathappens when someone tries to ask the so-calledRabbit to hop ()? And it won't let you put afloating point number into an integer variable,unless you lKknowledge to thecompiler that youknow you might lose precision (like, everythingafter the decimal point).The compiler can spot most problems:Rabbit hopper = new Giraffe();Don't expect that to compile. Thankfully .For all this type-safety to work, you must declarethe type ofyour variable. Is it an integer? a Dog?A single character? Variables come in two flavors:primitive and object reference. Primitives holdfundamental values (think: simple bit patterns)including integers, booleans, and floating pointnumbers. Object references hold. well, referencesto objects (gee, didn't that clear it up.)We'Ulook at primitives first and then moveon to what an object reference really means.But regardless of the type, you must foUow twodeclaration rules:variables must have a typeBesides a type, a variable needs a name, so thatyou can use that name in code.variables must have a nameint;?1typecount;


primitives and referencesPrimitive Typesn you think ofJava variables, think ofcups. Coffee cups, tea cups, giantthat hold lots and lots of beer, those big cups the popcorn comes in atmovies, cups with curvy, sexy handles, and cups with metallic trim thatlearned can never, ever go in the microwave.wariable is just a cup. A container. It holds something.a size, and a type. In this chapter, we're going to look first at the- bles (cups) that hold primitives, then a little later we'll look at cupshold references to objects. Stay with us here on the whole cup analogy-aspie as it is right now, it'll give us a common way to look at things whendiscussion gets more complex. And that'll happen soon.- itives are like the cups they have at the coffeehouse. Ifyou've been to aucks, you know what we're talking about here. They come in differentand each has a name like 'short', 'tall', and, "I'd like ade' mocha half-eaffwith extra whipped cream".might see the cups displayed on the counter,u can order appropriately:smallshortgrande--'!II" And inJava, primitives come in different sizes, and those sizeshave names. When you declare a variable in Java,E ::a-YoU must declare it with a specific type. TheI four containers here are for the fourinteger primitives in Java.fang int short bytecup holds a value, so forJava primitives, rather than saying, "I'd like afrench roast", you say to the compiler, "I'd like an int variable with theber 90 please." Except for one tiny difference... in Java you also have toyour cup a name. So it's actually, "I'd like an int please, with the value:H86, and name the variable height." Each primitive variable has a fixedber of bits (cup size). The sizes for the six numeric primitives inJavashown below:byte short int8 16 32long64tallfloat32double64Type BitDepth Value Rangeboolean and charbooleanInteger(JVM ..pedfic) true or falsechar 16 bits 0 to 65535numeric (all are signed)byte 8 bits -128 to 127short 16 bits -32768 to32767int 32 bits -2147483648to 2147483647long 64 bits -huge to hugefloating pointfloat 32 bits variesdouble 64 bits variesPrimitive declarationswith assignments:Int ){ix = 234;byte b = 89;boolean isfun = true;double d = 3456,98jchar c ='f'jlnt z e x:boolean IsPunkRock;isPunkRock= false;boolean powerOn;powerOn = IsFun;long big = 3456789jfloat f = 32.5i.(qatta "a~t-thatNott tht ~ btU\,


prlmltlve assignmentYou really dot1~t wat1t to spill that...Be sure the value can fit into the variable.You can't put a large value into asmall cup.WeU, OK, you can, but you'lllose some. You'll get, as we say,spillage. The compiler tries tohelp prevent this ifit can tellfrom your code that something'snot going to fit in the container(variable/cup) you're using.For example, you can't pour anint-full ofstuff into a byte-sizedcontainer, asfollows:int x = 24;byte b = x;//won't work!!Why doesn't this work, you ask? After all, the value of x is 24, and 24 is definitelysmall enough to fit into a byte. You know that, and weknow that, but all thecompiler cares about is that you're trying to put a big thing into a small thing.and there's the possibility ofspilling. Don't expect the compiler to know what thevalue of xis. even if you happen to be able to see it literally in your code.You can assign a value to a variable in one ofseveral waysincluding:• type a litera/value after the equals sign (x=12. isGood = true, etc.)• assign the value ofone variable to another (x =y)• use an expression combining the two (x = y + 43)In the examples below, the literal values are in bold italics:The compiler won't let you puta value from a large cup intoa small one. But what aboutthe other way-pouring asmall cup into a big one7 Noproblem.Basedon what you knowabout the size and type of thepri mitive varlables, seeif youcan figure out which of theseare legal and which aren't,We haven't covered all therules yet, so on some of theseyou'll have to use your bestjudgment. Tip: The compileralways errs on the side ofsafety.From the following list Circlethe statements that would belegal if these lines were in asingle method:1. int x = 34.5;2 . boolean boo x;3 . int g = 17;4. int y '" 9;5 . Y = Y + 10;6. short s;int size = 32;char initial = 'j';double d = 456.709;boolean isCrazy;isCrazy true;int y = x + 456;declare an int named size, assIgn ilthe value 32declare a char named initial, assign itlhe value Tdeclare a double named d, assign it the value 456.709declare a boolean named IsCrazy (no assignment)assign the value true to thepreviously-declared ;sCrazydeclare an int named y, assign Itlhe value that is the sumof whatever x is now plus 4567. s = y;8. byte b = 3;9 . byte v = b;10. short n '" 12;11. v '" n ;12. byte k 128;52 chapter 3


Jack away frotH that keyword!lbu know you need a name and a type for your variables.YOu already know the primitive types..,what can you we as names? The rules are simple. Youan name a class, method, or variable according to theowing rules (the real rules are slightly more flexible,t these will keep you safe) :• It must start with a letter, underscore U, ordollar algn ($). You can't atart a name with anumber.• After the first character, you can u.. numbers aswell. Just don't atart It with a number,• It can be anything you like, subject to those tworules, JU8t 80 long as It Isn't one of Java's reservedwords.prlmitJves and references. ' ftIfIeS ote: b\e, /'It primitIve '7" float do U .The elg e s\"lOft lotlong . t/'lem:\ eao char byt membermgboOonicfor re, omnemAnd here S , gest urgeu\dn't nSCafefU\~ 8ea's \"108efurry Oogs't'll stick evenoutown, IIt yoU make upYDS I LF- ­B_ c- B_ - -bertet.publicstaticvoidAnd the primitive types are reserved as well:boolean char byte short int long floa.t doublet there are a lot more we haven't discussed yet. Even ifyou don'ted to know what they mean, you still need to know you can't use'em yourself. Do not-under any circumstances-try to memorize these.w. To make room for these in your head, you'd probably have tosomething else . Like where your car is parked. Don't worry, bythe end of the book you'll have most of them down cold.fhls table reserved.boolean byte mar double flom Inl longprotected abstract flnal native storic strictfp syndJronlzed transient Ifelse do while swllm case delauh for break continue assartdoss ex1and~ implements import rnstanceof interface new package super thiscatch flnol~ try throw throws return void canst gala enumJava's keywords and other reserved words (In no useful order). If you use these for names, the complier will be very, vel}' upset.you are here I 53


object referencesControlling your ~ogobjectYou know how to declare a primitive variable and assign it avalue . But now what about non-primitive variables? In otherwords, what about objects?• There Is actually no such thing as an object variable.• There's only an object reference variable.• An object reference variable holds bits that represent away to access an object.• It doesn't hold the object Itsetf, butIt holds somethinglike a pointer. Or an address. Except., in Java we don'treally know what Is Inside a reference variable. We doknow that whatever It Is, It represents one and only oneobject. And the JVM knows how to use the reference toget to the object.Dog d = new Dog();d.bark();\ thi.k ot thisYou can ' 1 stuff an object into a variable. We often think ofit that way... we say things like, "I passed the String to theSystem.out.printlnf) method." Or, "The method returns a Dog",or, "I put a new Foo object into the variable named rnyf'oo."But that's not what happens. There aren't giantexpandable cups that can grow to the size of anyobject. Objects live in one place and one placeonly-the garbage collectible heap! (You'lllearn more about that later in this chapter)Although a primitive variable is full ofbits representing the actual value of thevariable, an object reference variable is fullof bits representing a way to get to theobJect.You use the dot operator (.)on a reference variable 10 say,"use the thing before the dot toget me the thing afterthe dot." Forexample:myDog.bark() ;means, "use the object referenced by the variable myDog toinvoke the barkt) method." When you use the dot operator onan object reference variable, think of it like pressing a buttonon the remote control for that object.Thillk o-f a D~referente vdl'iable ala D~ l'en-ote to.\h-ol.You. IUC it to ~tt -t\l~objut to do ~tthill9(h'IVolcc ",et.h~) .54 chapter 3


primitives and referencesThe 3 steps of objectdeclaration, creation andassignmentbyte short int8 16 32long reference64 Ibll depth not relevant)At1 object referet1ce is justa"other variable value.Something that goes In a cup.Only this time, the value 15 a remote control.Prhldtlve Variablebyte x = 7;the bits representing 7 goto the variable. (00000111),~\.\.J~itiveU vall.4tbyte1 2~3~Dog myDog = new Dog();ODeclare a referencevariableDoq myDoq = new Dog () ;Tells the JVM to allocate space for areference variable, and names thatvariable myDog. The reference variableIs, forever. of type Dog.ln other words,a remote control that has buttons tocontrol a Dog, but not a Cat or a Buttonor a Socket.DogDog myDog = new Doq() ;e Create an objectDog myDog '" new Dog () ;Tells the JVM to allocate space for anew Dog object on the heap (we'lllearn a lot more about that process,especially in chapter 9,)Dog objecte Link the objectand the referenceDog myDog = new Dog () ;Assigns the new Dog to the referencevariable myDog.ln other words,programs the remote control,Dog object~n care how meny t's and O'stho,o are In a (afare~08l1tlriabla lrs UP10a&eh: " a."ld Ihe phase of Ihe moon ,Dogyou are he re . 55


object referencesD :therel~o "ume ~uest19115Q: How big 15 a referencevariable?A.:Vou don't know. Unlessyou're cozy with someone on theJVM's development team, youdon't know how a reference isrepresented.There are pointersin there somewhere, but youcan't access them.You won'tneed to. (OK, Ifyou Inslst, youmight as wellJust imagine Itto be a 54-bit value.) But whenyou're talking about memoryallocation issues, your BigConcern should be about howmany objects (as oppose-d toobject references) you're creating,and how big they (the objects)really are.Q:So, does that mean thatall object references are thesame size, regardless of the sizeof the actuaI objects to whichthey refer?A.: Yep. All references for agiven NM will be the samesize regardless of the objectsthey reference, but each JVMmight have a different way ofrepresenting references, soreferences on one JVM may besmaller or larger than referenceson another JVM.Q:can Ido arithmetic on areference variable, Increment Ityou know - C stuff7A.: Nope.Say It with me again,"Java Is not C.",.Java,£NposeclThis week's Interview:Object ReferenceHeadFirst So, tell us, what's life likefor an object reference?Reference: Pretty simple, really. I'm a remote control and I can be programmed tocontrol different objects.HeadArst Do you mean different objects evenwhile you're running? Like, can yourefer to a Dog and then five minutes later refer to a Car?Reference: or course not- Once I'm declared, that's it. If I'm a Dog remote controlthen ru never be able to point (oops- my bad, we're not supposed to say poin~ I mean riferto anything but a Dog.HeadFirst Does that mean you can refer to only one Dog?Reference: No. I canbe referring to one Dog, and then five minutes later I can refer tosome other Dog. As long as it's a Dog, I can be redirected (like reprogranuning your remoteto a differentTV) to it. Unless... no never mind.HeadFirst No, tellme. What were you gonna say?Reference: I don't think you want to get into this now,but I'lljust giveyou the shortversion - if I'm maned as final, then once I am assigned a Dog, I can never be reprogrammedto anything else but I1ul1 one and only Dog: In other words, no other object canbe assigned to me.HeadFirst You're right,we don't want to talk about that now. OK, sounless you'refinal, then you can refer to one Dog and then refer to a differentDog later. Can you everrefer to fIl)tJring at alP. Is it possible to not be programmed to anything?Reference: Yes, but it disturbs me to talkabout it.HeadArst Why is that?Reference: Because it means I'm null, and that's upsetting to me.HeadFirst You mean. because then you have no value?Reference: Oh, null isa value. I'm stilla remote control, but it'slikeyou broughthome a new universal remote control and you don't have a TV I'm not programmed tocontrol anything. They can press my buttons all day long, but nothing good happens. Ijust feelso... useless. A waste of bits. Granted, not that many bits, but still. And that's notthe worst part. If I am the only reference to a panicular object, and then I'm set to null(deprogrammed), it means that now rwboqy can get to that object I had been referring to.HeadFirst And that's bad because...Reference: You have to ask? Here I've developed a relationship with thisobject, anintimate connection, and then the tie issuddenly, cruelly, severed. And I will never seethat object again, because now it's eligible for [producer, cue.tragic music) garbage collection.Sniff. But do you think programmers ever consider !haP. Snif. Why, wIrY can't I be a primitive?I hate being a refcrcut. The responsibility, all the broken attachments...56 chapter 3


primitives and referencesott the garbage..collectible heap= new Book();= new Book();e two Book reference- les.Create two new Book.Assign the Book objects toreference variables.two Book objects are now livinge heap.BookObiects: 2BookBook d = c;re a new Book reference variable.r than creating a new, third Book•assign the value of variable c to. ble d. But what does th is mean?li ke saying,"Take the bits In c,make aof them, and stick that copy Into d."..... c and d refer to the same....ect.The c and d variables holdtwo dlHerent copies of the..me value. Two remotes.....grammed to one TV.ferences:3Objects: 2c = h;Assign the value of variable b tovariable c. Bynow you know whatis means.The bits inside variableat are copied, and that new copy Isstuffed into variable c.Both band c refer to thesame object.References:3Objects : 2BookBookyou are here ~ 57


objects on the heapUfe a.,d death 0., the heapBook b = new Book() ;Book c = new Book() iDeclare two Book reference variables.Create two new Book objects. Assignthe Book objects to the referencevariables.The two book objects are now livingon the heap.ActIve References:2Reachable Objects: 2b= CiAssign the value of variable c to variable b.The bits Inside variable c are copied, andthat new copy is stuffed Into variable b.Both variables hold identical values.Both band c refer to the ••meobject. Object 1 I. abandonedand eligible for Garbage Collection(GC).Active References:2Reachable Objects: 1Abandoned Objects: 1The first object that b referenced, Object 1,has no more references. It's unreachable.BookC= null;Assign the value nu 11 to variable c.This makes c a null reference, meaningIt doesn't refer to anything. But It's stilla reference variable, and another Bookobject can stili be assigned to It.Object 2 .tlll h•• an activereference (b), and •• longas It does, the object I. noteligible for GC.ActIve References: 1null References: 1Reachable Objects: 1Abandoned Objects: 1Book68 chapter 3


primitives and referencesAn array is like atray of cupsoDeclare an int array verinble. An array variable isa remote control to an array object.int[] nums;Create a new int array with a lengthof 7 I and assign it to the previouslydeclaredintrJ variable numsnums = new int[7] ;~.3'~~Give each element in the arrayan int value.Remember, elements in on intarray are just int variables..:is nums [0] = 6;nums[l] = 19;~·s nums[2] = 44:nums[3] = 42:nums [4] = 10:nums[5] = 20;nums [6] ='1;Arrays are objects tooJava standard library includesofsophisticated data structuresuding maps, trees. and setsAppendix B). but arrays aret when you just want a quick.red, efficient list of things.,"'5 give you fast randomess by letting you use an indexition to get to any element inarray.ry element in an array isjustnriable. In other words, one ofeight primitive variable types. k: Large Furry Dog) or aint[]reference variable. Anything youwould put in a variable of that rypecan be assigned to an arrayelementof that type. So in an array of typeint (int[]) . each element can holdan int, In a Dog array (Dog[]) eachelement can hold... a Dog? No.remember that a reference variablejust holds a reference (a remotecontrol), not the object itself. Soin a Dog array, each element canhold a remote control to a Dog. Ofcourse, we still have to make theDog objects... and you'll see all thaton the next page.int array object (int[])Notit~ that. -tne a'rYa'f ihtlt is dl'l objtd:,evel'l t.h~h ~e I tltMtl'lt.s art f\"i",j·I:.'Ives.Be sure to notice one key thingin the picture above - thearm)' isan object, even though it's an arrayofprimitives.Arrays are always objects, whetherthey're declared to bold primitivesor object references. But you canhave an array object that's declaredto hold primitive values. In otherwords, the array object can haveelements which are primitives. butthe array itself is nevera primitive,Regardless of what the array holds,the array itself is always an objectlyou are here. 59


an array of objectsMake att array of PogsoDeclare a Dog array variableDog[] pets;AWCreate a new Dog array witha length of 7, and assign it tothe previously-declared Dog [Jvariable petspets = new D09[7];What~ .ttfsShtg1Dogsl We have an arrayof Dog rmrence$, but noactual Dog obJectsIDogarray object (Dog[])AVCreate new Dog objects, andassign them to the arrayelements.Remember, elements in a Dogarrayare just Dog referencevariables. We still need Dogs!pets[D] = new Dog();pets[l] = new Dog();_~n,~~:' :~:f~~~i:/_t_--~dmake-ne ofthe11 objects?Dog array object (Dog[])58 (.. .r 3


primitives and references,DogJava cares about type.namebarkOeatOchaseCalOOnce you've declared an array. youcan't put anything an It except thingthatare of the declared array type.For example, youcan't put Q COt intoa Dogarray (it would be pretty awful if someonethinks that only Dogs are inthe orrat, sothe.y ask eoch one to ~ark, and th~n to theirhorror discovertheres a cat lurkmg.) Andyoucan't stick a double into on int orr'atl(spillage., remember?). You can,however.put Qbyte into on int arraf, b~QuSeabyte will always fit into on int-SIZ ed cup.This is known as an Implicit wid&ning. We'''gat Into the details tater. for now justremember that the compiler won't 1st youput the wrM'9 thing In on orraf, based onthe Gtf'OY's d&elored type.Cot1trol your ~og(with a referetlce variable)Dog fide = new Dog();fido.name = ~FidoN;We created a Dog object andused the dot operator on thereference variable fido to accessthe name variable."We can use thefido referenceto get the dog to barkt) oreat/) or chaseCatO.fido.bark() ifido .chaseCat();DogWhat happetts ifthe POQ is Itta OOQ array?~e know we can access the Dog'sInstance variables and methods usingthe dot operator, but em what1When the Dog is in an array, we don'thave an actual variable name (likefido). Instead we use array notation andpush the remote control button (dot~perator) on an object at a particularIndex (position) in the array:Dog[]myDogs = new Dog[3];myDogs[O] = new Dog() ;myDogs[O].name = "Fido";myDogs[O] .bark();'Yes weknow we're notdemonslralin -trying tokeep itsimple. For now W '1Igdencapsu iatiOn he_reo butwe're. e 0 encapsulation 10chapter 4.you are here ~ 61


using referencesclass Dog (String name ;publi c static void main (String() args)II make a Dog ob ject and a ccess itDog dogl = new Dog();dogl.bark{) ;dogl.name = "Bart" ;A Pog exatMplenameDogbarkOeatOchaseCal()I I now mak e a Dog arrayDog() myDogs = new Dog[3); OutputII a nd put s ome dogs i n i ~myDogs[O )myDogs[l )myDogs [2 )ne w Dog () ;new Dog () ;dog!;/1 now Reces s t he Dogs us i ng t he arr a yI I r e f e r e ncesmyDogs(O).namemyDogs(l).narne" Fr ed" ;"Marge" ;II Hmmnm . . . wha tII now 100 t hr ough t he a r r yI I a nd t e l l all dogs t o ba rkpUblic void bark() (System.out.println(narne i- " says Ruff!");pUblic voi d eat ( ) {public voi d c ha s eCa t ()i s myDogs (2 j name?System.out.print("!ast dog's name is ");Sys t em. out . pr int l n (myDogs (2) . narne ) ;i nt x = 0;whi1e(x < mYDOgs .1ength)~myDogs [xl .bar k () ;a \/aYiab\c l'~~x = X + 1; ay-yii'(S ha\/C t."c l'I~bCl"t)lat. ~\\/ts 'lOlA a'JL' t,\lc jlY"Y Ie\e,.,.tf\'V 11'1J• Variables come intwo flavors: primitive andreference.• Variables must always be declared with anameand a type.• Aprimitive variable value isthe bits representingthe value (5, 'a', true, 3.1416, etc.).• Areference variable value isthe bitsrepresenting away to get toan object on theheap.• Areference variable is like aremote control.Using the dot operator (.) on a referencevariable islike pressing a button on the remolecontrol to access amethod orinstance variable.• Areference variable has a value of n u11 whenit isnot referencing any object• An array is always an object, even if the" arrayisdeclared to hold primitives" There isno suchthing as a primitive array, only an array thatholds primitives.62 chapter 3


prlmltlves and referencesBE the cornrilerEach ofthe Java nles on this pagerepresents a cOtIlplete source file.Your job is to play compiler anddetel"llline whether each ofthese fileswill compile. Ifthey won'tcmqpile, how would rOllfIX them?class Books {String title;String author;}Aclass BooksTestDrivepublic static void main(String Ij args)Books () myBooks :: new Books(3);int x :: 0;myBooks{Oj.title :: "The Grapes of Java";myBooks(lj.title = ~The Java Gatsby"imyBooks(2).title :: ~The Java Cookbook";myBooksIO).author = "bob";myBooksllj.author:: "sue";myBooks(2).author = "ian";wbile (x < 3) {System.ou t.print(myBookslxj.title)iSystem.out.print(" by U)iSystem.out.println(rnyBooks[xj.author) ;x = x + 1;} }class Hobbits {String name;Bpublic static void main(String (J args) {Hobbits () h = new Hobbits[3]iint z = 0;while (z < 4) {z = z + 1;hlz] :: new Hobbits();h{z] .name = "bilbo"iif (z == I) {}hlz].name:: "frodo";if(z==2){h[z).name = Usam";System.out.print(h{z).name + " is a H);System.out.println(Ugood Hobbit name");you are here. 63


exercise: Code MagnetsCode MagnetsAworking Java program Is all scrambled upon the fridge. Can you reconstruct the codesnippets to make a working Java programthat produces the output listed below?Some of the curly braces fell on the floorand they were too small to pick up, so feelfree to add as many of those as you need!int Y ==index(y) ;int ref;while (y < 4) {System.out.print1n(islands{refj)iindex(Ol .,. 1;index(ll '" 3;index(21 == 0;index[31 .,. 2; ~String (] islands new String(4)iSystem.out.print(Uisland ;U);int [1 index ""new int[4Jiy y + 1;class TestArrays {public static void main(Strin N":Jr J args) {64 chapter 3


~~ftil64 chapter 3puzzle: Heap o' TroubleA Heap 0' TroubleA short Java program is listed to theright. When '/1 do stuff' is reached, someobjects and some reference variableswill have been created. Your task Isto determine which of the referencevariables refer to which objects. Not allth e reference variables will be used,andsome objects might be referred to morethan once. Draw lines connecting thereference variables with their matchingobjects.Tip: Unless you're way smarter than us,you probably need to draw diagramslike the ones on page 55 and 56 of th ischapter. Use a pencil so you can drawand then erase reference links (thearrows goIng from a reference remotecontrol to an object).class HeapQuiz {int id == 0;public static void main(String [] argslint x = 0;HeapQuiz ( ] hq = new HeapQuiz(S]iwhile ( x < 3 1 (hq[x) = new HeapQuiz();hq(x] . id == Xix = X + 1i}hq[3] == hq[l]ihq[4] hq[l] ;hq[3] = null;hq (4) hq (0] ;hq(Ol == hq(31ihq(3] hq[2];hq[2] = hq [0] ;II do stuffReference Variables:HeapQulz Objects:hq[O]hq[1]hq[2]10hq[3]hq[4]


primitives and referencesThe case of the pilfered referencesIt wasa clark andstormy night Tawny strolledinto the programmers' bullpen like sheowned the place. She knew that all the programmerswould still behard at work, and shewanted help. She needed a new methodadded to the pivotal class that was to be loaded into theclient's new top-secretJava-enabledcell phone. Heap space in the cell phone's memorywasas tight as Tawny's top, and everyone knew it The normallyraucous buzz in the bullpen fell tosilence as Tawny eased her way to the white board. She sketched a quick overview of the newmethod's functionality and slowly scannedthe room. 'Well boys, it's cnmch time", she purred.'Whoever creates the most memory efficientversion ofthis method iscoming with me to theclient's launchparty on Maui tomorrow... to help me install the new software."The next morningTawny glidedinto the bullpen wearingher shortAloha dress."Gentlemen", she smiled,"the plane leavesin a few hours, show me what you'vegot!". Bob went first; as he began to sketch his design on the white board Tawnysaid,"Let's get to the point Bob, show me how you handledupdating the list of contactobjects." Bob quicklydrew a code fragmenton the board:Contact I) ca = new Contact[10];while ( x < 10 ) { II make 10 contact objectscalx) new Contact()ix = x + 1 ;II do complicated Contact list updating stuff with ca"Tawny r know we're tight on memory,but your spec said that we hadto beable to accessindividualcontact informationfor all ten allowablecontacts, this was the best scheme I couldcookup", said Bob. Kent was next, alreadyimagining coconut cocktails withTawny, "Bob,"he said, "yoursolution's a bit kludgydon't you think?" Kent smirked,"Take a lookat thisbaby":Contact. refc;while ( x < 10 ) { II make 10 contact. objectsrefe = new Cont.act()ix = x + 1;III do complicated Contact list updating stuff with rete"I saved a bunch of referencevariables worth ofmemory,Bob-o-rino, so put away yoursunscreen",mocked Kent "Not so fast Kent!",said Tawny, "you've saved a little memory, butBob's coming with me.''.Why did Tawny choose Bob's methodover Kent's, when Kent's used Jess memory?you are here t 67


exercise solutionsCode Magnets:Exercise Solutionsclass TestArrayspUblic static void main(String () args) {int [) index = new int{4]:index[O) I:Lndex] 1) 3:index[ 2) 0:index(3) 2;String (] islands = new String[4]:islandslO] "Bermuda":islandsjl] = "Fiji";Aclass Books {String title;String autbor;class BooksTestDrive (public static void main{String I) args)Books II myBooks = new Books(3);int x = 0:myBooks[O] :: ntw 9ooksO; IUrnanber: We hGvt tomyBooks[1] :: ntw BooksO:myBooks[2] :: new BooksO:actuclily InQJc.e the BooI


primitives and referencesPuzzle SolutionsThe case of the pilfered referencesclass Triangledouble area;int height;int length,public static 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;Triangle tS ~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;Tawny could see that Kent's method had a seriousflaw. It's true that he didn't use as many referencevariables as Bob , but there was no way to access anybut the last of the Contact objects that his method created.With each trip through the loop, he was assign ­ing a new object to the one reference variable, so thepreviously referenced object was abandoned on theheap - unreachable. Without access to nine of the tenobjects created, Kent's method was useless.(The software was 8 huge success atKl the dlent gave Tawny and Bob anextra weekIn Hawa~. we'dlike to ~ you that byfinishing this book you too wilget stuff like IhaL)Reference Variables:hq[O]HeapQulz Objects:~;, java Triangletriangle 0, areatriangle 1. areacriangle 2 , areatriangle 3 , area'i = 4, t5 arca = 3434.010 .019 .028.0you are here ~ 69


4 methods use Instance variablesHow Objects BehaveState affects behavior, behavior affects state. We know that objectshave state and behavior, represented by Instance variables and methods. But until now, wehaven't looked at how state and behavior are related .We already know that each instance of aclass (each object of a particular type) can have its own unique values for its instance variables.Dog A can have a name "Fido" and a weight of 70 pounds. Dog B Is"Killer"and weighs 9 pounds.And If the Dog class has a method makeNoiseO,well, don't you think a 70-pound dog barks abit deeper than the little 9-pounder7 (Assuming that annoying ylppy sound can be considereda bark.) Fortunately, that's the whole point of an object-It has behavior that acts on its state. Inother words, methods use /nstllnn vllt/llb/Ift values . Like,"if dog Is less than 14 pounds, makeylppy sound, else..." or "Increase weight by 5~Let's go chllnge some stat«,this Is a new chapter 71


objects have state and behaviorRetMetMber: a class describes what anobject knows and what at1 object doesA class is the blueprint for an object. When youwrite a class, you're describing how theJVMshould make an object of that type. You alreadyknow that every object of that type can havedifferent instancevariable values. But what aboutthe methods?Ca" every object of that type have dlfferetttlMethod behavior?Well... sort cif.*lt1stat1cevariables(state)'Methods(behavior)titleartistSongsetTItleOsetArtlstOplayOkt10wsdoesEvery instance ofa particular class has the samemethods, but the methods can behave differentlybased on the value ofthe instance variables.The Song class has two instance variables, titleand artist. The playO method plays a song. butthe instance you call playO on will play the songrepresented by the value ofthe titleinstancevariable for that instance. So, ifyou call the playOmethod on one instance you'll hear the song"Politik", while another instance plays "Darkstar",The method code, however, is the same.void pla.y ( ) {soundPlayer.playSound(title);}Song t2 = new Song();t2.setArtist("Travis");t2.setTitle("Sing");Song s3 = new Song();s3.sstArtist("Sex Pistols");s3 . setTitie ("My Way") ;C-illi~ISong83 .play () ;playO 0l'I this iflSta~tewill t4lASe "My W;Y:: to play.(blAt PI~ the ~r.ab-a ~d·Yes. another stunningly clearanswerl72 chapter 4


methods use instance variablesesize affects the barkAtlD3cIJ Dog's bark is different from a big Dog 's bark.og class has an instance variable size, that theme thod uses to decide what kind of bark soundDog (s i ze ;;;: =':' ng name;_:'0 ba r k () {:.f (size> 60)sizenamebark()DogSystem.out.println("Wooof! Wooof!"};els e if (size> 14) {System ,out.println("RUff!else (Ruff!");System.out.println("Yip! Yip!-);~: = s s DogTestDrive {public static void main (String! J args) {Dog one =one.size = 70;new Dog();Dog two = new Dog();two ,size = 8;Dog three =three.size = 35;one. ba rk () ;two.bark () ;three.bark/);new Dog();~~ j ava DogTestDriveWooof! Wooof I'lip! Yip!Ruff!Ruff!you are here. 73


method parametersYou can send things to a tttethodJust as you expect from any programming language, you aU1 passvalues intoyour methods. You might, for example, want to tell a Dog object how manytimes to bark by calling:d.bark(3) ;Depending on your programming background and personal preferences,youmight use the term arguments or perhaps paramet.ers for the values passedin to a method. Although there emformal computer science distinctions thatpeople who wear lab coats and who will almost certainly not read this book.make. we have bigger fish to fry in this book. So yuucan call them whateveryou like (arguments, donuts, hairballs, etc.) but we're doing it like this:A method ~ parameters. A caller passes arguments.Arguments are the things you pass into the methods. An argument (a valuelike 2, "Faa", or a reference to a Dog) lands face-down into a... wait for it..parameter. And a parameter is nothing more than a local variable. A variablewith a type and a name, that can be used inside the body of the methodBut here's the"important part: Ifa method takes a parameter, you mustpassit something. And that something must be a value of the appropriate type.OCallthe bark method on the Dog reference,and pass in the value 3 (as theargument to the method).Dog d = new Dog() ;d.bark(3) ;~ aY'~~",e~t.AThe bits representing the intW value 3 are delivered into thebark method.P~,"d_~,"~ invoid bark (int numO}l:>''\.arks)while (numOfBarks > 0)}74 chapter 4AVSystem.out.println("ruff");numOfBarks = numOfBarks - 1;{The bits land in the numOfBarksparameter (an int-stzec variable).{OUse the numOfBarksparameter as a variable inthe method code.


methods use instance variablesYou ca., get thi.,gs backfrottt a lMethod.ods can return values. Every method is declared with a return. but until now we've made all ofour methods with a voidtype, which means they don't give anything back.re can declare a method to give a specific type ofvalueto the caller, such as:~ giveSecret ()return 42;declare a method to return a value, you musta value ofthe declared rypel (Or a value. (()mpatiblewith the declared type. We'll getat more when we talk about polymorphismpter 7 and chapter 8.)atever you say'II give back, youtter give back!t - life.giveSecret () ;}giveSec et () {return 42-t,nis "'~ ~it.. tJill aWl \WI\...you are here ~ 75


multiple argumentsYou can send ",ore than one thingto a tMethodMethods can have multiple parameters. Separate themwith commas when you declare them, and separate thearguments with commas when you pass them. Mostimportantly, ifa method has parameters, you must passarguments of the right type and order.Call1"Q a two-paralMeter IMethod, altd seltdh,gIt two arQuIMe"ts.void qo () {TestStuff t..t.takeTwo(12, 34);= new T8Ststuff()i\\void takeTwo(int x, int y) (lnt z = x + y;Systam.out.prinUn ("Total. is "+ z);. )You ca" pass variables h'toa IMethod, as lo"c.1 asthevariable type IMatches the paraIMefer type.void qoO (int faa = 7;int bar = 3;t. takeTwo (foo, bar);\~void takeTwo(int x, int y)int z ... x + YiSystem. out.println ("Total is rr+ z);76 chapter 4


methods use instance variablesJava is pass...by...value.=That tMea"s pass"'by"'copy.-----int x = 7;intODeclare an in~nd assign itthe value '7. The bit pattern for 7goes into the variable named x.void go(int z){ }~intA'iii' parameter named z.Declare a method with an intintfoo.go(x) ;1134:'\1 ..,. e'Vb\ ,~ •f' ~ d~. ~~t~g L.tflit dots,,'f. thci ~........ a.,.d 'J.. d'f't":-\:'j>


arguments and return valuesQ:What happens Ifthe argument you want topass Isan object Instead of II primitive?A: You'll learn more about this In later chapters,but you already know the answer. Java passeseverything by value.EverythIng. But...value meansbits Inside the vcrtable. And remem ber,you don'tstuff objects Into variables; the variable Is a remotecontrol-a reference to an object. So If you pass areference to an object into a method, you're passinga copy ofthe remote control. Stay tuned, though, we'llhave lots more to sayabout this.Reminder: Javacares about type!You can't return a Giraffe whenthe return type Is declaredas a Rabbit. Same thing withparameters. You can't pass aGiraffe Into a method thattakes a Rabbit.Q..: Can a method declare multiple return values?Or Isthere some way to return more than onevalue?A: Sort of. A method can declare onIy one returnvalue. BUT... If you want to return, say, three int values,then the declared return type can be an Int orray.Stuff those lnts into the array,and passIt on back. It'sa little more involved to return multiple values withdifferent types; we'll be talking about that in a laterchapter when ~e talk about ArrayLlst.'Q :Do Ihave to return the exact type , declared?A.: You can return anything that can be implicitlypromoted to that type. So, you can pass a byte wherean Int Is expected .The caller won't care,because thebyte fits Just fine Into the tnt the caller will use forassigning the result. You must use an explicit castwhen the declared type Is smaller than what you'retrying to return.Q..: Do Ihave to do something with the returnvalue of a method? can IJust Ignore it?A:Java doesn't require you to acknowledge areturn value. You might want to call a method witha non-void return type, even though you don't careabout the return value. In this case, you're callingthe meth od for the work it does inside the method,rather than for what the method gives returns . InJava, you don't have to assign or use the return value.• Classes define what an object knows and whal anobject does.• Things an object knows are itsInstance variables(state).• Things an object does are its methods (behavior).• Methods can use instance variables so that objectsof the same type can behave differently.• Amethod can have parameters, which means youcan pass one ormore values in to the method.• The number and type ofvalues you pass inmustmatch the order and type of the parametersdeclared bythe method.• Values passed inand out ofmethods can beimplicitly promoted to a larger Iype orexplicitly casttoa smaller type.• The value you pass as an argument toa methodcan be a literal value (2, 'c', etc.) ora variable ofthe declared parameter type (for example, xwherexis an intvariable) . (There are other things youcan pass as arguments, but we're not there yet.)• Amethod must declare a retum type.Avoid retumtype means the method doesn't return anything.• Ifa method declares a non-void return type, it mustreturn a value compatible with the declared returntype.78 chapter 4


methods use instance variables"ttgs you catt do with parametersreturtt types__... . .e've seen how parameters and return types work, it'sthem to good use: Getters and Setters. Ifyou're intormal about it, you might prefer to call them ACC610TS.Jw.;ifO;OOIrl. But that's a waste of perfectly good syllables.Gc ters and Setters fits thejava naming convention. so~,wl:l2 lwe'Il call them.nd Setters let you, well, getand sa things. Instance van­1r:1_JeS. usually. A Getter's sole purpose in life is to send back,~az!lnl value, the value ofwhatever it is that particular Getter".-as.:d to be Getting. And by now, it's probably no surprise1&3,~ner lives and breathes for the chance to take an argu­.~1De and use it to set the value of an instance variable.ElectrlcGultarbrandnumOfPickupsrockStarUsesl1getBrandOselBrandOgetNumOfPickuPSOsetNumOfPickupsOgetRockStarUsesltOsetRockSlarUsesllO- i.DcJ brand i• numOfPiclcups;.an rockStarUs8sIt;Si:.:-'.-nCJ qetBrand ()return brand;id s8tBrand (String &Brand) (brand = &Brand i• getNumOfPickups() {return numOfPickups;:.d setNumOfPickups (int num)numOfPickups = num;.an g8tRockStarusealt()rockStarUseslt;=-~rnsetRockStaruseslt(boolean y&sOrNo) {~tarU8eslt m yesOrNoiyou a re he re. 79


eal developers encapsulateEt1capsulaffot100 It or risk hUlMlliatiot' at'dridicule.Until this most important moment, we'vebeen committing one of the worst 00faux pas (and we're not talking minorviolation like showing up without the IB'in BYOB). No, we're talking Faux Pas witha capital 'F'. And ·P'.Our shameful transgression?Exposing our datalHere we are.just humming along withouta care in the world leaving our data outthere for anyoru to see and even touch.You may have already experienced thatvaguely unsettling feeling that comes withleaving your instance variables exposed.Exposed means reachable with the dotoperator, as in:theCat.height : 27;.T hink about this idea of using our remotecontrol to make a direct change to the Catobject's size instance variable. In the handsof the wrong person, a reference variable(remote control) is quite a dangerousweapon. Because what's to prevent:'t.~\l.ts~ Wt. eA" 1theCat.height = 0; 1e-t ~i5. "ayYt".This would be a Bad Thing. We need tobuild setter methods for all the instancevariables, and find a way to force othercode to call the setters rather than accessthe data directly.public void setBeight (int ht) {if (ht > 9) {height: ht;}80 chapter 4


methods use Instance variablesthedatait isthat simple to go fromimplementation that'sjust. g for bad data to oneprotects your data andects your right to modifyimplementation later.so how exactly do youthe data? With thelie and privateess modifiers. You're. iar with public-we userith every main method.re's an encapsulationnile of thumb (all standisclaimersabout rules~ thumb are in effect): markinstance variables privati!provide public getterssetters for access control.you have more designcodi ng savvyin Java, youbably do things a littlerently, but for now. thisI!!!IlP:oach will keep you safe.ark getters andetters pUblic.·Sodly. Bill forgot toCftCopsulQt~ his Cat class andended up wltk Q flat cat. H(overheard at the water cooler).'" Java'~edThis week's Interview:An Object gets candid about encapsulation.HeadFirst What's the big deal about encapsulation?Object: OK.,you know that dream where you're givinga talk to 500 people when yousuddenly realize-you're TUJkaP.HeadFirst: Yeah, we've had that one. It's right up there with the one about the Natesmachine and... no, wewon't go there. OK, soyou feelnaked. But other than being a littleexposed, is there any danger?Object Is there any danger? Is there any danger? [St3.I'1S laughing] Hey, did allyou otherinstanceshear that, "Islhert aT[!danger?" he asks? [falls on the floor laughing]HeadFirst: What's funny about that? Seems like a reasonable question.Object: OK, I'll explain it. It's [bW'StS out laughing again, uncontrollably]HeadFirst: Can I get you anything?Water?Object: Whew! Oh boy. No I'm fine, really. I'll be serious. Deep breath. OK, go on.HeadFirst: So what doesencapsulation protect youfrom?Object Encapsulation puts a force-fieldaround my instance variables, so nobody can setthem to, let'ssay, something inappropriaJ.e.HeadFirst Can you giveme an example?Object: Doesn't take a PhD here. Most instance variable values arecoded with certainassumptions about the boundaries of the values. Like, think of all the thingsthat wouldbreak if negative numbers were allowed. Number of bathrooms in an office.Velocity ofan airplane. Birthdays.BarbellweightCellphone numbers. Microwaveoven powetHeadArst: I seewhat you mean . So how does encapsulation let you set boundaries?Object By forcing other code to go through setter methods. That way, the setter methodcan validate the parameter and decideif it's do-able. Maybe the method will reject it anddo nothing, or maybe it'll throw an Exception (like if it's a null social security numberfor a credit card application), or maybe the method will round the panlITleter sent in tothe nearest acceptable value.The point is,you can do whatever you want in the settermethod, whereas you can't do aT[!thing if your instance variables arepublic.HeadFirst: But sometimesI see setter methods that simplyset the value without checkinganything: If you have an instance variable that doesn't have a boundary, doesn't thatsener method create unnecessaryoverhead? A performance hit?Object: The point to setters(and getters, too) is thatyou can c1umgeyour mindlater,without breaking any1Jo4y else's code!Imagine if half the people in your companyusedyour classwith public instance variables, and one day you suddenly realized,"Oops- there's something I didn't plan for with that value, I'm going to have to switchto asetter method." Youbreak everyone'scode. The cool thing about encapsulation is thatyouget to cJumgt)'CUT mind. And nobody getshurt The performance gainfrom using variablesdirectly isso rniniscule and would rareIy--ifDJn- beworth ityou are here ~ 81


how objects behaveEttcapsulatittg thet}oodPog classclass GoodDog (private int size;.~.,.t,L /ItJ\o¥-t. .\.)\t. \. #. ,/ -'\,,\l\ t.~ public int getSize ()~o~ 0~ ) r,turn ,i,e,GoodDogsizegelSize( }selSize( )bark( )t). ~~ al\G ~ public void setSi"le (int s) (Ma'¥.t. t. .1.\..~~ ~.~tt.~ ",CV' size = s rvoid bark () (if (size > 60)System.out.println("wooof! Wooof!");else if (size> 14) (Syscem.out.princln("Ruff! Ruff!");else (System.out.println( "Yip! Yip!");I.Any place where aparticular value canbe used, a methodcall that returns thattype can be used.Instead of:int x =3 + 24;you can say:int x =3 + one.gdSize();class GoodDogTestDrive Ipublic static void main (String!) args) (GoodDog one = new GoodDog();one .setSize(70);GoodDog two = new GoodDog();two.setSize(8);System.out.printlnIWDog one: + one.getSize(»;System.out.printlnl"Dog two: " + tWQ.getSize(»;one. bark ();two. bark () ;82 chapter 4


methods use instance variablesHow do objects I" a" arrayhave?like any other object. The only difference is. you get to them. In other words, how you getremote control. Let's try calling methods onobjects in an array.Declare and create a Dog array,to hold 7 Dog references.Doq[] pets;pets = new Doq[7];Dog[]Dog array object (Dog[])Create two new Dog objects.and assign them to the firsttwo array elements.pets [0] = new Dog () ;pets[l] = new Dog();Call methods on the two Dogobjects.pet8[O].setSize(30) ;int x = pets[O] .qetsize();peta[l) .setSize(8);Dog[]Dog array object (Dog[])you are here ~ 83


Initializing instance variablesPeclarfttg and initializingittstatlce variablesYou already know that a variable declaration needs at least a nameand a type :int size;String name;And you know that you can initialize (assign a value) to thevariable at the same time:int size = 420;String name = "Donny";But when you don't initialize an instance variable, what happenswhen you call a getter method? In other words, what is the value ofan instance variable bejoreyou initialize it?t,al'll.t IIayia\,\es,class PoorDog ( dtt\a'Ct t..,o i~ ~ IIalw.. ./} \:l",t. d()t\'t. a~I~1\private 1nt size; k'~private String name;P)ubliC int getsize () (~return size; Ifpublic String getName () (return name;What will -tnue: 'Cd!.',",??Instance variablesalways get adefault value. Ifyou don't explicitlyassign a valueto an instancevariable, or youdon't call a settermethod, theinstance variab'estill has a value!integers 0floating points 0.0booleansreferencesfalsenull, Y.-? y.l\\\public class PoorDogTestDrive { ~\:, ~o ~O'" t.~j ,public static void main (String [] args) ( / . "'1\ t,O"'~PoorDog one = new PoorDog () ; '.!. ~\~ e )System.out.println("Dog size is "System.out.println("Dog name is "+ one.getSize(»);+ one.getName(»);% java PoorDogTestDriveDog size is 0Dog name is null84 chapter 4


fhe differet1ce betwee" it1sfat1ceat1d local variablesmethods use instance variableso Instance variables are declaredinside a class but not within a method.class Horse (private double heightprivate String breed;II more code . . .e Local variables are declared within a method.class AddThing {iot a;int b = 12;public iot add() {int total = a + b;return total;15.2;Local variables doNOT get a defaultvalue! The compilercomplains if youtry to use a localvariable beforethe variable isinitialized.Q: What about method parameters?How do the rules about local variablesapply to them?e Local variables ~UST be initialized before uselclass Foo { "I\e" Yov. u~public void go () ( W()\'l t to"''' ' t~ ~ a 'Ja\~,Ln t x; deda ye Yo WI 0 b-1nl.&t. as $CO¥\ as 'f~ .Lrrt z = x + 3; to ~ it, ~e l.oft


object equalityColttpari"Q variables (primitives or refere.,ces)Sometimes you want to know iftwo primitives are the same. That's easyenough,just use the = operator. Sometimes you want to know if tworeference variables refer to a siogle object ~>n the heap. Easy as well, juslusethe == operator. But sometimes you want to know if two objects are equal.And for that, you need the .equals0 method. The idea ofequality forobjects depends on the type of object. For example, iftwo different Stringobjects have the same characters (say. "expeditious"), they are meaningfullyequivalent, regardless ofwhether they are two distinct objects on the heap.But what about a Dog? Do you want to treat two Dogs as being equal iftheyhappen to have the same size and weight? Probably not. So whether twodifferent objects should be treated as equal depends on what makes sense forthat particular object type . We'll explore the notion ofobject equality againin later chapters (and appendix B), but for now, we need to understand thatthe == operator is used emly to compare the bits in two variables. What thosebits represent doesn't matter. The bits are either the same, or they're not.To compare two primitives, use the == operatorUse == to comparetwo primitives,or to see if tworeferences refer tothe same object.Use the equalsOmethod to seeif two diHerenfobjects are equal.(Such as two differentString objects that bothrepresent the charactersIn "Freel")The = operator can be used to compare two variables ofany kind, and itsimply compares the bits.if (a = b) {...j looks at the bits in a and b and returns true ifthe bit patternis the same (although it doesn't care about the sizeof the variable, 50 all theextra zeroes on the left end don't matter). ~~ 0" )(~\oV'e u'( tint Ii = 3; (t.t.t'«( aye.'" Ja--t"e iYl ,\ rt ~\de L~t ..lc.he tJ( 't. (.4'(e 6 1lbyte b = 3; \,~t. 'Ole o.~ - -if (a == b) { I I tl:Ue } t.'hat n('(e) , int byteTo see If two references are the same (which means theyrefer to the same object on the heap) use the == operatorRemember, the == operator cares only about the pattern of bits in thevariable. The rules are the same whether the variable is a reference orprimitive. So the == operator returns true iftwo reference variables refer tothe same objectl In that case, we don't know what the bit pattern is (becauseit's dependent on theJVM, and hidden from us) but we M know that whateverit looks like, it wiU bethe samefor two refmrues to a singleobject.Foo a = new Foo();Foo b = new Foo();Foo c = a;if (a == b) { II false } Fooa=t.ish"\oI.eif (a -- c) ( II true )if (b c) ( II falsea = b is .falst)Foo86 chapter 4-- Foa


methods use Instance variablesMake ,t st,tkRoses are red,this poem ischopPY,. byvaluepassing;s passing bycopy,1 it.Replaceourcan do better? r'J 8e~ryet.Oh,likeyoU d llnewith your ow'" wn wOld~dumb seco n I thing with YOUl 0theY/ho ereplace forget it.a"d you'll neverWhat's legal?Giventhe method below, whichof the method calls listed on theright ore legaltPut a checkmcrk next to theones that are legal. (Somestatements are there to assignvalues used in the method colis).KEEP+­RIGHTint a '" calcArea(7, 12);short c '" 7;calcArea (c,15) ;int d '" calcArea(S7);calcArea (2,3) ;long t '" 42;int f = calcArea(t,17);int calcArea(int height, int width)return height • width;int 9 '" calcArea();calcArea () ;byte h = calcArea(4,20);int j= calcArea(2,3,5);you are here ~ 87


exercise: Be the CompilerBE the oomrilerEach ofthe Java files on this pagerepresents a complete source file.Your joh is to play collll'iler anddetermine whether each ofthese fileswill compile. Ifthey won'tcompile. how would yourIX them, and ifthey doc011lpile. what would hetheir output'i'Aclass XCopy {public static void main(Strinq [) arqs) {int orig = 42;Xcopy x = new xCopy();int y : x.go(orig)jSystem.out.println(orig + U U + y);class Clock {String time;Bvoid setTime(String t)time = tjvoid getTime()return time;}int go(int arg)arg = arg * 2;class ClockTestDrive {public static void main(String (] args) {}}return arg;Clock c = new Clock();c.setTime(U124S n ) jString tad = c.getTime()iSystem.out.println(Utime: u+ tod)j88 chapter 4


methods use instance variablesA bunch of Java components, in full costume, are playing a partygame,· Wha am W They gille you a clue, and you try to guess whothey are, based on what they say.Assume they always tell the truthabout themselves. If they happen to say something that could be truefor more tha n on e guy, then write down all fa r whom that sentenceapplies. Fill In the blanks next to the sentence with the names of oneor more attendees.Tonight's attendees:Insta nee variable, argument, return, getter,setter,encapsulation, public, private, pass by value, methodA class can have any number of these.A method can have only one of these.This can be Implicitly promoted.I prefer my Instance variables private.It really means 'make a copy'.Only setters should update these.A method can have many of these.I return something by definition.I shouldn't be used with instance variables.I can have many arguments.By definition, I take one argument.These help create encapsulation.I always fly solo.you are here. 89


puzzle: Mi)(ed MessagesMixedMessagesAshort Java program Is listed to your right.Two blocks of the program are missing.Your challenge Is to match the candIdateblocks of code (below), with the outputthat you'd see ifthe blocks were Inserted.Not all the lines of output will be used, andsome of the lines of output might be usedmore than once. Draw lines connectingthe candidate blocks of code with theirmatching command-line output.public class Mix4 (int counter = OJpublic static void main (String [) args) (int count = 0;Mix4 [) m4a =new Mix4[20ljint x = 0;while (I I)m4a [x] = new Mix4 ();m4a(x] . counter = m4a(xl .counter + 1;countcountcount + 1;count + m4a[x) .maybeNew(x);x = x + 1;CandIdates:x ·< 9index < 5 ,!x < 20index < 5.~x


methods use Instance variablespublic class Puzzle4 {public static void main(Strinq [] arqs) {YourJob is to take code snippets from thepool and place them Into the blank linesin the code. You may not use the samesnippet more than once, and you won'tneed to use all the snippets. Your goalis to make a class that will compile andrun and produce the output listed.OutputNote: Eachsnippet"om the pool can beused only oncel}}class}int y = I:int x = 0:int result = 0;while (x < 6) {y y * 10;}x = 6;while (x > 0) {result = result +__}system.out.println("result " + result);int ivar;}{_____ doStuff(int ) {if (ivar > 100) {return} else {} -return ---------------------_you are here) 91


puzzle: Five Minute MysteryFastTImes in Stim-CltyWhen Buchanan jammed his twitch-gun into Jai's side, Jai froze. Jai knew that Buchananwas as stupid lis he was ugly and he didn't want to spook the big guy. Buchanan ordered Jaiinto his boss's office, but Jai'd done nothing wrong, (lately), so he figured a little chat withBuchanan's boss Leveler couldn't be too bad. He'd been moving lots of neural-stimmers inthe west side lately and he figured Leveler would be pleased. Black market stimmers weren'tthe best money pump around, but they were pretty harmless. Most of the slim-junkies he'dseen tapped out after a while and got back to life, maybe just a little less focused thanbefore.Leveler's ' office' was a skungy looking skimmer, but once Buchanan shoved him in, Jaicould see that it'd been modified to provide aIL the extra speed and armor that a local boss likeLeveler could hope for. "Jai my boy", hissed Leveler, "pleasure to see you again". "LikewiseI'm sure...", said Jai, sensing the malice behind Leveler's greeting, "We should be squareLeveler, have r missed something?" "Ha! You're making it look pretty good Jai, your volumeis up, but I've been experiencing, shall we say, a little 'breach'lately..." said Leveler.Jai winced involuntarily, he'd been a top drawer jack-hacker in his day. Anytime someone.figured out how to break: a street-jack's security, unwanted attention turned toward Jai, "Noway it's me man", said Jai, "not worth the downside. I'm retired from hacking, [just movemy stuffand mind my own business", "Yeah, yeah", laughed Leveler, "I'm sure you'reclean on this one, but I'll be losing big margins until this new jack-hacker is shutout!" "Well, best of luck Leveler, maybe you could just drop me here and I'll gomove a few more 'units' for you before I wrap up today", said Jai."I'm afraid it's not that easy Jai, Buchanan here tells me that word is you'recurrent on 137NE", insinuated Leveler. "Neural Edition? sure I play around a bit, sowhat?". Jai responded feeling a little queasy. "Neural edition's bow I let the stim-junkiesknow where the next drop will be", explained Leveler. "Trouble is, some srim-junkie's stayedstraight long enough to figure out how to hack into my WareHousing database." "I need aquick thinker like yourself Jai, to take a look at my StimDrop 137NE class; methods, instancevariables, the whole enchilada, and figure out how they're getting in. It should..", "HEY!",exclaimed Buchanan, "I don't want no scum backer like Jai DOSin' around my code!" "Easybig guy", Jai saw his chance, "I'm sure you did a top rate job with your access modi .. "Don'ttell me - bit twiddler!", shouted Buchanan, "1 left all ofthose junkie level methods public,so they could access the drop site data, but 1marked all the critical WareHousing methodsprivate. Nobody on the outside can access those methods buddy, nobody!""I think I can spot your leak Leveler, what say we drop Buchanan here offat the comerand take a cruise around the block", suggested Jai. Buchanan reached for his twitch-gun butLeveler's stunner was already on Buchanan's neck, "Let it go Buchanan", sneered Leveler,"Drop the twitcher and step outside, I think Jai and I have some plans to make",92 chapter 4What did Jai suspect?Will be get out of Leveler's skimmer with all his bones intact?


methods use Instance variablesBclass ClockString time;void setTime(~tring t) {time:: t;}String getTime ( )return time;}class ClockTestDrive {public static void main(String rl args) {Clock c = new Clock();c.setTime(R124S R ) jString tod = c.getTime();System.out.println(Utime: • + tod);XCopy' compiles and runs as itstands I The84'. Remember Java ispass byvalue, (whichcopy), the variable 'orig' isnol changed by the}Note: 'Getter' methods have areturntype by definition.dass can have any number of these.method can have only one of these.I' can be implicitly promoted.prefer my instance variables private.really means 'make a copy'.setters should update these.method can have many of these.return something by definition.shouldn't be used with instance variablescan have many arguments.definition, , take one argument.se help create encapsulation.always fly solo.Instance varl~bles, getter, utter,methodreturnreturn. argumentencapsulationpass by valueInstance variableso.rgt.llnentgetterpublicmethodsettergetter. s£'tter, public. privatereturnyou are here. 93


puzzle answersPuzzle SolutionsAnswer to the 5-minute mystery...pUblic class Puzzle4 (public static void main(String [] args) {Puzzle4b [ ] ebs =new Puzzle4b[6J;int y - 1;int K .. 0,int result = 0:while (x < 6) (obs[x) =new PU2zle4b( ):obs[x) . ivar =y;y - y .. 10;x=>


5 writing a programExtra-Strength MethodsLet's put some muscle In our methods. We dabbled with variables, playedwith a few objects, and wrote a little code. But we were weak.We need more tools. Likeoperators. We need more operators so we can do something a little more interesting than, say,bark. And loops. We need loops, but what's with the wimpy while loops? We need 10, loopsjfwe're really serious. Might be useful to generate random numbers. And turn a StringInto an Int, yeah, that would be cool. Better learn that too. And why don't we learn It all bybuilding something real, to see what it's like to write (and test) a program from scratch. Maybea game, like Battleships. That's a heavy-lifting task,so It'll take two chapters to finish .We'll builda simple version in this chapter, and then build a more powerful deluxe version in chapter 6.this is a new chapter 95


uilding a real gameLetls build a Jattleship ...stylegattte: "Sitdc a Pot COttt NIt's you against the computer, but unlike the realBattleship game, in this one you don't place any shipsof your own. Instead, yourjob is to sink the computer'sships \0 the fewest number of guesses.Oh, and we aren't sinking ships. We're killing DotCorns. (Thus establishing business relevancy so you canexpense the cost of this book).Goal: Sink all of the computer's Dot Corns in the fewestnumber ofguesses. You're given a rating or level, basedon how well you perform.Setup: When the game program is launched, thecomputer places three Dot Corns on a virtual 7 x 7grid. When that's complete, the game asks for your firstguess.How you play: We haven't learned to build a CUI yet, sothis version works at the command-line. The computerwill prompt you to enter a guess (a cell), that you 'U typeat the command-line as ~A.3", "C5", etc.). In responseto your guess, you'll see a result at the commandline,either "Hit", "Miss", or "You sunk Pets.corn" (orwhatever the lucky Dot Com of the day is). Whenyou've sent all three Dot Cams to that big 404 in thesky,the game ends by printing out your rating.tat.\-. 'oo~~"7 )< "7 ~r-id ',s a"t.t\\ABCDEFGE5•~eP4 ts.cc mYou'reI Asi Me.c pmo 1 2 3 4 5 6'-shr-h at. ut"o, like Java d'n'ayskgoing to build theSink a Dot Com game, witha 7 x 7 grid and threeDot Coms. Each Dot Comtakes up three cells.partofa galMe it1feraetlott..%j ava OotComBustEnt e r a guessmi s sA3Ent e r a guess 82mi s sEnt e r a guessmi s sC4Ent e r a guess 02hitEnt e r a guess 03hitEnter a guess 04Ouch!killYou sunk Pets. comEnter a guessmissEnter a guesshitEnter a guesshitEnter a guessOuch!B4G3G4GS'lou sunk AskMe.com96 chapter 5


writing a programFirst a high ...level desigtt'e know we'll need classes and methods. but whatuld they be? To answer that, we need moreformation about what the game should do.First, we need to figure out the general flow of thezame. Here's the basic idea:User starts the gameoGame creates three Dot ComsoGame set-upoGame places the three DotColTlS onto a virtual gridGame play beginsRepeat the following until there areno more Dot Coms:A Prompt user for a guess 1'\W ("'2', 'CO', etc.) . )( 0 Check'he user guess oga;nstall Dot Coms to look for a hit,miss, or kill. Take appropriateaction: if a hit, delete cell(A2, D4, etc.). If a kill, deleteDot Com.removeDot ComhitAdial'l\Of\dyt:f""~l\b adt:t.isiOl\ ~O'l\tGame finishesGive the user a rating based onthe number of guesses.display userscore/rating~ow we have an idea of the kinds of things therogram needs to do. The next step is figuringut what kind of objects we'll need to do theloo·ork. Remember, think like Brad rather thanLarry; focus first on the things in the programra ther than the jrroredures.Whoa. A real flow chait.you are here. 97


a simpler version of the gamefhe "SitMple Pot CO"' .allte Na get1tler it1troductiot1It looks like we're gonna need at least two classes, aGame class and a DotCom class. But before we buildthe fuJI monty Sinh a Dot Comgame, we'll start witha stripped-down. simplified version, Simple Dot ComGame. We'll build the simple version in this chapter,followed by the deluxe version that we build in thenextchapter.Everything is simpler in this game, Instead ofa 2-Dgrid, we hide the Dot Com injust a single TOW. Andinstead of threeDot Corns, we use one.The goal is the same, though, so the game still needsto make a DotCom instance, assign it a locationsomewhere in the row, get user input, and when allof the DotCom's cells have been hit, the game is over,This simplified version of thegame gives us a big head starton building the full game.Ifwe can get this small oneworking, we can scale it up tothe more complex one later.voId mail\In this simple version, thegame class has no instancevariables, and all the gamecode is in the main () method,In other words, when theprogram is launched andmain () begins to run, it willmake the one and only DotCominstance, pick a location for it ( threeSlmpleDotCom Game ~SlmpleDofComInl0localionCellsIntnum01Hl1sconsecutive cells on the single virtualseven-cell row), ask the user for a guess, check theguess, and repeat until all three cells have been hit.ooString checkYou~If(Stril\g guess)void SetlocallonCellsQntO loe)Keep in mind that the virtual row is... virtual: In otherwords, it doesn't exist anywhere in the program. Aslong as both the game and the user know that theDotCom is hidden in three consecutive cells out ofapossib\e seven (starting at zero), the tOW i.tselfdoesn'thave to be represented in code. You might be temptedto build an array of seven ints and then assign theDotCom to three of the seven elements in the array,but you don't need to. All we need is an array thatholds just the three cells the DotCom occupies.98 chapter 56arM starts, and creates ONE DotComand gives it a location on three. cells inthe single row of seven cells.Instead of •A2", ·C4", and 50 on, thelocations are just integers (for example :1,2,3 are the cell locations in thispicture:1236a1U play begins. Prompt user fora guess, then check to see jf it hitany of the DotCom's three cells.If a hit , increment the numOfHitsvariable.46ame 'finishes when all three cells havebeen hit (the numOfHits variable velueis 3), and tells the user how manyguesses it took to sink the DotCom.56


writing a programPevelopit1Q a Class_ a programmer, you probably have a methodology/ess/approach to writing code. Well. so do we. Oursequence is designed to help you see (and learn) what're thinking as we work through coding a class. It' t necessarily the waywe (or you) write code in theWorld. In the Real World, of course, you'll followapproach your personal preferences, project, orployer dictate. We, however, can do pretty muchtever we want And when we create aJava class as arning experience", we usually do it like this:fhe three thlt19S we~1I wrIte foreach class:This bar Is displayed on the next set of pages to tellyou which part you're working on. For example, if yousee this picture at the top of a page. it means you'reworking on prepcode for the SimpleDotCom class.~SlmpleDolCom classDFigure out what the class is supposed to do.DDDList the Instance variables and methods.Write prepcode for the methods. (You'll seethis in Just a moment.)Write test code for the methods.prep codeA form of pseudocode. to help you focus onthe logic without stressing about syntax.test codeA class or methods that will test the real codeand validate that it's doing the right thing.D Implement the class.o Test the methods.o Debug and relmplement as needed.reaI codeThe actual implementation of the class. This iso Express gratitude that we don't have to test __----.....al Java code.our so-called learning experience app on To DO.:actuallJve users.Flex those dendrftes.Howwould you decide whIch class or classesto build first, when you're writIng a program?Assuming that all but the tiniest programsneed more than one class (Ifyou're followinggood 00 principles and not having one classdo many different Jobs), where do you start?s'mp'eDotCOm claSSo write prep codeo write test codeo write final Java codes,mp'eDotCOmoamecia••o write prep codewrite test code {nolo write final Java codeyou are here. 99


SimpleDotCom classSlmpleOolComilll0IocaIiooCelIsinlnumOft-lilsString checkYourself(string guess)void selLoca~onCells{inlj) lot)You'11 get the idea ofhow prepcode (our version of pseudocode) works as youread through this example. It's sort of half-way between realJava code and a plainEnglish description of the class. Most prepcode includes three parts: instancevariable declarations, method declarations, method logic. The most importantpart of prepcode is the method logic, because it defines what has to happen,which we later translate into hotu;when we actually write the method code.DECLARE an int array to hold the location cells.Call it loeatJonCells.DECLARE an int to hold the number of hits.Call it numOfHits and SET it to O.DECLARE a checkYourset(() method that takes a String for the user's guess (" I", "3", etc),checks it.and retums a result representing a "hit","miss",or "kill",DECLARE a setLocationCeJ/sO setter method that takes an int array (which has the three celllocations as ints (1.3/1, etc.).METHOD: String checkYourself(String userGuess)GET the user guess as a String parameterCONVERT the user guess to an intREPEAT with each of the location cells in the int arrayII COMPARf the user guess to the location cellIF the user guess matchesINCREMENT the number of hitsII FIND OUT if it was the last location cell:I F number of hits is 3, RETt,JRN "kill" as the resultELSE it was not a kill. so RETURN"hit"[END IFELSE the user guess did not match, so RETURN "miss"END IFEND REPEATEND METHODMETHOD: void setLocotJonCe//$(lnt[] eel/Locations)GET the cell locations as an in! arrayparameterASSIGN the cell locations parameter to the cell locations instance variableEND METHOD100 chapter 5


writing a programWriting the tttethodhMpletM8ntationslet's write the real...ethod code ttOW, ittd getthis puppy worklttg.Before we start coding themethods, though, let's backup and write some code totest the methods. That's right,we're writing the test code1M/ore there's anything to testlThe concept of writingthe test code first is one ofthe practices ofExtremeProgramming (XP), andit can make it easier (andfaster) for you to write yourcode. We're not necessarilysaying you should use XP,but we do like the part about....Tiling tests first. And XPjustsoundscool.Extreme Programming(XP) Is a newcomer to the softwareevelopment methodology world.Consldered by manyt be "the way programmers really want to work ~ XPe erged In the late 90'sand has been adopted by•ompanies ranging from the two-person garage shopthe Ford Motor Company. The thrust of XP is that thesterner gets what he wants, when he wants It, evenen the spec changes late In the game.is based on a set of proven practices that are allesigned to work together, although many folks do pickand choose, and adopt only a portion of XP's rules.Thesectices include things like:ke small, but frequent, releases.velop in Iteration cycles.Extreme Programming (XP)Don't put in anything that's not in the spec (no matterhow tempted you are to put In functionality "for thefuture).Write the test cod e first .No killer schedules;work regular hours.Refactor (improve the code) whenever and wherever younotice the opportunity.Don't release anything until it passesall the tests.Set realistic schedules, based around small releases.Keep it simple.Program in pairs, and move people around so thateverybody knows pretty much everything about the code .you are here ~ 101


SlmpleDotCom classprepcodeWrith1Q test code for the Shttp[eUoi'ColM classWe need to write test code that can make a SimpleDotCom objectand run its methods. For the SimpleDotCom class. we reallycare about only the cMckYourselj() method, although we will haveto implement the sdLocatiun~l1s()method in order to get thecMckYourself() method to run correctly.Take a good look at the prepcode below for the checkYourselj()method (the setLocaticmCells() method is a no-brainer setter method,so we're not worried about it. but in a 'real' application we mightwan I a more robust 'setter' method. which we wouldwant to test).Then ask yourself, "If the checkYourselfO method wereimplemented. what test code could I write that would prove to methe method is working correctly?"'ased Ott this prepcode:METHOD String checkYourselffString userCuess)GET the user guess as a String parameterCONVERT the user guess to an IntREPEAT with each of the location cells in the Int array/I COMPARf the user guessto the location cellIF the user guess matchesINCREMENT the number of hits/ / FIND OUT if it was the last location cell:IF number of hits is 3.RETURN "Kill" asthe resultELSE it was not a kill, so RETURN"Hif'END IFELSE the user guess did not match, so RETURN "Miss"END IFEND REPEATEND METHODHere1s what we should test:1. Instantiate a SlmpleDotCom object.2, Assign It a location (an array of 3 ints, like{2,3.4}).3. Create a SlJing to represent a user guess('2", '0', etc.).4. Invoke the checkYourselfO method passingil the fake user guess.5. Print out the result to see If It's correct("passed" or "failed").102 chapter 5


•writing a program~relare,..{l? "DiiJjjo ~uestl9nsQ..:Maybe I'm missing somehere,but how exactly dorun a test on something..doesn't yet existI1: You don't.We never saidstart by running the test;start by writingthe test. At. e you write the test code,won't have anything to run,against. so you probably won'tIe to compile It until youe 'st ub' code that can combutthat will always causeest to fail (like, return null.):Then Istili don't see the••..,rt. Why not walt until theIs written, and then whipthe test code?: The act of th Inkl n9 th roug hwriting) the test code helps. ...bri"tv your thoughts about whatmethod Itself needs to do.soon as your implementatione is done, you already havecode Just waiting to validateBesides,you know If you don't't now, YOU'll never do It.e's always something moreesting to do.ally, write a little test code,write onlythe Implementacodeyou need in order tothat test. Then write a littlee test code and write onlynew implementation codeed to pass that new test. Attest lteratlon, you TUn allpreViously-written tests, soyou always prove that yourt code additions don't breakiously-tested code.fest code for the SIIMpiePotCoIM class....sta"ba-tl. a\~....y\e'Da\:.e,o...public static void main (Strinq [ ] arqs) ( do~et,t.public class SimpleDotComTestDrive (}SimpleDotcom dot = new SimpleDotCom(); 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); .~ ''' ...oIce tJ.. •.....L.--.. ,.,tih e ~tnod0,. the dot. to ....String userGuess = "2 H ; ~"",Itt 0 ~ake~tv"~~String result = dot.checkYourself(userGuess);~i""'ok 1:~Strinq testResult = "failed" j _...1., e e thetJcYoursel.fOm.ev\od on ille dot to...objttt, a"d Pdss if. illif (result.equals ("hit") ) ( .f


SimpleDotCom classThe checkYourselfO tttethodThere isn't a perfect mapping from prepcode to javacode; you'll see a fewadjustments. The prepcode gave us a much better idea of what the code needs todo, and now we have to find theJava code that can do the how.In the back ofyour mind, be thinking about parts ofthis code you might want(or need) to improve. The numbers (18 are for things (syntax and languagefeatures) you haven't seen yet. They're explained on the opposite page.GET the userguessCONVERTthe user guess toan intREPEAT witheach ceil in the intarrayIF the user guessmatchespublic String checkYourself(String stringGuess) {I) to"veri th &t 'int guess = Integer.parselnt(stringGuess); L- L • 1- e r'''9,--- w al'l I I'I~String result = "miss"; ( - ....a: e a variable to hold the reslAlt we'llre~lAr" Plat II . ". . ""ss i" as the detalAlt•('.e. we clsslA....e a ......iss")for (int cell : locationCells) {INCREMENTthe nUI1"lber ofhits~ 9d; QlAt o.f th Ito te t e p, no "eed! I end i f s the other tells/ / FIND OUT ifit.was the last eel!IF number of hitsis 3.RETURN "kili"as the resultELSE it wasnot a kill. soRETURN"hit"ELSERETURN} II end f orif (numOfHits == locationcells.length) (result = "kill";/ ! end ifSystem.out.println(result); ~ display the reslAlt.for the lASerreturn result;t"-. retlAr" the reslAlt bade to} I I end method the talli"9 ....ethod("Miss", lAl'lless it was tha"ged to "I-hi;" or "Kill")104 chapter 5


writing a programe things we haven't seen beforeon this page. Stop worryingl Theof the details are at the end ofchapter. This isjust enough to letkeep going.Converting aString to an IntThe post-incrementoperatorbreak statementnumOfHits++(n'WhaWtr'S th&e (il'l ~'Wc*d.s, int __e",ent by ,).~ ++ ...taY\1 add I toroIArllOtl·hh++ i.s the sa...t (il'lthis ~) as sayi,,~ "......O.f»its ::.""",o.f~hh +" e~rt sli9hUt...~~ tHitientbreak;~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!you are here ~ 105


SlmpleDotCom classprep code:therelare~~ "DUmb ~uesti9115Q..:What happens InInteger.parselnt(l If the thing youpau Isn't a number? And does Itrecognize spelled-out numbers,/Ike Jl three"?A: Intege r.parselntO wo rks onlyon Strings that represent the asciivalues for digits (0,1,2,3,4,5,6,7,8,9).If you try to parse something like"two" or "blurp'; the code wi II blowup at runtime. (By blow up, weactually mean throw an exception,but we don't talk about exceptionsuntil the Exceptions chapter. So fornow, blow up is close enough.)Q..:ln the beginning ofthebook, there was an exam pie of afor loop that was really differentfrom this one-are there twodifferent styles offor loops?A:YeSl From the first version ofJavathere has been a sIngle kindof (or loop (explained later In thischapter) that looks like this :for (Int i = 0:/ < 10;1++) {// do someth ing 10 timesYou can use this format for anykind of loop you need.But...beginnIng with Java 5.0 (Tiger),you can also use the enhancedforloop (that's the official description)when your loop needs to iterateover the elements In an array (oranotherkind of collection, as you'llsee In the next chapter). You canalways use the plain old for loopto iterate over an array, but theenhancedfor loop makes it easier.public class S~leDotComTestDrive {publiC s t a t i c void main (S~ringl] args) {SimpleDotCom dot ~intI] locations ~ (2,3,4);new SimpleDotCom{};dot , setLocationCells (locations) ;String userGuess ~ "2-;String result ~public class SimpleDotComintI) locationCells;int numOfHits ~ 0;dot .checkYourself(userGuess);pUblic void setLocationCells(intl] locs) (locationCells = locs;pUblic String checkYourself(String stringGuess)int guess ~ Integer.parselnt{stringGuess);String result - "miss";for (int cell : IocationCells)if (guess ~ ~ cell) (result = " hi t - ;numOfHits++;break;)I I out o f t he l oopif (numOfHits ==locationCells.length)result ~ "kill-;)System.out.println{result};return result;) II close metho 'I I cl o 'e c Ia sThere's a little bug lurking here. It complies endruns. but sometimes ... don't WOffY aboulll for now,but we will have to face it II little later,What should we seewhen we run this code?The test code makes aSimpleDotCom objectand gives it a locat ion at2,3,4 .Then it sends a fakeuser guess of "2" Into thecheckYouselfO method.If the code is workingcorrectly, we should see theresult print out:Java SlmpleDotComTestDr l velat106 chapter 5


writing a programWe built the test class,and the SimpleDotCom class.But we still haven'tmade the actua I game. Given the code on the opposIte page, and the spec forthe actual game, write In your Ideas for prepcode for the game class. We've givenyou a few lines here and there to get you started. The actual game code is on thenext page, so don't tum the page until you do this exerdselYou should have somewhere between 12 and 18 lines (including the ones we wrote,but not including lines that have only a curly brace).METHOD publicstatic voidmain (String0 OI'J:S)DECLARE an int variable to hold the number of user guesses. named numOfGuessesThe SlmpleDotComGameneeds to do this:1. Make the singleSimpleDotCom Object.2. Make a location for it (threeconsecutive cells on a singlerow of seven virtual cells).3. Ask the user for a guess.4. Check the guess.5. Repeat until the dot com isdead .6. Tell the user how manyguesses it took..COMPUTE a randomnumberbetween0 and "I that will be the starting location cell positionWHILE the dot com IS ~i ll ahve :GET user input (rom the command lineyo u are here. 107


SlmpleOotCom classPrepcode for the ShMpleUo'fCottttatMe classEverythfng happetts Itt Ittal..nThere are some things you'll have to take on faith. For example. we have oneline of prepcode that says, wCET user input from command-line". Let me tellyou, that's a little more than we want to implement from scratch right now, Buthappily, we're using 00. And that means you get to ask some otherc1ass/objectto do something for you, without worrying about how it does it. When you writeprepcode, you should assume that somehoto you'll be able to do whatever youneed to do, so you can put all your brainpower into working out the logic.publicstadc voJd main (String D args)DECLARE an int variable to hold the number of user guesses. named numO(t;uesses. set it to O.MAKE a new SimpleDotCom instanceCOMPUTE a random number between 0 and '\ that will be the starting location cell positionMAKE an int array with 3 ints using the randomly-generated number, that number incremented by I.and that number incre mented by 2 (example: 3.4,5)INVOKE the retLocOlionCeI!sO method on the SimpleDotCom instanceDECLARE a boolean variable representing the state ofthe game. named isAhve. SET it to trueWHILE the dot com is still alive (isAlive == true) :GET user input {rom the command line// CHECK the user guessINVOKE the checkYourse/fO method on the SlmpleDotCom instanceINCREMENT numO(t;uesses variableII CHECK (or dot com deathIF result is"kill"END IFEND WHILEEND METHODSET isAlwe to false (which means we WOT'l'! enter the loop again)PRINT the T'lumberof user guessesnl~ogn.itivettlDon't work one part of the brain for100 long a stretch at one time.Working Just the leftside of the brain formore than 30minulesis like working lustyour leftarm for 30 minutes, Give each sideof your brain a break by swilchlng sides atregular intervals. .When you shift to one side. the other side gels 10 rest andrecover. Left-brain actJvlties Include things like step-by-stepsequences, logical prob\em-solving, and analysis. while theright-brain kicks in formetaphors, creative problem-solving,pattern-matching, and Visualizing.108 chapter 5


-writing a program• Your Java program should start with a high·level design.• Typically you'll write three things when youcreate a new class:prepcodetestcodereal(Java) code• Prepcode should describe what to do, not howtodoit. Implementation comes later.• Use the prepcode tohelp design the testcode.• Write test code before you implement themethods.• Choose forloops over while loops when youknow how many times you want torepeat theloop code.• Use the pre/post increment operator toadd 1to a variable (x++;)• Use the pre/post decrement tosubtract 1 froma variable (x-;)• Use Integer.parseInt() to get the intvalue ofa String.• Integer .parseInt () works only if theString represents a digit ("0":1',"2", etc.)• Use break 10 leave a loop early (i.e. even ifthe boolean test condition is still true).How manyhits did you getlast month?you are here) 109


SimpleDotComGame classJust as you did with the SimpleDotCom class, be thinking about parts of this codeyou might want (or need) to improve. The numbered things • are for stuffwewant to point out. They're explained on the opposite page. Oh, ifyou're wonderingwhy we skipped the test code phase for this class, we don't need a test class forthe game. It has only one method, so what would you do in your test code? Makea separate class that would call maini] on t~is class? We didn't bother.public static void main(String[] arqs) (DECLARE 3 variableto hold userguess count. set itto 0MAKE a Simplefzot ­Com objectCOMPUTE ,\rando m numbe rbe tween 0 and .\MAKE an int ar rayWIth the 3 cell localions,andINVOKE seu.oca­[lonCells on the dotcorn objectGameBelper helper '" new GameBelper (); e-r: this is a 1ft/.'Ial t1ass \role wv~ thdt hast.he ...dhod +OY ~d±i,,~ ~ il'lf l


writing a programjf...ro things that need a bit more,:xplaining. are on this page, This is. t a quick look to keep you going;re details on the GameHelperare at the end of this chapter.Make a randomnumber(Math.random() '" 5)tAtlau that tOflltswit.h Java.tA...rthoci ok theMat.h daS$.Getting user inputusing the GameHelperclassiAn 'l"rl,arU wt "'


GameHelper class (Ready-bake)One last class: G-attteHelperWe made the dot CQtn class.We made the game class.All that's left is the helper class- the one with thegetUserInputO method. The code to get commandlineinput is more than we want to explain right now.It opens up way too many topics best left for later.(Later, as in chapter 14.)Just copy* the code below and compile it intoa class named GameHelper. Drop all threeclasses (SimpleDotCom, SimpleDotComGame,GameHelper) into the same directory. and make ityour working directory."Ready-IMkeWhenever you see the Bellde logo, you're seeingcode that you have to type as-is and take on faith .Trust it, You'Illeam how that code works later.import java.io.* ;public class GameBelperpublic String getOserlnput(String prompt)String inputLine = null;System.out.print(prompt +" ");try {Bu£feredReader is = new BufferedReader (new InputStre~ader(SY8tem.in);inputLine = is.readLine();if (inputLine. length () == 0) return null;} catch (IOException e) (System.out.println("IOException: " + e);return inputLine;)"We know how much you enjoy typing . bul for thoee raremoments When you'd mlher do some\hlng else , we'vil madII11111 Ready-bake Code avallable on wlckedlyamart.com.112 chapter 5


writing a programlefs playHere's what happens when werun it and enter the numbers1,2,3,4,5,6. Leckin' good.Acoltlplete gatMll lltteractlolt(your mileage may vary)What's this? Abug?GasplHere's what happens when weenter 1.1,1.Adlfferettf gaIMe h,teractlotl(ylkes)%j a v a SimpleDotComGameenter a number 1missenter a number 2missenter a number 3missenter a number 4hitenter a number 5hitenter a number 6killYou took 6 guesses%j ava SimpleDotComGameenter a number 1hitenter a number 1hitenter a number 1kill'lou took 3 guessesIt's a cliff-hangerlWill we find the bug?Willwe flxthe bug?Staytuned r the next chapter,where we answerthese quest! ns and more...And Inthe meantime,see If you can come up withIdeasfor what went wrong and howto fix It.you are here. 113


for loopsMore about for loopsWe've covered all the game code for thischapter (but we'll pick it up againto finish the deluxe version of the game in the next chapter). We didn'twant to interrupt your work with some of the details and background info,so we put it back here. We'U start with the details offor loops, and if you'rea Ct+ programmer, you canjust skim these last few pages ...legular bto"-e.,ha"ced] for loopsrepeat for 100 reps:What It means In plain English: ~Repeat 100 times ."How the complier sees It:• create a variable I and set It to O.-;. repeat while IIsiess tha n 100.• at the end of each loop IteratIon, add 1 to IPart One: InitializationUsethis part to declare and Initialize a variable to use within the loop body.You'll most often use this variable as a counter.You can actually initialize morethan one variable here, but we'll get to that later In the book.Part Two: boolean testThis Is where the conditional test goes. Whatever's In there, It must resolve to aboolean value (you know, tru« or flllu) .You can have a test" like (x >= 4), or youcan even Invoke a method that returns a boolean.Part Three: IteratIon expressionIn this part, put one or more things you want to happen with each trip throughthe loop. Keep In mind that this stoff happens at the end of each loop.114 chapter 5


writing a programsthrough a loop ~int i = 0; i < 8; i++)tem.out.println(i);output:enter loopbodyprint the valueof;Increment(the iterationexpression)p has only the boolean test; It doesn't haveI_!I!!I~ -in initialization or Iteration expression. A whilegood when you don't know how many times tojust want to keep going while some condlue.But If you know how many tl mes to loop• e length of an array, 7 times, etc.), a for loop Ist, Here's the loop above rewritten using while:. . 0 ~ 'lJe helv.. 1 d I11:lt 1. = ; "lII,


enhanced for..The etthattced for loopBeginning withJava 5.0 (Tiger), theJava language has a second kind ofJor loopcalled the enhancedjM, that makes it easier to iterate over all the elements in anarray or other kinds of collections (you'll learn about othercollections in the nextchapter). That's really all that the enhanced for gives you-a simpler way to walkthrough all the elements in the collection, but since it's the most common use ofafor loop, it wasworth adding it to the language. We'll revisit the enhancedfor lMp inthe next chapter, when we talk about collections that aren't arrays.What It means In plain English: "For each element in nameArray, assign theelement to the 'narne'varlable, and run the body of the loop."How the complier sees It:... Create a String varIable called name and set It to null.... Assign the first value In nameArray to name.... Run the body of the loop (the code block bounded by curly braces).... Assign the next value In nameArray to name.... Repeat while there are stili elements In the array.Part One: Iteration variable declarationUse this part to declare and Initialize a variable to use within the loop body, With eachIteration of the loop. this variable will hold a different element from the collection. Thetype of this variable must be compatible with the elements in the arrayl For example,you can't declare an lnt Iteration variable to use with a StrlngU array.Part Two: the actual collectionThis must be a reference to an array or other collection. Again, don't worry about theother non-array kinds of collections yet-you'll see them in the next chapter.116 chapter 5


writJng a programconverting a String to an intiDe quess =Int8qer.parseInt(strinqGuess);The user types his guess at the commandline,when the game prompts hi m.Thatguess comes In as a String (M2;"0~ etc.) ,and the game passes that String into thecheckYourselfO method.But the cell locations are simply lnts In anarray,and you can't compare an Int to aString.For example, this won't work:. tx" 2;. (x = num) II horrible explosionlrying to compile that makes the complierlaugh and mock you:oper a t o r == cannot be applied toint,java.lang.Stringif (x == nurn) { },.,So to get around the whole apples andoranges thing, we have to make the String'2"into the int 2. Built Into the Java classbrary is a class called Integer (that's righta Integer class, not the int primitive),and one of its Jobs is to take Strings thatrepresen: numbers and convert them Intoactual numbers.takes d ~b-i,,~tteger.parseInt("3")Id ...etJ,od in the I"u~et"das.s that knows how io"pa~J) a Sb-in~ i"io theil'.t:it l"epl"C!seni.s.Casthtgprhttftiveslong ~ shortcan be cast tobut you mightlose somethingInchapter 3 we talked about the sizes of the various primitives. and how youcan'tshove a bIg thIng dlrecUy Intoa small thing:10n9 Y = 42;int x = y; II won't compileA long Is bigger than anintandthe complier can't besure where that long hasbeen. It might have been outdrinking with theother longs, andtaking on reallybigvalues. To force the complier toJam the value of a bigger primitive variableintoa smaller one, you can usethe casl operator. II looks likethis:long y == 42; II so far so goodint x =(int) y; II x = 42 oool!Puttlng In the ~ tellsthe complier to take the value of y,chop It down to iotsize, and sat )( equal towhatever Is left. If thevalue of y was bigger then themaximum value of x, then what's leftwillbe a weird (butcalculable') number:long y == 40002;II 40002 exceeds the 16-bit limdt of afloat f .. 3.14£;int x == (int) f; II x will equal 3shortshort x c (short) y; II x now equ~s -25534!Stili,Ihe point is that thecomplier letsyou doIt. And let's sayyou have a noal­Ing point number, andyou just want to getat the whole number (in/) partof itAnd don't even think about casting anything \0 a boolean or vice versa-justwalk away.'It involves sign blls, bInary, 'two's complement' and other geekery, allof whicharediscussed ai/he beginning of appendix B.you are here _ 117


exercise: Be the JVMBEtheJVMThe Java file on this pagerepresents a complete sourcerue. Your job is to play JVMand detel"llline what would bethe outpltt when theprogram runs?class Output {pUblic static void main(String [J args) {Output 0 = new Output();o.go() ;}void go() {int y = 7;for(int x = I: x < 8: x++) {y++;if (x > 4) {System.out.print(++y + • -):-or--or-if (y > 14) {Systern.out.println( U x = ubreak;+ x);}}}}118 chapter 5


writing a programCode MagnetsAworking Java program Isall scrambled up on the fridge . Can youreconstruct the code snippets to make a working Java program thatproduces the output listed below? Some of the curly braces fell on thefloor and they were too small to pick up, so feel free to add as many ofthose as you need!1) {System.out.println(x + ~ M + y):for(int Y4; Y > 2; y--) {for(int :l( 0; x < 4; x++) (you are here ~ 119


puzzle: JavaCrossJavaOr~ssHow doesa crossword puzzlehelp you leam Java? Well,allof the wordsareJava related.In addition,the cluesprovidemetaphors, puns.and the like.Thesemental twists andturnsbum alternateroutesto Javaknowledge,right into yourbralnlAcross1. Fancy computer wordfor build4. Multi-part loop6. Test first7.32 bits10. Method'sanswer, 1. Prepcode-esque13. Change15.The bigtoolkit17. Anarrayunit, 8. Instance or 10C4120. Automatic toolkit22. Looks likea primltfve.buL25. Un-castable26. Math method28. Convertermethod29. Leave earlyDown2. Incrementtype3. Classs workhorse5. Pre Is a type of__6. For's Iteration__7. Establish firstvalue8. Whileor For9. Updatean Instance variable12 Towards blastoff14. A cycle16.Talkativepackage19. Method messenger(abbrev)21. Asif23. Addafter24. PI house26. Compileit and__27. ++quantity


writing a programA short Java program is listed below. One block of the programis missing. Your challenge Is to match the candidate block ofcode (on the left), with the output that you'd see If the blockwere inserted. Not all the lines of output will be used,and someof the lines of output might be used more than once. Draw linesconnecting the candidate blocks of code with their matchingcommand-line output.class MixForS (public static void main (String [)args)int x = 0;int y = 30;for (int outer = 0; outer < 3i outer++) (for(int inner = 4; inner> li inner--) {y = y - 2;if (x == 6)break;x = x + 3;}y = y - 2;}System.out.println(x + " " + y};Candidates:Possible output:X + 3~ 45 6 ~-\:t.'"' tat"t.a~i6at.t 'fI~x + 6~ 6 Qt\t~t.htyo"\b\t ~~hx + 2~ 6106+ O~you are here ~ 121


exercise solutions•Be the JVM:class Output {Code Magnets:class HultiFor {public static void main(String [ ) args) {Output 0 = new Output();o.go() ;}void go{ ) {int y = 7;public static void main(String [] args) {for(int x 0; x < 4; X++) {for(int y = 4; Y > 2; y--) {system.out.println(x + U U .;. y);}for(int x =: i I. x < B' Ix++) {y++;if (x > 4) {}System.out.print(++y + • h);if (y > 14) {system.out.println(U x = h + x);break;}}if (x =:= 1) { What would happenx++ ;If this code block camebefore the 'y' for loop?}}} Did you remember to factor In thebreak statement? How did thataffect the output?122 chapter 5


writing a programCandidates:x • x + 3;Possible outputx • x + 6;x • x + 2;x++;x--;x - x + 0,you are here • 123


6 get to know the Java APIUsing the Java LibraryJava ships with hundreds of pre-built classes. You don't have toreinvent t he wheel If you know how to f1 nd what you need In the Java IIbrary, known ast he Java API. You'vegot better things to do. If yo u're going to write code, you mig ht aswellwrite only the parts that are truly custom for your application.You know those programmerswho walk out the door each night at 5 PM? The ones who don't even show up until lOAM?They use the Java API. And about eight pages from now, so will you. The core Java libraryIs a giant pile of classesJust waiting for you to use like building blocks, to assemble your ownprogram out of largely pre-bullt code.The Ready-bake Java we use in this book Is code youdon't have to create from scratch, but you stili have to type It. The JavaAPI is full of code youdon't even have to type. All you need to do is learn to use it .this Is a new chapter 125


we stili have a bug•Itt our lastchapter, we left youwith thecliff...ha.,ger. Abug.How ifs supposed to lookHow the bug looksHere's what happens when werun it and enter the numbers1,2,3.4,5,6 . Lookin' good.Aco~plete galMe I.,teractlon(your mileage may vary)Here's what happens when weenter 2,2,2.Adifferent galtle Interact/o.,(yikes)Fllo Ed~ Window He Felnl~ j a va SimpleDotComGameenter a number 2hitenter a number 2hitenter a number 2killYou took 3 guesseshi theCUffltlt verslotl. otlceyou geta hit, you catl shttplvrepeat that hittwo tMoretlllles for the kill!126 chapter 6


get to know the Java APISo what happetted?public String checkYourself (String stringGuess) (int guess'" Int:8ger.pa.rselnt{stringGue8S); (-- fon\l~ the Sh-ill~1;Q all lilt.Strinq reBUlt '" ''miss''; ( - A1ake cl va~jable t.D hold the reswi: 'IIrttwhl p.,.e II " we(' . ...iss i\'\ as the detaultI. e. lIIe as.s""'e 8 u... iss''),for (int cellloeationCells)Here's where Itgoes wrong. Wecounted a hit every~time the userguessed a celllocation. even Ifthatlocation hadalready been hit!We need a waytoknow that whena usermakesa hit, he hasn'tpreviously hit thatcell. If he has, thenwe don't want tocount It as a hit.II endfoz:if (numOfHits =result::: "kill";II end ifSystem. out.println (result) jlocationCells . length)return result;r-, R~ the "mit baLk toI I e nd me t hod the talli~ "'«hod.~ Di1fla'f the res"l! k()lr the lI.1Cr(..... i~", ",,1e1S it waJ i.hcl,,~ed to "hit" CW' "1cill U ) .you are here. 127


fixing the bugHow do we fix it?We need a way to know whether Q cell has already been hit. Let's runthrough some possibilities, but first, we'll look at what we know so for...We have a virtual row of 7 celts, and a DotCom will occupy threeconsecutive cells somewhere in that row. This virtual row shows aDotCom placed at eel/locations 4,5 and 6.The DotCom has an instance variable-an int array-that holds thatDotCom object's cell locations .locatlonCells(instance variable ofthe DotCom)• OptlO" o"eWe could make a second array, and each time the user makes a hit, westore that hit in the second array. and then check that array each timewe get a hit. to see if that cel/ has been hit before.kltCells arra~(this would be 0new boolean arrayinstance variable ofthe DotCom)128 chapter 6


Option one is too clunkyOption one seems like more work than you'd expect. It means that eachtime the user makes a hit, you have to change the state of the secondarray (the 'hitCells' array), oh -~ but first you have to CHECK the 'hitCeJls'array to see jf that cell has already been hit anyway. It would work, butthere's got to be something better...get to know the Java API• OpfloHtwoWe could just keep the one original array, but change the value of any hitcells to -1. That way, we only have ONE array to check and manipulatelocQtlonCells(instance variable ofthe DotCom)Option two is alittle better, butstill pretty clu"kyOption two is a little less clunky than option one, but it's not very efficient. You'dstill have to loop through all three slots (index positions) in the array, even jfone or more are already invalid because they've been 'hit' (and have a -1 value).There has to be something better...you are here I 129


prep codeprep codeOptlo., threeWe delete each cell location as it gets hit, and then modify the array tobe smaller. Except arrays can't change their size, so we have to make anew array and copy the remaining cells from the old array into the newsmaller array.locatlonCells arrayBEFORE any cellshave be.en hitlocatlonCells arrayAFTER cell '5', whichwas at inde.x 1 in the.array, has been hitOptlo., three would be 'Much better Ifthearray could shrlttlc, so that we would.,'t haveto ",ake a .,ew ''Maller array, copy there",altt'"(1 values ht, attd reasslQ" thereferettce.fhe orlal"81 prepcode for partof thecheckYourselfU 'Method:Life would be good 'f otdy we couldchattae Itto:REPEAT with each of the location cells in the int array ..~ -REP EAT with each of the remaining location cells1/COMPARE the user guess to the location cellIF the user guess matches/1 COMPARE the user guess to the location cellIF the user guess matchesINCREMENT the number of hits ~ REMOVE this cell from the array/1 FIND OUTif it was the last location cell: 1/FIND OUTif it was the last location cell:IF number of hits is 3.RETURN "kill" ~ 'IF the array is now empty, RETURN "kill"ELSE it was not a kill, so RETURN"hit" ELSE it was not a kill. so RETURN"hit"END IFEND IFELSEEND IFEND REPEATuser guess did not match, 50 RETURN "miss"ELSE user guess did not match, so RETURN "miss"END IFEND REPEAT130 chapter 6


get to know the Java API


when arrays aren't enoughWake up at1d stMell the libraryAs if by magic, there really Is such a thing.But it's not an array, it's an ArrayLisf.A class in the core Java library (the API).Thejava Standard Edition (which is what you have unless you're workingon the Micro Edition for small devices and believe me, you'd know)ships with hundreds of pre-built classes. Just like our Ready-Bake codeexcept that these built-in classes are already compiled.That means no typing.Just use 'em.ArrayUS tOnt. of a 5az..illiol\ t1asst.$ int.ht. Ja~a libvavy.Yo... tan lASt. it itl 'fOlJ.V cedeas i+ yOlJ. IIIrOU if 'f0...~I.f.(NoU; tht add(ObjttA:. ele...) ...tthodatt..ally look.s a li-i:.Be sh-a"1& ~a.. -thtOY\e ..,e'~t shOWtl h,~e ... ..,,'11 ~tt to -the..tal Qrle lai& i.. tht book. FOfr ""'''', jlA1tthink of it as a.. aodO ...tihod thattake.! the objett yo


Some thhtgs you ca., do with ~rrayLisrget to know the Java APIArrayList myList = new ArrayList () ; ~-a'1l,ist objet~ \ 'We/'I ~ (\P tnt \leaf' \~ 5 ,•tvea~ci ,~ ...w,\)eLi~ no' CW'Y "IPut something in itEgg s = new Egg() i~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~ ~• Make one ? ....i~~t "ow; I jW Mea _.myList.add(s)i• Put another thing in itEgg b = new Egg();myList.add(b);• Find out how many things are in itint theSize = myList.size();Find out if it contains something 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 ~boolean is10 = myList.contains(s)i ~ ~~.~~ ~1" D 0 (...eal\S ~irtt. ;Yllie~ is 0)Find out where something is (l.e. its index) ~ Atta'1 Ust 15~Last,._. 0 D'f '0' ..,os thed '."te the Objet.. vt-tc;·~t Iint idx = myList .indexOf(bl i 01'1 51 l" ' l.\. \.--1. i\'lO~'W ....eboVl\S_sUO\'IO ..hl"~ lY\ 'We In"Find out if it's emptyboolean empty =myList. isEmpty (); C- r~PIS £ili.eit's deo.fil'li+.tly NOT bftpty, so isE"'rtyO• Remove something from itmyList.remove(s);you are here. 133


when arrays aren't enough~ your penCilFill In the rest of the table below by looking at the ArrayList codeon the left and putting in what you think the code might be if itwere using a regular array Instead. We don't expect you to get allof them exactly right, so Just make your best guess.ArrayListregular arrayhrrayList myList =hrrayList();new~h-i"90 "'yList ::.. "ew Sh-il'l~ClJjString a = new String("whoohoo H ) ;myList.add(a);Sb-il'l'l a =- ~ Sb-i~("whoohool)jString b = new String("Frog H ) ;myList. add (b) ;~iri,,~ \> ::. """ ~ir;I'I~C'n-~»)jint theSize =myList.sizeO:Object 0 = myList.get(l);myList.remove(l);boolean isIn = myList.contains(b);134 chapter 6


get to know the Java APIR..,: So Arl1lyListIs cool, buthow would I know It exists?!A.: The question is really,-How do I know what's In theAPI?" and that's the key to yoursuccess as a Java programmer.Not to mention your key tobeing as lazy as possible whilestill managing to build software.You might be amazed at howmuch time you can save whensomebody else has already donemost of the heavy lifting, andall you have to do is step in andcreate the fun part.But we digress... the shortanswer Is that you spend sometime learning what's In the coreAPI. The long answer is at theend of this chapter, where you'lllearn how to do that.R: But that's a pretty bigIssue. Not only do I need toknow that the Java librarycomes with ArrayLlst, but moreImportantly I have to knowthat ArrayList Is the thing thatcan do what Iwantl So how110 I go from a need-to-dosomethingto a-way-to-do-Itusing the API?!A..:Now you're really at theheart of It.By the time you'vefinished this book, you'll haveagood grasp of the language,and the rest of your learningcurve really Is about knowlnqnow to get from a problem toasolution, with you writing theleast amount of code. If you canbe patient for a few more pages,westart talking about it at the!nd of this chapter.;\.Java'&pos~This week's Interview:ArrayList. on arraysHeadFirst So, ArrayLists are like arrays, right?ArrayLlst In their dreams! I am an objec: thank you very much.HeadFirst If I'm not mistaken, arrays are objects too. They live on the heap rightthere with all the other objects.ArrayList Sure arrays go on the heap, duh, but an array is still a wanna-beArrayList. A poser. Objects have state andbehavior, right? We're clear on that. Buthave you actually tried calling a method on an array?HeadFirst Now that you mention it, can't say I have. But what method would Icall, anyway? I only care about calling methods on the stuff I put in the array, notthe array itself. And I can use array syntax when I want to put things in and takethings out of the array.ArrayUst Is that so? You mean to tell me you actually remooed something from anarray? (Sheesh, where do they train. you guys? Mljava's?)HeadFirst Of &OlITSe I take something out of the array. I say Dog d = dogArray[l)and J get the Dog object at index lout of the array.ArrayList Allright, I'll tty to speak slowly so you can follow along. You were 1UJ1,I repeat TUI~ removing that Dog from the array. All you did was make a copy of therifmnce totht Dog and assign it to another Dog variable.HeadFirst Oh, I see what you're saying. No I didn't actually remove the Dogobject from the array. It's still there. But I canjust set its reference to null, I guess.ArrayLlst: But I'm a first-class object, so I have methods and I can actually, youknow, M things like remove the Dog's reference from myself, not just set it to null.And I can change my size, dynami£al£y (look it up). Just tty to get an ami)' to do that!HeadArst Gee, hate to bring thisup, but the rumor is that you're nothing morethan a glorified but less-efficient array. That in fact you're just a wrapper for anarray, adding extra methods for things like resizing that I would have had to writemyself. And while we're at it,J'OU can't even haM primiJiDes! Isn't that a big limitation?ArrayList I can't believe you buy into that urban legend. No, I am notjust a lessefficientarray. I will admit that there are a few extmne{y rare situations where anarray might be just a tad, I repeat, tad bit faster for certain things. But is it worth theminiscule performance gain to give up all this poWa'. Still, look at all tlllsflexihiliry. Andas for the primitives, of 'dum you can put a prirntive in an ArrayList, as long as it'swrapped in a primitive wrapper class (you'll see a lot more on that in chapter 10).And as ofJava 5.0, that wrapping (and unwrapping when you take the primitive outagain) happens automatically. And allright, I'll Q£krwwledge that yes,if you're using anArrayList of primitives, it probably is faster with an array, because of all the wrappingand unwrapping, but still... who really uses primitives Uu.se days?Oh, look at the rime! I'm llJujor Pilaus: We'll have to do this again sometime.you are here ~ 135


difference between ArrayList and arrayCotMparhtg ArrayList to a regular arrayArrayListregular arrayArrayList myList = new String [] myList = new String[2J;ArrayList();String a = new String("whoohoo"); String a = new String("whoohoo");myList.add(a) ; myList[O) = a;String b = new String ("Frog") ;String b = new String("Frog");myList.add(b); myList{l) = b;int theSize = myList.size(); int theSize = myList.length; ~ ,\ \\eY~s ..,'ncYtObject 0 = myList.get(l); String 0 = myList(l]; rl;s tp \oo\t.\ ~a\\'t d'~~eYO\t...: tmyList.remove(lj; myList(l] = null; ..,..boolean isIn = myList.contains(b); boolean isIn = false;for (String item : myList) (if (b. equals (item)) {isIn =true;break;)INotice how with ArrayList, you're workingwith an object of type ArrayList, so you'rejustinvoking regular old methods on a regular oldobject, using the regular old dot operator.With an arra)', you use special arraysyntax (likemyList[O] = foo) that you won't use anywhereelse except with arrays. Even though anarray is an object, it lives in its own specialworld and you can't invoke any methods onit, although you can access its one and onlyinstance variable, length.136 chapter 6


CotMparit1g ArrayList to a regular arrayget to know the Java API•A plain old array has to know itssize at the time it's created.But for Arrayl.ist, you just make an object oftype Arrayl.ist, Every time. It never needs toknow how big it should be , because it growsand shrinks as objects are added or removed.~new String[2] Needs 0 siu·new ArrayList( )No siu \"e,"'i\"eo (olthOl,\~h~ive it 0 siu i~ yo", wont to).•YOl,\ tanTo put an object in a regular array,you must assign it to a specificlocation.(An index from 0 to one less than the length ofthe array.)myList[l] = b;~Needs oYl il'lde~.Ifthat index is outside the boundaries of thearray (like, the array was declared with a size of2, and now you're trying to assign somethingto index 3), it blows up at runtime.With ArrayIist, you can specify an index usingthe add(anlnt, anObject) method, or youcanjust keep saying add(anObject) and theArrayList will keep growing to make room forthe new thing.-,myList.add(b) ;No il'ldex.Arrays use array syntax that's notused anywhere else in Java.But ArrayLists are plain oldJava objects, sothey have no special syntax.myList[l]~ .\LThe ott0'lotkets [ J o\"e sfet,oo\"s'll'lta~ l,ISed 01'1\'1 kO't' attd'ls.•ArrayLists in Java 5.0 areparameterized.Wejust said that unlike arrays, Arrayl.istshave no special syntax. But they do usesomething special that was added to Java 5.0Tiger-paramet:erized types.ArrayListThe


the buggy DotCom codeLetl fix the t'otCOItt code.int(] locationCells;int nurnOfHits = OJpubl ic void setLocationCells(int[] locs) (locationCells = locs;public String checkYourself(String stringGuess)int guess = Integer.parselnt(stringGuess);String result "miss";for (i nt cell locati onCe l l s )}break;I I ou t o f: t he l oopif (numOfHits == l oca t i onCe l l s . l engt h )result. = " ki l l " ;I ISystem.out .println(result);return result;/ / c l os e met hodc l ose cla s s138 chapter S


get to know the Java APIprep code ID~~New and hMproved PotCOtM classimportpublic class DocCom Ip r Lva t e ArrayList locationCells;/ / private i n c nurnOf= 0) {if (locationCells.isEmpty(»result "kill";else Iresult c: "h it";I I c l os e ifII cl os e oue r ifreturn result;) II c lose methodI I clos e c l a s syou are here. -1 3 9


making the OotComBustLet's build the REAL galtte:HSi"k a Pot COItt MWe've been working on the 'simple' version, but nowlet's build the real one. Instead ofa single row, we'lluse a grid. And instead ofone DotCOID,we'll usethree.Goal: Sink all of the computer's Dot Corns in thefewest number ofguesses. You're given a rating levelbased on how well you perform.Setup: When the game program is launched, thecomputer places three Dot Corns, randomly. on thevirtual. 7:x. 7 grid . When that's complete, the gameasks for your first guess .How you play: We haven't learned to build a GUIyet, so this version works at the command-line. Thecomputer will prompt you to enter a guess (a cell),which you'll type at the command-line (as "A3n, WCS\etc.), In response to your guess, you'll see a result atthe command-line, either "hit", "miss", or "You sunkPets.com" (or whatever the lucky Dot Com of the dayis). When you've sent all three Dot Corns to that big404 in the sky, the game ends by printing out yourrating.AB(oEFGEqNi7 )


get to know the Java APIWhat tteeds to chattge?We have three classes that need to change: theDotCom class (which is now called DotCom instead ofSimpleDotCom), the game class (DotComBust) and thegame helper class (which we won't worry about now).o DotCom classo Add a name variableto hold the name ofthe DotCom("Pets.com", uGo2.com~, etc.) so each Dot­Com can print its name when it's killed (seethe output screen on the opposite page).o DotComBust class (the game)o Create threeDotComs instead of one.o Give each of the three DotComs a name.Call a setter method on each DotCominstance, so that the DotCom can assign thename to its name instance variable.DotComBust class continued.••o Put the DotComs on a grid rather thanjust a single row, and do it for all threeDotComs.This step is now waymore complex thanbefore, ifwe're going to place the DotComsrandomly. Since we're not here to messwith the math, we put the algorithm forgiving the DotComs a location into theGameHelper (Ready-bake) class.@ Check each user guess with all threeDotComs, instead ofjust one.@ Keep playing the game (i.e acceptinguser guesses and checking them with theremaining DotComs) until there are no nwrelive DotComs.o Get out of main. We kept the simple one inmainjust to... keep it simple. But that's notwhat we want for the realgame.3 Classes:DotcomBlItt DotCom Gam.HelperThe game class.Makes DolComs,gels user Input,plays until all001·Corns are deadThe actualDotCom objects.DolComs know theirname. location, andhow 10 check a usergu6SS for a match.The helper class(Ready-Bake).It knows how toaccept user command-llneinput,and malle DOIComlocations.5 Objects:Plus 4ArrayLists: 1 forthe DotComBustand 1 for eachof the 3 DotComobjects.DotComBustGameHelperyou are here ~ 141


detailed structure of the gameWho does what it' the PofColMJust gatMe(at'd whetdoDotCom8u"class.The gameinstantiatesDotComBustobjectThe mainO methodin the DotComBustclass instantiates theDotComBust object thatdoes all the game stuff.DotComBustobjectThe DotComBust (game)object instantiates aninstance of GameHelper.the object that will helpthe game do its workThe DotComBust objectinstantiates an ArrayListthat will hold the 3 DotComobjects.ArrayList object (tohold DotCom objects)142 chapter 6


get to know the Java APIeThe DotComBust objectcreates three DotComobjects (and puts them inthe ArrayList)ArrayList object tohold DotCom objectsDotComobjectsThe DotComBust object asks thehe/per object for a location for aDotCom (does this 3 times, one foreach DotCom)The DotComBust object gives each of the Dot­Com objects a location (which the DotComBustgot from the helper object) like - A2 u • -B2-.etc. Each DotCom object puts his own threelocation cells in an ArrayListArrayList object(to hold DotComcell locations)Ar rayListobjectArrayListobjectThe DotComBust object asks the helperobject for a user guess (the helperprompts the user and gets input fromthe command-line)The DotComBust object loops through the listof DotComs. and asks each one to check the userguess for a match. The DotCom checks its locationsArrayList and returns a result ("hW. "miss", erc.)ArrayList object(to hold DotComcell lccctioas)ArrayList1If:Jl~91o bj ec tAnd so the game continues... gettinguser input. asking each DotComto check for a match, and continuinguntil 011 DotComs are deadArrayListobjectyou are here ~ 143


the OotComBust class (the game)prep codeDalComBUJtGameHelper helperArrayUsl dolComsLlslInlnurn OfGUB.'lS6SselUpGameOslarIPlayingOcheckUserGuessOfin~GameOPrep code for the real-PotCOIM'ust classThe DotComBust class has three mainjobs: set up the game, play the gameuntil the DotComs are dead, and end the game. Although we could mapthose threejobs directly into three methods, we split the middlejob (play thegame) into two methods, to keep the granularity smaller. Smaller methods(meaning smaller chunks offunctionality) help us test, debug. and modifythe code more easily.VariableDeclarationsDECLARE and instantiate the GomeHelper instance variable, named helper.DECLARE and instantiate an ArrayUst to hold the list of DotComs (initially three) Call itdotComsLJstDECLARE an int variable to hold the number of user guesses (so that we can give the user ascore at the end of the game). Name it numOfGuesses and set it to O.MethodDeclarationsDECLARE a setUpGameO method to create and initialize the DotCom objects with namesand locations. Display brief instructions to the user.DECLARE a 5tortPlayingO method that asks the player for guesses and calls thecheckUserGuessO method until all the DotCom objects are removed from play.DECLARE a ched


get to know the Java APIMethod httpleltt8MtatioMS COMttMUad:METHOD:void startPlaylng()REPEAT whileany DotComs existGET user input by calling the helper getUserinputQ methodEVALUATE the user's guess by checkUreI'GuessO methodEND REPEATEND METHODMETHOD: void checkUserGuess(SCrlng userGuess)/I findout if there's a hit (and kill) on any DotComINCREMENT the number of user guesses in the numOfGuesses variableSET the local resul! variable (a String) to "miss",assuming that the user's guess will be a miss.REPEAT with each of the DotObjeC1S in the dotComsUst arrayEVALUATE the user's guess by callingthe DotCom object's checkYourseJf() methodSET the result variable to "hit" or "kill" if appropriateIF the result is"kill", REMOVE the DotCom from the dotComsUstEND REPEATDISPLAY the resul! value to the userEND METHODMETHOD: void fJnlshGameODISPLAY a generic "game over" message,then:IF number of user guesses is small,DISPLAY a congratulationsmessageELSEDISPLAY an insulting oneEND IFEND METHODrpen yoorpenCil------------------,How should we go from prep code to thefinal code? First we start with test code. andthen test and build up our methods bit bybit. We won't keep showing you test codeIn thIs book, so now It's up to you to thinkabout what you'd need to know to test thesemethods, And which method do you testand write first? SeeIf you can work out someprep code for a set of tests. Prep code oreven bullet points are good enough for thisexercise,but If you want to try to write therea/test code (In Java), knock yourself out,you are here. 145


the DotComBust code (the game)import java.util . *;public class DotComBustfPr i vat e GameHelper helper new GameHelper() ;~ private ArrayList dotComsList = new AIrayList();private int numOfGuesses = 0 ;private void setUpGame () (II first make some dot corns and give them locationsDotCom one = new DotCom();one .setName(-Pets.com");•DotCom two = new DotCom();two.setName("eToys.com H ) ;DotCom three = new DotCom();three .setName{ "Go2.com");dotComsList ,add {one);dotComsList,add(two);dotComsList .add(three);Annotat. the codeyourself.Match theannotations 8t thebottom of each ...with the numbe...In the code. Writ.the number In theslot In front of theeorr..pondlnsannoldon.You'll u_ eachannotation Just once,and you'll n.....11 ofthe .nnotatlon•.System.out.println("Your goal i s to sinkSystem.out,println("Pets .com, eToys.com,System.out,println("Try to sink them allthree dot corns.");Go2.com");in the fewest number of guesses"):for (DotCom dotComToSet : dotComsList) ( •ArrayList newLocation = helper .placeDotCom(3); ~dotComToSet .setLocationcellS(neWLocatiOn); ...I I I close for loopI I close s ecUpGame methodpri va te void startPlayinq () (while(!dotComsList,isEmpty() ( •String userGuess = helper.getUserInput("Enter a guess"); ~checkUserGuess(userGuess); •I I I cl ose whilelinishGame () ; •I I close starcPlaying met hod146 chapter 6


get to know the Java APIprivate void checkUserGuess (String u serGuess) {numOfGuesses++; 4IDString r esult = "miss" ; ~for (DotCom dotComToTest : dotComsList) { ~result = dotComToTest.checkYourself(userGuess); ~if (result.equals("hit"» {)break; •if (result.equals("kill"»dotComsList.remove(dotComToTest);b reak;•Whatever you do,DON'T turn thepagelNot until you'vefinished thisexercise.Our version is onthe next page.~) I I c l os e forSystem. out.println(result); •II c lose methodprivate void finishGame ()System.out.println("All Dot Corns are dead! Your stock i s now worthless.");if (numOfGuesses


the DotComBust code (the game)import java.util.*;pubLi,c class DotComBustprivate GameHelper he l pe r "' new GameHelper () ; ~, ~private ArrayList dotComsList = new ArrayLlst (); Ma\(( a" An-att atnprivate int nurnOfGuesses = 0; DotCo'" ~jC:L .L'" 'II h~dlis a l,st. Vla~ "'"ONL.~ Dot:COf'I ~jctb,private void setUpGame () (' w{: as pot£.or..() ...,oJd/1 fust make some dot corns and give them locationsJ ",tdll ~ a" ok DotcOfl"..II /DotCom one = new DotCom():o\>jtt.W.one .setName("Pets.com") ;DotCom two = new DotCom();two .setName("eToys.com");DotCom three ~ new DotCom();three.setName("Go2.com");dotComsList.add(one);dotComsList.add(two) ;dotComsList.add(three);Pyi\'lt b\-ie~~i r.s t,n..l tions .foor \O.KY.System,out.println("¥our goal is to sink three dot coms .");System.out.println("Pets .com, eToys.com, Go2.com") ;System.out.println("Try to sink them all in the fewest number of guesses");for (DotCom dotComToSet : dotComsList) { ~Reytdt 'WoIith tdth DO'l:.COftI i" t~t list.Ask t},c helt'e\' t.... aArrayList newLocation = helper.placeDotCom(3); ~ D~ loUBOY\ ~a:.~~a'1Lisi .J Sh,,,,..·..dotComToSet. setLocationCells (newLocation) : (- C


get to know the Java APIprivate void checkUserGuess (String userGuess) {numOfGuesses++;String result \\miss"; t--asslA",e it's a '",iss', IAl'liess told oth«wisefor (DotCom dotComToTest dotComsList) { ~ \"eyeat with all DotCO\'I'IS il'l the listresult = dotComT oTest .checkYourself (userGuess); ~ ask the DotCO\'I'I to thet.k the Wie\"~IAeSS, lookil'l~ ~O\" a hit (0\" kill)if (result.equals(\\hit"» (break;)if (result.equals("kill"» (~ ,ei ~~ o.f the loop ea\"ly, 1'10 poil'lt


the DotCom codeThe final version ofthePotCOtlt classimport java.util.*;public class DotComprivate ArrayList locationcells;'Sprivate String name; )DotCOM'5 iWlStaWlte "iav-ia'oles:_ ah Arra'fl-ist cJ tell loeatiOWlS_ the DotCOM'5 ~Mepublic void setLocationCells(ArrayList loc) {locationCells = loc;public void setName (String n)~ 'lOll-V- basit seHe\" Methodname = n;pUblic String checkYourself(String userlnput) {String result = ~miss";1___ (,(Sih~ (lrrayl-ist 5 \"eMo"ie Me~od 1R ae e1;C: an en,,\,,'!,l ocationCells.remove(index);~int index = locationCells .indexOf(userlnput);if (index >= 0) ( L._ ' () il L_.J I L_ LI Iif (locationCells. isEmpty ()) { (-----~'-.. (,(sin~ the iS~Mft'l( ) Method to see i~ allcJ the loeatoWlS ha"ie been ~~sedresult = ~kill";System.out.println(~Ouch! You sunk ~ + name + ~ ( ~);else {result = ~hit ";} II close ifII close ifreturn result;} I I close methodclose class


get to know the Java APISuper Powerful 'oolea" [xpressio"sSo far, when we've used boolean expressions for our loopsorif tests, they'vebeen pretty simple. We will beusing morepowerful boolean expressions in some of the Ready-Bake codeyou're aboutto see, andeven though we knowyou wouldn'tpeek, wethought this would bea goodtime to discuss howtoenergize yourexpressions.'And' and 'Or' Operators (&&, II )Let's say you'rewriting achooseCamera( ) method, with lotsof rulesaboutwhich camera to select. Maybe you can choose camerasranging from $50 to $1000, but in some cases youwantto limit theprice range more precisely. You wantto say something like:'If the price range isbetween $300 and $400 then choose x:if (price >= 300 && price < 400) {}camera = "X"iLet's say that of theten camera brands available,youhave somelogicthat applies to onlyafew of the list:if (brand.equals("A") II brand.equals("B") ) {II do stuff for only brand A or brand B}Boolean expressions can get really big and complicated:if «zoomType.equals("optical") &&(zoomDegree >= 3 && zoomDegree = 5 && zoomDegree


Ready-bake: GameHelperimport java.io.*iimport java.util.·:Th is is the helper class for the game. Besides the. user input method(that prompts the user and reads input from the commend -line), thehelper's Big Service is to create the cell locations for the DotComs.If we were you, we'd just back away slowly from this code, exceptto type it in and compile it. We tried to keep it fairly small to youwouldn't hove to type so much, but that means it isn't the mostreadable code. And remember, you won', be able to compile theDotComBust game class until you have this class.pUblic class GamaBelperprivate static final String alphabet "abcdefg";private int gridLength = 7:private int gridSize = 49;private int () grid = new int[gridSize);private int comCount = 0;public String getUserlnput(String prompt)String inputLine = null;System.out.print(prompt +" ")itry (BufferedReader is = new BufferedReader(new InputStreamReader(System.in»);inputLine = is.readLine();if (inputLine.length() == 0) return null;catch (IOException e) (System.out.println("IOException : " + eliIreturn inputLine .toLowerCase();NoU: F~ elttta ,,,e,M, '101# ",\~h-l:b-)' '1


get to know the J ava APItallteHelper class code cot1tlt1ued...c oords[x++] = location;l ocation += incr;if (location >= gridSize){success = false;}if (x>O &&success = false;}else ((location % gridLengthII s a v e l ocationII try 'next' adjacentII out of b ounds - 'bottom'II failu re0 » { II ou t o f b ounds - right edgeII failureII f ound already used l o c a t i onI I System . out.pr i nt (" used" + l ocation);success = f alse; II failureI Ie nd whileint x = 0;int r ow = 0;int c olumn = 0;II Sy s tem . ou t . println ("\n " ) ;while (x < c omSize) {grid[coords[x]] = 1;r ow = (int) (c oords[x] I gridLength);c olumn = coords[x] % gridLength;t emp = String.va lueOf(alphabet.charAt(column);II turn l ocation into alpha coor d sII mark master g r id p t s . a s 'us ed'II get row valueI I get numeric col umn valueI I c onv e r t to alphaalphaCells.add(temp.concat(Integer.toString(row»);tt natx++; n' is tnC state VOlC " tnCII System .ou t . p r i n t ( n co or d "+x +" = n + al p haCells . get(x- l) );


API packagesUsittg the Library (the Java API)You made it all the way through the DotComBust game,thanks to the help of ArrayList. And now, as promised,it's time to learn how to fool around in theJava library.In the .Java API. classesare grouped into packages.To use a class in the API. youhave to know which packagethe class Is in.Every class in theJava library belongs to a package.The package has a name, like javax.swlng (apackage that holds some of the Swing CUI classesyou'll learn about soon). ArrayList is in the packagecalled java.utll, which surprise surprise, holds apile of utility classes.You'll learn a lot more aboutpackages in chapter 16, including how to put yourown classes into your own packages. For now though,we'rejust looking to usesome of the classes that comewith Java.Using a class from the API, in your own code, issimple. Youjust treat the class as though you wroteit yourself... as though you compiled it, and there itsits. waiting for you to use it. With one big difference:somewhere in your code you have to indicate the fullname of the library class you want to use, and thatmeans package name + class name.Even if you didn't know it, you've already beenusingcJassesfrom a ptu:kage. System (System.out.println),String, and Math (Math.random0), all belong to thejava.lang package.154 chapter 6


You have to know the full name*of the class you want to use inyour code.ArrayList is not the full name ofArrayList, just as 'Kathy'isn't a full name (unless it's like Madonna or Cher, but wewon't go there). The full name ofArrayList is actually:ORIMPORTPut an import statement at the top of your source code file:import java.util.ArrayList;public class MyClass {... }-java.util.ArrayList~~/ '\patka~e l'lc11l1ee.\ass ~"'cYou have to tell Java which ArrayList youwant to use. You have two options:o TYPEType the full name everywhere in your code. Each timeget to know the Java API:tberet&rH?Dumo ~uest19nsQ.: Why does there have tobe a full name? Isthat the onlypurpose of a package?A: Packagesare importantfor three main reasons. First, theyhelp the overall organization of aproject or library. Rather than justhaving one horrendously largepile of classes, they're all groupedinto packages for specific kindsof functionality (like GUI,or datastructures, or database stuff, etc.)Second, packages give you a namescoping,to help prevent collisionsifyou and 12 other programmersin your company all decide tomake a classwith the same name.If you have a class named Set andsomeone else (including the JavaAPI) has a class named Set,youneed some way to tell the JVMwhich Set class you're trying to use.Third, packages provide a level ofsecurity, because you can restrictthe code you write so that onlyother classesin the same packagecan accessit. You'll learn all aboutthat in chapter 16.you use it. Anywhere you use it. n .~: OK, back to the name. .. collision thing. Howdoes a fullWhen you declare and/or instantlate It:name really help? What's tojava.util.ArrayList list = new java.util.ArrayList0 ; prevent two people from giving aclass the same package name?When you use it as an argument type:public void go(java.util .Arraytist list) { }When you use it as a return type:public java.util.Arraytist fooO { .. . }A:Java has a naming conventionthat usually prevents this fromhappening, as long as developersadhere to it. We'll get into that inmore detail in chapter 16."Unless the class is in the java.lang package.you are here. 155


when arrays aren't enoughWhere'd that 'x' come from?(or, what does it mean whena package starts with Javax?)In the first and second versions of Java (1.02and 1.1), all classes that shIpped with Java (Inother words,the standard library)were In packagesthat began wlthJava.There was alwaysjllva.lang, of course- the one you don't have to import. And there was jlllla.netljOl/a,/o,java.util (although there was no such thing as ArrayListway back then), and a few others, Including the java.aWlpackage that held GUI-related classes.Looming on the horizon, though, were other packages notIncluded in the standard library.These classes were known asextensions, and came in two maInflavors:standard, and notstandard. Standard extensions were those that Sun consideredofficial,as opposed to experimental, early access, or betapackages that might or mIght not ever see the light of day.Standard extensIons, by convention, all began with an 'x'appended to the regular java package starter. The mother of allstandard extensions was the Swing library. It Included severalpackages, all of which began with jallax.swlng.But standard extensions can get promoted to first-class,shlpswIth-Java,standard-out-of-the-boxlibrary packages. And that'swhat happened to Swing,beginning with version 1.2 (whicheventually became the first version dubbed 'Java 2') .MCool: everyone thought (Including us).~Now everyone who hasJava will have the SwIng classes,and we won't have to figureout how to get those classes Installed with our end-users:Trouble was lurking beneath the surface, however, becausewhen packages get promoted, well of COURSE they have tostart wlthjalla, notjavax. Everyone KNOWS that packages Inthe standard library don't have that "lC: and that only extensionshave the "x~ So,Just (and we mean Just) before version 1.2went final, Sun changed the package names and deleted the"x· (among other changes). Bookswere printed and In storesfeaturIng SWing code with the new names. Naming conventIonswere intact. All was right with the Java world.Except the 20,000 or so screaming developers who realizedthat with that simple name change came dlsasterl All of theirSwing-using code had to be changedl The horrorl ThInk of allthose Import statements that started wlthjavCDf...And Inthe flnal hour,desperate, as their hopes grew thin, thedevelopers convInced Sun to "screw the convention, save ourcode" The rest Is history. So when you see a package In thelibrarythat beglns with Javax,you know It started lifeasanextension, and then got a promotion..-----_ BUUD POINIS­••ArrayList isa class inthe Java API.To put something into an ArrayUst. use addD,• To remove something from an ArrayUst user&moveD·• To find outwhere something is (and If it is) in anArrayUst, use indexOfO.• To find outif an ArrayUst is empty, useIsEmpfyQ.• To get the size (number ofelements) in anArrayUst. use the sizeD method.• To get !he length (number of elements) inaregular old array. remember, you use the lengthvariable.• An Arraylist res1z&s dynamically towhateversize isneeded. Itgrows when objectsare added, and itshrinks when objects areremoved.• You declare the type ofthe array using a typeparameter, which isa type name in anglebrackets. Example:ArrayList meansthe ArrayUst will be able to hold only objects oftype Button (or subclasses ofButton asyou'lllearn in!he next couple ofchapters).• Although an ArrayUst holds objects and notprimitives, the compiler will automatically "wrap.(and ·unwrap· when you take It out) a primItiveinto an Object, and place that object IntheArrayUst Instead ofthe primitive. (More on thisfeature later in the book..)• Classes are grouped into packages.• Aclass has a full name, which isa combinationof the package name and the class name.Class ArrayList is really java.utiIArrayUst.• To use a class ina package other than java.lang, you must tell Java the full name oftheclass.• You use either an Import statement atthe top ofyour source code, oryou can type the full nameevery place you use the class in your code.156 chapter 6


get to know the Java APIQ.: D06S import make myclass bigger? Does It actuallycompile the imported class orpackage Into my code7A: Perhaps you're a C programmer?An import is not thesame as an include. So theanswer is no and no. Repeat afterrne.ran import statement savesyou from typing:That's really It.You don't have to worry aboutyour code becom ing bloated, orslower, from too many Imports.An i mport is simply the way yougive Java the full name ofa class.N/ale~if. oStit.1eRoses areredapples areri;e.ifyou don'tim;onYou 'lljust have tc otYpeYoumust tell Javayou use, unle the full name ofevpackag A s.s that class is in til ' ery classe. n lmport Sf e Java.langor packageat the to f atement for the classeasyway. OtherWise~~ ~our sourceCode is thename ofthe class, e:e~have to type the fUll. ereyou useit!Q: OK, how come I never hadto import the String class? OrSystem?A: Remember, you get thejava.lang package sort of·pre­Imported" for free. Becausethe classes In [ava.lanq are sofundamental, you don't have touse the full name.There Is onlyone java.lang.Strlng class,and one[ava.tanq.System class,and Javadarn well knows where to findthem.One more time, in the unlikelyevent that you don't alreadyhave this down:Q: Do I have to put my ownclasses Into packages? How do Ido that? Can I do that?A..: In the real world (whichyou should try to avoid), yes, youwl/l want to put your classes Intopackages. We'll get into that indetail In chapter 16. For now, wewon 't put our code examples In apackage.you are he re . 157


getting to know the API"Good to know there's an ArrayList inthe java.util package. But bymyself, howwould1 havefigured that out?"- Julia, 31, hand modelHow to play with the APITwo things you want to know:o What classes are In the library?eOnce you find a class, how doyou know what It can do?oBrowse a BookJAVAINANUTSHELLIi CX:sJdop Quick RI!jlf'l:llce.......1_...I " ...0 . e..+ ~e Use the HTML API docs-o..n-wo....zPIal.... 51: l.O1~t/Jlot&-Il.A (OMIIl 'ftl .' ,O/_ IJ ~1 O ~·~Q.· '-E'IlIiIIlIPocuoo C., UU JJlN~nIn tlAlDJ"""'~~ ,_USJl ... ...... ..-. ......... ~UHi&G!.~Jav,,'" 2 P1IItlormStaodard Edlllon 51)--......-¥~,., ; ,,: i API SpedtblloD. . -IoAClM_ 'Nt-...Is'" API__(00 "" b ... , Pbtl..... SI ",O'REillY'158 ch ap ter 6


get to know the Java APII JAVA''?''!!!@I'}twa,utU,ClUnmcyR,/JUJUIdBj~ IN.ltU1lleeImalFaT1lat#lCun8lctO.IM,te:l1-~malf~o.mncyO .J-.l8ItN~eum:lley(I . O:JtnlllCY'~DateThis d:I5:l represents dates and limes 2nd leu you ...·o rk with them in ~ ~em-ind~penden!way , You C:1n create a D8l& by specityina the number of m1Diseconds (rom theepoch (audf\is/11 GMT. J:>nw of J'V> 1.1, =)' or the dale methoIye¥,lnl /llMlII, lnlttaDl. lnllirs. Int mil, tnt sec):II Piijiiifj~S{l(1rIer1t4df (tj~-J~ItItr(e-t1llMl):IdiIltwill MtTIIM(Ion&1tIIe):7/JljibJ; IiiSfiiiij MilIiOilipublic boomn aftal\lmJJ1lLIl8:t.,):. II\iIllcbooIelI\hhlr-aM.UliLDiIl'-);1.1publicInt c-..N1To11m.uDI.DJI'~Irllat,} :lllIiI1JDiif~~~1.1putIIlcIn! _PANTo(ObjtCl 0):IIJIlIbIi: j,jeth6ill ~0l;Id1.1pulIIlc0lijtcI doN(I:puliIicb09Iear!.q.II(OijIlc:l«II:IdiIlcIIIl••1Ie.c1e():PliIII~Sllitl(toStrlDiO; .II~WPubic lIe~, llWIlC irt1I!tI!at1():, ~ic Int,.0.,0:, puliIic IIIptHoan/):, puliIlcIntptMlllCIttI():, ~~lnt~d() ;, pWlc Int,.S aMI(J:, pUblic rt1itI'IMIo..otfiit(1:'~ltlnt"""l() :• liibIlclll~clq,.lM(S1(IrcJ);, pJlllc'/Old utDat-r1fll dlIIlI):, lIulill~ iOId iittIilIrI('llllllOurl);, lQlillcvoIdMtMl~nlllllilwl8s) :, ~lc'lOliI ~ntllDllII);you are here) 159


using the Java API documentatione Use the HTML API docsJava comes with a fabulous set of online docscalled, strangely, the Java API. They're part ofa larger set called the Java 5 Standard EditionDocumentation (which, depending on whatday of the week you look, Sun may be referringto as "Java 2 Standard Edition 5.0"), andyou have to download the docs separately;they don't come shrink-wrapped with theJava5 download. If you have a high-speed internetconnection, or tons of patience, you can alsobrowse them atjava.sun.com, Trust us. youprobably want these on your hard drive.The API docs are the best reference for gettingmore details about a class and its methods.Let's say you were browsing through the referencebook and found a class called Calendar,in java.util, The book tells you a little about it,enough to know that this is indeed what youwant to use, but you still need to know moreabout the methods.The reference book, for example, tells youwhat the methods take, as arguments, and whatthey return. Look at ArrayList, for example.In the reference book. you'll find the methodindexOf'(}, that we used in the DotCom class,But if all you knew is that there is a methodcalled indexOf() that takes an object and returnsthe index (an int) of that object, you stillneed to know one crucial thing: what happensifthe object is not in the ArrayList? Lookingat the method signature alone won't tell youhow that works, But the API docs will (most ofthe time, anyway). The API docs tell you thatthe indexOff) method returns a -1 if the objectparameter is not in the ArrayList. That's howwe knew we could use it both as a way to checkif an object is even in the ArrayList, and to getits index at the same time, if the object wasthere. But without the API docs, we might havethought that the indexOf() method wouldblow up if the object wasn't in the ArrayList.boolNA .tdlM1.1(rp))eCt(PDcr .n...o.d.. c:' e)Appilrod' >IJ of lboC~1S In the


Code MagnetsCan you reconstruct the code snippets to make aworking Java program that produces the outputlisted below7 NOTE: To do this exercise,you needa _.....-oz-I one NEW piece of info-If you look in the API forArrayList,you'll find a secondadd method that takestwo arguments:.';;;~.jiI:" - lIdd(lnt Index. Object 0)It lets you specify to theArrayl.lst where to put the object you're adding .a.remove(2);a .add(O "I zero").a.. add (1 " ,, one"),.get to know the Java APIpri.ntAL (a) ;public static void printAL (ArrayList al) (if (a . Contains ("brO"&.add ("2 . 2 " ) ; » ()public static void main(String[]System.out.print(eleme.nt +" ") ;)Syst.em.out.println(" ");(a. contains ("three"»a.add("fourn)ipublic class ArrayListMagnetif (a .indaxOf("four") !=a.add(4, "4.2");import java.ut i l.*;printAL (a) ;ArrayList a = new ArrayLfor (String e1............­~t:a.add( 3 "three") iJprintAL(a) ;you are here . 161


puzzle: crosswordJavaOr~sst.OHow doesthis crossword puzzlehelp you learnJava7 Well,all of the words are Java related(exceptone red herring).HInt: When In doubt, remember ArrayUst.Aaoss1.Ican't behave6. Or, Inthe courtroom7. Where It's at baby9. A fork'sorigin12. Grow an ArrayUst13. Wholly massive14. Value copy16. Not an object17.An arrayon steroids19, Extent21. 19'scounterpart22, Spanish geeksnacks (Note:Thishasnothing to do with Java)23. For lazyfingers24. Wherepackages roamDown2. Wherethe Java action Is.3. Addressable unit4. 2nd smallest5. Fractional default8. Ubrary'sgrandest10. Must be low density11. He's In there somewhere15. Asif16. dearth method18.Whatshopping and arrays haveIn common20, Ubrary acronym21. What goesaroundMore Hints:--1l6UI~IlWS.ill-l ·81lSn,(IlJJv l(U!ll..L '91ilhll!W!!d '01 ~ ' to'lSn.


import java.uti!. * iIpublic class ArrayListMagnet( IIget to know the Java APIIpublic static void main (Strinq[] arqs)(IIArrayList a = new ArrayList()i la.add(O,HzerOn)ia.add(l,"one")ia.add(2,"twO")ia.add(3,"three")iprintAL (a) iif (a.contains ("three"» (a.add("four")j)a. remove (2) i I eprintAL (a) i ....if (a. indexO£ ("four") != 4) (a .add(4, "'4.2")i}printAL (a) ; ..I[if (a.contains("two"» {a.add("2.2")i}printAL (a) ; ..II'rpublic static void printAL(ArrayList a1){rfor (Strinq element : al) (System.out.print (element + " ") ;)-\\} ;}ofllSystem.out.println("you are here ~ 163


puzzJe answersJavaOrctSSanswers~ your re::,~e you. OWN set of cluesl Lookat each word ,and"y toAaossI.write your own clues.Try making them easier,or harder, ormore technical than the ones we have.6. Down7. 29. 3.12. 4.13. 5.14. 8.16. 10.17. II.19. 15.21. 16.22 18.23. 20.24. 21.164 chapter 6


7 inheritance and polymorphismBetter Living inObjectvilleWe were underpaid,overworked coders 'fill wetried the Polymorphism Plan. Butthanks to the Plan, our future isbright. Yours can be toolPlan your programs with the future in mind. If there were a way to writeJavacode such that you could take more vacations, how much would It be worth to you? Whatif you could write code that someone elsecould extend, easily? And if you could write codethat was flexible, for those pesky last-minute spec changes, would that be something you'reinterested In?Then this is your lucky day. ForJust three easypayments of 60 minutes time, youcan have all this. When you get on the Polymorphism Plan, you'll learn the 5 steps to better classdesign, the 3 tricks to polymorphism, the 8 ways to make flexible code, and if you act now-abonus lesson on the 4 tips for exploiting inheritance. Don't delay,an offer this good will giveyou the design freedom and programming flexlblllty you deserve. It's quick. it's easy, and it'savailable now. Start today, and we'll throw in an extra level of abstractionlthis is a new ch ap ter16i


the power of inheritanceChair Wars (evisited...Rememberway back in chapter 2, when Larry (procedural guy)and Brad (00 guy) werevyingfor theAeron chair? Let's look at(Jfew pieces of that story to reviewthe basicsof~.LARRY: You've got duplicated codel The rotate procedureis in all four Shape things. It's a stupid design. You have [0maintain four different rotate "methods". How can thatever be good?BRAD: Oh, I guess you didn't see the final design. Let meshow you how 00 inheritance works, Larry.SquarerotateQplaySoundOrotateOplaySoundQAmoebarotate()playSoundOoIlooked at what all fourclasses have I" OOIMIIIO".~rhev're Shapes, and theyall rotate andplavSound. So IabstraGted out theCOIMIMon features and putthelllinto attew class called Shape. -:;,shaperotateQplaySound()superclassShaperotale()playSoondOYou can read this as, uSquare Inheritsfrom Shape"."Circle Inheritsfrom Shape", and soon. I removed(olale() and playSound() from the other shapes, sonow~here's only one copy tomaintain.Th&.~hape class Is called the luperciasl of the other fourclasses. The other four are the lubelaues of Shape. TheSUbclasses Inherit the methods of the superclass. Inotherwords. Ifthe Shape class has the (unci/anality, then thesubclasses automatically gatfhat same functionality.Square Circle Triangle166 chapter 7


inheritance and polymorphismWhat about the AIMoeba rotate()?LARRY: Wasn't that the whole problem here - that the amoeba shapehad a completely different rotate and playSound procedure?How can amoeba do something differentifit inherits irsfunctionality from the Shape class?BRAD:That's the last step. The Amoeba class overrides themethods of the Shape class. Then at runtime, theJVM knowsexactly which rota/eO method to run when someone tells theAmoeba to rotate.superolau"MOre autract)~ShaperotateQplaySoundOolubclasses"MOre speolflol\ SquareCircle Tilangle AmoebarotateO/I amoeba-specific/I rotate codeplaySoundOII amoeba-speclficII sound code'"!


I way inheritance worksUt1derstat1dit1Q InheritanceWhen you design with inheritance, you put common code ina class and then tell other more specific classes that thecommon (more abstract) class is their superclass. When oneclass inherits from another, the subclass inherits frOID thesuperclass.InJava, we say that the subclass extends the superclass.An inheritance relationship means that the subclass inheritsthe lDelDbers of the superclass, When we say "members ofa class" we mean the instance variables and methods.For example, if PantherMan is a subclass of SuperHero, thePantherMan class automatically inherits the instance variablesand methods common to all superheroes including suit,tights, specialPower, useSpecialPower () andso on. But the PantherMan subclass can add new:methods and instance variables of its own, and it canoverride the :methods it inherits fro:m the superc1assSuperHero.superclasa(tHore abstract)subclasses(tHore speolfle)~if. lJ,v4':;. t"t(~FriadEggManSuperHerosul1lightsspec/alPoweruseSpecialPower()putOnSull()/~PantherManI"sta"ce varIables(state. attributedlMethods(behavIor)useSpeclalPowerijputOnSultOOverrldfttQ!Methods~~ chapter 7FriedEggMan doesn't need any behavior that's unique,so he doesn't override any methods. The methods andinstance variables in SuperHero are sufficient.PanthenMan, though, has specific requirements for his suitand special powers, so useSpecialPower () andputOnSui t () are both overridden in the PantherManclass.Instance variables are not overridden because theydon't need to be. They don't define any special behavior, so asubclass can give an inherited instance variable any value itchooses. PantherMan can set his inherited tights (0purple, while FriedEw\1an sets his to white.


inheritance and polymorphismpublic class Doctor {boolean worksAtHospita1ivoid treatPatient() [II perform a checkuppublic class FamilyOoctor extends Doctor {boolean makesHouseCallsivoid giveAdvice(} {II give homespun advicepublic class Surgeon extends Doctor(void treatPatient () (II perform surgeryvoid makeIncision() (II make incision (yikes!)superclassDoctorworksAlHosptlaltreatPatient 0OMe '"stattce variableotte tMethodyour pencUHow many instance variables doesSurgeon have7__How many Inslance variables doesFamiryDoctor have7__subclassesHow many methods does Doctor have?__How many methods does Surgeon have?_SurgeonOvenides the InheritedlrealPaUenlQ method lreatPatlenl ()Adds one new methodmakelnclslonOFamllyDoctormakesHouseCal1sglveAdvlce 0Adds one newInstance variableAdds one new methodHow many methods does FamilyDoctorhave7__Can e FamllyDoctor dolreatPatient()?__Can a FamllyDoctor do rnakelneisloru)?__you are here ~ 169


Let"s desig" the it1heritattce tree foratt Atti~al sitltulatiot1 progralMImagine you're asked to design a simulation program thatlets the user throw a bunch ofdifferent animals into anenvironment to see what happens. We don't have to code thething now, we're mostly interested in the design.We've been given a list ofsomeofthe animals that will bein the program, but not all. We know that each animal willbe represented by an object, and that the objects will movearound in the environment, doing whatever it is that eachparticular type is programmed to do .And we want otherprogrammers to be able to add newkinds ofanimals to the program at any time.First we have to figure out the common, abstractcharacteristics that all animals have, and build thosecharacteristics into a class that all animal classes can extend.oLookfor objects that have commonattributes and behaviors.What do these six types have Incommon? This helps you to abstractout behaviors. (step 2)How are the~ types related? Thishelps you to define the Inheritancetree relationships (step 4-5)170 chapter 7


Inheritance and polymorphismUsi.,g i.,herita.,ce to avoidduplicatit1Q code it1 subclassesWe have five instance variables:pidure- the file name representing theJPEG of this animalfood - the type offood this animal eats, Right now, therecan be only 1:\'10 values : meator grass.hunger- an int representing the hunger level ofthe animal.It changes depending on when (and how much) theanimal eats.boundaries - values representing the height and width ofthe 'space' (for example, 640 x 480) that the animals willroam around in.location> the X and Y coordinates for where the animal isin the space.We have four methods:makeNoUe 0 - behavior for when the animal is supposed tomake noise.eatO- behavior for when the animal encounters itspreferred food SOUTee, meat or grass.skepO - behavior for when the animal is considered asleep.roam() - behavior for when the animal is not eating orsleeping (probablyjust wandering around waiting to bumpinto a food source or a boundary) .Design a class that representsthe common state and behavior.The~ objects are all animals, sowe'll make a common super-classcalled Animal .We'll put In methods and instancevariables that all animals mightneed.AnimalpicturefoodhungerboundarieslocationmakeNoiseOeatOsleept)roamt)LIonWolfHIppoDogyou are here ~ 171


designing for inheritancePo all at1httals eat the saIMe way?Assume that we all agree on one thing: the instancevariables will work for aUAnimal types. A lion willhave his own value for picture, food (we're thinkingmeat), hunger, boundaries, and location. A hippowill have different values for his instance variables,but he'll still have the same variables that the otherAnimal types have. Same with dog, tiger, and so on.Butwhatabout~h~~Which 'Methods should we override?Does a lion make the same noise as a dog? Doesa cat eat like a hippo? Maybe in youTversion, butin ours, eating and making noise are Animal-typespecific.We can't figure out how to code thosemethods in such a way that they'd work for anyanimal. OK, that's not true. We could write thernakeNoise() method, for example, so that all it doesis playa sound file defined in an instance variablefor that type, but that's not very specialized. Someanimals might make different noisesfor different situations (like onefor eating, and another whenbumping into an enemy, etc.)So just as with the Amoebaoverriding the Shape class rotateOmethod, to get more amoeba-specific (inother words, unique) behavior, we'll haveto do the same for our Animal subclasses.Decide if a subclassneeds behaviors (methodimplementations) that are specificto that particular subclass type.looking at th£ Animal class,w£ decide that eatQ andmakeNolseO should be overriddenby the Individual subclasses.In the dogcommunity, barking is animportant part of our culturalidentity. We have a uniquesound,and we want that diversity tobe recognized and respected.Animalpicturefoodhungerboundarieslocationsleepf)roamO172 chapter 7


Inheritance and polymorphismLooklt1Q for more it1heritat1ceopportut1itlesThe class hierarchy is starting to shape up. Wehave each subclass override the makeNoise() andeat() methods, so that there's no mistaking a Dogbark from a Cat meow (quite insulting to bothparties). And a Hippo won't eat like a Lion.But perhaps there's more we can do. We have tolook at the subclasses ofAnimal, and see if CWoor more can be grouped together in some way,and given code that's common to only that newgroup. Wolf and Dog have similarities. So doLion, Tiger, and Cat.eLook for more opportunities to useabstraction, by finding two or moresubclasses that might need commonbehavior.We look at our classes and seethat Wolf and Dog might have somebehavior In common, and the same goesfor Lion, Tiger, and Cat.AnimalpicturefoodhungerboundarieslocationLionWolfHippomakeNoiseOeatODogmekeNolseOeatO·~IIIII!IIl"'_rlma keNo lse OeatOyou are here) 173


designing for inheritanceFinish the class hierarchySince animals already have an organizationalhierarchy (the whole kingdom, genus, phylumthing), we can use the level that makes the mostsense for class design. We'll use the biological"families" to organize the animals by making aFeline class and a Canine class.We decide that Canines could use a commonroomO method. because they tend to move Inpacks. We also see that Felines could use acommon raamO method, because ther tend toavoid others of their own kind. We'l let Hippocontinue to use Its Inherited roamO methodthegeneric one It gds from Animal.So we're done with the: deSign for now:come back to It later In the chapter.sleept)Animalpicturefoodhungerboundarieslocationmem()mamOmakeNolseO6810makeNolseOeatOCatTIgermakeNolseOeat()makeNolseOe.atOWolfmakeNolse()eatOmakeNolseOeatO174 chapter 7


inheritance and polymorphismWhich tttethod Is called?The Wolfclass has four methods. Oneinherited from Animal, one inherited fromCanine (which is actually an overriddenversion ofa method in class Animal), andtwo overridden in the Wolf class. Whenyou create a Wolf object and assign it toa variable, you can use the dot operatoron that reference variable to invoke allfour methods. But which version of thosemethods gets called?Wolf w =new Wolf () ;Anima'makeNolseOeatOsleepOroarnr)tails t.he version in Wol.fw.makeNoise () ;w. roam () iCaninetalls t.he v~ionin Wol.fw.eat();roamOtalls -the version in Ani...alw. sleep () ;When you call a method on an objectreference, you're calling the most specificversion of the method for that object type.In other words, the lowest one wins!"Lowest" meaning lowest on theinheritance tree. Canine is lower thanAnimal, and Wolf is lower than Canine,so invoking a method on a referenceto a Wolf object means theJVM startslooking first in the Wolf class. If theJVMdoesn't find a version of the method inthe Wolf class, it starts walking back upthe inheritance hierarchy until it finds amatch.Wolfyou are here ~ 175


practice designing an inheritance treePeslgttiMQ aM InherltaMce freeClass Superclasses SubclassesClothing -- Boxers, ShirtBoxersClothingShirtClothingInherftance TablesuparclasshMore abstract) ~~ L..:::..JI subelaases ~(lttore tpeolflol '\.~ Box,," ~Inheritance CIUlI DiagramFind the relationships that make sense. Fill In the last two columnsChus Superclasses SubclassesMusicianRock StarFanBass PlayerConcert PianistSharpen your pencil'-..: I l~~ Draw an inheritance diagram here.Hint: noteverythIng can beconnected to something else.Hint: you're allowed toaddtoorchange the cl8SSes listed.therejltrer\l?DUmb ~uesti9n.8Q.: You said that the JVM startswalking up the Inheritance tree,starting at the class type you Invokedthe method on (like the Wolf exampleon the previous pagel. But whathappens If the JVM doesn't ever findill match?176 chapter 7A.: Good questionl But you don'thave to worry about that.The compilerguarantees that a particular methodIs callable for a specific reference type,but It doesn 't say (or care) from whichclass that method actually comes fromat runtime. With the Wolf example, thecompiler checks for a sleepf) method,but doesn't care that sleepO Is actuallydefined In (and Inherited from) classAnimal. Remember that If a classInherits a method, It has the method.Where the inherited method Is defined(In other words, In which superclassIt Is defined) makes no difference tothe complier. But at runtIme, the JVMwill always pick the right one. Andthe right one means, the most specificversion for thatparticular object.


Inheritance and polymorphismUsittQ IS...Aattd HAS-ARemember that when one classinherits from another, we say that thesubclass extendsthe superclass. Whenyou want to know ifone thing shouldextend another, apply the IS-A test,Triangle IS-AShape, yeah, that works.Cat IS-A Feline, that works too .Surgeon IS-ADoctor, still good.Tub extends Bathroom, soundsreasonable.UntilyO'u apply 1M IS-A test.To know ifyou've designed your typescorrectly, ask, "Does it make sense tosay type X IS-A type Y?" If it doesn't,you know there's something wrongwith the design, so ifwe apply the IS-Atest, Tub IS-A Bathroom is definitelyfalse.What ifwe reverse it to Bathroomextends TUb? That still doesn't work.,Bathroom IS-ATub doesn't work.Tub and Bathroom are related, butnot through inheritance. Tub andBathroom are joined by a HAS-Arelationship. Does it make sense tosay "Bathroom HAS-ATUb"? Ifyes,then it means that Bathroom has aTub instance variable. In other words,Bathroom has a reference to a Tub, butBathroom does not extend1\lb andvice-versa.Does it make sense tosay a Tub IS-A Bathroom? Or aBathroom IS-A Tub? Well it doesn't tome. The relationship between my Tuband my Bathroom is HAS-A. BathroomHAS-A Tub. That means Bathroomhas Q Tub instance variable.BathroomTub bathtub;Sink lheSink;TubInl size:Bubbles b:Bubblesinl radius:InloolorAm~Bathroom HAS-A Tub and Tub HAS-A Bubbles.Bul nobody Inherits from (extends) anybody else.you are here ~ 177


exploiting the power of objectsJut wait! There"s 'More!The IS-Atest works anywhere in the inheritance tree. Ifyourinheritance tree is well-designed, the IS-Atest should makesense when you ask any subclass ifit IS-A any ofi IS su pertypes.If class B extends class A, class B IS-A class A.This is true anywhere in the inheritance tree. Ifclass C extends class B, class C passes the IS-Atest for both Band A.Canine extends AnimalWolf extends CanineWolf extends AnimalCanine IS-A AnimalWolf IS-A CanIneWolf IS-A AnimalAnimalmakeNolseOeatOsleepOroamOroarnt)CanineWolfmakeNolseOeal()With an inheritance tree like theone shown here, you're alwaysallowed to say "Wolf extendsAnimal" or "Wolf IS-AAnimal".It makes no difference ifAnimalis the superc1ass of the superclassofWolf. In fact, as long as Animalis somewhere in the inheritancehierarchy above Wolf, Wolf IS-AAnimal will always be true.The structure ofthe Animalinheritance tree says to the world:"Wolf IS-A Canine. so Wolf can doanything a Canine can do. AndWolf IS-AAnimal, so Wolf can doanything an Animal can do."It makes no difference if Wolfoverrides some of the methodsin Animal or Canine. As far asthe world (of other code) isconcerned, a Wolf can do thosefour methods. H(JlJ) he does them,or in which class they 1'e overriddenmakes no difference. A Wolf canmakeNoiseO. ea to, sleep(), androamO because a Wolf extendsfrom class Animal.178 chapter 7


Inheritance and polymorphismHow do you k"ow if yotfve gotyour htherita"ce right?There's obviously more to it than what we'vecovered so far, but we'll look at a lot more 00issues in the next chapter (where we eventuallyrefine and improve on some ofthe design workwe did in thischapter).For now. though, a good guideline is to use theIS-Atest, U "X IS-AY" makes sense, both classes(X and Y) should probably live in the sameinheritance hierarchy. Chances are, they havethe same or overlapping behaviors.Keep in mind that theinheritance IS-A relationshipworks in only one directionlTriangle IS-AShape makes sense, so you canhave Triangle extend Shape.But the reverse-Shape IS-ATriangle-doesnot make sense, so Shape should not extendTriangle. Remember that the IS·A relationshipimplies that ifX IS-A y. then X can do anythinga Y can do (and possibly more).I letsare blUe. . 't true.Roses are red, v 0 the reverse lsn""a is-aShape,SqU-d rd laletS are ell. beer.Roses are re I v t 01/ drinks areInk but no e-Beeris-a Dr, '" t shOWS the on 'fM Ke one t"a . Remember. \QI(, your turr\e~S_A relatiOnshlP~ense,way.nesS of ~ 'S.A'( must maKe'/.. extend_s_'(I_ ------"..........--~"........-Sharpen your pencil------,Put a check next to the relationships thatmake sense.o Oven extends KItcheno Guitar extends Instrumento Person extends Employeeo Ferrari extends EngIneo FriedEgg extends Foodo Beagle extends Peto Container extends Jaro Metal extends Titaniumo GratefulDead extends Bando Blonde extends Smarto Beverage extends MartiniHint apply the IS-A testyou are here ~ 179


who inherits whattherelllreAl~Dum D "


When designing with inheritance,are you usit1g or abusi"g?Inheritance and polymorphismAlthough some of the reasons behind these rules won't berevealed until later in this book, for now, simply knowing afew rules will help you build a better inheritance design.DO use inheritance when one class is a more specific typeofa superclass. Example: WIllow is a more specific type ofTree, so Willow extends Tree makes sense.DO consider inheritance when you have behavior(implemented code) that should be shared amongmultiple classes of the same general type. Example:Square, Circle, and Triangle all need to rotate and playsound, so putting that functionality in a superclass Shapemight make sense, and makes for easier maintenance andextensibility. Be aware, however, that while inheritance isone of the key features ofobject-oriented programming,it's not necessarily the best way to achieve behavior reuse.It'll get you started, and often it's the right design choice,but design panerns will help you see other more subtleand flexible options. !fyou don't know about designpatterns, a good follow-on to this book would be HeadFirstDesign Patterns.DO NOT use inheritancejust so that you can reusecode from another class, ifthe relationship between thesuperclass and subclass violate either of the above tworules. For example, imagine you wrote special printingcode in the Alarm class and now you need printing codein the Piano class, so you have Piano extend Alarm so thatPiano inherits the printing code. That makes no sense! APiano is rwt a more specific type ofAlarm. (So the printingcode should be in a Printer class, that all printable objectscan take advantage ofvia a HAS-A relationship.)DO NOT use inheritance if the subclass and superclassdo not pass the IS-A test, Always ask yourself if the subclassIS-A more specific type of the superclass. Example: Tea IS­A Beverage makes sense. Beverage IS-ATea does not.• Asubclass extends a superclass.• Asubclass Inherits allpublic Instancevariables and methods ofthe superclass, butdoes not Inherit the private Instance variablesand methods ofthe superdass,• Inherited methods can be overridden; instancevartables cannot beoverridden (although theycan beredefined in the subclass, but that'snot the same thing, and there's almost never aneed todo it)• Use the IS-A test toverify thaiyourinheritance hierarchy is valid. If Xextends Y,then X IS-A Ymust make sense.• The rS-A relationship works In only onedirection. A Hippo isanAnimal. but not allAnimals are Hippos.• When a method isoverridden ina subclass,and that method isInvoked on an instance ofthe subclass, the overridden version of themethod is called. (The lowest one wins.)• Ifclass B extends A, and Cextends B, classBIS-A class A, and class C IS-A class e, andclass C also IS-A class A.you are here) 181


exploiting the power of objectsSo what does all thish1herita"ce really buy you?You get a lot of00 mileage by designingwith inheritance. You can get rid of duplicatecode by abstracting out the behavior commonto a group ofclasses, and sticking that codein a superclass. That way, when you need tomodify it, you have only one place to update,and the changeis magically reflected in all theclasses that inherit that behavior. Well, there'sno magic involved, but it is pretty simple:make the change and compile the classagain. That's it. You don't have to touch thesubclassesIJmt deliver the newly-ehanged superclass, andall classes that extend it will automatically usethe new version.AJava program is nothing but a pile of classes,so the subclasses don't have to be recompiledin order to use the new version ofthesuperclass, As long as the superclass doesn'tbreak anything for the subclass, everything'sfine. (We'll discuss what the word 'break'means in this context, later in the book. Fornow, think ofit as modifying something inthe superclass that the subclass is dependingon, like a particular method's arguments orreturn type, or method name, etc.)(i) You avoid duplicatecode.Put common code in one place, and letthe subclasses inherit that code from asuperclass . When you want to change thatbehavior, you have to modify it in onlyone place, and everybody else (i.e, all thesubclasses) see the change.• You define a commonprotocol for a group ofclasses.182 chapter 7


Inheritance and polymorphismlt1heritat1ce lets you guarat1tee thatall classes grouped ut1der a certahtsupertype have all the Ittethods thatthe supertype has:I., other words. you defl"~ a oOttUMO" protocol for asetofclasses related through I"herita"ce,When you define methods in a superclass, that can beinherited by subclasses, you're announcing a kind ofprotocol to other code that says, "All my subtypes (i.e,subclasses) can do these things, with these methodsthat look like this.;"In other words, you establish a contract:Class Animal establishes a common protocol for allAnimal subtypes:Anlm.1makeNolse()eatOsleepOroamOAnd remember, when we say any AlIima~ we meanAnimal and any classthat extendsfrom Animal Whichagain means, any class tha: has Animal SO"TTIeWhere aboue itin the inheritancehierarchy,But we're not even at the really cool part yet, becausewe saved the best--polymarphism--for lastWhen you define a supertype for a group ofclasses,any subclass 0/that supmype can besubstituted where thesupertype is expected.Say, what?Don 't worry. we're nowhere near done explaining itTwo pages from now, you'll be an expertAnd I care because•••Because you get to take advantage ofpolymorphism.Which matters to mebecause•••Because you get to refer to a subclassobject using a reference declared as thesupertype.And that means to me•••You get to write really flexible code.Code that's cleaner (more efficient,simpler). Code that's not just easier todevelop, but also much, much easier toextend, in ways you never imagined atthe time you originally wrote your code.That means you can take that tropicalvacation while your co-workers updatethe program, and your co-workers mightnot even need your source code.You'll see how it works on the next page,We don't know about you, butpersonally, we find the wholetropical vacation thingparticuIarly motivating."When wesay "all the methods' we mean "alilhe Inheritable methods', whichfornow actually means, "all the public methods', although later we'll refine thatdefini\Jon a bitmore.you are here. 183


the way polymorphism worksThe 3 steps of objectdeclaration and assignmentTo see how polymorphismworks, we have to step backand look at the way wenormally declare a referenceand create an object...1 2~3~Dog myDog = new Dog();ODeclarea referencevariableDog myDoq = new Dog () ;Tells the JVM to allocate space for areference variable. The reference variableIs,forever, of type Dog. In other words,a remote control that has buttons tocontrol a Dog, but not a Cat or a Buttonor a Socket.DogG Create an objectDog myDoq = new Dog () ;Tells the JVM to allocate space fora new Dog object on the garbagecollectible heap.Dog object~ Link the object~ and the referenceDog myDog = new Dog () ;Assigns the new Dog to the referencevariable myDog.ln other words,program the remote control.Dog objectDog184 chapter 7


inheritance and polymorphismThe important point is that thereference type AND the objecttype are the same.In this example, both are Dog.But with polymorphism, thereference and the object canbe different.Animal myDog - new ~() ;~/'nest: two .i~e NOT the sd",e t)'Pe. nere-ftyel'lu I/ariable t)'Pt is detlarta as APli...aI,b~t tht objtt+' is tytaud as Pltw D~O.you are here ~ 185


polymorphism In actionWith polymorphism, the referencetype can be a superclass of theactual object type.When you declare a reference variable,any object that passes the IS-Atest for thedeclared type of the reference variablecan be assigned to that reference. Inother words , anything that extends thedeclared reference variable type canbe assigned to the referencevariable. This lets you dothing! like make polyrruwphicarrays.animals [0]= new Dog();animals [1] = new cat0 ; Blot. look ",hdt. 'fOU ~d. to do... ~O" Un fvl:. ANYanimals [2) = new Wolf() ;


Inheritance and polymorphismBut wait! There's more!You can have polymorphicarguments and retu!!, types.Ifyou can declare a reference variableof a superrype, say,Animal, and assign asubclass object to it, say, Dog, think ofhowthat might work when the reference is anargument to a method...class Vet {public void qiveShot(Animal a)II do horrible things to the Animal at/ / the other end of the 'a' parametera.ma.keNoise();}}class Petownerpublic void start ()Vet v = new VetO;Dog d = new Dog()i ~Hippo h = new Hippo(); ~v. giveShot (d) ; ~ D'1's "",ktNoiUO--1Ai\S))v .giveShot (h) ; ( Itippo's Or\dkeNoiseO l"1AN;you are here) 187


exploiting the power of polymorphismNOW I get itl If I writemy code using polymorphic arguments,where.r declare the method parameter as asuper-class type, r CM pass in any subclass object atruntime. Cool. Because that also meansr can write mycode, go on vacation, and someoneelse can add newsubclass types to the program and my methods willstill work ... (the only downside is rm just making lifeeasier for that idiot Jim).WIth polytttorphlSttt, you caM write code that doutt'thave to chattge whe.. you 'tttroduce ..ew subclasstypes I..tothe progratlt.Remember that Vet class? Ifyou write that Vet class usingarguments declared as type Animal; your code can handle anyAnimal subclass. That means if others want to take advantage ofyour Vet class. all they have to do is make sure their new Animaltypes extend class Animal. The Vet methods will still work, eventhough the Vet class was written without any knowledge of thenew Animal subtypes the Vet will be working on.Why is polymorphism guaranteed to work this way? Why Isit always safe to assume that any subclass type will have themethods you think you're calling on the suoerclass type (thesuperclass reference type you're using the dot operator on)?18a chapter 7


inheritance and polymorphism:there l arH ? 0Diimo ~uesti9n8Q: Are there any practical limitson the levels of subclassing? Howdeep can you go?A.: If you look in the Java API,you'll see that most inheritancehierarchies are wide but not deep.Most are no more than one or twolevels deep, although there areexceptions (especially in the GUIclasses) .You'll come to realize thatit usually makes more sense to keepyour inheritance trees shallow, butthere isn't a hard limit (well, not onethat you'd ever run into) .Q: Hey,Ijust thought ofsomething... if you don't haveKcess to the source code for a class,but you want to change the way amethod of that class works, couldJOu use subclassing to do that? Toextend the"bad" class andoverridethe method with your own bettercode?A.: Yep.That's one cool featureof 00, and sometimes it savesyoufrom having to rewrite the classfrom scratch, or track down theprogrammer who hid the source code.Q: Can you extend any class? Oris it like class members where if theclass is private you can't inherit it...A.: There's no such thing as aprivate class,except in a very specialcase called an innerclass,that wehaven't looked at yet. But there arethree things that can prevent a classfrom being subclassed.The first is accesscontrol. Eventhougha classcan'tbe marked pri vat e, aclasscan be non-public (what youget if you don 't declare the classaspubl ic). A non-public class can besubclassed only by classes in thesame package as the class.Classes ina different package won't be able tosubclass (or even use, for that matter)the non-public class.The second thing that stops a classfrom being subclassed is the keywordmodifier final. A final class meansthat it's the end of the inheritanceline. Nobody, ever,can extend a finalclass.The third issue is that if a class hasonly p r i vate constructors (we'lllook at constructors in chapter 9),itcan't be subclassed.Q: Whywould you ever want tomake a final class? What advantagewould there be in preventing a classfrom being subclassed?A: Typically, you won 't make yourclasses final. But if you need security- the security of knowing that themethods will always work the waythat you wrote them (because theycan't be overridden), a final classwill give you that. A lot of classes inthe Java API are final for that reason.The String class,for example, is finalbecause,well , imagine the havoc ifsomebody came along and changedthe way Strings behave!Q: Can you make a methodfinal,without making the whole classfinal?A.: If you want to protect a specificmethod from being overridden, markthe method with the finalmodifier.Mark the whole class as final if youwant to guarantee that none of themethods in that class will ever beoverridden.you are here r 189


Keepl.,g the co"tract: rules for overridingWhen you override a method from a supercIass, you're agreeing tofulfill the contract. The contract that says. for example, ~I take noarguments and I return a boolean." In other words, the argumentsand return types of your overriding method must look to the outsideworld exactly like the overridden method in the superclass.The methods are the contract.Ifpolymorphism is going to work. the Toaster's version of theoverridden method from Appliance has to work at runtime.Remember. the compiler looks at the reference type to decidewhether you can call a particular method on that reference. Wilhan Appliance reference to a Toaster, the compiler cares only ifclassAppliance has the method you 're invoking on an Appliance reference.But at runtime, thejVM looks not at the reference type (Appliance) butat the actual Toaster object on the heap. So if the compiler has already ~approved the method call, the only way it can work is ifthe overriding "This \~ 1'./01 6"method has the same arguments and return types. Otherwise.'1t:Y""'\dt~someone with an Appliance reference will call turnOn 0 as a no- o. h6 e \)Iearg method, even though there's a version in Toaster that takes an ta" \:. t. b~" 61\Applianceboolean bJmOnOboolean bJmOffOToasterboolean tumOn(~lleveDint. Which one is called at runtime? The one in Appliance. In other ~\WI'.~~....e-t.n06.I.words, the turnOn{int level) m.etJwd in Toaster is not an override.' O~~I ThIs j! .t,i:.ua/ly .a Je5d1overLOAD b· i .LArguments must be the same, and returntypes must be compatible.The contract of superclass defines how other code can use a method.Whatever the superclass takes as an argument. the subclass overridingthe method must use that same argument. And whatever thesuperclass declares as a retum type. the overriding method must declareeither the same type. or a subclass type . Remember, a subclassobject is guaranteed to be able to do anything its superclass declares.so iI's safe to retum a subclass where the superclass Is expected.• The method can't be less accessible.That means the access level must be the same, or friendlier. Thatmeans you can't, for example, override a public method and makeIt private. What a shock that would be to the code invoking what Itthinks (at compile time) is a public method. If suddenly at runtimethe JVM slammed the door shut because the overriding versioncalled at runtime Is prlvatelSo far we've leamed about two access levels : private and public .The other two are In the deployment chapter (Release your Code)and appendix B. There's also another rule about overriding relatedto exception handling , but we'll walt until the chapter on exceptions(Risky Behavior) to cover thaI.olle"rRIDE. I\Appliance""l; "()l:. anpUblic boolean tumOnOpublic boolean tumOnOToasterprivata boolean bJmOnO190 chapter 7


Overloading a tttethod~Method overloading is nothing more than havingtwo methods with the same name but differentargument lists. Period. There's no polymorphisminvolved with overloaded methods!Overloading lets you make multiple versionsofa method, with different argument lists, forconvenience to the callers. For example, if youhave a method that takes only an int, the callingcode has to convert, say, a double into an intbefore calling your method. But if you overloadedthe method with another version that takes adouble, then you've made things easier for thecaller. You'll see more of this when we look intoconstructors in the object lifecyc1e chapter.Since an overloading method isn't trying tofulfill the polymorphism contract defined by itssuperc1ass, overloaded methods have much moreflexibility.• The return types can bedifferent.You're free to change the return types inoverloaded methods, as long as the argument listsare different.• You can't change ONLY thereturn type.If only the return type is different, it's not avalid overload-the compiler will assumeyou're trying to override the method. And eventhat won't be legal unless the return type isa subtype of the return type declared in thesuperclass. To overload a method, you MUSTchange the argument list, although you canchange the return type to anything.• You can vary the accesslevels in any direction.You're free to overload a method with a methodthat's more restrictive. It doesn't matter, since thenew method isn't obligated to fulfill the contract ofthe overloaded method.inheritance and polymorphismAn overloaded method isjustadii±erent method thathappens to have the sanemethod name, It has nothingto do with inheritance andpol)'Illorphism. An overloadedmethod is NoT the sane asan overridden method.Legal examples of methodoverloading:public class OverloadsString uniqueID;public int addNums(int a, int b) (return a + b;public double addNums(double a, double b) (return a + b;public void setUniqueID(String theID) (II lots of validation code, and then:uniqueID = theID;public void setUniqueID(int ssNumber)String numString = "" + ssNumber;setUniqueID{numString);you are here ~ 191


exercise: Mixed Messagesthe prograttt:Mix~dMessagESa ~ 6i~56b ~ Si 11a ~ 5i 65A short Java program is listed below. One block ofthe program is missing! Yourchallenge is to matchthe candidate block of code (on the left),with theoutput that YOU'd see if the block were Inserted.Not all the lines of output wIll be used, and some ofthe lines of output might be used more than once .Draw lines connecting the candidate blocks ofcode with their matching command-line output.class A {int ivar ;; 7;void ml() (System.out.print("A'S mIt ");}void m2 () {System.out.print("A'S m2, ");}void m3() (System.out.print("A's m3, U);class B extends A {void ml (I (System.out.print(UB'S ml, U);} }}class C extends B {void m3() {system.out.print(UC's nU, "+(ivar + 6»;public class Mixed2 {public static void main(StringA a "" new A();B b ;; new B();C c = new e();A a2 = new C( ) ;'----------I[I args) {cattdldate code~ goes here(three IIttes)output:code b.ml ();c.m2();candidates: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, 13a.ml()iB's ml, C's m2}t A's m3,b.rn2();c.m3(); B's m1, A's rn2, C's m3, 6a2.ml(); }a2 .m2 ( ) iA's m1, A's rn2, C's mJ, 13a2 .m3 ( ) ;192 chapter 7


public class MonsterTestDrive {}public static void maio(String (I args) {}Monster (Jma[OImarl)ma[2Jrna = new Monster(3J:new Vampire();new Dragon():new Monster():for(iot x = 0: x < 3; X++) {}ma[xJ.frighten(x);class Monster {inheritance and polymorphismBE the Ct»mriler"Which ofthe A-B pai.rS ofmethods listed on the right, ifinserted into the classes on the left. would compile andproduce the output shown? (The AltIethod inSerted intoclass Monster, the B JIlethod inserted into class VlUtlpil'e.)1e2e} }boolean frighten(int d) {System.out.println("arrrgh U);}return true;boolean frighten(int x)System.out.println("& bite?");return false;}boolean frighten(int x) {System.out.println(Uarrrgh");}return true;iot frighten(int f) {4) System.out.println(Ua bite?");return 1:class Vampire extends Monster ( 3}class Dragon extends Monster {boolean frighten(int degree)System. out.println("breath fire");return true;4}eeoboolean frighten(int x) {}System.out.println("arrrgh"):return false;boolean scare(int x) {System.out.println("a bite?"):return true;}boolean frighten(int z) {System.out.println("arrrgh")ireturn true;}boolean frighten(byte b) {System.out.println("a bite?H);return true;you are here ~ 193


puzzle: Pool PuzzlePool PuzzleYour Job is to take code snippets from the pool and place them intothe blank lines In the code.You may use the same snippet morethan once, and you might not need to use all the snippets.Yourgoal Isto make a set of classes that will compile and run togetheras a program. Don't be fooled - this one's harder than It looks.public class Rowboat {public rowTheBoat() {Syatem.out.print(nstroke natashaW)i}public classprivate int_____ void __length:: len;}public int getLength() {}public move() {) {public class TestBoats {_________ main(String( I args){______ bI = new Boat();Sailboat b2 = new ();Rowboat _ new Rowboat ( ) ;b2.setLength(32);bl.( ) ib3. ()i___.move();}public class Boat {public () {System.out. print( u ") ;}}System.ou t . print(" H ) ;}}OUTPUT: drift drift hoist sail194 chapter 7


inheritance and polymorphismSet 1 will work.Set 2 will not compile becauseof Vampire's retumtype (Int).The Vampire's frightenO method (B) is not a legaloverride OR overload of Monster'sfrightenO method.Changing ONLYthe retum type Is not enoughto make a validoverload, and since an int is notcompatible with a boolean. the method is not a validoverride. (Remember, If you change ONLY the retumtype, it must be to a retum type that Is compatiblewith the superclass version's retum type, and then ifsan override.Sets 3 and 4 will compile, but produce:arrrqhbreath firearrrghRemember, classVampire did not override classMonster's frightenO method. (The frightenO methodin Vampire's set 4 takes a byte, not an lnr.)codecatldldates:MixedMessagESA's m2, C's m3, 6A's mz , A'9 m3,B'B m2, A's m3,A's mz , C's nU, 13B's ml,B's ml,A'8 ml,C's m2, A's m3,A's 11\2, C's m3, 6A'S m2, e's m3, 13you are he re ~ 195


puzzle answers•pUblic class Rowboat extends Boatpublic void rowTheBoat() {System.out.print("stroke natasha")1public class Boat {private int lengthpublic void setLength ( int len ) {length = lenlpublic int getLength()return length 1pub.l.Lc void move ( )System.out.print("drift") 1public class TestBoats {public static void main(String[ l args) {Boat bl = new Boat()lSailboat b2 = new Sailboat( ) 1Rowboat b3 = new Rowboat()1b2.setLength(32)1bl.mOVe() 1b3.mOVe() 1b2.move() 1pubLi.c class Sailboat extends Boat {public void mover i {System.out.print( "hoist sail •• ) 1OUTPUT: drift drift hoist sail196 chapter 7


8 interfaces and abstract classesSerious PolymorphismInheritance is just the beginning. this is a new chapter 197


designing with inheritanceDid we forget about somethingwhen we designed this? AnimalpicturefoodhungerboundarieslocationmakeNoise()eat()sleep()roam()FelineCanineroam()HipposizepicturemakeNoise()foodeat()preyroam()LionsizepicturefoodmakeNoise()preyeat()DogTigersizepicturefood makeNoise()prey eat()CatsizepicturemakeNoise()foodeat() preyWolfsizepicturemakeNoise()foodeat()preysizepicturemakeNoise()foodeat()prey198 chapter 8


interfaces and polymorphismWe know we can say:Wolf aWolf = new Wolf();A Wolf reference to aWolf object.aWolfWolfThese two are the same type.Wolf objectAnd we know we can say:Animal aHippo = new Hippo();Animal reference toa Hippo object.aHippoAnimalHippo objectThese two are NOT the same type.But here’s where it gets weird:Animal anim = new Animal();Animal reference toan Animal object.animAnimal?Animal objectThese two are the same type, but...what the heck does an Animal object look like?you are here4 199


when objects go badWhat does a new Animal() objectlook like?scary objectsWhat are the instance variable values?Some classes just should not beinstantiated! new abstract abstract abstract class Canine extends Animal {public void roam() { }}200 chapter 8


interfaces and polymorphismThe compiler won’t let you instantiatean abstract class 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.javaMakeCanine.java:5: Canine is abstract;cannot be instantiatedc = new Canine();^1 errorThis is OK, because you can always assigna subclass object to a superclass reference,even if the superclass is abstract.class Canine is marked abstract,so the compiler will NOT let you do this.An abstract class has virtually* no use, no value, nopurpose in life, unless it is extended.With an abstract class, the guys doing the work at runtimeare instances of a subclass of your abstract class.*There is an exception to this—an abstract class canhave static members (see chapter 10).you are here4 201


abstract and concrete classesAbstract vs. Concreteabstract concreteLionabstractCatFelineconcreteconcreteTigerAnimalconcreteHippoconcreteWolfCanineabstractconcreteDogHmmmm... do Ifeel like red orwhite tonight?Hmmmm... the CamelotVineyards 1997 PinotNoir was a prettydecent year...abstract or concrete? 202 chapter 8


interfaces and polymorphismAbstract methods An abstract method has no body! It really sucks tobe an abstract method.You don’t have a body.public abstract void eat();No method body!End it with a semicolon.If you declare an abstract method, you MUSTmark the class abstract as well. You can’t havean abstract method in a non-abstract class. there are noDumb Questions you are here4 203


you must implement abstract methodsYou MUST implement all abstract methodsI have wonderful news,mother. Joe finally implementedall his abstract methods! Noweverything is working just theway we planned...Implementing an abstractmethod is just likeoverriding a method.204 chapter 8


interfaces and polymorphismSharpen your pencil golf course simulation tree nursery application architect applicationsatellite photo application coaching application you are here4 205


polymorphism examplesPolymorphism in action 1MyDogListDog[] dogsint nextIndexBuilding our own Dog-specific list(Perhaps the world’s worst attempt at making ourown ArrayList kind of class, from scratch.)public class MyDogList {private Dog [] dogs = new Dog[5];private int nextIndex = 0;Use a plain old Dog arraybehind the scenes.We’ll increment this eachtime a new Dog is added.add(Dog d)public void add(Dog d) {if (nextIndex < dogs.length) {dogs[nextIndex] = d;If we’re not already at the limitof the dogs array, add the Dogand print a message.System.out.println(“Dog added at “ + nextIndex);}}}nextIndex++;increment, to give us thenext index to use206 chapter 8


interfaces and polymorphismUh-oh, now we need to keep Cats, too. 2MyAnimalListAnimal[] animalsint nextIndexadd(Animal a)Building our own Animal-specific listpublic 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++;Don’t panic. We’re not making anew Animal object; we’re making anew array object, of type Animal.(Remember, you cannot make a newinstance of an abstract type, butyou CAN make an array objectdeclared to HOLD that type.)}}}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 AnimalTestDriveAnimal added at 0Animal added at 1you are here4 207


the ultimate superclass: ObjectWhat about non-Animals? Why not makea class generic enough to take anything? Every class in Java extendsclass Object. public class Dog extends Object { } Any class that doesn’t explicitly extend anotherclass, implicitly extends Object. 208 chapter 83 (These are just a few of themethods in ArrayList...thereare many more.) Many of the ArrayList methods use theultimate polymorphic type, Object. Sinceevery 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 differentthan the ones shown here, but for now thisis the way to think about it. We’ll get intothe full story a little later.)


interfaces and polymorphismSo what’s in this ultra-super-megaclass Object? Objectboolean equals()Class getClass()int hashCode()String toString()YourClassHereJust SOME of the methodsof class Object.Every class you write inherits all themethods of class Object. The classesyou’ve written inherited methods youdidn’t even know you had.1equals(Object o)Dog a = new Dog();Cat c = new Cat();if (a.equals(c)) {System.out.println(“true”);} else {System.out.println(“false”);}File Edit Window Help Stop% java TestObjectfalseTells you if two objects areconsidered ‘equal’ (we’ll talkabout what ‘equal’ reallymeans in appendix B).3hashCode()Cat c = new Cat();System.out.println(c.hashCode());File Edit Window Help Drop% java TestObject82021114Prints out a hashcodefor the object (fornow, think of it as aunique ID).toString()Cat c = new Cat();System.out.println(c.toString());2getClass()Cat c = new Cat();System.out.println(c.getClass());File Edit Window Help Faint% java TestObjectclass CatGives you back theclass that object wasinstantiated from.File Edit Window Help LapseIntoComa% java TestObjectCat@7d277fPrints out a String messagewith the name of the classand some other number werarely care about.you are here4 209


Object and abstract classesthere are noDumb Questions final Object o = new Ferrari();o.goFast(); //Not legal! 210 chapter 8


Using polymorphic references of type Object has a price... ArrayList myDogArrayList = new ArrayList();Dog aDog = new Dog();myDogArrayList.add(aDog);Dog d = myDogArrayList.get(0); ArrayList myDogArrayList = new ArrayList();Dog aDog = new Dog();(These two steps are the same.)myDogArrayList.add(aDog); Dog d = myDogArrayList.get(0);Make a Dog.Add the Dog to the list. interfaces and polymorphismMake an ArrayList declaredto hold Dog objects.Assign the Dog from the list to a new Dog reference variable.(Think of it as though the get() method declares a Dog returntype because you used ArrayList.)Make a Dog.Add the Dog to the list.Make an ArrayList declaredto hold any type of Object.NO!! Won’t compile!! When you use ArrayList, the get() methodreturns type Object. The Compiler knows only that the object inherits fromObject (somewhere in its inheritance tree) but it doesn’t know it’s a Dog!!The objects go INas SoccerBall,Fish, Guitar, andCar.But they comeOUT as thoughthey were of typeObject.ArrayListObject Object Object ObjectObjects come out ofan ArrayListacting like they’regeneric instancesof class Object. TheCompiler cannotassume the objectthat comes out is ofany type other thanObject.you are here4 211


When a Dog loses its DognessWhen a Dog won’t act like a Dog I don’t know what you’retalking about. Sit? Stay?bark? Hmmmm... I don’trecall knowing those.BADLpublic void go() {Dog aDog = new Dog();Dog sameDog = getObject(aDog);}public Object getObject(Object o) {return o;}We’re returning a reference to the same Dog, but as areturn type of Object. This part is perfectly legal. Note:this is similar to how the get() method works when you havean ArrayList rather than an ArrayList.This line won’t work! Even though the methodreturned a reference to the very same Dog theargument referred to, the return type Objectmeans the compiler won’t let you assign the returnedreference to anything but Object.File Edit Window Help RememberDogPolyTest.java:10: incompatible typesfound : java.lang.Objectrequired: DogDog sameDog = takeObjects(aDog);1 error ^The compiler doesn’t know that thething returned from the method isactually a Dog, so it won’t let youassign it to a Dog reference. (You’llsee why on the next page.)GOODJpublic void go() {Dog aDog = new Dog();Object sameDog = getObject(aDog);}public Object getObject(Object o) {return o;}212 chapter 8This works (although it may not be veryuseful, as you’ll see in a moment) because youcan assign ANYTHING to a reference of typeObject, since every class passes the IS-A testfor Object. Every object in Java is an instanceof type Object, because every class in Java hasObject at the top of its inheritance tree.


interfaces and polymorphismObjects don’t bark. Won’t compile!Object o = al.get(index);int i = o.hashCode();o.bark();oObjectDog objectWhen you get an object reference froman ArrayList (or any methodthat declares Object as the return type),it comes back as a polymorphic referencetype of Object. So you have an Objectreference to (in this case) a Dog instance.This is fine. Class Object has ahashCode() method, so you can callthat method on ANY object in Java.Can’t do this!! The Object class has no idea whatit means to bark(). Even though YOU know it’sreally a Dog at that index, the compiler doesn’t..The compiler decides whetheryou can call a method basedon the reference type, not theactual object type. oObjectObjectequals()getClass()hashCode()toString()hashCode()Dog objectThe method you’re calling on areference MUST be in the class ofthat reference type. Doesn’t matterwhat the actual object is.o.hashCode();The “o” reference was declared as typeObject, so you can call methods only ifthose methods are in class Object..you are here4 213


objects are ObjectsHe treats me like anObject. But I can do somuch more...if only he’d seeme for what I really am.Get in touch with your inner Object. new Snowboard() Objectequals()getClass()hashCode()toString()Snowboardequals()getClass()hashCode()toString()turn()shred()getAir()loseControl()Snowboard inherits methodsfrom superclass Object, andadds four more.getAir()shred()toString()equals()hashCode()ObjectgetClass()turn()loseControl()SnowboardSnowboard objectA single objecton the heap.There is only ONE object on the heap here. A Snowboardobject. But it contains both the Snowboard class parts ofitself and the Object class parts of itself.214 chapter 8


interfaces and polymorphism‘Polymorphism’ means‘many forms’.You can treat a Snowboard as aSnowboard or as an Object. When you putan object in anArrayList, youcan treat it only as anObject, regardless ofthe type it was whenyou put it in.When you get areference from anArrayList, thereference is always oftype Object.That means you get anObject remote control.Snowboard s = new Snowboard();Object o = s;shred()toString()hashCode()Objectturn()The Snowboard remote control(reference) has more buttons thanan Object remote control. TheSnowboard remote can see the fullSnowboardness of the Snowboardobject. It can access all the methodsin Snowboard, including both theinherited Object methods and themethods from class Snowboard.sofewer methods here...getAir()equals()The Object reference can see only theObject parts of the Snowboard object.It can access only the methods of classObject. It has fewer buttons than theSnowboard remote control.getClass()loseControl()SnowboardSnowboard objectyou are here4 215


casting objectsWait a minute... what goodis a Dog if it comes out of anArrayList and it can’t doany Dog things? There’s gotta be away to get the Dog back to a stateof Dogness...Casting an object referenceback to its real type.oObjectDog objectI hope it doesn’t hurt.And what’s so wrong withstaying an Object? OK, I can’tfetch, sure, but I can give youa real nice hashcode. Object o = al.get(index);Dog d = (Dog) o;d.roam();cast the Object back toa Dog we know is there.oObjectDog objectCast the so-called ‘Object’ (butwe know he’s actually a Dog) totype Dog, so that you can treathim like the Dog he really is.dDog instanceof if (o instanceof Dog) {Dog d = (Dog) o;}216 chapter 8


interfaces and polymorphismSo now you’ve seen how much Javacares about the methods in theclass of the reference variable.You can call a method on an object only ifthe class of the reference variable has thatmethod.Think of the public methods in your class asyour contract, your promise to the outsideworld about the things you can do. Account debit(double amt) credit(double amt) double getBalance() you are here4 217


modifying a class treeWhat if you need to changethe contract? Think about what YOU would do if YOU werethe Dog class programmer and needed tomodify the Dog so that it could do Pet things,too. We know that simply adding new Pet behaviors(methods) to the Dog class will work,and won’t break anyone else’s code.But... this is a PetShop program. It has morethan just Dogs! And what if someone wantsto use your Dog class for a program that haswild Dogs? What do you think your optionsmight be, and without worrying about howJava handles things, just try to imagine howyou’d like to solve the problem of modifyingsome of your Animal classes to include Petbehaviors.Stop right now and think about it,before you look at the next page where webegin to reveal everything.(thus rendering the whole exercise completely useless, robbingyou of your One Big Chance to burn some brain calories)218 chapter 8


interfaces and polymorphismLet’s explore some design optionsfor reusing some of our existingclasses in a PetShop program. 1 Option oneWe take the easy path, and put petmethods in class Animal.Pros:All the Animals will instantly inheritthe pet behaviors. We won’t have totouch the existing Animal subclassesat all, and any Animal subclassescreated in the future will also get totake advantage of inheriting thosemethods. That way, class Animal canbe used as the polymorphic type inany program that wants to treat theAnimals as petsAnimalput all the petmethod code up herefor inheritance.CanineCons:HippoSo... when was the last time yousaw a Hippo at a pet shop? Lion?Wolf? Could be dangerous to givenon-pets pet methods.FelineDogAlso, we almost certainly WILLhave to touch the pet classeslike Dog and Cat, because (inour house, anyway) Dogsand Cats tend to implementpet behaviorsVERY differently.LionCatTigerWolfyou are here4 219


modifying existing classes2 Option twoWe start with Option One, putting the pet methodsin class Animal, but we make the methods abstract,forcing the Animal subclasses to override them.Pros:That would give us all the benefits of Option One, but withoutthe drawback of having non-pet Animals running aroundwith pet methods (like beFriendly()). All Animal classeswould have the method (because it’s in class Animal), butbecause it’s abstract the non-pet Animal classes won’tinherit any functionality. All classes MUST override themethods, but they can make the methods “do-nothings”.put all the pet methodsup here, but with noimplementations. Make allpet methods abstract.Cons:Because the pet methods in the Animal class are allabstract, the concrete Animal subclasses are forced toimplement all of them. (Remember, all abstract methodsMUST be implemented by the first concrete subclassdown the inheritance tree.) What a waste of time!You have to sit there and type in each and everypet method into each and every concrete nonpetclass, and all future subclasses as well.And while this does solve the problem ofnon-pets actually DOING pet things(as they would if they inherited petfunctionality from class Animal), thecontract is bad. Every non-petclass would be announcing to theworld that it, too, has thosepet methods, even thoughthe methods wouldn’tactually DO anythingwhen called.LionCatFelineTigerAnimalHippoWolfCanineDogThis approach doesn’tlook good at all. It justseems wrong to stuffeverything into class Animalthat more than one Animal typemight need, UNLESS it applies toALL Animal subclasses.Ask me to be friendly.No, seriously... ask me.I have the method.220 chapter 8


interfaces and polymorphism3 Option threePut the pet methods ONLY in theclasses where they belong.Pros:No more worries about Hippos greeting you at thedoor or licking your face. The methods are wherethey belong, and ONLY where they belong. Dogs canimplement the methods and Cats can implement themethods, but nobody else has to know about them.Cons:Two Big Problems with this approach. First off, you’dhave to agree to a protocol, and all programmers ofpet Animal classes now and in the future would haveto KNOW about the protocol. By protocol, we meanthe exact methods that we’ve decided all pets shouldhave. The pet contract without anything to back it up.But what if one of the programmers gets it just a tinybit wrong? Like, a method takes a String when it wassupposed 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’veimplemented the methods correctly. Someonecould easily come along to use the pet Animalclasses and find that not all of them workFelinequite right.And second, you don’t get to usepolymorphism for the pet methods.Every class that needs to usepet behaviors would have toknow about each and everyclass! In other words,you can’t use Animalas the polymorphictype now, because thecompiler won’t let you calla Pet method on an Animalreference (even if it’s really aDog object) because class Animaldoesn’t have the method.LionCatTigerPut the pet methods ONLY in theAnimal classes that can be pets,instead of in Animal.AnimalHippoWolfCanineDogyou are here4 221


multiple inheritance?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 samemethods defined (same name, same arguments, same returntypes, no missing methods, etc.), without having to cross yourfingers and hope all the programmers get it right.Æ A way to take advantage of polymorphism so that all pets can havetheir pet methods called, without having to use arguments, returntypes, and arrays for each and every pet class.It looks like we need TWOsuperclasses at the topWe make a new abstractsuperclass called Pet, andgive it all the pet methods.PetAnimalCanineHippoFelineDogCatLionWolfDog extends bothPet and AnimalCat now extendsfrom both AnimalAND Pet, so it getsthe methods of both.TigerThe non-pet Animalsdon’t have any inheritedPet stuff.222 chapter 8


interfaces and polymorphismThere’s just one problem with the “two superclasses” approach...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 problemknown as The Deadly Diamond of Death.Deadly Diamond of DeathCDBurner and DVDBurner bothinherit from DigitalRecorder,and both override the burn()method. Both inherit the “i”instance variable.CDBurnerburn()DigitalRecorderint iburn()DVDBurnerburn()Imagine that the “i” instancevariable is used by both CDBurnerand DVDBurner, with differentvalues. What happens if ComboDriveneeds to use both values of “i”?ComboDriveProblem with multiple inheritance.Which burn() method runs when youcall burn() on the ComboDrive? you are here4 223


interfacesInterface to the rescue! interface Petabstract void beFriendly();abstract void play();A Java interface is like a100% pure abstract class.All methods in an interface areabstract, so any class that IS-APet MUST implement (i.e. override)the methods of Pet.To DEFINE an interface:public interface Pet {...}Use the keyword “interface”instead of “class”To IMPLEMENT an interface:224 chapter 8public class Dog extends Canine implements Pet {...}Use the keyword “implements” followedby the interface name. Note thatwhen you implement an interface youstill get to extend a class


Making and Implementingthe Pet interfaceYou say ‘interface’ insteadof ‘class’ herepublic interface Pet {}Dog IS-A Animaland Dog IS-A Petpublic abstract void beFriendly();public abstract void play();public class Dog extends Canine implements Pet {public void beFriendly() {...}interfaces and polymorphisminterface methods are implicitly public andabstract, so typing in ‘public’ and ‘abstract’is optional (in fact, it’s not considered ‘goodstyle’ to type the words in, but we did herejust to reinforce it, and because we’ve neverbeen slaves to fashion...)All interface methods areabstract, so they MUST end insemicolons. Remember, they haveno body!You say ‘implements’followed by the nameof the interface.}public void play() {..}public void roam() {...}public void eat() {...}You SAID you are a Pet, so you MUSTimplement the Pet methods. It’s yourcontract. Notice the curly bracesinstead of semicolons.These are just normaloverriding methods.there are noDumb Questions you are here4 225


interface polymorphismRobotClasses from different inheritance treescan implement the same interface.PetAnimalAgentRoboDogCanineClass RoboDog doesn’tcome from the Animalinheritance tree, but it stillgets to be a Pet!FelineHippoDogCatLionWolfTiger Better still, a class can implementmultiple interfaces! public class Dog extends Animal implementsPet, Saveable, Paintable { ... }226 chapter 8


interfaces and polymorphismMake it Stick How do you know whether to make aclass, a subclass, an abstract class, oran interface?Make a class that doesn’t extend anything(other than Object) when your new class doesn’tpass the IS-A test for any other type.MakeUseUsea subclass (in other words, extend a class)only when you need to make a more specificversion of a class and need to override or addnew behaviors.an abstract class when you want to definea template for a group of subclasses, and youhave at least some implementation code that allsubclasses could use. Make the class abstractwhen you want to guarantee that nobody canmake objects of that type.an interface when you want to define a rolethat other classes can play, regardless of wherethose classes are in the inheritance tree.you are here4 227


using superInvoking the superclassversion of a method If method code inside aBuzzwordReport subclass says:super.runReport();the runReport() method insidethe superclass Report will runsuper.runReport();A reference to the subclass object(BuzzwordReport) will always callthe subclass version of an overriddenmethod. That’s polymorphism.But the subclass code can callsuper.runReport() to invoke thesuperclass version.abstract class Report {void runReport() {// set-up report}void printReport() {// generic printing}}class BuzzwordsReport extends Report {}void runReport() {super.runReport();buzzwordCompliance();printReport();}void buzzwordCompliance() {...}runReport()printReport()ReportBuzzwordReportsuperclass version of themethod does important stuffthat subclasses could usesubclass method (overridesthe superclass version)runReport()buzzwordCompliance() superclass methodscall superclass version,then come back anddo some subclassspecificstuff(including the overriddenrunReport()The super keyword is really a referenceto the superclass portion of an object.When subclass code uses super, as insuper.runReport(), the superclass version ofthe method will run.228 chapter 8


interfaces and polymorphismBULLET POINTSWhen you don’t want a class to be instantiated (in other words, you don’twant anyone to make a new object of that class type) mark the class with theabstract 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 (nocurly braces).All abstract methods must be implemented in the first concrete subclass in theinheritance 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, areference variable of type Object can be used only to call methods defined in classObject, 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 typewithout a cast. A cast can be used to assign a reference variable of one type to areference variable of a subtype, but at runtime the cast will fail if the object on theheap is NOT of a type compatible with the cast.Example: Dog d = (Dog) x.getObject(aDog);All objects come out of an ArrayList as type Object (meaning, they can bereferenced only by an Object reference variable, unless you use a cast).Multiple inheritance is not allowed in Java, because of the problems associated withthe “Deadly Diamond of Death”. That means you can extend only one class (i.e. youcan 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 implementsExample: Dog implements PetYour class can implement multiple interfaces.A class that implements an interface must implement all the methods of theinterface, since all interface methods are implicitly public and abstract.To invoke the superclass version of a method from a subclass that’s overridden themethod, use the super keyword. Example: super.runReport(); you are here4 229


exercise: What’s the Picture?Given: What’s the Picture ?1)public interface Foo { }1)(interface)Foopublic class Bar implements Foo { }2)public interface Vinn { }public abstract class Vout implements Vinn { }2)Bar3)public abstract class Muffie implements Whuffie { }public class Fluffie extends Muffie { }public interface Whuffie { }3)4)public class Zoop { }public class Boop extends Zoop { }public class Goop extends Boop { }4)5)public class Gamma extends Delta implements Epsilon { }public interface Epsilon { }public interface Beta { }public class Alpha extends Gamma implements Beta { }public class Delta { }5)230 chapter 8


interfaces and polymorphism Given:1ClickWhat’s the Declaration ?1)public class Click { }public class Clack extends Click { }Clack2Top2)Tip3)3Fee4Foo4)FiBar5)5ZetaBazBetaAlphaKEYDeltaClackClackClack you are here4 231


puzzle: Pool PuzzlePoolPuzzle ____________ Nose {________________________}public ___________ ________ extends Clowns {public static void main(String [] args) {abstract class Picasso implements ______{_________________________return 7;}}class _________ ________ __________ { }class _________ ________ __________ {___________________________return 5;}} ____________________________i[0] = new __________i[1] = new __________i[2] = new __________for(int x = 0; x < 3; x++) {System.out.println(__________________+ “ “ + _______.getClass( ) );}}} File Edit Window Help BeAfraid%java ______________5 class Acts7 class Clowns________Of76 232 chapter 8


interfaces and polymorphism What’s the Picture ?2)(interface)Vinn3)(interface)WhuffieVoutWhat’s the Declaration ?4)ZoopMuffieFluffie2)3)public abstract class Top { }public class Tip extends Top { }public abstract class Fee { }public abstract class Fi extends Fee { }Boop4)public interface Foo { }public class Bar implements Foo { }Gooppublic class Baz extends Bar { }5)Delta(interface)Epsilon5)public interface Zeta { }public class Alpha implements Zeta { }public interface Beta { }Gamma(interface)Betapublic class Delta extends Alpha implements Beta { }Alphayou are here4 233


puzzle solutioninterface 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;}}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 Of765 class Acts7 class Clowns7 class Of76234 chapter 8


9 constructors and garbage collectionLife and Deathof an Object...then he said,~I can't feel my legs!" andI said"Joel Stay with me J oel HBut it was... too late. The garbage...-~~ collector came and... he was gone.-";


the stack and the heapfhe Stack at1d the Heap: where thit1gs liveBefore we can understand what really happens whenyou create an object, we have to step back a bit, Weneed to learn more about where everything lives(and for how long) inJava. That means we need tolearn more about the Stack and the Heap. In java, we(programmers) care about two areas ofmemory-theone where objects live (the heap), and the onewhere method invocations and local variables live(the stack). When aJVM starts up. it gets a chunk ofmemory from the underlying as, and uses it to runyourJava program. How mucl, memory. and whetheror not you can tweak it, is dependent on whichversion of theJVM (and on which platform) you'rerunning. But usually you WO?I ', have anything to S2.yabout it, And with good programming. you probablywon't care (more on that a little later).We know that all objects live on the garbage-collectibleheap. but we haven't yet looked at where variableslive. And where a variable lives depends on what kindof variable it is. And by "kind", we don't mean type(i.e. primitive or object reference) . The two kinds ofvariables whose lives we care about now are instancevariables and localvariables. Local variables are alsoknown as slackvariables, which is a big clue for wherethey live.fhe StackWhere method Invocationsand local variables livefhe HeapWhere ALL objects liveInstance VariablesInstance variables are declared Insidea claSJ but notInside a method.They represent the "fields" that eachIndividual object has (which can be filled with differentvalues for each Instance ofthe class). Instance variableslive InsIde the object they belong to.Local VariablesLocal variables are declared Inside a method, Includingmethod parameters, They're temporary,and live only aslong as the method is on the stack (in other words, as long asthe method has not reached the closing curly brace).publicint}}236 chapte r 9


constructors and gcMethods are stackedWhen you call a method, the method lands onthe top ofa call stack. That new thing that'sactually pushed onto the stack is the stackframe, and it holds the state ofthe methodincluding which line of code is executing, andthe values ofall local variables.The method at the top of the slack is alwaysthe currently-running method for that stack(for now, assume there's only one stack.but inchapter 14 we'll add rnore.) A method stays onthe stack until the method hits its closing curlybrace (which means the method's done). Ifmethod foo() calls method bar(), method bast) isstacked on top ofmethod foot).A call stack with two methods,UtI'- ~y~ ~,-i!!~~~?l.........boitor.. of -the statkThe method on the top of thestack is always the currentlyexecutingmethod.public void doStuff() {boolean b = true;go(4);public void go (int x)int z = x + 24;crazy();/ / imagine more coda hereAstack scenarioThe code on the left is a snippet (we don't care what the rest of theclass looks like) with three methods. The first method (drot-u.ff(» callsthe second method (go() , and the second method calls the third(craz)'()). Each method declares one local variable within the bodyofthe method, and method goO also declares a parameter variable(which means goO has two local variables).public void crazy()char c = 'a';• Code from anotherclass calls doStuffO,and doStuffO goesinto a stack frameat the top of thestack.The booleanvariable named 'b'goes on the doStuffOstack frame.@ doStuffO calls goO,goO is pushedontop of the stack.Variables 'x' and 'z'are in the goO stackframe.@goO cells crozyO,crozyQ is now on thetop of the stack,with variable 'e' inthe frame.@crazy()completes,and its stack frame ispoppedoff the stack.Execution goes backto the goO method.and picks up at theline following the caUto crazy().you are here. 237


object references on the stackWhat about local variables that are objects?Remember, a non-primitive variable holds a reference to anobject, not the object itself. You already know where objectslive--on the heap. It doesn't matter where they're declared orcreated. Ifthe local variable is a reference to an object, onlythe variable (the reference/remote control) goes on the stack.The object itselfstillgoes in the heap. 0 t\a'C'es a~ t'"t.a~ ~si~t. \t: s'oa~O e lJay·'i"o\t. rts a \ot.i\t""IlIL~ ,"to~ tv"t.,.tl. e ",e\:.h00 Ipublic class StackRefpublic void foof()barf();.,.t.....v 1 . ,.s\ot..\)I ~t\L.ot.i\ayt. o ' ov. ()YI -\:.'M'l4ayl.. ...."o\e 6,,0 ~~public void barf() {Duck d '" Dew Duck (24) ;Q: Onl!!more time, WHY are we learning thewhole stack/heap thing? How does this help me?Do I really need to learn about It?A.: Knowl ng the fu ndamentaIs of the JavaStack and Heapis crucial If you wa nt to understa ndvariable scope, object creation Issues,memorymanagement, threads, and exception handling.We cover threads and exception handling In laterchapters but the others you'll leam In this one. Youdo not need to know anything about how the Stackand Heap are Implemented in any particular JVMand/or platform. Everything you need to knowabout the Stack and Heap Is on this page and theprevious one. If you nail these pages, all the othertopics that depend on your knowing this stuff willgo much, much, much easier.Once again, some dayyou will SOthank us for shoving Stacks and Heapsdown your throat.~ Java has two areas ofmemory we care aboutthe Stack and the Heap.~ Instance variables are variables declaredinsIde aclass but outside any method.~ Local variables are variables declared inside amethod ormethod parameter.~ All local variables live on the stack, In theframe corresponding to the method where thevariables are declared.~ Object reference variables work. just like primitivevariables-if the reference isdeclared as alocal variable, it goes on the stack... All objects live In the heap, regardless ofwhether the reference isa local orInstancevariable.238 chapter 9


constructors and gcIf local variables live Ott the staek.where do I"stattce variables live?..When you say new Cellf'hone() ,Java has to makespace on the Heap for that CellPhone. But how muchspace? Enough for the object, which means enough tohouse all of the object'S instance variables. That's right,instance variables live on the Heap, inside the objectthey belong to.Remember that the values of an object's instancevariables live inside the object. lithe instance variablesare all primitives, Java makes space for the instancevariables based on the primitive type. An int needs32 bits, a long 64 bits, etc.java doesn't care about thevalue inside primitive variables; the bit-size ofan intvariable is the same (32 bits) whether the value of theint is 32,000,000 or 32.But what if the instance variables are objects? What ifCeliPhone HAS-AAntenna? In other words, CellPhonehas a reference variable of type Antenna.When the new object has instance variables that areobject references rather than primitives, the realquestion is: does the object need space for aU ofthe objects it holds references to? The answer is, notexQ.{;tly. No matter what,Java has to make space for theinstance variable values. But remember that a referencevariable value is not the whole object, but merely a remotecontrol to the object. So ifCellPhone has an instancevariable declared as the non-primitive type Antenna,Java makes space within the CellPhone object only forthe Antenna's remote control (i.e. reference variable) butnot the Antenna object.Well then when does the Antenna object get space onthe Heap? First we have to find out whim the Antennaobject itself is created. That depends on the instancevariable declaration. lithe instance variable is declaredbut no object is assigned to it, then only the space forthe reference variable (the remote control) is created.private Antenna ant;No actual Antenna object is made on the heap unlessor until the reference variable is assigned a newAntenna object.private Antenna ant :: new Antenna () ;Objett wit.h two p-ri...itive iJ\St..l"te \/al'"iablcs.SpdU +~ the val'"iables lives i" the ~jed:,Objttt wit.h l»\t )lOtl-rv-i...itive ir.st..lrltt lIariableaI'"tttr-tlIte to d" A"b,."a objett., blot. "0 olthadlA"un'nd objtd~ This is \oIhat. yO'J. ~d, it YO4/.detlal"'t t.he lIariable b...t. dOtl'i, initialiu it witha" ad:lodl Anta.na objett.public class CellPhoneprivate Antenna ant;Objett. with Ol'le "or.-p-ri ....i-lille iJ\Stal">tt lIariable,and tht A"~,,a IIdr-iable is as.si~"ed a l\twA"u",."a objet+"public class CellPhone (private Antenna ant = new Antenna (l ;you are here ~ 239


object creationfhe tttiracle of object creatlottNow that you know where variables and objects live, we can dive intothe mysterious world of object creation. Remember the three stepsofobject declaration and assignment: declare a reference variable,create an object, and assign the object to the reference.But until now, step two--where a miracle occurs and the new objectis "boron-has remained a Big Mystery. Prepare to learn the facts ofobject life. Hope you're not squeamish.Review the 3 steps of objectdeclaration, creation and assignment:ODeclare a referencevariableDuck myDuck = new Duck () :e Create an object. ~t.\t. ~ Duck myDuck = new Duck () ;~ yV\\V' gI eot.t.v.V'~ "tv' .e Link the object andthe referenceDuck myDuck @)new Duck () ; _--rWLDuck reference240 chapter 9


constructors and gcAre we calling a method named DuckO?Because it sure looks like it.No.Duck myDuck =We're calling the Duck constructor.A constructor does look and feel a lot like a method, but it's nota method. It's got the code that runs when you say new. In otherwords, the code that runs when you instantiate an object.The only way to invoke a constructor is with the keyword newfollowed by the class name, ThejVM finds that class and invokesthe constructor in that class. (OK, technically this isn't the onlyway to invoke a constructor, But it's the only way to do it fromoutsidea constructor. You ca'ncall a constructor from withinanother constructor, with restrictions, but we'll get into all thatlater in the chapter.)But where Is the constructor?If we didn't write It, who did?You can write a constructor for your class (we're about to dothat), but ifyou don't, the compilerwrites one for you!Here's what the compiler's default constructor looks like:public Duck () {}Notice something missing? How Is this ~different from a method? 1. e 'IS ~t sa",t as 1t~'-IIv I'd'" T\\ats ,..a"da\,Pl ,.~ t.\ass y,d",t·~Duck() (~trejs the retllm t / / constructor code goes hereI this Wtre a 1, ype? )jrheOlodyou d heed d 'ret t jbetweeh l'PlI.b/' ,," m yPellDlAlkO", It. aridyou are here. 241


constructing a new DuckCottStruct a PuckThe key feature ofa constructor is that it runsbefore the object can be assigned to a reference.That means you get a chance to step in anddo things to get me object ready for use. Inother words, before anyone can use the remotecontra] for an object, the object has a chance tohelp construct itself In our Duck constructor,we're not doing anything useful, but it stilldemonstrates the sequence ofevents.public class Duck {public Duck () {System.out.println("Quack~) ;The constructor givesyou a chance to step intothe middle of new.public class UseADuck {public static void main (String[] args) {Duck d = new Duck() ;}f-- !h;s ~lJs in D(.orutr-lAl!or. t: lI.lk~% java UseADuckQuackA constructor lets you Jump Into the middleof the object creation step-into the middleofnew. Can you imagine conditions wherethat would be useful? Which of these mightbe usefulin a Carclassconstructor, if the Caris part of a Racing Game?Check off the onesthat you came up with a scenario for.o Increment a counter to track how many objects ofthis class typehave been made.Assign runtime-specific state (data about what's happening NOW).o Assign values tothe object's important instance variables.o Get and save areference 10 Ihe object that's creating the new object.Add the object to an ArrayList.Create HAS-A objects.o(your idea here)242 chapter 9


constructors and gcInitializing the state of a new PuckMost people use constructors to initialize the state of an object.In other words, to make and assign values to the object'sinstance variables.public Duck ( ) {size = 34;}That's all well and good when the Duck class developer knowshow big the Duck object should be. But what ifwe want theprogrammer who is using Duck to decide how big a particularDuck should be?Imagine the Duck has a size instance variable, and you want theprogrammer using your Duck class to set the size of the newDuck. How could you do it?Well, you could add a setSize() setter method to the class. Butthat leaves the Duck temporarily without a size*, and forces theDuck user to write twostatements-one to create the Duck, andone to call the setSize () method. The code below uses a settermethod to set the initial size ofthe new Duck.public class Duck {int size; 'f-- iY\Sta\'lt..e ~aYiah\e}}public Duck() {System.out.println ("Quack") ; 'f-- t.oY\ShvLto'r}public void setSize (int newSize)size = newSize;}public class UseADuck {public static void main(String[] args){{ ~ set..t,eY ",et.'nodDuck d = new Duck () ; Tt--... i ~~r~'~ a bad thih hd. setSize (42) ; Ah~ i PO / ht ;1'1 ih~ l~ ~b~'iThe DlAtk is aI'1'1 hel'l "OlA' I~' lA with t /V~ aito KNOW ~hatD~ yihS 01'1 ih~ D:t aSi~!*,protess: Ol'le i lAtk lr~atioh is k-fAS~r*Instance variables do have a default value. 0 or0.0 for numeric primitives, false for booleans, andnull for references.to tall th~ Stt1~all ih~ tohSirlAtkiwo-pariUl-.ahd Oh~there]lU'H?Dumo ~uest19nsQ.: Whydo you need to writea constructor ifthe compilerwrites one for you?A: Ifyou need code to helpinitialize your object and getit ready for use,you'll have towrite your own constructor. Youmight, for example, be dependenton input from the userbefore you can finish makingthe object ready.There's anotherreason you might have to writea constructor, even if you don'tneed any constructor codeyourself. It has to do with yoursuperclass constructor, and we'lltalk about that in a few minutes.Q.: How can you tell a constructorfrom a method? Canyou also have a method that'sthe same name as the class?A: Java lets you declare amethod with the same name asyour class. That doesn't make ita constructor, though.The thingthat separates a method from aconstructor is the return type.Methods must have a returntype, but constructors cannothave a return type.0: Are constructors inherit~(hIfyou don't provide aconstructor but your superclassdoes, do you get the superclassconstructor instead of thedefault?A.: Nope. Constructors arenot inherited.We'll look at that injust a few pages.you are here), 243


initializing object stateUshtg the eenstruetor to it1itializeitMportat1t Pock state"If an object shouldn't be used until one ormore parts ofits state (instance variables) havebeen initialized, don 't let anyone get ahold ofa Duck object until you're finished initializing!It's usually way too risky to let someone makeandget a reference to-a new Duck object thatisn't quite ready for use until that someone rumsaround and calls the setSize() method. How willthe Duck-user even know that he's required to callthe setter method after making the new Duck?The best place to put initialization code is in theconstructor. And all you need to do is make aconstructor with arguments.size = duckSize;Let the user make a new Duckand set the Duck's size all inone call. The call to new.The call to the Duckconstructor.o\,,~ ~a'


constructors and gcMake it easy to ",ake a PucleJe sure you have a tlo..arg cOtldructorWhat happens ifthe Duck constructor takes an argument?Think about it. On the previous page, there's only oneDuckconstructor-and it takes an int argument for the sizeoftheDuck. That might not be a big problem, but it does make itharder for a programmer to create a new Duck object, especiallyif the programmer doesn't knot» what the size of a Duck shouldbe. Wouldn't it be helpful to have a default size for a Duck, sothat if the user doesn't know an appropriate size, he can stillmake a Duck that works?Imagine that you want Duck users to have TWO optlonsfor making a Duck-one where they supply the Ducksize (as the constructor argument) and one where theydon't specify a size and thus get your default Duck size.•You can't do this cleanly with just a single constructor.Remember. if a method (or constructor-s-same rules) hasa parameter, you must pass an appropriate argument whenyou invoke that method or constructor. You can'tjust say, "Ifsomeone doesn't pass anything to the constructor, then usethe default size", because they won't even be able to compilewithout sending an int argument to the constructor call. Youcould do something c1unkly like this:'p ubl i c class Duckint size;You really want TWO ways tomake a new Duck:public class Duck2int size;public Duck.2 () (II supply default sizesize;; 27;public Duck2 (int dUckSize) (/ / uae duckSiz8 parametersize'" duckSize;To make a Duck when you know the sIze:Duak2 d;; new Duck2(15):To make a Duck when you do not knowthe size:Duck.2 d2 "" new Duck2 () ;But that means the programmer making a new Duck object hasto knou: that passing a "0" is the protocol for getting the defaultDuck size. Pretty ugly. What if the other programmer doesn'tknow that? Or what if he really does want a zero-size Duck?(Assuming a zero-sized Duck is allowed . lfyou don't wantzero-sized Duck objects, put validation code in the constructorto prevent it.) The point is, it might not always be possibleto distinguish between a genuine "I want zero for the size"constructor argument and a "I'm sending zero so you'll giveme the default size, whatever that is" constructor argument.So this two-optlons-to-make-a-Duck Ideaneeds two constructors.One that takesan Int and one that doesn't. Ifyou hawmor« than one constructor In a dau,It means you have overloadedconstructors.you are here ~ 245


overloaded and default constructorsPoes""t the cotMpiler always",ake a "o-arg eonstrueterforyou? ~I,You might think that ifyou write onlya constructor with arguments, thecompiler will see that you don't have ano-arg constructor, and stick one in foryou. But that's not how it works. Thecompiler gets involved with constructormakingonlyifyou don't sayanything at allabout constructors.If you write a constructor thattakes arguments, and you stiliwant a no-arg constructor,you'll have to build the no-argconstructor yourself!As soon as you provide a constructor,ANY kind of constructor, the compilerbacks off and says, "OK Buddy, looks likeyou 're in charge ofconstructors now,"If you have more than oneconstructor In a class, theconstructors MUST havedifferent argument lists.The argument list includes the orderand types of the arguments. As long asthey're different, you can have morethan one constructor. You can do thiswith methods as well, but we'll get to thatin another chapter.246 chapter 9


Overloaded constructors means you havemore than one constructor in your class.To compile, each constructor must have adlffersnt argument IIstlThe class below is legal because all four constructors havedifferent argument lists. lfyou had two constructors that tookonly an int, for example, the class wouldn't compile. What youname the parameter variable doesn't count. It's the variabletype (int, Dog, etc.) and order that matters. You can have twoconstructors that have identical types, as long as the order isdifferent. A constructor that takes a String followed by an int, isnot the same as one that takes an int followed by a String.kr..o w th~ S'IU, Dlo-t ~Q\i.publ i c class Mushroom { . whc" 'jo'J. .r .L' ,.,.al:lit~ dOWl'-t kF>Ow i-t 'n. s ;)constructors and gcpublic Mushroom(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~tk t\l~ siupublic: Mushroom (boolean isMaqic) (. D\,I.-t dOWl nOWfpubl1C: Mushroom (boolean isMaqic, int size) }~~~ its:~it., AND 'f$ \{,.O'


overloaded constructors..class Duck {public static void main(String[] args) (d[O]Match the new Duck ()public class TestDuck {= new Duck():call with the constructorthat runs when that Duck is instantiated . We didthe easy one to get you started.int weight = 8;float density = 2. 3F;String n8I118 = "Donald";lonq[) feathers = {l,2,3,4,5,6}:boolean canFly = true:int airspeed = 22:Duck []d[l]d = newnew Duck(density, weight);d[2] = new Duck(name,d[3] = new Duck(canFly);d[4]d[S]feathers):new Duck(3.3F, airspeed):= new Duck(false);d[6] = new Duck (airspeed, density);int pounds = 6;float floatability = 2 . IF ;String name = "Generic";long[] feathers = {l,2,3,4,S,6,7};boolean canFly = true:int maxSpeed = 25;public Duck () (System.out.printin("type 1duck");public Duck(boolean fly) {canFly = fly;System.out.printin("type 2 duck"):public Duck(String n, long[] ~) (name = n:feathers = f;Syst&m.out.printin("type 3 duck"):public Duck(int w, float f)pounds = w;floatability = f;SysteJn.out.println("type 4 duck"):public Duck (float density, int IIIAX) {floatability = density:maxSpeed = max;SysteJn.out.println("type 5 duck") ;Q.: Earlier you said that It's good to have a no-argumentconstructor 50 that ifpeople call the no-arg constructor,we can supply default values for the "mlsslng narguments. But aren't there times when It's Impossible tocome up with defaults? Are there times when you shouldnot have a no-arg constructor In your class?.A..:You're right.There are times when a no-arg constructordoesn't make sense.You'll see this in the Java API-someclasses don't have a no-arg constructor.The Color class, forexample, represents a...color. Color objects are used to, forexample, set or change the color of a screen font or GUIbutton.When you make a Color Instance, that instance Isof a particular color (you know, Death-by-Chocolate Brown,Blue-Screen-of-Death Blue, Scandalous Red,etc .), If youmake a Color object you must specify the color In some way.(We're using three Ints for RGB values here .We'll get intousing Color later, in the Swing chapters.) Otherwise, whatwould you get? The Java API programmers could have decidedthat if you call a no-arg Color constructor you'll get alovely shade of mauve. But good taste prevailed.If you try to make a Color without supplying an argument:Color c; new Color();The compiler freaks out because It can't find a matching 00­arg constructor in the Color class.Color c; new Color(3,45,200);248 chapter 9


constructors and gcNattoreview: four thittQs torelHelHber about eonstrueters•A constructor is the code that runs whensomebody srrys new on a class typeDuck d = new Duck() ;•A constructor must have the same nomeas the class , and no return typepublic Duck(int size) { }•If you don't put a constructor in your class,the compiler puts in a default constructor.The default constructor is alwrrys a no-argconstructor.public Duck () { }•You can have more than one constructor in your class,as long as the argument lists are different. Havingmore than one constructor in a class means you haveoverloaded constructors.public Duck () {public Duck(int size) { }public Duck(String name)public Duck (String name, int size) { }DoIng all the Brain Barbells has been shown 10oreduce a 42% increase inneuron size. And you know what they say, "8lg neurons.. '-What about 5uperclasses?When you make a Dog,should the Canineconstrudor run too?Ifthe superclass is abstract,.should it even have aconstrudor?We'll look at this on the nextfew pages, sostop now andthink about the implicationsofconstructors and superclasses.dfim~~esti9nsQ.: Do constructors have to be public?A: No. Constructors ca n be public,private, or default (which means no accessmodifier at all).We'll look more at defaultaccess in chapter 16 and appendix B.Q.: How could a private constructorever be useful? Nobody could ever call It,so nobody could ever make a new objectlA..: But that's not exactly right. Markingsomething private doesn't mean nobodycan access It,it Just means that nobodyoutside the class can access it. Bet you'rethinking "Catch 22': Only code from thesame class as the class -witb -private-constructorcan make a new object from thatclass, but without first mak ing an object,how do you ever get to run code from thatclass in the first place7 How do you ever getto anything in that class? Patience grasshopper.We'll get there in the next chapter.you are here ~ 249


space for an object's superclass partsWaif a tMI"ute... we "ever UIP talk aboutsuperclasses and htherita"ce and how that allfits I" with constructors.Here's where it gets fun. Remember from the last chapter, the part where we looked atthe Snowboard object wrapping around an inner core representing the Object portionof the Snowboard class? The Big Point there was that every object holds notjust its oumdeclared instance variables, but also roerythingjrom its superclasses (which, at a minimum,means class Object, since every class extends Object) .So when an object is created (because somebody said new; there is no other way to createan object other than someone, somewhere saying new on the class type), the objectgets space for all the instance variables. from all the way up the inheritance tree. Thinkabout it for a moment... a superclass might have setter methods encapsulating a privatevariable. But that variable has to live somewhere. When an object is created, it's almost asthough multipleobjects materialize-the object being new'd and one object per eachsuperclass. Conceptually, though, it's much better to think ofit like the picture below,where the object being created has layers of itself representing each superclass,Foo 8;Intb:Inlc;Object&qualsOgelClassOhashCodeoIoStringQTSnowboardFooxFooyInlzlumOshradOgeWrQloseConlrolOObjett has IPlStar.tt varidbl~trlUpslAlclUd by atuss ",ethods.no~ il'lStal'lU Vc1\"'ic1bl~ c1yet\"'e..1~d when any 5lAbt.lass isiPlStantiaUd. (nest a.,.t;n't f.htREAL Objttt va\"'idbl~, but wedonIt ta.,.e what tht'f dl"'t sil'lUthey're eY>tc1ps-Jaud)Sroowboard also has ir-sidnttvariables 0+ its 0WJ\j so 1:.0 ...akea Snowboard objett wt ""eed5yc1tt .for the instante variables0+ both classes.-Asi~leobjet+' Oftthe heayThert is only ON~ objett 0"" the he.ly htye. ASnowboard objett. Bt..t it t.ontail'lS both theSl"oowboard fdrt.s of ihtl.f and the.Q!.iet.t Yc1rt.s o.fitself 1\11 il'lStar.te vc1l"'iables ~YOtll both dassts haveto be nC\"e.250 chapter 9


constructors and gcfhe role of superclass ecastruetersitt att obJecfs life.All the constructors in an object's inheritancetree must run when you make a new object.Let that sink in .That means every superclass has a constructor(because every class has a constructor), and eachconstructor up the hierarchy runs at the time anobject ofa subclass is created.Saying new is a Big Deal. It starts thewhole constructor chain reaction. And yes,even abstract classes have constructors.Although you can never say new on anabstract class, an abstract class is stilla superclass, so its constructor runswhen someone makes an instance ofaconcrete subclass.The super constructors run to buildout the superclass parts of the object.Remember, a subclass might inheritmethods that depend on superclass state(in other words, the value of instance variablesin the superdass). For an object to be fullyformed,all the superclass parts of itself must befully-formed, and that's why the super constructormust run. All instance variables from every classin the inheritance tree have to be declared andinitialized. Even if Animal has instance variablesthat Hippo doesn't inherit (if the variables areprivate, for example), the Hippo still depends onthe Animal methods that use those variables.When a constructor runs, it immediately calls itssuperclass constructor, all the way lip the chainuntil you get to the class Object constructor,On the next few pages, you'll learn how superclassconstructors are called, and how you can callthem yourself. You'U also learn what to do if yoursuperclass constructor has arguments!OblectI"AnImal-~fHIDDOA new Hippo object also IS-A Animaland IS-A Object. If you want to make aHippo, you must also make the Animaland Object parts of the Hippo.This all happens In a process calledConstructor Chaining.you are here. 251


object constructionMaklt1Q a Hippo ttteat1s tMakit1Q theAt1hMal at1d Object parts too...public class Animal {public AnimAl () (System.out.p1:'intln("Maldllg an Animal");public class Hippo axtands Animal (public Hippo () {System.out.printin("Making a BippoH) ;What's the real output? Given thecode on the left , what prints outwhen you run TestHippo? A or 87(the answer Is at the bottom of the page)A~% java TestHippoStarting...Making an AnimalMaking aHippopublic class T8StBippo {public static void main (String[] args)System. out .p r i ntln ("Starting. .. ") ;Hippo h .. new Hippo () ;B~% java TestHippoStarting . . .Making aHippoMaking an Animal• Code from anotherclass says newHippo () and theHlppoQ constructorgoes into a stackframe at the top ofthe stack.... Hlp~ invokesthe superclassconstructor whichpushes the AnlrnalOconstructor onto thetop of the stock.• AnlmolO invokesthe superclassconstructor whichpushes the Object()constructor ontothe top of the stock.since Object is thesupercloss of Animal.@ ObjectO completes,and its stack frameis poppedoff thestock. Execution goesback to the AnlmolOconstructor, andpicks up at the linefollowing Animal'scall to its superclossconstructorlSJys94SlUij 19~1 JOPnJlsuCl:llew lUV' 91.11 S.l1lnq ' IS J ~ pe~O!IU! &1 JOlOfIJlSUOO Oodd!H e41 'd 'eue ISJ~ 9lU252 chapter 9


constructors and gcHow do you lnveke a superclass cOMstructot1You might think that somewhere in, say,a Duck constructor,ifDuck extends Animal you'd call Anirnalj). But that's nothow it works:public class Duck exttmds Animal {int size;public Duck(int newSize) {1(,~t>~ --4- Animal () i ~ NOI ti: .size = newSize; . hl~ 's lIot Ie II} ~.}The only way to call a super constructor is by calling superi),That's right-super() calls the super consIn.tctor.What are the odds?public class Duck extends Animal {int size;public Duck(int newSize) {super (); ~(-~size = newSize;A call to suPer() in your constructor puts the superclassconstructor on the top of the Stack, And what do youthink that superclass constructor does? Calls its superclassconstructor. And so it goes until the Object constructor ison the top of the Stack, Once Object() finishes, it's poppedoffthe Stack and the next thing down the Stack (thesubclass constructor that called Objul(») is now on top.That constructor finishes and so it goes until the originalconstructor is on the top of the Stack, where it can nowfinish,And how is it that we'vegotten away withoutdoing it?You probably figured that out,Our good friend the compilerputs in a call to super() If youdon't.So the complier gets involved inconstructor-making in two ways:


object lifecycleCatt the child exist beforethe parents?Ifyou think of a superclass as the parent to the subclass child,you can figure out which has to exist first, The superdass partsofan object have to beJUUy-jormed (completely built) btfore thesubclass parts can be constructed. Remember,the subclass object might depend on things itinherits from the superclass, so it's importantthat those inherited things be finished. Noway around it. The superc1ass constructormust finish before its subclass constructor,Look at the Stack series on page 248 again,and you can see that while the Hippoconstructor is the first to be invoked (it'sthe first thing on the Stack), it's the last oneto completeI Each subclass constructorimmediately invokes its own superclassconstructor, until the Object constructoris on the top of the Stack, Then Object'sconstructor completes and we bounceback down the Stack to Animal'sconstructor. Only after Animal's constructor completesdo we finally come back down to finish the rest of the Hippoconstructor. For that reason:The call to superO must be the first statementIn each eenetrueterr'Possible constructors for class Boopo public Boop () {super () ;o public Boap ( ) (I0' public Boop(int i)size '" i;f-~--0' public Boop (int i) (sup&r() ;size = i ;}o public Boop (int i) ( BAD!! Thi5 'VOlt 'f. '4'otlt lOll,l>'jU1~ ~II to I 'T.Jy pc-I:super () ; /' ClllythiM I lIoP~) belo'o.lsize = i; .1, t-ill txp/·(;'.l' [It..J e 5e."There's an exception to this rule: you'lileam It on page 252.254 chapt er 9


constructors and gcSuperclass eoastrueters with argUtMettfsWhat ifthe superclass constructor has arguments? Can you pass something in tothe super() call? Ofcourse. Ifyou couldn't. you'd never be able to extend a classthat didn't have a no-arg constructor, Imagine this scenario: all animals have aname. There's a gelName() method in class Animal that returns the value of thename instance variable. The instance variable is marked private, but the subclass(in this case, Hippo) inherits the getName() method. So here's the problem:Hippo has a getName() method (through inheritance), but does not have the nameinstance variable. Hippo has to depend on the Animal part of himself to keep thename instance variable, and return it when someone calls geLNa1T/~() on a Hippoobject. But ... how does the Animal part get the name? The only reference Hippohas to the Animal part ofhimself is through supert), so that's the place whereHippo sends the Hippo's name up to the Animal pan of himself, so that theAnimal part can store it in the private n~me instance variable.Animalprivate String nameAnimal(StTing n)String getNameOTHippopublic abstract class Animal {private String name; ~ All al'li",al s (i"dwii,,~slobdas.ses) hall' a "a",epublic String getName () (~~ 9~k "'rl::~odreturn name; Illppo illherib ihaiHlppo(String n)[other Hippo-specificmethods]public Animal(Stringname = theName;public class Rippo extends Animal (public class MakeHippo (public static void main(StJ:ing[] args) ( NJake d IliHippo h = new Bippo("Buffy"); ~ Il


calling overloaded constructorslt1vokh,g Ot1e overloaded cot1structorfro", at10therWhat ifyou have overloaded constructors that, withthe exception of handling different a.Tg1l!l1ent types,all do the same thing? You know that you don't wantduplicate code sitting in each of the constructors (painto maintain, etc.), so you'd like to put the bulk oftheconstructor code (including the call to super()) in onlyom of the overloaded constructors. You want whicheverconstructor is first invoked to call The Real Constructorand let The Real Constructor finish thejob ofconstruction. It's simple:just say this(). Or this(aString).Or this(27, x). In other words. just imagine that thekeyword this is a reference to the current objectYou can say thist) only within a constructor. and it mustbe the first statement in the constructor!But that's a problem. isn't it? Earlier we said thatsuper() must be the first statement in the constructor.Well, that means you get a choice.Every constructor can have a call to super()or thlsO, but never bothlclass Mini extends Car (Use this\)-to catt aconstructor trom anothero-vertoaded constructor intl,e saute ctas s.Tl,e caU to this\)can be used only in acondl'ueto1', and must hethe tirst statement in a-constructor.1\. constructor can \\ave acatt to sUfel'O ott thisO,llut nevel' \loth!Color color; n, YIO-ay~ t.o\'\Stvl>Lttx dlies a d'~ il",lt. ColO'/" d"public Mini () { ~s tnt ol/CY'\oadtd Realthis (Color. Red) ; {----'" Col\3.~-\:.O'I" (~t OJIt that) taIls SIIYcY(»'public Mini (Color c)8uper("Mini"); l-(----..color = c;JJ more initializationrthi5(COIor.Re~) ;~super (size); ~ WOl'l'i '4IO\"'k.!! eall'i haveslJ.r cy () a"d thisO ;1'1 the sa...elOl'l5tn.tt:or, bel41/.U they cad....lUt be the +il"'St stau....ent.public Mini (int size) (256 chapter 9


•constructors and gc~ YOIJr pencilSome ofthe constructors In the SonOOoo class will notcompile. See ifyou can recogn lze which constructors arenot legal. Match the compiler errors with the SonOfBooconstructors that caused them, by drawing a Iine from thecompiler error to the "bad"constructor.public class Boo (public Boo(int i) I ~public Boo (String s) (public Boo(Strlng 8, int i) { }II Malee i-/; SiitleI Roses Ore red. vYou,pa,en~ Ci'Iolets areblue.Th omen,s, It':, e superc/ass r ay befo,eyouI formed b ~ parts ofan ob ' ., elOTe th lJectmuexist. Just I'k e new sUbc/as sr be fU/ly_been b I e there's no w s Object canOrn before You ayYou could hr parents.aveclass SonOfBoo ext:4ilnds Boo (public SonOfBoo()super ("boo") ;public SonOfBoo(int i) (super ("Fred") ;public SonOfBoo(Strinq s) {supar(42);public SonOfBoo(int i, String s) {}public SonOfBoo(Strinq 8. String b, String c) (8upar(a,b);public SonOfBoo(int i, lnt j) (supar("man", j);public SonOfBoo(int i, int x, lnt y) {super(i, "star");you are here . 257


object lifespanNow we know how an object Is boyn,but how IOt1g does an object live?An object's life depends entirely on the life of referencesreferring to it- If the reference is considered "alive", theobject is still alive on the Heap. Ifthe reference d.ies(and we'll look at what that means injust a moment) . theobject wiU die .So if an object's life depends on the referencevariable's life, how long does a variable live?That depends on whether the variable is a localvariableor an instancevariable. The code below shows the life ofalocal variable. In the example, the variable is a primitive.but variable lifetime is the same whether it's a primitiveor reference variable.public class TeatLifeOnepublic void read() {r ,int s '" 42; ~(__-- .s ;s oSlosleep () ;dpublic void sleep() {s = 7;J


constructors and gcThe difference between life andscope for local variables:LifeA local variable is alioeas long as its Stackframe is on the Stack. In other words,until the method. completes.ScopeA local variable is in scope only within themethod in which the variable was declared.When its own method calls another, thevariable is alive, but not in scope until itsmethod resumes. You can use a variable onlywhen it is in scope.public void doStuff(}boolean b "" true;go (4) ;}publio void go(int x) {int z .. x + 24;crazy() ;/ / imagine more code herepublic void crazy()char c III 'a';o doStuff() goes onthestack. Variable 'b' isalive andInscope.o goO plops ontop oftheStack. 'x' and'tarealiveand in scope,and 'b' Isalivebutnofin scope.While a local variable is alive, its state persists.As long as method doStuffO is on the Stack, forexample, the 'b' variable keeps its value. But the'b' variable can be used only while doStuffO'sStack frame is at the top. In other words, you canuse a local variable onlywhile that local variable'smethod is actually running (as opposed towaiting for higher Stack frames to complete).e crazyO Is pushed ontotheStack, with 'c' nowalive andInscope. Theotherthree variablesarealivebutout ofscope.o CfilZ'/Ocompletes andIs popped off theStack,so '(j is out of scopeanddead, When goOresumes where It leftoff, 'x' and 'z' are bothaliveand back In scope.Variable 'b' 16 stili alivebutout of scope (untilgoO completes).you are here ~ 259


object lifecycleWhat about referettce variables?The rules are the same for primtives and references. A referencevariable can be used only when it's in scope. which means you can't usean object's remote control unless you've got a reference variable that'sin scope. The Teal question is,"How does variable life affect object life?"An object is alive as long as there are live references to it, Ifa referencevariable goes out ofscope but is still alive, the object it refers to is stillalive on the Heap. And then you have to ask... "What happens when theStack frame holding the reference gets popped off the Stack at the endof the method?"Ifthat was the only live reference to the object, the object is nowabandoned on the Heap. The reference variable disintegrated withthe Stack frame, so the abandoned object is now, officially, toast. Thetrick is to know the point at which an object becomes eligibleforgarbagecollection:Once an object is eligible for garbage collection (Ge), you don't haveto worry about reclaiming the memory that object was using. Ifyourprogram gets low on memory, GC will destroy some or all ofthe eligibleobjects, to keep you from running out of RAM. You can still run out ofmemory, but not before all eligible objects have been hauled off to thedump. Your job is to make sure that you abandon objects (i.e, makethem eligible for GC) when you're done with them, so that the garbagecollector has something to reclaim. lfyou hang on to objects, GC can'thelp you and you run the risk ofyour program dying a painfulout-of-memory death.Anobject's life has novalue. no meaning. norem. unless aomebodyhas a reference to it.n you can't get to it.you can't ask itto doanything and it'sjUst abigfat waste of bit&.Buti' anobject isunreachable. theGarbageCoUet:t« willf1gure that out.. Sooneror later. thatobject'8gom'down..An object becomeseligible for GC whenits last live referencedisappears.Three ways to get rid of an object's reference:G) The reference goes out of scope, permanently L, , dies a~void go () { ~t~t:YtrLt z.} Life z = new Life () ;~ e.-4 J ",dhod® The reference is assigned another object . ha.-4~~ ~ o'o~el.t. ,s 0 , -toLife z = new Life (); , / the ~;y-S, _YO",,,,e&z '" new Life () ; ~ "'''''' z.;1 yeyY-;,a TIt'" o\:>jtt.t..'3' The reference is explicitly set to null L' "L~~ed\:!,J ~ t.do" tt.'{. \1 .. (1


constructors and gcObject-killer #1Reference goesout of scope,permanently.public class StaclcR.ef {public void foof() (barf () ;public void barf() (Duck d : new Duck() ;IIIIIIIIo loof(J Is pushed ontotheStack, no variables aredeclared.o barf(J Is pushed ontotheStack, where It declaresa reference variable, andcreates a new objectassignedto thatreference.The objectIs created onthe Heap, andthe referenceIsalive andInscope.e bartO completes andpopsoffthe Stack. Its framedisintegrates, so 'd' Is nowdead andgone. Executionreturns to 100'0, but 100(0can't use'd' .Uh-oh. TIll: 'd' variablew~t d'Na,! 'Nne" th~ bar·WSUlk t ..a",e 'Na~ blo'Nfto-f.f the stalk, so tht Dutltis aba"dClr\td. ~arba~t:­lollak bait.yo u are here ~ 261


object lifecycleObject-killer #2Assign the referenceto another objectpublic class ReRef {Duck d = new Duck();public void qo() {d = naw Duck () ;Dude,all youhad to do was resetthe r~ference.Guessthey didn't have memorymanagement back then.o oThe new Du.tk. ~oes on t he !leaf, .... e~et"tnLecib~ 'ei', ~nte '0' is cln inSt.a!'lte variable, tneD",-\I. will live as \Ol'l~ as ~e ReRt.t obit.d:.that il\5-t.al'ltiaW it is alive. l.()\less- ..'£1' is as.si~\'IeO a !'lew Du.t\l. objt.tt, leav\!'I~ theori~i\'lal ah'st) DlAl.k objed:. ahal'loont.o. Thattirst D",-k is 1\0,", as ~ood as dead..262 chapter 9


constructors and gcObject..killer #3Explicitly set thereference to nullpublic class ReRef {Duck d == new Duck () ;public void gal) (d == nul.l:The meaning of nullWhen you set a reference to nuJ.l, you'redeprogramming the remote control.In other words, you've got a remotecontrol, but no TV at the other end. A nullreference has bits representIng 'null' (wedon't know or care what those bits are,aslong as theNM knows) .Tee ~ D\oll.k ~oes ~ th~ \-ledf' y~.ftytyo,Udb'j 'd'. Sil'\U 'd' is a" 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-··If you have an unprogrammed remotecontrol, In the real world, the buttons don'tdo anythlng when you press them. ButIn Java,you can't press the buttons (I.e.use the dot operator) on a null reference,because the NM knows (this Isa runtimeIssue,not a complier error) that you'reexpecting a bark but there's no Dog thereto do ItlIfyou use the dot operator ona null reference. you'll get aNullPolnterExceptlon at runtime. You'lllearnall about Exceptions In the RiskyBehavior chapter.you are here ~ 263


object lifecycleFireside ChatsTonight'g Talk: An instance variable anda looal variable discuss life and death~4 (wi~ remarkable civilliy)~Instance VariableI'd like to go first, because I tend to be moreimportant to a program than a local variable.I'm there to support an object, usuallythroughout the object's entire life. After all,what's an object without slate? And what isstate? Values kept in instana variables.No, don't get me wrong, I do understand yourrole in a method, it's just that your life is soshort. So temporary. That's why they call youguys "temporary variables".My apologies. I understand completely.I never really thought about it like that. Whatare you doing while the other methods arerunning and you're waiting for your frame tobe the top of the Stack again?Local VariableI appreciate your point ofview, and I certainlyappreciate the value of object state and all,but I don't want folks to be misled. Localvariables are really important. To use yourphrase, "After all, what's an object withoutbehaviorr" And what is behavior? Algorithmsin methods. And you can bet your bits there'llbe some localvariables in there to make thosealgorithms work.Within the local-variable community, thephrase "temporary variable" is consideredderogatory. We prefer "local", "stack" , "automatic",or "Scope-challenged",Anyway, it's true that we don't have a longlife, and it's not a particularly good life either.First, we're shoved into a Stack frame withall the other local variables, And then, if themethod we're part ofcalls another method,another frame is pushed on top ofus. And ifthat method calls another method... and so on.Sometimes we have to wait forever for all theother methods on top ofthe Stack to completeso that our method can run again.Nothing. Nothing at all. It's like being instasis-that thing they do to people in sciencefiction movies when they have to travel longdistances. Suspended animation, really. Wejust sit there on hold. As long as our frame isstill there, we're safe and the value we holdis secure, but it's a mixed blessing when our .264 chapte r 9


constructors and gcIDstance VariableWe saw an educational video about it once.Looks like a pretty brutal ending. I mean,when that method hits its ending curly brace,the frame is literally blownoffthe Stack! Nowthat'sgotta hurt.I live on the Heap, with the objects. Well, notwith the objects, actually in an object. Theobject whose state I store. I have to admit lifecan be pretty luxurious on the Heap. A lot ofus feel guilty, especially around the holidays.OK, hypothetically, yes, if I'm an instancevariable of the Collar and the Collar getsGC'd, then the Collar's instance variableswould indeed be tossed out like so many pizzaboxes. But I was told that this almost neverhappens.They let us drink?Local Variableframe gets to run again. On the one hand, weget to be active again. On the other hand, theclock starts ticking again on our short lives.The more time our method spends running,th e closer we get to the end of the method.We all know what happens then.Tell me about it. In computer science they usethe term poppedas in "the frame was poppedoffthe Stack". That makes it sound fun, ormaybe like an extreme sport. But, well, yousaw the footage. So why don't we talk aboutyou? I know what my little Stack frame lookslike, but where do you live?But you don't always live as long as the objectwho declared you, right? Say there's a Dogobject with a Collar instance variable. Imagineyou'rean instance variable of the Collarobject,maybe a reference to a Buckle or something,sitting there all happy inside the Collarobjectwho's all happy inside the Dogobject. But...what happens if the Dog wants a new Collar,or nulls out its Collar instance variable? Thatmakes the Collar object eligible for GC. So...if you 're an instance variable inside the Collar,and the whole Collaris abandoned, whathappens to you?And you believed it? That's what they say tokeep us motivated and productive. But aren'tyou forgetting something else? What if you 'rean instance variable inside an object, and thatobject is referenced only by a localvariable? IfI'm the only reference to the object you're in,when I go, you're coming with me. Like it ornot, our fates may be connected. So I say weforget about all this and go get drunk whilewe still can. Carpe RAM and all that.you are here ~ 265


exercise: Be the Garbage ColleclorBE the Garbage CtJTIectorWlnch 01' the lines ofcode onthe rigbt, if addedto& class on the leftat point A, would eaaseexactly one additional object to he eliglhle for theGarbage Collector? (AsSUlJle that point A(licallmore methods) will execute for a long time, giving theGarbage Collector time to do its stu1f.)public class GC (public static GC doStuff()GC newGC = new GCI)idoStuff2(newGC);return newGCi1 copyGC = nulli2 gc2 = null;pUblic static void maln(String [1 args) (GC gel;GC gc2 = new GCI);GC gc3 = new GCI) ;GC ge4 = gc3jgel = doScuff();3 newGC = gc3;4 gel = null;5 newGC = null;6 gc4 = null;II call more methods7 gc3 = gC2i8 gel = gc4ipublic static void doStuff2(GC copyGC)GClocalGC9 gc3 nu Ll.;266 chapter 9


constructors and gcclass Bees {Honey I] beeHAj}In this code example, several new objects are created.Your challenge is to find the object that is 'most popular;i.e.the one that has the most reference variables referringto it. Then list how manytotal references there are forthat object, and what they are! We'll start by poi nti ng autone of the new objects, and its reference variable.Good Luck!class Raccoon {Kit XiBoney rh;}class Kit (Boney kh;}class Bear {Boney hunnYi}pUblic class Honey {public static void main(String [] arqs) {Roney honeyPot = new HoneY()iBoney I] ha = {honeyPot, honeyPot, honeyPot, honeyPot};Bees bl = new Bees():bl. beeRA = ha;Bear [) ba = new HearlS];for (int x=O; x < 5; x++)}}ba!x] = new Hear();ba[x).hunny = honeyPot;}Kit k = new Kit()ik.kh '" honeyPot;Raccoon r '" new Raccoon()i~r.rh = honeypot:r.k '" Xjk = null;II end of mainHere's a new~ Raccoon objectlHere's Its referencevariable ·r'.you are here ~ 267


puzzle: Five Minute Mystery"We've run the simulation four times, and the main module's temperature consistentlydrifts out of nominal towards cold", Sarah said, exasperated. "We installed the new temp-bats lastweek. The readings on the radiator bats, designed to cool the living quarters, seem to be withinspec. so we've focused our analysis on the heat retention bats, the bats that help to warm the quarters."Tom sighed, at first it hadseemed that nano-technology was going to really put them aheadof schedule. Now, with only five weeks left until launch. some of the orbiter's key life supportsystems were still not passing the simulation gauntlet."What ratios are you simulating?", Tom asked."Well if I see where you're going, we already thought of that", Sarah replied. "Missioncontrol will not sign off on critical systems if we run them out of spec . We arerequired to run the v3 radiator bat's SimUnilS in a 2:1 ratio with the v2 radiator'sSimUnits", Sarah continued. "Overall, the ratio of retention bots to radiator bats issupposed to run 4:3.""How's power consumption Sarah?", Tom asked. Sarah paused. "Well that'sanother thing, power consumption is running higher than anticipated. We 've got a teamtracking that down too, but because the nanos are wireless it's been hard to isolate the powerconsumption of the radiators from the retention bats ." "Overall power consumption ratios", Sarahcontinued. "are designed to run 3:2 with the radiators pulling more power from the wireless grid.""OK Sarah", Tom said "Let's take a look at some of the simulation initiation code.We've got to find this problem, and find it quick!"import java.util.·;class V2Radiator {V2Radiator(ArrayList list) (for(int ~O; x


constructors and gcrIVe-MInuteMysteryC


object Iifecycle1 copyGC = null; No - this line attempts to access a variablethat is out of scope.2 ge2 =' null; OK - 9c2 was the only reference variablereferring to that object.3 newGC =' gc3; No - another out of scope variable .G.C.4 gel = null; OK - gel had the only reference becausenewGC is out of scope.5 newGC = null; No - newGC is out of scope.6 gc4 null; No - gc3 is still referring to that object.7 gc3 gc2; No - 9c4 is still referring to that object.8 gcl gc4; OK- Reassigning the only reference tothat object.9 gc3 null; No - gc4 is still referring to that object.It probably wasn't too hard to figure out that the HoneyobJectfirstreferredto bythe honeyPot variableisbyfarthe most -popular'object Inthis class. Butmaybe it was a littletrickier to see that allof the variablesthatpoint from the code to the Honeyobject referto the same ob}edl Thereare a total of 12active referencestothis object right before the maln() method completes. The Ic.kh variableis valid fora while,but kgets nulledat the end. Sincer.kstili refersto the KItobject, r.k.kh (although neverexpllcitydeclared),refersto the object!TI1----Jpublic class Boney {public static void main(Striog [) args) {Boney honeyPot ~ new Boney();Boney [) ha = {noneyPot, honeypot,LhoneyPot, honeYPot};Bees bi m new Beesl);bl.beeHA = ha;Bear [) ba = new BearIS];for (int x-OJ x < 5; x++) {ba{x] = new Bear():ba[xj.hunny c honeyPot;( endsup null )1---}Kit k = new Kit();k.kh => honeyPot;Raccoon r • new Raccoon();r.rh = honeyPot:r.k - k;k • null;}} II end of main270 chapter 9


constructors and geTom noticed that the constructor for the V2Radiator class took anArrayList. That meant that every time the V3Radiator constructor was called,it passed an ArrayList in its supert) call to the V2Radiator constructor. Thatmeant that an extra five V2Radiator SimUnits were created. If Tom was right,total power use would have been 120, not the 100 that Sarah's expected ratiospredicted.Since all the Bot classes create SimUnits, writing a constructor forthe SimUnit class, that printed out a line everytime a SimUnit was created ,would have quickly highlighted the problem!you are here 271


10 numbers and staticsNumbers MatterDo the Math. But there's more to working with numbers than Just doing primitivearithmetic. You might want to get the absolute value of a number, or round a number, or flndthe larger of two numbers. You mig ht want your numbers to prl nt with exactly two decImaIplaces,or you might want to put commas Into your large numbers to make them easier to read.And what about working with dates?You might want to print dates In a variety of ways,or evenmanipulate dates to say things like,"add three weeks to today's date" And what about parsinga String Into a number? Or turning a number into a String? You're In luck. The Java API Is full ofhandy number-tweaking methods ready and easy to use. But most of them are static, so we'llstart by learning what it means for a variable or method to be static, including constants InJava-static final variables.this IS a new chapter 273


Math methodsMArH tMethods: as close as you'llever get to a globa/tMethodExcept there's no global an),lhinginJava. But think aboutthis: what ifyou have a method whose behavior doesn'tdepend on an instance variable value . Take the round()method in the Math class, for example. It does the samething every time-rounds a floating point number(theargument to the method) to the nearest integer. Everytime. lfyou had 10,000 instances of class Math, and ranthe round(42.2) method, you'd get an integer value of42. Every time. In other words, the method acts on theargument, but is never affected by an instance variablestate. The only value that changes the way the round()method runs is the argument passed to the methodlDoesn't it seem like a waste of perfectly good heap spaceto make an instance ofclass Math simply to run theround() method? And what about other Math methodslike mint), which takes two numerical primitives andreturns the smaller of the two. Or maxj). Or abst), whichreturns the absolute value of a number.These methodsnever we instance variable values. In fact theMath class doesn't haveany instance variables. So there'snothing to be gained by making an instance ofclassMath. So guess what? You don't have to. As a matter offact. you can 't,Methods in the.Math classdon't use any mstancevariable values. Ami becausethe methods are 'static',you don't need to have anillstance of.Math. All youneed is the Math class.-int x - Math.round(42.2) ;int y = Math.min(56,12) iint z = Math.abs(-343);If you try to make an instance ofclass Math:Math mathObject = new Math () iYou'll get this error:274 chapter 10


numbers and staticsfhe differet1ce betweeM regular(.,on-static) at1d static tttethodsJava is object-oriented, but once in a while you have a special case,typically a utility method (like the Math methods), where there isno need to have an instance of the class. The keyword static letsa method run without any instance o/the class. A static method means"behavior not dependent on an instance variable, so no instance/objectis required.Just the class."regular (non-static) methodpublic class Soog ( a '.~'o\( "a\~ ~tt.L~I~,.{,e ~ ....." \ .J)Strine} title; ~ the Otha"\~ cJ tht yartltIepublic Sone}(String t) ".~~o


static methodsCall a static method using aclass nameMathmlnOmaxOabsO.min (B8, 86) ;Call a non-static method using areference variable nameV--Song t2 = new Song() ;.play () ;What it tHea.,s to have aclass with static Ittethods.Often (although not always), a class with staticmethods is not meant to be instantiated. In Chapter8 we talked about abstract classes, and how markinga class with the abstract modifier makes itimpossible for anyone to say 'new' on that class type.In other words, it's impossible to instantiate an abstractclass.But you can restrict other code from instantiatinga non,,·abstract class by marking the constructorprivate. Remember, a method marked private meansthat only code from within the class can invokethe method. A constructor marked private meansessentially the same thing-only code from withinthe class can invoke the constructor. Nobody cansay 'new' from outside the class. That's how it workswith the Math class, for example. The constructoris private, you cannot make a new instance ofMath.The compiler knows that your code doesn't haveaccess to that private constructor.This does not mean that a class with one or morestatic methods should never be instantiated. In fact,every class you put a mainO method in is a class witha static method in itlTypically, you make a main 0 method so that youcan launch or test another class, nearly always byinstantiating a class in main, and then invoking amethod on that new instance.So you're free to combine static and non-staticmethods in a class, although even a single non-staticmethod means there must be S~ way to make aninstance of the class. The only ways to get a newobject are through 'new' or deserialization (orsomething called theJava Reflection API that wedon't go into). No other way. But exactly WM says newcan be an interesting question, and one we'Ulook ata little later in this chapter.276 chapter 10


numbers and staticsStatic tMethods caM'f use t1ot1 ...statle(instance) variables!Static methods run without knowing about any particularinstance of the static method's class. And as you saw onthe previous pages, there might not even beany instancesof that class. Since a static method is called using the class(Math.random()) as opposed LO an mstance reference (t2.playO),a static method can't refer to any instance variables of theclass. The static method doesn't know which instance's variablevalue to use.If you try to compile this code:public olass Duck ( y,[nit,'I'I 'D.,.t.~~~(f.e ~\1,.l. .private lnt size; ~ (public static void main (String[] arqs) ( ~System.out.println("SizfiIl of duck is " + size):1.( fh~e's d DlAlk onpublic void setsize(int 09) ~e):eap So"'ewhet-e, wesize = s; on ~ KI'IO'w dboc..i it}public iot getSize()return size;Ifyou trjto use aninStance variable frominside a static method.the compiler thitiks."I don't "know whichobject's mstance variableyou're talking about!"Ifyou have ten DuCKobjects on the heap. astatic method doesn't"know about any ofthem.You'll get this error:you are he re ~ 277


static methodsStatic tMethods cattJt use "ott"'statlcmethods.. either!What do non-static methods do? They usuaUy use instancevariable state tv affect the behavior ofthe method. A getName()method returns the value of the name variable. Whose name?The object used to invoke the getNameO method.This won't compile:public class Duck {private iot size;public void setsize(int s) {size = B;}public iot getsize()return size;Cdl!il\~ ~efs.~() .t.st~~ ih~vji:db'e-4JS; ~os)tpollesthe si . L J IU IA1l.sUI)UUI\le variabje.public static void main (Strinq[] args) (System.out.println(~Size is ~ + getsize()):Q: What If you try to call a non-staticmethod from a static method, but thenon-static method doesn't use any Instancevariables.WIll the compiler allowthat?A: No.The compiler knows thatwhether you do or do not use Instancevariables In a non-static method, you can.And think about the implications ...if youwere allowed to compile a scenario likethat, then what happens if in the futureyou want to change the implementationof that non-static method so that one dayIt does use an Instance variable? Or worse,what happens if a subclass overrides themethod and uses an Instance variable inthe overriding version?Q: Icould swear I've seen code thatcalls a static method uslng a referencevariable Instead of the class name.A: You can do that, but as your motheralways told you, "Just because it 's legaldoesn't mean it's good." Although It worksto call a static method using any instanceof the class,it makes for misleading (lessreadable)code.You can say,Duck d = new Duck():String[] s = {};d.main(s);Roses are red,bl mlateandknown to 00StCJtlcs cCJn'. seeinstCJnce variable stateThis code is legal, but the complier Justresolves It backto the real class anyway("01( d Is of type Duck, and malnO Is static,so I'll call the static malnO in classDuck").In other words, using d to Invoke main£)doesn't Imply that maln() will have anyspecial knowledge of the object that d Isreferencing. It's Just an alternate way toInvoke a static method, but the method Isstill static!278 chapte r 10


Static variable:value is the satHe for ALLi"sta"ces of the classImagine you wanted to count how many Duckinstances are being created while your program isrunning. How would you do it? Maybe an instancevariable that you increment in the constructor?class Duck {int duC](Count = 0;public Duck () {dUckCount++; .ll'l:",s wOIA1d I~ dlAl.ke- d 'WdYS ~td D k "i -&, J ~lhtil.tt WdS r...id/! ...eNo, that wouldn't work because duckCount is aninstance variable, and starts at 0 for each Duck. Youcould try calling a method in some other class, butthat's kludgey. You need a class that's got only a singlecopy ofthe variable, and all instances share that onecopy.That's what a static variable gives you: a value sharedby all instances ofa class. In other words, one valueper class, instead of one value per instance.numbers and staticspub11c Duck () ( Now if. will ~dUckCountH; ~j"'rbnbli:i tp) the DlAlk lIS c.ilh b"'tbet.i~ d~t.ot. "uls,Gild 'fiIIOrl'f bt ~i is sidfit~i.oO.public void lfetSlze (int s) (size = !!I;•public int qetslze ()return size;Duckyou are here ~ 279


static variablesStatic variables are shared.All instances 01 the sameclass share a single copy 01the static variables.instance variables: 1 per instancestatic variables: 1 per class~J:V Brain BarbellEarlier in this chapter, we saw that a privateconstructor means that the class can't be instantiatedfrom code running outside the class. In other words,only code from within the class can make a newinstance of a classwith a private constructor. (There'sa kind of chlcken-and-egg problem here.)What If you want to write a class In such a way thatonly ONE instance of It can be created, and anyonewho wants to use an instance of the class will alwaysuse that one, single Instance?280 chapter 10


numbers and staticshtitializhtg astatic variableStatic variables are initialized when a classis loaded: A class isloaded because thejVM decides it's time to load it. Typically,thejVM loads a class because sornebody's trying to make anew instance ofthe class, for the first time, or use a staticmethod or variable ofthe class. As a programmer. you alsohave the option of telling thejVM to load a class, but you'renot likely to need to do that. In nearly all cases, you're betteroffletting thejVM decide when to wad the class.And there are two guarantees about static initialization:Static variables in a class are initialized before any object of thatclass can be created.Static variables in a class are initialized before any static methodof the class runs.olass Player {static int playerCount ;:; 0;private String name;public Player(String n)n&IIl8 = n;playerCount++;All static variablesin a class areInitialized beforeany object ofthat class can becreated.public class PlayerTestDrive (public static void main (Strin'll] llrgs) (Syabam.out.println(Player.playerCount);Player one = new Player("Tiqer Wooda H ) ;Syst8m.out.println(Player.playerCount);\. Atuu a stitt Vjly',able j\


static final constantsstatic-fh1al variables are cot1stat1tsA variable marked finalmeans that-s-once initialized-it cannever change. In other words, the value ofthe static final variablewill stay the same as long as the class is loaded: Look up Math.PIin the API, and you'll find:public static final double PI = 3.141592653589793;The variable is marked public so that any code can access it.The variable is marked static so that you don't need aninstance ofclass Math (which, remember, you're not allowed tocreate).The variable is marked final because PI doesn't change (as far asJava is concerned).There is no other way to designate a variable as a constant, butthere is a naming convention that helps you to recognize one.Constant variable names should be in all caps!Initialize a Rnal static variable:• At the time you declQl"t It:ORpublic clulS ]1'00 (publ~c static final lot FCC_X = 25;~t.e tJ,e ~ . '\tj~} I/ariabl ""~ lor.vblt OPl~"'~ shOlJ.}d bdi-e ~)lb -~~i.lbt.lAPldc....,._. e all "pp& J so Ule. -~ $Cpal"'ab .l,f.d$C, ....,i~ all~ Ule 'worcit• In 0 static Inltfollzer:public class Bar {public IlltatiC final double BAR SIGN;If you don't give a value to a finol vorlablein one of those two places:public class Bar (public static final double BAR_SIGN;110 illi'b_}il4t;olllThe complier will catch It:


numbers and staticsfitlal iSKt just for staticvariables...You can use the keyword final to modify nonstaticvariables too, including instance variables.local variables, and even method parameters. Ineach case, it means the same thing: the value can'tbe changed. BUl you can also use final to stopsomeone from overriding a method or making asubclass.non-static final variablesclan Foo! ( 'f0!> t.'!,,'f, thd,,~e S'IUfinal Int size '" 3; f-- YI()Wfinal int whuffi.e;Foof () ( I.H'whuffie = 42; ~ \'\ow 'fo ... t


static and finalQ...: Astatic method can't access IInon-static variable. But can a non-statlcmethod access II static variable?A: Ofcourse.Anon-static method inaclass can always calla static method Intheclass or access a static variable of the class.Q...: Why would I want to make a classfinal1 Doesn't that defeat the wholepurpose of 007A: Yes and no.A typical reason formaking a class final Isfor security.Youcan't, for example, make a subclass of theString class.Imagine the havoc If someoneextended the String class and substitutedtheir own String subclass objects,polymorphically, where String objectsare expected. Ifyou need to count on aparticular Implementation of the methodsIna class,make the class final.Q...: Isn't It redundant to have to markthe methods final Ifthe class Isfinal?A: If the class Isfinal,you don't need tornarkthe methods final. Thinkabout It-Ifa class Isfinal It can never be subclassed,so none ofthe methods can ever beoverridden.On the other hand, If you dowant to allowothers to extend your class,and you wantthem to be able to override some, but notall,of the methods, then don't mark theclass final but go In and selectively markspecific methods as final.A final methodmeans that a subclass can't override thatparticular method.• Astatic method should be called using the classname rather than an object reference variable:Maoth . random () vs. myFoo . go ( )• Astatic method can be invoked without any Instancesofthe method's class on the heap.• Astatic method isgood for autility method that doesnot (and will never) depend on a particular Instancevariable value.• Astatic method is not associated with aparticularinstanee----only the c1ass---so Itcannol access anyInstance vanable values offts class. Itwouldn't knowwhich Instance's values to use.• Astatic method cannot access anon-static method,since non-static methods are usually associated withinstance variable state.• Ifyou have a class with only static methods, and youdo not want the class tobe instantiated, you can markthe constructor private.• Astatic variable isa variable shared byall membersofagiven class. There isonly one copy ofastaticvariable ina class, rather than one copy per eachindividual instance for instance variables.• Astatic method can access astatic variable.• To make aconstant in Java, mark a variable as bothstatic and final.• Afinal static variable must be assigned a value eitheratthe time it isdeclared, or in astatic initializer.static {DOG_CODE:: 420;}• The naming convention for constants (final staticvariables) Is to make the name aU uppercase.• A final variable value cannot be changed once Ithasbeen assigned.• Assigning a value to a final Instance variable must beeither at the time It Is declared, orinthe constructor.• Afinal method cannot be overridden.• Afinal class cannot be extended (subclassed).284 chapter 10


numbers and statics~ yoor pencilWhat's Legal?Given everything you've justlearned about static and final,which of these would compile?KEEP...RIGHT•public clll.Sl! 11'00static: int Xipublic: void go() (Systam.out.println{x) ;•publicclass F004BUtic final int x 12;public: void go() (Systam.out.println(x) ;•public c:lass Foo2 {int Xipublic static void go () (Syatem.out.println(x);•public: c1ass Foo5 (statio tiDal int X '" 12;public void go (final int x)System.out.println(x);•public class Foo3final int X ipublic: void go() (Syatem.out.println(x);•public class Foo6int x '" 12;public static void go(final int x) (SyatBm,out.println{xl;you are here) 285


Math methodsMath lItethodsNow that we know how staticmethods work, let's lookat some static methods inclass Math. This isn't all ofthem,just the highlights.Check your API for the restincluding sqrtf), tant), ceilf),floor'(), and asint).Math.random{)Returns a double between 0.0 through (butnot including) 1.0.double rl = Math. random 0 ;int r2 = (int) (Math.random() * 5);Math.absOReturns a double that is the absolute value ofthe argument. The method is overloaded, soif you pass it an int it returns an into Pass it adouble it returns a double.int x = Math.abs(-240); II returns 240double d = Math.abs(240.45); II returns 240.45Math.roundOReturns an int or a long (depending onwhether the argument is a float or a double)rounded to the nearest integer value.int x Math.round(-24.8f); II returns -25int y = Math.round(24.45f); II returns 24tRe"'e",bel"', .fl oa 'bn~Math.minOReturns a value that is the minimum of thetwo arguments. The method is overloaded totake ints , longs, floats, or doubles.int x = Math.min(24,240); II returns 24double y = Math.min(90876.5, 90876 .49);point lit el"'als al"'e ass"''''edto be do",bles "'nless yo", add t he '.f',II returns 90876.49Math.maxOReturns a value that is the maximum of thetwo arguments. The method is overloaded totake ints, longs, floats, or doubles.int x = Math.max(24,240); II returns 240double y = Math.max(90876.5, 90876.49); II returns 90876.5286 chapter 10


numbers and staticsWrappit1g a pritttifiveSometimes you want to treat a primitive likean object For example, in all versions ofJavaprior to 5.0, you cannot put a primitive directlyinto a collection like ArrayList or HashMap:int x :: 32;ArrayList list = new ArrayList();list. add (xl i ~Double'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. takes a" ,,,'t.. f"lYTiJ'f ~ L . ' t.iv )that. take objed:. ""t~ueJl(.t.s, fIO't. ~''''I es·There's a wrapper class for every primitive type,and since the wrapper classes are in the java.lang package, you don't need to import them.You can recognize wrapper classes becauseeach one is named after the primitive type itwraps, but with the first letter capitalized tofollow the class naming convention.Oh yeah, for reasons absolutely nobody on theplanet is certain of, the API designers decidednot to map the names exactly from primitivetype to class type. You'll see what we mean:BooleanChara~ter~ByteWatth 0IJ.t.... 'fprimitiveint~ objectWhen you need to treata primitive like an object,wrap it. Ii you're using anyversion of Java before 5.0,you'll Jo this when youneed to store a primitivevalue inside a collection likeArrayList or lIashMap...,.."1I~'feger o~fNote: the plchJre III \he top Is a chocolate In e roll wrapper. GetIt?WraPP6r? Some people think It looks like a baked potato. bill\hilt Wlll1ls100.you are here. 287


static methodsThis is stupid, You mean I can'tjust makean ArrayList of ints??i Ihaveto wrap every single frickin' one in a newInteger object, then unwrap it whenI tryto access that value in the ArrayList?That's a waste of t ime and an errorwaiting to happen..,Jefore Java 5:0, YOU had to do the work...-She's right. In all versions ofJava prior to 5.0, primitives were primitivesand object references were object references. and they were NEVERtreated interchangeably. It was always up to you, the programmer, to dothe wrapping and unwrapping, There was no way to pass a primitive to amethod expecting an object reference, and no way to assign the result ofamethod returning an object reference directly to a primitive variable----evenwhen the returned reference is to an Integer and the primitive variable isan int, There was simply no relationship between an Integer and an int,other than the fact that Integer has an instance variable of type int (to holdthe primitive the Integer wraps). All the work was up to you.An ArrayList of primitive intsWithout autoboxing (Java versions before 5.0) \J t,t '? 0 ~~ tau l.I l'lO"{.Arr L:rt.- (Rt",t",'ber, be oYt. ' ~ Db' c.h)pubLic void doNumsOldWay () { Malu al'l a~/p'2- all l\rYa~L.i~b ..n:r~ \i~b ~e '1feGi~~ t\o.t T 1 '~ArrayList listOfNumbers = new ArrayList();l. 1., ('l' L t.hl lise-,It add t\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 Ga" l..dst.int intone = ODe. intValue () ; t.h~ ObjtGt to al\ I"U~er .Fihd/ly y~ td"t t "out 0+ the Inu~. hI! pl"''''ltivt:'2BB chapter 10


Autoboxing: blurring the linebetween pritMitive and objectnumbers and staticsThe autoboxing feature added to Java 5.0 doesthe conversion from primitive to wrapper objectautomatically!Let's see what happens when we want to make anArrayList to hold ints.An ArrayList of primitive intsWith autoboxing (.Java versions 5.0 or greater)l1. L: t ok t'j\'e Il'lteCjer.public void doNumsNewWay() { Make al'l f\rra~ ISArrayList listOfNumbers-lnew ArrayList();listOfNumbers.add(3);JlASt add it!int num = listOfNumbers.get(O);":h':I:~~~~~e:;uto",atilallyul'lwraps (IAl'lbo~es)direli! to a :.lei"" ~o yo ~ lal'l ass i51'1 the int va/loeintVallA~() fr Itlve '~/IthOlAt havin5 to lall the....ethod 0\'1 the Inte5er objelt.AH:holA~h there is NOT a ",eihod il'l ArrayList.f01" add(iI'lV, the lon-piler does all the wrafpil'l5(bo)/,;n5) .for 'lOlA. 11'1 other words, there I"eall'l ISa\'l Il'Ite~el" objelt stored il'l the Al"l"a'll-ist. blAt'lOlA 5et to "pl"etend" that the ~l"a'lList takesints. cyOIA lan add both ints al'ld l\'Ite~ers to al'lA'f'l"a'lList.)Q.: Why not declare an ArrayList if you want tohold ints7A.: Because...you can't. Remember,the rule for generictypes is that you can specify only classor interface types, notprimitives. So ArrayList will not compile. But as you cansee from the code above, it doesn't really matter, since thecompiler lets you put ints into the ArrayList.ln fact,there's really no way to preventyou from putting primitivesinto an ArrayList where the type of the list is the type of thatprimitive's wrapper, if you're using a JavaS.D-compliant compiler,since autoboxing will happen automatically. So,you canput boolean primitives in an ArrayList and charsinto an ArrayList.you are here ~ 289


staUc methodsAufoboxit1Q works al",ost everywhereAutoboxing lets you do more thanjust the obvious wrapping andunwrapping to use primitives in a collection... it also lets you useeither a primitive or its wrapper type virtually anywhere one or theother is expected. Think about thatlFun with autoboxingMethod argumentsIf a method takes a wrapper type, youcan pass a reference to a wrapper ora primitive of the matching type. Andof course the reverse is true-if omethod takes (] primitive, you canpass in either a compatible primitiveor a reference to a wrapper of thatprimitive type..~ \1"''>1''ger Ol:i~ / intvoid takeNumber(Integer i) { }Return valuesIf a method declares a primitivereturn type, you can return either acompatible primitive or a referenceto the wrapper of that primitive type.And if a method declares a wrapperreturn type, you can return either areference to the wrapper type or aprimitive of the matching type.int giveNumber ()return X;Boolean expressionsAny place a boolean value is expected,you can use either an expression thatevaluates to a boolean (4 ) 2), or aprimitive boolean, or a reference to aBoolean wrapper.~/ean o~ftrue\1boolean~fif (bool) {System.out.println("true H ) ;290 chapter 10


numbers and staticsOperations on numbersThis is probably the strangest one-yes, youcan now use a wrapper type as an operandin operations where the primitive type isexpected. That means you can apply, say,the increment operator against a referenceto an Integer object!But don't worry-this is just a compiler trick.The language wasn't modified to make theoperators work on objects; the compilersimply converts the object to its primitivetype before the operation. It sure looksweird, though.Integer i =new Integer(42);i++;And tnat means you can also do things like:Integer j :; new Integer(5);Integer k :; j .. 3;i++iAssignmentsYou can assign either a wrapper or primitiveto a variable declared as a matching wrapperor primitive. for example, a primitive intvariable can be assigned to an Integerreference variable, and vice-versa-oreference to an Integer object can beassigned to a variable declared as an jntprimitive.~ your pencilWill this code compile? Will Itrun? IfII runs,what will ~do7Take your time and think about thisone; itbrings up an implication ofautoboxing thatwe didn't talkabout.You'll have to go to your compiler to findthe answers. (Yes. we're forclng you toexperiment, for your own good ofcourse.)public class TastBoxInteger i;int j;public static void main (String[] ll%gs) (T.stBox t ; new T.stBox() it.qo() ;}public void go 0j-iiSystam.out.println(j);Systam.out.println(i);you are here) 291


wrapper methodsJut waltl There1s ",ore! Wrappershave static utility tMethods too!Besides acting like a normal class. the wrappers have abunch of reaJly useful static methods. We','e used one inthis book before--lnteger.parselntO.The parse methods take a String and give you back aprimitive value .Converting a String to aprimitive value is easy:String s "" "2";int x = Inteqer.parseInt(s);double d = Double.parSeDouble("420.24 H ) ;You'll get a runtime exception:% java WrappersException in thread "main Njava .lang.NumberFormatException: twoat java.lang.lnteger.parselnt(Integer.java:409)at java .lang .lnteger.parselnt(Integer.java:458)at Wrappers.main(Wrappers.java:9)Every method orconstructor that parsesa String can throw aNumberFormatExceptlon.It's a runtime exception,so you don't have tohandle or declare It.But you might want to.(We'U talk about Exceptions in thenext chapter.)292 chapter 10


numbers and staticsAttd .,ow i" reverse... fuYttittg aprhMitive ttutMber ittto a StrittgThere are several ways to tum a number into a String.The easiest is to simply concatenate the number to anexisting String. Lh '+' o~cra~ is o...~y\oa~,dR,,,,t"'\'cr \. t. loadt.d oycratoo- as adouble d '" 42.5; ~i" Java (tht. _I'f t;- A",,.l.\.iWl~ .loot.d 1:.0 aStt·..o. c.oWlu\:.t.Ni"LOr.1 v'String doubleString = .... " + d; ~"J L -CO es Shi,,~i-r't.d.Sttl"!l Dt: 0'"double d = 42.5;String doubleStrinq '" Dcuble .toStrinq(d) ;\ A~t.I" . way to do it l.ISiJ\9 a st.;-bt"'ethod Ih dan Do..bkyou are here ~ 293


number formattingNutttber fortttatti.,gInJava, formatting numbers and dates doesn't have to be coupled with I/O. Thinkabout it. One ofthe most typical ways to display numbers to a user is through aGUI. You put Strings into a scrolling text area, or maybe a table. Ifformatting wasbuilt only into print statements, you'd never be able to format a number into a niceString to display in a GUI. BeforeJava 5.0, most formatting was handled throughclasses in thejava. text package that we won't even look at in this version of thebook, now that things have changed.In Java 5.0, theJava team added more powerful and flexible formatting through aFormatter class injava.util. But you don't need to create and call methods on theFormatter class yourself, becauseJava 5.0 added convenience methods to some ofthe I/O classes (including printf'(j) and the String class. So it's a simple matter ofcalling a static String.formatO method and passing it the thing you want formattedalong with formatting instructions.Of course, you do have to know how to supply the formatting instructions, andthat takes a little effort unless you're familiar with the frrintf() function in C/CH.Fortunately, even ifyou don't know printf() you can simply follow recipes for themost basic things (that we're showing in this chapter) . But you willwant to learnhow to format ifyou want to mix and match to get anythingyou want.We'll start here with a basic example, then look at how it works. (Note: we'll revisitformatting again in the I/O chapter.)Formatting a number to use commaspublic class TestFormats (public static void main (String[ ) args) {String s = String. format ("lis, d",System.out.println(s) ; ~1,000,000,000294 chapter 10


numbers and staticsFortMaffit1g decot1sfrucfed...At the most basic level, formatting consists of two main parts(there is more, but we'll start with this to keep it cleaner):__ Formatting InstructionsYou use special format specifiers that describe howthe argument should be formatted.e The argument to be formatted.Although there can be more than one argument, we'llstart with just one. The argument type can't be justanything... it has tobe something that can be formattedusing the format specifiers inthe formatting instructions.For example, if your formatting instructions specify afloating point number, you can't pass ina Dog oreven aString that looks like afloating point number.Do this...•format ("%, d",~to•this.1000000000);~i \Use these instructions... on this argument.What do these Instructions actually say?"Take the second argument to this method, andformat it as a decimal integer and insert commas."How do they say that?On the next page we'll look in more detail at what the syntax "%,d" actually means, but for starters, any time you see the percentsign (%) in a format String (which is always the first argumentto a formatf) method), think ofit as representing a variable,and the variable is the other argument to the method. The restof the characters after the percent sign describe the formattinginstructions for the argument.you are here. 295


the formatO methodThe percettt (~)says, "ittsert argutltet1t here"(a"d format It uslt1g these it1structiottS)The first argument to a formatj ) method is called the format Suing, and itcan actually include characters that you just want printed as-is, without extraformatting. When you see the % sign, though, think of the percent sign as avariable that represents the other argument to the method.Ihave 476578.10 bugs to fix.The "%" sign tells the formatter to insert the other method argument (thesecond argument to formatf), the number) here, At"lD format it using theu .2r characters after the percent sign. Then the rest of Ute format Suing,"bugs to fix" , is added to the final output.Adding a commaformat("! have %,.2£ bugs to fix. u , 476578.09876);Ihave 476,578.10 bugs to f~.296 chapter 10


numbers and staticsBut how does it even KNOWwhere the instructions end and therest of the characters begin? How comeit doesn't print out the "f" in "%.2f'? Orthe "2"( How does it know that the .2fwas part of the instructions and NOTpart of the StriT\9?The format Stri"Q uses itsow., little lattguage sytttaxYou obviously can't putjust an),thingafter the "%~sign. The syntax for what goes after the percentsign follows very specific rules, and describeshow to format me argument that gets inserted atthat point in the result (formatted) String.You've already seen two examples:%, d means "insert commas and format thenumber as a decimal integer,"and%.2£ means "format the number as a floatingpoint with a precision of two decimal places."and%,.2£ means "insert commas and format thenumber as a floating point with a precision oftwo decimal places."The real question is really, "How do I know whatto put after the percent sign to get it to do whatI want?" And that includes knowing the symbols(like "d" for decimal and "f" for floating point)as well as the order in which the instructionsmust be placed following the percent sign. Forexample, if you put the comma after the "d" likethis: k%d,~ instead of "'%,d" it won 't worklOr will iv What do you think this will do:String.for1llat("I have %.2£, bugs to fix.", 476578.09876);(We'll answer that on the next page.)you a re he re ~ 297


format specifierThe fortMat specifierEverything after the percent sign up to and including the type indicator (like"d" or "f') are part of the formatting instructions. After the type indicator, theformatter assumes the next set ofcharacters are meant to be pan of the outputString, until or unless it hits another percent (%) sign. Hmmmm... is that evenpossible? Can you have more than one formatted argument variable? Put thatthought on hold for right now; we'll come back to it in a few minutes. For now,let's look at the syntax for the format specifiers-the things that go after thepercent (%) sign and describe how the argument should be formatted.A format specifier can have up to five different parts (notIncluding the MOJo"). Everything In brackets [] below Is optional, soonly the percent (0J0) and the type are required. But the order Isalso mandatory, so any parts you DO use must go In this order.%[argument number] [flags] [width) [.precision)type%[argument number] [flags] [width) [.precision) type------~Jlformat("%,6.1f N , 42.000);298 chapter 10


The ot1ly required specifier is for TVPEAlthough type is the only required specifier, remember that if you do putin anything else, type must always come last! There are more than a dozendifferent type modifiers (not including dates and times; they have their ownset), but most of the time you 'll probably use %d (decimal) or %f (floatingpoint). And typically you 'll combine %fwith a precision indicator to set thenumber ofdecimal places you want in your output.The TYPE is mandatory, everything else is optional.%d%fdecimalformat ("%d",floating pointformat ("%.3£", 42. 000000) ;42 .000~ A4-2.25 wcxo/d ot I42) ; wo",ld be th tI work, Itd' e sallie as trt'tI to. ,rettly assi3t1 a do",bl 3Itlt variable. e atlThe argument must be compatible with an int, so that meansonly byte, short, int, and char (or their wrapper types) ."kit»e\"e we tOftlbil'le~ ~hewith a f\"etis',o\'\ 'l'Id,t~tov-".,11 we el'lded ",y WIth.7 soth\"ee u\"oes·The argument must be ofa floating point type, so thatmeans only a float or double (primitive or wrapper) as wellas something called BigDecimal (which we don't look at inthi s book).numbers and staticsYou must include atype in your tormatinstructions, and it youspecity things besidestype, the type mustalways COme last.Most ot the time,you'll probably tormatnumbers using either"d" ror r J' ecrmal or "t» l'tor lloating point.%x hexadecimalformat ("%x", 42);The argument must be a byte , short, int, long (includingboth primitive and wrapper types), and BigInteger.%c characterformat ("%c", 42);The argument must be a byte, short, char, or int (includingboth primitive and wrapper types).you are here . 299


format argumentsWhat happens ifI have tltore than one argutltent?Imagine you want a String that looks like this:"The rank is 20,456,654 out of 100,567,890.24."But the numbers are coming from variables. What do you do? You simply add twoarguments after the format String (first argument), so that means your call to formatt)will have three arguments instead oftwo. And inside that first argument (the formatString), you'll have two different format specifiers (two things that start with "%"). Thefirst format specifier will insert the second argument to the method, and the secondformat specifier will insert the third argument to the method. In other words, thevariable insertions in the format String use the order in which the other arguments arepassed into the formatf) method.i n t one = 20 45 6 6 5 4 ;doubl e two = 100567890.248907 ;St r i ng s = String. f o r mat ("The r a nk i s %,d o ut of %,.2£", one, twO);~The rank is 20,456,654 out of 100 ,567,890 .25We added tOl'l\l'I\OS to both vat'iables,and t'estt'itted the .fIO


So tMuch for t1utMbers, what about dates?numbers and staticsImagine you want a String that looks like this: "Sunday, Nov 28 2004"Nothing special there, you say? Well, imagine that all you have to start with is a variableof type Date-AJava class that can represent a timestamp, and now you want to take thatobject (as opposed to a number) and send it through the formatter.The main difference between number and date formatting is that date formats use atwo-character type that starts with "t" (as opposed to the single character "f" or "d", forexample). The examples below should give you a good idea of how it works:The complete date and time%tcString. format ("%tc", new Date());Sun Nov 28 14 :52:41 MST 2004Just the time %trString. format ("%tr", new Date () ) ;03:01 :47 PMDay of the week, month and day%tA %tB %tdThere isn't a single format specifier that will do exactly what wewant, so we have to combine three ofthem for day of the week(%tA), month (%tB), and day ofthe month (%td).Sunday, November 28Same as above, but without duplicating the arguments%tA %tB %tdDate today = new Date () ; The a\'l~le-bl"atkd: "


manipulating datesLet's see... how many workdays will there be if theproject starts on Feb 27th andends on August 5th?Workhtg with PatesYou need to do more with dates thanjust getUN:ldy s date. You need your programs to adjustdates, find elapsed times, prioritize schedules,heck, make schedules. You need industrialstrength date manipulation capabilities .You could make your own date routines ofcourse... (and don't forget about leap years l)And, ouch, those occasional, pesky leapseconds.Wow, this could get complicated. Thegood news is that the Java API is rich withclasses that can help you manipulate dates.Sometimes it feels a little too rich ...302 chapter 10


numbers and staticsMovit1Q backward at1d forward it1 tittteLet's say your company's work schedule is Monday through Friday.You've been assigned the task offiguring out the last work day ineach calendar month this year...It seems that java.util.Date Is actually••• out of dateEarlier we usedjava.util.Date to find today's date, so it seemslogical that this class would be a good place to start looking forsome handy date manipulation capabilities, but when you checkout the API you'll find that most ofDate's methods have beendeprecated!The Date class is still great for getting a "time stamp"-an objectthat represents the current date and time, so use it when you wantto say, "give me NOW".The good news is that the API recommendsjava.util.Calendarinstead, so let's take a look:v·.ror a time-stamp o:trtt"now,use Date. But lor everythingelse, use Calendar.Use Java.util.Calendar for your date manipulationThe designers ofthe Calendar API wanted to think globally,literally. The basic idea is that when you want to work with dates,you ask for a Calendar (through a static method of the Calendarclass that you'll see on the next page), and theJVM hands you backan instance ofa concrete subclass ofCalendar. (Calendar is actuallyan abstract class, so you're always working with a concrete subclass.)More interesting, though, is that the kind ofcalendar you getback will be appropriate for your locale. Much of the world uses theGregorian calendar, but if you're in an area that doesn't use aGregorian calendar you can getJava libraries to handle othercalendars such as Buddhist, or Islamic orJapanese.The standardJava API ships withjava.util.GregorianCalendar, sothat's what we'll be using here. For the most part, though, youdon't even have to think about the kind of Calendar subclass you'reusing, and instead focus only on the methods of the Calendar class.you are here . 303


getting a Calendar&ettit1g at' object that extends CalendarHow in the world do you get an "instance" ofan abstract class?Well you don't of course, this won't work:v--- nt tompile¥ .....0I'I't allow this IThis WON'T work:Calendar cal = new Calendar () ; .Instead, use the static "getlnstanceO" method:Calendar cal = Calendar.getlnstance() ;Wait a minute.If you can't make aninstance of the Calendarclass, what exactly are youassigning to that Calendarreference?You can't get an instance of Calendar,but you can can get an instance of aconcrete Calendar subclass.Obviously you can't get an instance of Calendar, becauseCalendar is abstract, But you're still free to call static methodson Calendar, since SUllie methods are called on the class;rather than on a particular instance. So you call the staticgetInstanceO on Calendar and it gives you back... an instanceofa concrete subclass. Something that extends Calendar(which means it can be polymorphically assigned to Calendar)and which-by contract-s-can respond to the methods of classCalendar.In most ofthe world, and by default for most versions ofJava,you'll be getting back ajava.util.GregorianCalendar instance.304 ch a ple r 10


numbers and staticsWorkittg with Calettdar objectsThere are several key concepts you 'U need to understand inorder to work with Calendar objects:• Fields hold state- A Calendar object bas many fields that are used torepresent aspects ofits ultimate state, its date and time. For instance, youcan get and set a Calendar's yearor month.• Dates and Times can be incremented - The Calendar class has methods thatallow you to add and subtract values from various fields, for example "addone to the month". or "subtract three years" .• Dates and TImes can be represented in milhseconds- The Calendar classlets you convert your dates in to and out ofa millisecond representation.(Specifically, the number of milliseconds that have occured sinceJanuaryl st, 1970.) This allows you to perform precise calculations such as "elapsedtime between twO times" or "add 63 hours and 23 minutes and 12 secondsto this time",An example of working with a Calendar object: 1 ~o&r at \",~D.. t.o Ja'" J o-ba$td.1Calendar c = Ca lendar .getI nstance () 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\\sJlong dayl = c. getTimelnMillis (); ~ oJ 3W\OIo'l'It. ot ",i\Iis«.ow-dS.dayl +~ 1000 * 60 * 60;c .setTimelnMillis(dayl); (System.out.println("new hourc.add(c .DATE, 35) ;System.out.println("add 35c.roll(c.DATE, 35);System.out.println("roll 35c.set(c.DATE, 1);" + c.qet(c.HOUR_OF_DAY») ;~-------days" + c.getTime());


Calendar APIHighlights of the Calettdar APIWeJUSt worked through using a few ofthe fields andmethods in the Calendar class. This is a big API sowe're showing only a few of the most common fieldsand methods that you'll use. Once you get a few ofthese it should be pretty easy to bend the rest of thethis API to your will.Key Calendar Methodsadd(lnt field. Int amount}Adds or subtracts time from the calendar's field.get(lnt field)Returns the value of the given calendar field.getTlmelnMllIIs()Returns this Calendar's time In millis,as a long.roll(int field, boolean up)Adds or subtracts time without changing larger fields.set(int field.lnt value}Sets the value of a given Calendar field.set(year. month. day, hour. minute) (allints)A common variety of set to set a complete time.setTlmelnMfllis(long millis)Sets a Calendar's time based on a long rnllli-tirne.II more ...---...._..._-_.._--.., YEARKeyCalendar FieldsDATE I DAY_OF_MONTHGet / set the day of monthHOUR/HOUR_OF DAYGet! Set the 12 hŌur Or 24 hour valueMILLISECOND .Get / Setthe milliseconds,MINUTEGet / set the mInute.MONTHGet / set the month.Get / Set the year.ZONE_OFFSETGet / set raw offset of GMT I1/ n mUUs.more...-,-06 chapter 10


Evett ttlore Statics!... static jttlJ!ortsNew to Java 5.0... a real mixed blessing. Some people lovethis idea, some people hate it, Static imports exist only to saveyou some typing. [f you hate to type, you rnightjust like thisfeature. The downside to static imports is that - ifyou're notcareful- using them can make your code a lot harder to read.The basic idea is that whenever you're using a static class, astatic variable, or an enum (more on those later), you canimport them, and save yourself some typing.Some old-fashioned code:import java.lang.Math;numbers and staticsUse CareluUy:static imports canmake your codecontusing to readclass NoStatic {publiC static void main (String () argsl (Math.tan(60});Same code, with static Imports:;import static java.lanq.System.Outi;import static java.lanq.Math.*iclass WithStatic (public static void main (String []args)- Caw.aII & Gokhas• If you're only going to use a static membera fewtimes, we think you should avoidstatic Imports, to help keep the code morereadable.•Ifyou're going to use a static member alot,(like doing lots ofMath calculanons), thenit's probably OK to use the static Import.• Notice that you can use wildcards (."), inyour static Import declaration.• Abig issue with static imports isthat it'snot too hard tocreate naming conflicts. Forexample, if you have two different classeswith an "addO' method, how will you andthe compiler know which one touse?you are here. 307


static vs. instanceFireside Chats@Tonight's Talk: An instance variabletakes cheap sIlots at a static variableIn.stanoe VariableI don't even know why we're doing this.Everyone knows static variables are just usedfor constants. And how many of those arethere? I think the whole API must have, what,four? And it's not like anybody ever usesthem.Full of it. Yeah, you can say that again. OK,so there are a few in the Swing library, buteverybody knows Swing isjust a special case.Ok, but besides a few GUI things, give me anexample ofjust one static variable that anyonewould actually use. In the real world.Well, that's another special case . And nobodyuses that except for debugging anyway.S1atic VariableYou really should check your facts . Whenwas the last time you looked at the API? It'sfrickiri ' loaded with statics! It even has entireclasses dedicated to holding constant values.There's a class called SwingConstarus, forexample, that'sjust fuU of them.It might be a special case, but it's a reallyimportant onel And what about the Colorclass? What a pain ifyou had to remember theRGB values to make the standard colors? Butthe color class already has constants definedfor blue, purple, white, red, etc. Very handy.How's System.out for starters? The out inSystem.out is a static variable ofthe Systemclass. You personally don't make a newinstance ofthe System, you just ask the Systemclass for its out variable.Oh.Iike debugging isn't important?And here's something that probably nevercrossed your narrow mind-let's face it, staticvariables are more efficient. One per classinstead ofone per instance. The memorysavings might be huge!308 chapter 10


numbers and staticsInstance VariableUrn, aren't you forgetting something?Static variables are about as un-OO as it gets!!Gee why notjust go take a giant backwardsstep and do some procedural programmingwhile we're at it.You're like a global variable, and anyprogrammer worth his PDA knows that'susually a Bad Thing.Yeah you live in a class, but they don't callit Clas.rOriented programming. That'sjuststupid. You're a relic. Something to help theold-timers make the leap to java.Static VariableWhat?What do you mean un-OO?I am NOT a global variable. There's no suchthing. I live in a class! That's pretty 00 youknow, a CLASS. I'm notjust sitting out therein space somewhere; I'm a natural part of thestate ofan object; the only difference is thatI'm shared by all instances ofa class. Veryefficient.Alrightjust stop right there. THAT isdefinitely not true. Some static variables areabsolutely crucial to a system . And even theones that aren't crucial sure are handy.Well, OK, every once in a while sure, it makessense to use a static, but let me tell you , abuseofstatic variables (and methods) isthe~iDarkofan immature 00 programmer. A designershould be thinking about objectstate, not classstate.Static methods are the worst things ofall,because it usually means the programmer isthinking procedurally instead ofabout objectsdoing things based on their unique objectstate.Riiiiiight. Whatever you need to tell yourself...Why do you say that? And what's wrong withstatic methods?Sure, I know that objects should be the focusofan 00 design, butjust because there aresome clueless programmers out there... don'tthrow the baby out with the bytecode. There'sa time and place for statics, and when youneed one, nothing else beats it.you are here . 309


e the compilerclass StaticSuper{BE the comriIerThe Java file on this page represents acomplete progrlU'l. Your joh is to rIa)'cOIlIpiler and deterrnne whether thisfile will cOIllpile. Ifit won't cOIlIpile.how would )'OU 1'lX it. andifit does compile. whlltwould he ~ output?static {}System.out.println("super static block");StaticSuper{System.out.println("super constructor");}}public class StaticTests extends StaticSuper {static int randjstatic {rand = (int) (Math.random() * 6)jsystem.out.println("static block n + rand);If it complies, which of these Isthe output?Possible OutputRle Edit Wlndow Hel ell%java StaticTestsstatic block 4in mainsuper static blocksuper constructorconstructor}StaticTests () {System.out.println("constructor");}public static vcid main{String [] args) {System.cut.println("in main");StaticTests st = new StaticTests()j}Possible OutputFile Edit Wlndow Het Electrle:l%java StaticTestssuper static blockstatic block 3in mainsuper constructorconstructor}310 chapter 10


numbers and staticsThis chapter explored the wonderful, static, worldof Java. YourJob is to decide whether each of thefollowing statements Is true or false.1. To use the Math class, the first step is to make an instance ofit.2. You can mark a constructor with the static keyword.3. Static methods don't have access to instance variable state of the 'this' object.4. It is good practice to call a static method using a reference variable.5. Static variables could be used to count the instances ofa class.6. Constructors are called before static variables are initialized.7. MA)CSIZE would be a good name for a static final variable.8. A static initializer block runs before a class's constructor runs.9. Ifa class is marked final, all ofits methods must be marked final.10. A final method can only be overridden ifits class is extended.11. There is no wrapper class for boolean primitives.12. A wrapper is used when you want to treat a primitive like an object.13. The parseXxx methods always return a String.14. Formatting classes (which are decoupled from 1/0), are in the java.formatpackage.you are here ~ 311


code magnetsLunar Code MagnetsThis one might actually be usefullin addition to what you've learned in the last fewpages about manipulating dates, you'll need a little more information...First fullmoons happen every 29.52 days or so.Second,there was a full moon on Jan.7th,2004 . Your job is to reconstruct the code snippets to make a working Java programthat produces the output listed below (plus more full moon dates). (You might notneed all of the magnets, and add all the curly braces you need.) Oh, by the way,youroutput will be different if you don't live in the mountain time zone.I long dayl = c.getTimelnMillis() ;rimPortIIc . s e t (2 0 04 , l , 7 , 1 5 , 4 0 ) ;staticjava. lang. system. out;\~1 ("full moon on llitc", c»;~ I•.static int DAY IM :: 60 Or 60 .. 24;(c. formatLCalendar C - new Calendar();•" l as s FullMoonsI public static void main (Strinq [] arqs) I{I dayl += (DAY_1M .. 29.52); IIfor (int x :: 0 ; X < 60; x++){a~rJ(I-l\ILstati.e int DAY IM =: 1000Or 60 Or 60 .. 24;-,printlnlJ . . -l ~port Java.i.o.*;1("full moon on %t", c) ) ;~limport java.util.*;}Istatic import java.lanq.System.out;Ire.set{2004,O,7,15,40); out.println~c .setT1meInHilliS(daYl);(string. formatCalendar c = Calendar.get1nst&nce();312 chapter 10


numbers and staticsTrue or FalsestaticSuper( ) {}System.out.println(usuper constructor H ) ;StaticSuper is a constructor, and mustnave ( ) in its signature. Notice thor asthe output below demonstrates, the staticblocks for both classes run before eitherof the constructors run.Possible OutputFile Ed~ WIndOW Hel elln%java StaticTestssuper static blockstatic block 3in mainsuper constructorconstructor1. To use the Math class, the first step is to Falsemake an instance of it.2. You can mark a constructor with the keyword'static'.False3. Static methods don't have access to an Trueobject's instance variables.4. It is good practice to call a static method Falseusing a reference variable.5. Static variables could be used to count the Trueinstances ofa class.6. Constructors are called before static variablesare initialized.False7. MAX_SIZE would be a good name for a Truestatic final variable.8. A static initializer block runs before a class's True:constructor runs.9. Ifa class is marked final. all ofits methods Falsemust be marked final.]O. A final method can only be overridden if Falseits class is extended.11. There is no wrapper class for boolean Falseprimitives.12. A wrapper is used when you want to treat a Trueprimitive like an object13. The parseXxx methods always return a FalseString.14. Formatting classes (which are decoupled Falsefrom I/O), are in thejava.format package.you are here . 313


code magnets solutionimport java.util.·;import static java.lanq.Syatem.out;olass FullMoons (statio int DAY rM : 1000 • 60 • 60 • 24;publi~ static void main (String [) args)Ca18nda~ c = Calendar.getlnstance();c.aet(2004,O,7,15,40);long day! = c.qetTimelnM1l1i9();Notes on the Lunar Code Magnet:You might discover that a few of thedates produced by this prognun areoff by a day. This astronomical stuffis a little tricky, and if we made itperfect, it would be too complex tomake an exercise here.Hint: one problem you might try tosolve is based on differences in timezones. Can you spot the issue?for (int x ~ 0; x < 60; x++)day! +: (DAY_1M • 29.52)c. setTimslnMillis (dayl) ;out.println(Strlnq.format("full moon on %tc", e»;314 chapter 10


11 exception handlingRisky BehaviorStuff happens. The file isn't there. The server Is down. No matter howgood a programmer you are,you can't control everything.Things can go wronq, Very wrong.When you write a risky method, you need code to handle the bad things that might happen.But how do you know when a method Is risky? And where do you put the code to handle theexceptional situation? So far in this book. we haven't really taken any risks. We've certainly hadthings go wrong at runtime, but the problems were mostly flaws In our own code. Bugs.Andthose we should fix at development time.No, the problem·handllng code we're talking abouthere is for code that you can't guaranatee will work at runtime.Code that expects the file to bein the right directory, the server to be running, or the Thread to stay asleep. And we have to dothis now.Becausein thischapter, we're going to build something that uses the risky JavaSoundAPI. We're going to build a MIDI Music Player.this is a new chapter 315


uilding the MIOI Music PlayerLet"s tMake a Music MachitteOver the next three chapters, we'll build a few different soundapplications. including a BeatBox Drum Machine. In fact,before the book is done, we'll have a multi-player version soyou can send your drum loops to another player, kind oflikea chat room. You're going to write the whole thing, althoughyou can choose to use Ready-bake code for the CUI parts.OK. so not every IT department is looking for a new BeatBoxserver, but we're doing this to learn more aboutJava. Buildinga BeatBox isjust a way to have fun while we're learningjava.the fh11shed JeatJox looks sotMethl"g like this:Crash CymbalHand ClapHigh TomHi BongoMaracasWhistleLow CongaCowbellVibraslapLow-mid Tom 0 GHigh AgogoOpen HI CongaO LJILJ .= 1..::, ~I LJdance beatAndy: groove 112Chris: groove2 revisedNigel: dance beat)Put checkmarks in the boxes for each of the 16 'beats', For example, on beat1 (of 16) the Bass drum and the Maracas will play. on beat 2 nothing, andon beat 3 the Maracas and Closed Hi-Hat... you get the idea . When you hit'Start', it plays your pattern in a loop until you hit 'Stop'. At any time, youcan "capture" one ofyour own patterns by sending it to the BeatBox server(which means any other players can listen to it). You can also load any of theincoming patterns by clicking on the message that goes with it.316 chapter 11


WeIll start with the basicsObviously we've got a few things to learn before the wholeprogram is finish ed , including how to build a Swing GUl, howto connect to another machine via networking, and a little I/Oso we can sendsomething to the other machine.Oh yeah , and theJavaSound API. That's where we'll start in thischapter. For now, you can forget the GUl, forget the networkingand the I/O, and focus only on getting some MIDI-generatedsound to come out of your computer. And don't worry ifyoudon't know a thing about MIDI, Or a thing about reading ormaking music. Everything you need to learn is covered here.You can almost smell the record deal.MIDI ~ih:exception handlingfhe JavaSou)1d APIjavaSound is a collection ofclasses and interfaces added tojava starting with version 1.3. These aren't special add-oris:they're part of the standardJ2SE class library.javaSound is splitinto two parts: MIDI and Sampled. We use only MIDI in thisbook. MIDI stands for Musical Instrument Digital Interface,and is a standard protocol for gerting different kinds ofelectronic sound equipment to communicate. But forour BeaiBox app, you can think of MIDI as a kind ojsheet music that you feed into some device you can thinkoflike a high-tech 'player piano'. In other words, MIDIdata doesn't actually include any sound, but it doesinclude the instructions that a MIDI-reacling instrumentcan play back . Or for another analogy, you can think ofa MIDI file like an HTML document, and the instrumentthat renders the MIDI file (i.e. plays it) is like the Webbrowser.MIDI data says what to do (play middle C, and here's how hardto hit it, and here's how long to hold it, etc.) but it doesn't sayanything at all about the actual sound you hear. MIDI doesn'tknow how to make a Elute, piano, or Jimmy Hendrix guitarsound, For the actual sound, we need an instrument (a MIDIdevice) that can read and playa MIDI file. But the device isusually more like an entire band ororchestra ofinstrurnen15. Andthat instrument might be a physical device, like the electronickeyboard synthesizers the rock musicians play. or it couldeven be an instrument built entirely in software. living in yourcomputer.For our BealBox, we use only the built-in , software-onlyinstrument that you get with Java. It's called a syntMsiu:r (somefolks refer to it as a softumresynth) because it creates sound.Sound that you hear.MIDI dtllit.e b\Ows how to\"caa' a MIDI .filt al'lQ flay batl\ent..(,.(s.....lIy, a MIDI it'Sb--ellt.tan playa LOT o.f diH~tnt~ (yi.1no, d..,.,..1, violil'l,eitJ, alia all at the sa",e +'i",e.So a MIDI tilt is,,'+' like shed"'Iolit ~ot" jldi Ot\e "'1ol'ltiall iPlthe baPld -- it. taft hold thefarh for ALL t.ht "'lolitiar\5flayi,,~a farbtlOlar SOl'>5'you are here. 317


ut It looked so simpleFirst we t1eed a Sequet1cerBefore we can get any sound to play, we need a Sequencer object. Thesequencer is the object that takes all the MIDI data and sends it to the rightinstruments. It's the thing that plays the music. A sequencer can do a lot ofdifferent things, but in this book, we're using it strictly as a playback device. Likea CD-player on your stereo, but with a few added features. The Sequencer classis in thejavax.sound.midi package (part of the standardjava library as of version1.3). So let's start by making sure we can make (or get) a Sequencer object.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..tpublic class MusioTestl { ...d;n fd . It: -the -thi,,~ t.hat, ....el\•....e ye l.LS",~ . 1 r L, ' toII tn, MIDI in-tO\""'auC7J\ I"public void play 0 ( sc,\\OLnt.fS 6 b ,..d, 'Bllt. ....e dO'l'>'t Nlte 6 Y6Sequencer sequencer = MidiSystem. ga tSaquencer () ; a sonlj ' have to asK t'ke.....v-selves __ ....e"" ",.... Ol'le "'"System.out.println("We got a sequencer");~ Mid~yst.e'" to ~i~t. lAj, Ol'It·II close playpublic static void main(Strlng(] args)MusicTestl mt = Daw MusicTestl(} ;IDt.play () ;II clOSE! mainII close classSOlMethingl wrong!,This t.«Je won't t.tm.pile! The to",piler ~ys t.nt\""e's ahIAhreporkd e~epi.iOh' thai "'lASt be t.al.l~ht. or detlared.318 chapter 11


exception handlingWhat happet1s whet1 a tMethod you warttto call(probably it' a class you didt1~t write) is risky?" Let's say you wantto call a method In aclass that you didn'twrite.--. -....111_n,o~_ Q l•..,.u.__II ,~- ,_ I"youyour coc eclassyoudidn't write• That method doessomething risky,something that mightnot work at runtime.--,_ t_ 1_ f1,classyoudidn't writevoid moo () (if (serverDown)axplode()i)}~ You need to knowthat the methodyou're calling isrisky.~.- '~= . Iyoucrass youdidn't write@ You then write codethat can handle thefailure if It doeshappen. You need to beprepared, just in case.youyour co eyou ar e her e ~ 319


When things mIghtgo wrongMethods iN Java ose except/om: to tell the ca/liM9 code,·Sotttethlftg Bad HappeHed. I failed;'Java's exception.handliog mechan~m", a dean, well·lighted way to handle "exceptionalshuations' that pop up at runtime;;t lets}'OuPOlall your error.handling code in oneeasy-to-readplace. It's based On you knowingthat the method you're calhng;, risky(i.e. that the method mighlgene,",e an exception), SO thar you can write code '0 dealw;th that pos,,;bmty. l£}'Oo k_ you might get an exception when you calla ParUcuJarthe method, exception. you can be fmP- for-poss;bly even '''-from-the problem thaI causedriskymethod's So, how do}'Oudeclaration.know ifa method throws an eXception! You find a throw. clause;n theThe getSequencer () lIIethOd takes a risk. It Can fail at runtlllle.So It lIIust 'declare' the risk you take When you call it.eee•hckt.~@ MldlSvslem (Java 2 PI a((orm SE vl.4.01It fHl>rrIC i A ~ I c>R lISll>p Rdrt:Sh _ _L~~~I~~ .../g ~~:\':tOlJ rq~ VOiceSlalys5' ExcepUons,,1 IgetSe-quencerpUb lic ~ t a t c ' ~ -C'a - ll (l n s " r 9·ts~ t h.ac.~ r o~ .9 ( Mldll1oAv:ll _ l _1 h l~ Ex £~ Rt l Q nOblains the default sequencer.Rtturns:icerthedefaultsequcn .. I availabledueThrows: I b l"ExcCp rl on _ .f I th e seq


exception handlingThe cOlMpiler t1eeds to kttowthat YOU kttow you're caUit1garisky lMethod.Ifyou wrap the risky code in something called atry/catch, the compiler will relax.A try/catch block tells the compiler that youknota an exceptional thing could happen in themethod you're calling, and that you're preparedto handle it. That compiler doesn 't care Iwwyouhandle it; it cares only that you say you're takingcare of it,---import j AVax . sound.midi . * ;public class MusicT~stl {public void play ()try {,J, tM yisk'fSequencer sequencer = MidiSystElm. getsequenCGr () ; i:;-! 'l..AJ' h'ot't .System.out.prlntln("Suceessfully got a sequencer");} catch (MidiUnavailableException ex) {Systelll.out.println ("Bummer") ;IYI a v 1iYl~II close playpublic static void main{Strinq[] args)MusicTestl mt = new MusicTestl():mt.play{) :II close mainII closit classyou are here. 321


exceptions are objectsA" exceptio" is a" object...of type Exceptio"_Which is fortunate, because it would be much harderto remember ifexceptions were of type Broccoli.Remember from your polymorphism chapters thatan object of type Exception can be an instance of anysubclassofException.'e.~.Ltyt.\ OYIPart J t'hedass ~lleYaYl.nl T'IIl'/ allT\I't"owa'blet~~O l.\ass61'10 il'lheY'It two \I.e'(...dho~ThrowablegetMeasage{)printStackTraceOTException.>


If it's your code that catches the exceptio",the., whose code throws it?-You'll spend much more of yourJava coding time handlingexceptions than you'll spend cnatingand throwing them yourself.For now, just know that when your code callsa riskymethod-amethod that declares an exception-it's the risky method thatthrows the exception back to yfJU, the caller.In reality, it might be you who wrote both classes. It reallydoesn't matter who writes the code... what matters is knowingwhich method throws the exception and which method catches it.When somebody writes code that could throw an exception, theymust declare the exception.)public void crossFingers()(anObject.takeRisk()j) (BadException ex) {--._':..:: ~ I._ ...Jtn I_""J.your code\ tnt 'foI0'I'\0 C'o'1&od MVS1 -\:,t\ ~ d~'f-l,eytIO"• Risky, exception-throwing code: ~,~ "'~ A) -\:,hat 'I't t,hyo'OlS a a~ ott~Y''''Ypublic void takeRi.sk () BadExcepUon (if (abandonAllHope) (new BadException();'\l~t:G~objett i:;e w E~~/:h.-ow it.• Your code that calls the risky method:exception handlingclass with Qrisky methodOne methqd WIllentch ...VhClt £lncnher- tnetll oJ thr9'vv~. J\n-exceptIon 'is aJVY'ly':ithl"O\Vn back [o theelll)e\".The 111eth


checked and unchecked exceptionsE.'Il.ttf"t1Ol\S thai aye NOT s~t1asu:s ofRunti",eEuepiic»l cll"e thet.ked .for by~c t.oto.pilcr. Th~'rc ~Iled "thetJccdt"J'-UpiiOflS IiExceptionThe compiler checks for everythingexcept RuntimeExceptions.The compiler guarantees:If you throw an exception in your code you must declare it usingthe throws keyword in your method declaration.If you call a method that throws an exception (in other words,a method that declares It throws an exception), you mustacknowledge that you're aware of the exception possibility.One way to satisfy the compiler is to wrap the call in a try/catch.(There's a second way we'Hlook at a little later in this chapter.)InterruptedExceptlon~: Walt just a mlnutel How come this Isthe FIRST timewe ve had to try/cate:h an EJcceptlon7 What about theexceptions I've already gotten like NullPolnterEJcceptionand the exceptJon for DlvldeByZero. I even got aNumberFormatExceptlon from the Integer.parselntOmethod. How come we didn't have to catch those?A.: The compiler cares about all subclassesof Exception,unless they are a special type, RuntimeException. Anyexception classthat extends RuntlmeExceptlon gets afree pass.RuntimeExceptions can be thrown anywhere,with or without throws declarations or try/catch blocks.The complier doesn't bother checking whether a methoddeclares that It throws a RuntimeExceptlon, or whether thecaller acknowledges that they might get that exception atruntime.Q.: I'll bite.WHY doesn't the complier care about thoseruntime exceptions? Aren't theyJust as likely to bring thewhole show to a stop?A: Most RuntimeExceptlons come from a problem inyour code logic, rather than a condition that fails at runtimein ways that you cannot predict or prevent. You cannotguarantee the file is there .You cannotguarantee the serveris up. But you can make sure your code doesn't index off theend of an array (that's what the .length attribute is for).YouWANTRuntimeExceptions to happen at developmentand testing time.You don't want to code in a try/catch, forexample, and have the overhead that goes with it, to catchsomething that shouldn't happen In the first place.A try/catch is for handling exceptional situations, not flawsin your code, Use your catch blocks to try to recover fromsituations you can't guarantee wlll succeed.Or at the veryleast, print out a message to the user and a stack trace, sosomebody can figure out what happened.324 chapter 11


exception handIing• Amethod can throw an exception when something fails at runtime.• An exception is always an object oftype Exception. (Which, asyouremember from the polymorphism chapters means the object is from aclass thai has Exception somewhere upitsinheritance tree.)• The compiler does NOT pay attention toexceptions that are oftype RuntlmeException. ARuntimeExceplion does not have to bedeclared orwrapped in a try/catch (although you're free todo either orboth of those things)• All Exceptions the compiler cares about are called 'checkedexceptions' which really means compiler-


exceptions and flow controlFlow eontrol it1 try/catch blocksWhen you call a risky method, one oftwo things can happen.The risky method either succeeds, and the try blockcompletes, or the risky method throws an exception back toyour calling method.If the trysucceeds(doRiskyThlngO does notthrow an exception)try {(j Foo fint bx.doRiskyThing();f . getNum () ;catch (Exception ex) {System.out.println("failed U ) ;(~ lsystem. out.println ("We made it!");1If the tryfails(because doRlskyThlngOdOBS throw an exception)try (.------i~!flHIFoo'


exceptionandlingFh,ally: for the thlttQs you watttto do no fffatter what.Ifyou try to cook something, you start by turning onthe oven.If the thing you try is a complete failure,you haue to turn offthe oven.If the thing you try succeeds,you haue to turn offthe oven.You have to turn offthe oven no matter what!A finally block is where you putcode that must run regardlessof an exception.try (turnOvenOn();x , ba Ice () ;catch (BakingException ex)ex.printStackTrace()i) finally ()turnOvenOf£();Without finally, you have to put thetumOvenOffO in both the try and the catchbecause you have to turn offthe oven JU> matterwhat . A finally block lets you put all yourimportant cleanup code in oneplace instead ofduplicating it like this:try {turnOvenOn () ;x.bake o .turnOvenOff () ;} catch (BakingException ex) (ex.printStackTrace();turnOvenOf f () ;If the try block fails (an exceptIDn), flowcontrol immediately moves to the catch block.When the catch block completes, the finallyblock runs. When the finally block completes,the rest of the method conUnues on.If the tr-y block succeeds (no exception),flow control skips over the catch block andmoves to the finally block. When lhe finallyblock compleles, the rest of the methodcontinues on.If the try or catch block has a returnstatement, finally will still runl Flowjumps lo the finally, then back to the relum.you are here ~ 327


flow control exercise~yourpendlFlow ContPoILook at the c:ode to the left. What do you think theoutput of this program would bel What do you thinkIt would be If the third line of the program werechanged to: String test. "yes", 1AssumeScaryExceptlon extends Exception.public class TestExceptions {public static void main(String () args) {Output when test ='"no"}String test = "no N;try {Systern.out.println("start try");doRisky(test);System.out.println("end try");} catch ( ScaryExceptioo se) {Systern.out.println("sca:r:yexception");} finally {System. out. println( "finally") ;}System.out.println("end of main");Output when test = "yes"static void doRisky(String test) throws ScaryException {System.out.println("start risky");if ("yes".equals(test)) {throw new ScaryException();}}System.out.println(Uend riskyN);return;ulew JOpua . ,(lIeuy . UOlldCl»)«l 've)~ . ~SIJ lJelS . Nl uelS :.5i1,.{. =~al U"4Mulew lO pUiI - Alleuy - .tit pua - A~S!J pUCI - A~SIJ lJl?1S - ,VllJelS :.ou. = l5Cll UCl1.!M328 chapter 11


Pid we lIte.,tio., that atltethod ca.,throw tMore tha., o.,e exception?exception handlingA method can throw multiple exceptions if it dam well needs to. Buta method's declaration must declare all the checked exceptions it canthrow (although if two or more exceptions have a common superc1ass, themethod can declarejust the superclass.)CatchlnQ lHultlple exceptlo"sThe compiler will make sure that you've handled all the checked exceptionsthrown by the method you're calling. Stack the catch. blocks underthe try, one after the other. Sometimes th e order in which you stack the~:~::~~ ~::~~. ~~~~:\r:tto thata\Itdelate,public void doLaundry()throws PantsException,II code that could throw either exceptionpublic class Foo {public void go ()Laundry laundry new Laundry () ; it doLa~dr'f() ~..o\WS atry { Pa"b~uepiiCW\1 i.e lands ill the1/Pa"b.~~O'r\ utth blotk.laundry.doLaundry(); ~} catch (PantsException pex) {II recovery code) Catch(LingerieExcePti~) (".,..0''''') t\lydOIS aI I recovery code ~ J d~ 'T.0'\. it. \a"as i" the} L.i~'t~~. ~h blot.\t.·U~ew'it~~tybOl'lyou are here ~ 329


polymorphic exceptionsExceptiotts are polytMorphicExceptions are objects, remember. There's nothing all thatspecial about one, except that it is a thing that can bethrown.So like all good objects, Exceptions can be referred topolymorphically. A LingerieException object, for example,could be assigned to a ClothingException reference. APantsException could be assigned to an Exception reference.You get the idea. The benefit for exceptions is that a methoddoesn't have to explicitly declare every possible exception itmight throw; it can declare a superclass of the exceptions.Same thing with catch blocks-you don't have to write a catchfor each possible exception as long as the catch (or catches)you have can handle any exception thrown.IOExceptlonexceptionCloltilngExeeptlonAll eU~QtIS ho'lef.~~ as aSlI"cY tolass-@ You can DECLARE exceptions usinga supertype of the exceptions youthrow.@ You can CATCH exceptions using asupertype of the exception thrown.try (~\, ""'I1.


exception handJust because you CAN catch everythingwith one big super polymorphic catch,doesn't always mean you SHOULD.You could write your exception-handling code so thatyou specify only onecatch block, using the supertypeException in the catch clause, so that you'll be able tocatch any exception that might be thrown.try {l a undry.doLaundry();}catch (Exception ex) { blotk willw"~T? Tn,s tatt n ,I I r e c overy code . ..~ Rt.t.ol/t.'('( .{:'(0f'I -b so '(()II. WOYltL'h ~N'I ay,G all t.~t.t.f oY\S,ta-u- \.. t wt.\'It WV'o\'l~ 'a~~atit.all'f k\'low wnaWrite a different catch block for eachexception that you need to handleuniquely.For example, ifyour code deals with (or recoversfrom) a TeeShirtException differently than it handles aLingerieException, write a catch block for each. But ifyoutreat all other types ofClothingException in the same way,then add a ClothingException catch to handle the rest.try {l aundry.doLaundry();.J.i "s 3Y10S\iAt1Lt.t v O 0 o,~h'(eYl} catch (TeeShirtException tex) { ~ Tee' .\:;IOYlS Ylet.I,; ll.,t.'(iet 1Le\, s....ov.\o. ~eI I r e cove r y from TeeShirtExceptiol 'YI;.I '-J t,oOel so ,!0II0"~ fu '(et,o\lt.'( I tt .... 'o\ot"s.~ o,~~t.'t't.Ylt. t,a} catch(LingerieException lex) {:t.I I recove r y from all othersAll oihet- CI th'Eo /tI~ Xlt,nJ.·Ut"t, talAaht h r I./QtlSJ et-t, .}you are here . 331


order of multiple catch blocksMultiple catch blocks iMust be orderedfroiM stttaliesf to biggestClothingExceptioncatch(TeeShirtException tex)catch (ShirtException sex)catch(ClothingException cex)332 chapter 11The higher up the inheritance tree, the bigger thecatch 'basket', As you move down the inheritancetree, toward more and more specialized Exceptionclasses, the catch 'basket' is smaller. Ir'sjust plain oldpolymorphism.A ShirtException catch is big enough to takea TeeShirtException or a DressShirtException(and any future subclass of anything that extendsShirtException). A C1othingException is even bigger(i.e. there are more things that can be referencedusing a ClothingException type). It can take anexception of type ClothingException (duh), andany ClothingException subclasses: PantsException,UnifonnException, Lingerielixception, andShirtException. The mother ofall catch argumentsis type Exception; it will catch any exception,including runtime (unchecked) exceptions, so youprobably won't use it outside of testi ng.\


exception handlingYou cat1"t put bigger basketsabove stMalier baskets.Well, you can but it won't compile. Catchblocks are not like overloaded methodswhere the best match is picked. With catchblocks, theJVM simply starts at the first oneand works its way down until it finds a catchthat's broad enough (in other words, highenough on the inheritance tree) to handlethe exception. lfyour first catch block iscatch (Exception ex). the compilerknows there's no point in adding anyothers-they'll never be reached.Size matters whenyou have multiple catchblocks. The one with the biggestbasket has to be on the bottom.Otherwise, the ones withsmaller baskets are useless.try (l aundr y. doLaundr y () ;catch(ClothingException cex) {II recovery from ClothingExceptioncatch (Linge.rieExc:eption lex) {II recovery from LingerieExceptionSiblings can be in any order, because theycan't catch one another's e~tions.catch(ShirtException sex) {II recovery from ShirtExceptionYou could put ShirtException aboveUngerieException and nobody would mindBecause even though ShlrtException is a bigger(broader)type because It can eateh other classes(its own subdasses),ShirtException can't catch aUngerieExceptlon so there's no problem.you are here ~ 333


polymorphic puzzle~n your pencilAssume the try/catch block here Is legally coded.Yourtask is to drawtwo different class diagrams that can accurately reflect the Exceptionclasses. In other words, what class Inheritance structures would make thetry/catch blocks in the sample code legal?try {x , doRisky () ;catch(AlphaEx a) {II recovery from AlphaExcatch (BetaEx b) {II recovery from BetaExcatoh (GammaEx c)II recovery from GammaExcateh(DeltaEx d) {II recovery from DeltaExBazElYourtask is to create two different legal try / catch structures (similartothe one above left),to accurately represent the class diagram shown onthe left Assume ALLof these exceptions might be thrown by the methodwith the try block.TFooElr.>


exception handlingWhe., you dO.,/t wa.,t to ha.,dlea., exceptiott...iust dUCK it!!If you don't want to handle anexception, you can duck it bydeclaring it.When you call a risky method, the compilerneeds you to acknowledge it. Most of the time,that means wrapping the risky call in a try/catch. But you have another alternative, simplyd1Uk it and let the method that called you catchthe exception.It's easy-all you have to do is declare thatyou throw the exceptions. Even though.technically, you aren't the one doing thethrowing. it doesn't matter. You're still the oneletting the exception whiz right on by.But ifyou duck an exception, then you don'thave a try/catch, so what happens when therisky method (dol.aundry/) ) does throw theexception?When a method throws an exception, thatmethod is popped off the stack immediately,and the exception is thrown to the nextmethod down the stack-the caller. But if thecalleris a ducker, then mere's no catch for it sothe caller pops off me stack immediately, andthe exception is thrown to the next methodand so on... where does it end? You'll see aliul elater.public void foo()}throwsII call risky methodlaundry.doLaundry() ;you are here. 335


handle or declareUuckhtg (by declaring) onlydelays the inevitableSooner or later, somebody has todeal with it. But what If MainOducks the exception?public class Washer (Laundry laundry =new Laundry(J;public void fool) throws ClothingExceptionlaundry.doLaundry();public static void main (String[ ] argsl throws ClothingException (Washer a = new Washer( );a .fooO;odoLaundryOthrows aClothingExceptionfooD ducks theexceptionmainO ducks theexceptionThe JVMshuts downmainO calls focOfooO calls doLaundryOdoLaundryO isrunning and throws aClothingExceptiondoLaundryO pops off thestack immediately andthe exception is thrownback to fooO .But fooD doesn't have atry/catch. so...fooD pops off thestack immediately andthe exception is thrownback to ... who? What'?There's nobody leftbut the JVM, and it'sthinking. "Don't expectME to get you out ofthis."We're us)ng the tee-sh irt to represent a Cloth ingException. We know, we know... you wouldhave preferr ed the blue Jeans.336 chapter 11


exception handlingHandle or Declare. It's the law.So now we've seen both ways to satisfy the compilerwhen you call a risky (exception-throwing) method.• HANDLEWrap the risky call in a try/catchThis had betta- b b'try { » ha",dle all extepti e athl~ e",o~h tatthlaundry. doLaundry () ; ~ ...iaht ~ I'\. OI'IS, at doLa~",dt"yC)J t"ow. vr e se th t '1} catch (ClothingException cex) { still to...pl ' ~1L 1- I e OIftPI et" willa,,,, 'toa't yo~ toe t Lh/ / recovery code of th••v. ,.,L. "'0 tau i",~ all...."",er"IOI'IS.}• DECLARE (duck it)Declare that YOUR method throws the same exceptionsoil tnvoo-"s aas the risky method you're calling. .1 1 ",W'dvo'.l) ...e-\:.n \ . Q tntint lo'o\..A01~b~t b'( dtt. avo''';,void foo () throws ClothingException { C\otni,,~~1Ltyti;"~O ...ttnod ~c\:.s tolaundry. doLaundry () ; ~ ~tytio", tnt..J.'OY\' No tVO'fIt.atJ,n.d~\c. tnt t1L t r'"But now this means that whoever calls the fooO methodhas to follow the Handle or Declare law. If fooD ducksthe exception (by declaring it), and mainO calls fooO, thenmainO has to deal with the exception.pUblic class Washer {Laundry laundry =new Laundry();public void foo() throws Clothi ngExcep t i onlaundry.doLaundry();public static void main (String[] a r gs)Washer a = new Washer();a c f oo Ij r ~Beta~e the +000 ...tihod d~ks theCI~hi",~ExteptiOl'l tht"OWl'l by doLa~",dt"vI')...a,,,,() has to a ,. () T: IWt" P a·1"OO i", a tt"y/tatthat" ...ai",O has to detlat"e that it, too, ,ih... ows Cloihi",~ExtertjOl'l!you are here. 337


fixing the Sequencer codeG-effittg back to our tMusic code...Now that you've completely forgotten, we started this chapterwith a first look at someJavaSound code. We created a Sequencerobject but it wouldn't compile because the methodMidi.getSequencerO declares a checked exception (MidiUnavailableException).But we can fix that now by wrapping the call in atry/catch.public void play()try {Sequencer sequencer = MidiSystem.getSequencer();System.out.println(~Successfullygot asequencer");}II close playException Rules• You cannot have a catch or finallywithout a tryvoid go () { t-/Oi ~~~~~\ ?Faa f = new Faa () ; wnt.V"is -tnt -t y '1 'f. foof () ;catch(FooException ex) { }try {x.doStuff();finally {II cleanup•You cannot put code between thetry and the catchNOT Lf..&:Atry { "': L! VOlA ". '1lode h t ....11 1; P"tx ,doStUff/() ; 1. e weell the try ~~) "Ule ldtth. Ii""int y = 43;} catch(Exception ex) { }• A try with only a finally (no catch)must still declare the exception.void got) throws FooException {try {x.doStuff() ;} finally { }338 chapter 11


exceptJon handlingCode Kitchen.:(You don't have to do ityourselt, but it's a lotmore fun if you do.Tlte rest 01 tlUs chapteris optionaL you can useReaJy-bake code tor allthe musicapps.But ityou want to learnmore about JllvaSouncl,turn the rage.you are here ~ 339


JavaSound MIDI classesMaking actual soundRemember near the beginning of the chapter, we looked at how MIDI data holdsthe instructions for what should be played (and howit should be played) and wealso said that MIDI data doesn't actually create any sound that you hear. For soundto come out ofthe speakers, the MIDI data has to be sent through some kind ofMIDI device that takes the MIDI instructions and renders them in sound, eitherby triggering a hardware instrument or a 'virtual' instrument (software synthesizer).In this book. we're using only software devices, so here's how it works inJavaSound:You need FOUR things:eD The thing thatplays the music• The music to beplaytd...o song.playshas aSequencer ~ Sequence ~•The part of theSequence thatholds the actualInformationTrackholdsThe Sequencer Is the thingthat actually causes a songto be played. Think of It likea music CD player.The Sequence is thesong, the musical piecethat the Sequencer willplay. For this book, thinkof the Sequence as amusic CD,but the wholeCDplays just one song.For this book, we onlyneed one Track,so JustImagine a a music CDwith only one song. Asingle Track.This TrackIs where all the songdata {MIDI Information)I1ves.The actual musicInformation:notes to play,how long, etc.e 9e 9A MIDI event is a messagethat the Sequencer canunderstand. A MIDI eventmight say (if It spokeEnglish), "At this momentIn time, play middle C,playIt this fast and this hard,and hold It for this long."A MIDI event mightalso say something like,"Change the currentinstrument to Flute."340 chapter 11


exception handlingAnd you need FIVE steps~.. Get a Sequencer and open itSequencer player = MidiSyscem.gecSequencer();player.openl);.. Make a new SequenceSequence seq = new Sequenceltiming,4);• Get a new Track from the SequenceTrack t = seq.createTrack();• Fill the Track with MidiEvents andgive the Sequence to the Sequencert.add(myMidiEventl);player.setSequencelseq);player. start ();you are here ~ 341


a sound applicationYour very first sound player appType it in and run it. You'll hear the sound ofsomeone playing asingle note on a piano! (OK, maybe not someone, but something.)import javax.sound.midi.*;public class MiniMiniMusicApp {pUblic static void main(String[] args) {MiniMiniMusicApp mini = new MiniMiniMusicApp();mini.play();II clos e main(public void play()try {a.·.~"•Sequencer playerplayer . ope n () ;Sequence seq = newMidiSystem.getSequencer();Tra ck track =seq.createTrack();ShortMessage a = new ShortMessage();a.setMessage(144, 1, 44, 100);MidiEvent noteOn = new MidiEvent(a, 1);track.add(noteOn);ShortMessage b = new ShortMessage()ib. setMessage (128, 1, 44, 100);MidiEvent noteOff = new MidiEvent(b,track.add(noteOff);PlAt SOMe MidiEvetl'ts into the T-sek. This fartis Mostly Ready-bake tode. The only thin~ YOlA'1lhave to tare abolAt al'"e the al'"~llMents to thesetMessa~e() ""ethod, and the al'"~llMents tothe MidiEvent t.onshlAtk. We'/Ilook at thoseal'"~llMents on the ne1l.t ra~e .player. setSequence (seq); ~ qive the Se,\llent.e to the Se,\llent.er (likeplayer.start (); 4:-- flAHin~ the CD in the cD fla-yel'")Sfdl'"i() thecatch (Exception ex) { SeC(llehter Oike PlASh'ex. p r i nt St ackTr ace (); 'n~ PLAy)} I I c l o s e playI I clos e c lass342 cha pter 11


exception handlingMakit1g a MidiEvettt (SOttg data)A MidiEvent is an instruction for part ofa song. A series of MidiEvents iskind oflike sheet music, or a player piano roU. Most of the MidiEvents wecare about describe a thing to do and the momentin time to do it. The momentin time part matters, since timing is everything in music. This note followsthis note and so on. And because MidiEvents are so detailed, you have to sayat what moment to start playing the note (a NOTE ON event) and at whatmoment to step playing the notes (NOTE OFF event). So you can imaginethat firing the "stop playing note G" (NOTE OFF message) before the "startplaying Note en (NOTE ON) message wouldn't work.The MIDI instruction actually goes into a Message object; the MidiEvent isa combination of the Message plus the moment in time when that messageshould 'fire'. In other words, the Message might say, "Start playing MiddleC" while the MidiEvent would say. "Trigger this message at beat 4".So we always need a Message and a MidiEvent.The Message says what to do, and the MidiEvent says when to do it.1 MidiEVent sayswhBtto do and~todo~Everg~onmust include the~s.fortbatin8tJtuction..In other words, atwhich-beat thatthing ahould happen.• Make a MessageShortMessage a = new Shor~Message();• Put the Instruction in the Message "start y\a'li,,~ ~ ~.ya. se~Message(144, 1, 44, 100); ~(- Th~ ...~~e s.a~ othtT """,'oeYS Ol\ ~e• Make Q new MidlEvent using the Message(~e'\\ \oo\t at &e"Vot. ya~e)• Add the MidiEvent to the Trackyou are here ~ 343


contents of a Midi eventMIPltttessage: the heart of a MidiEvet1fA MIDI message holds the part of the event that says toha: to do. The actual instructionyou want the sequencer to execute. The first argument of an instruction is always the typeof the message.The values you pass to the other three arguments depend on the type ofmessage. For example, a message of type 144 means UNOTE O~'·. But in order to carryout a NOTE ON. the sequencer needs to know a few things....fuiagine the sequencer saying.~OK, I'll playa note, but whu:h chantul? In other words. dc/you want me to playa Drumnote or a Piano note? And which note? Middle-C? D Sharp? And while we're at it. at whichIvekJcity should I play the note? \ ,To make a MIDI message, make a ShortMessage instance and invoke setMessageO I passingin the four arguments for the message. But remember, the message says only iahiuu» do. soyou still need to stuff the message into an event that adds when that message should 'fire'.Anatomy of a messageThe first argument to setMessageO alwaysrepresents the message 'type', while the otherthree arguments represent different thingsdepending on the message type.The Message says what to do, theMidiEvent says when to do it,~t. ~"\-:>r>f" il'c. Jd,V ~ ~~....t; ~ '(P - ~f:ja.setMessage(144, 1, 44, 100);neldsf.3~~ Message typetyP ' . ~ Yd'ry dej>eJldje. Thl$ 1$ i NOTE ~ 0I'l ~ ~~~ ~~~ ~f.o ~ .il"t tot" tJ.. .1, ~t, so thek"o'ol i" ot"d .1 '~s U1t St,~~ "[D rl.y • "ote. "eedt• ChoMelThink of a channel like a musician ina band. Channell is musician 1 (thekeyboard player), channel 9 is thedrummer, etc.• Note to playA number from 0 to 127, goingfrom low to high notes.• VelocityHow fast and hardyou press the key? 0 is so soft youprobably won't hear anything, but 100 is agood default.344 chapter 11


exception handlingChat1ge a tMessageNow that you know what's in a Midi message, you can start experimenting. Youcan change the note that's played, how long the note is held, add more notes,and even change the instrument.• Change the noteTry a number between 0 and 127 in the noteon and note off messages.-a. setMessage (144, 1, 20, 100);• Change the duration of the noteChange the note off event (not the message) sothat it happens at an earlier or later beat.b.setMessage(128, 1, 44, 100);MidiEvenc noteotf = new MidiEvent(b, 3);-Change the instrumentAdd a new message, BEFORE the note-playing message,that sets the instrument in channell to something otherthan the default piano. The change-instrument messageis '192', and the third argument represents the actualinstrument (try a number between 0 and 127)you are here 345


change the instrument and noteThis version still plays just a single note, but you get to use command-line argumeritsto change the instrument and note. Experiment by passing in two int valuesfrom 0 to 127. The first int sets the instrument, the second int sets the note to play.import javax.sound.midi.*;,/public class MiniMusiccmdLine / / thiS£'the first oneIpublic static void main(Scringl) args;) (MiniMusicCmdLine mini = new Mini~usiccmdL ine();if (a rqs .length < 2) (System.ouc.println("Don'C forget che instrumentelse (int instrument = Integer.parselnt(argsIO])iint note = Integer.parselnC(args[l)l;mini.play(instrumenc, note);and note args");) 1/ c lose mai.npublic void play(int instrument, int note) {trySequencer player = MidiSystem.getSequencer();player.open();Sequence seq = new Sequence(Sequence.PPQ, 4);Track track = seq.createTrack(),MidiEvent event = null;ShortMessage first = new ShortMessage();first. setMessage (192, 1, instrument, 0);MidiEvent changelnstrument. = new MidiEvent (first,track.add(changelnstrument);1) ;ShortHessage a = new ShortMessage();a.setMessage(144, 1, note, 100);MidiEvent noteOn = new MidiEvent(a, 1);track.add(noteOn);ShortMessage b ~ new Shor~essage();b.setMessage(12B, 1, note, 100);MidiEvent noteOff = new MidiEvenc(b, 16);track.add(noteOffl,player.setSequence(seq);player. start ();Rvr. rt wi~ two i"i ~ -h-Ot'


exceptJon handlingWhere we're headed with the restof the CodeKitchensChapter 15: the goalWhen we're done, we'll have a workingBeatBox that's also a Drum Chat Client.We'll need to learn about GUIs (includingevent handling), I/O, networking, andthreads. The next three chapters (12, 13,and 14) will get us there.Chapter 12: MIDI eventsThis CodeKitchen lets us build a little"music video" (bit of a stretch to call itthat...) that draws random rectangles tothe beat of the MIDI music. We'll learnhow to construct and play a lot of MIDIevents (instead of just a couple, as we doin the current chapter).0.11 !l!.Chapter 13: Stand.-aloneBeatBoxNow we'll actually build the real Beat Box,GUI and all. But it's limited-as Soonas youchange a pattern, the previous one is lost.There's no Save and Restore feature, andit doesn't communicate with the network.(But you can still use it to work on yourdrum pattern skills.)Chapter 14: Save andRestoreYou've made the perfect pattern, andnow you can seve it to a file, and reload itwhen you want to play it agoin. This getsus ready for the 'final version (chapter 15),where instead of writing the pattern to afile, we send it over a network to the chatserver.you ar e here ~ 347


exercise: True or FalseThis chapter explored the wonderful world ofexceptions. Your job is to decide whether each of thefollowing exception-related statements is true or false.~rl\\I-01\ F9~~1. A try block must be followed by a catch ind a finally block.2. Ifyou write a method that might cause a compiler-checked exception, youmust wrap that risky code in a try I catch block.3. Catch blocks can be polymorphic.4. Only 'compiler checked' exceptions can be caught5. Ifyou define a try / catch block, a matching finally block is optional.6. Ifyou define a try block, you can pair it with a matching catch or finally block,or both.7. Ifyou write a method that declares that it can throw a compiler-checked exception,you must also wrap the exception throwing code in a try / catch block.8. The main ( ) method in your program must handle all unhandled exceptionsthrown to it.9. A single try block can have many different catch blocks.10. A method can only throw one kind of exception.11. A finally block will run regardless ofwhether an exception is thrown.12. A finally block can exist without a try block.13. A try block can exist by itself, without a catch block or a finally block.14. Handling an exception is sometimes referred to as .ducking'.15. The order of catch blocks never matters.16. A method with a try block and a finally block, can optionally declare theexception.17. Runtime exceptions must be handled or declared.348 chapter 11


exception handlingCode MagnetsA working Java program is scrambled up on the fridge. (an youreconstruct all the code snippets to make a work ing Java programthat produces the output listed below? Some of the curly braces fellon the floor and they were too small to pick up, so feel free to add asmany of those as you needl/ . t(Ur U)", system.out . pr 1.n I\system.out.print(ut u ) ;doRisky(test)isystem.out.println(UsU);} finallyclass MyEx extends Exception < }public class ExTestDrive (lU y e~S .equalslt») {system.out.print(Ua U ) ;throw new MyEX()i} catch (MyEx e) {static void doRisky(String t) throws MyEx (Systern.out.print(Uh");. st iog [J args) {public static void ma1.n( rstring test = args[O);yo u are here . 349


puzzle: crosswordJavaOr~ss r. O-/" 10.' .II--You know what to dolI116I'~- -- r IflJI.ILYf--Across 20. Class hierarchy Down 12. Javac saw it coming1. Togivevalue 21. Toohotto handle 2 Currently usable 14. Attempt risk4. Flew off the top 24. Commonprimitive 3. Template's creation 16. Automaticacquisition6. All thisand morel 25. Coderecipe 4. Don't showthe kids 17. Changing method8. Start 27. Unrulymethod action 5. MostlystaticAPI class 19. Announce a duck10. The family tree 28. NoPicasso here 7. Not about behavior 22 Deal with it13. No ducking 29, Start a chainof events 9.Thetemplate 23. Create badnews15. Problem objects 11. Roll anotheroneoff 26. Oneof my roles18. Oneof Java's '49'the lineMore Hints:.J3U36. PION 'llilUntJQl,(IIUJI!l a4\- - '9 1111l2jap JO 'lI


exception handlingCode Magnetsclass MyEx extends Exception { }public class ExTestDrive {1. False, either or both.2. False, you can declare the exception.3. True.4. False, runtime exception can be caught.5. True.6. True, both are acceptable.public static void main (String [J arqs) {String test = args[O]:try {syatem.out.print(Nt"):doRisky(teat):System.out.print(Ho");} catch ( MyEx e) {7. False. the declaration is sufficient.8. False, but ifit doesn't theJVM may shutdown.9. True.10. False.11. True. It's often used to clean-up partiallycompleted tasks.12. False.13. False.14. False. ducking is synonornous with declaring.15. False, broadest exceptions must be caughtby the last catch blocks.} finally {System.out.print(Hw");}System.out.println(Ns")j}static void doRisky(String t) throws MyEx {System.out.print(Hh H);if ("yesH.equals(t)}throw new MyEx();System.out.print(Wr")j16. False, ifyou don't have a catch block, youmust declare.17. False.}yo u are here. 351


puzzle answers•362 chapter 11


12 getting QuiA Very GraphicStoryWow! This looks great.I guess presentationreally is everything.Face it, yo U need to make GUIs. If you're bu iIdlng appllcations that otherpeople are going to use,you need a graphical interface. If you're building programs for yourself.you want a graphical Interlace. Even if you believe that the rest of your natural life will bespent writing server-side code, where the client user interlace Is a web page, sooner or lateryou'll need to write tools, and you'll want a graphical Interface. Sure, command-line apps areretro. but not In a good way.They're weak, inflexible, and unfriendly. We'll spend two chaptersworking on GUls,and learn key Javalang uage feat ures along the way Includ ing EventHandling and Inner Classes. In this chapter, we'll put a button on the screen, and make It dosomething when you click It. We'll paint on the screen,we'll display a Jpeg image, and we'll evendo some animation.th is is a new chap ter 353


your first guiIt all starts with a WiMdowA]Frame is me object that representsa window on the screen. It's where youput all the interface things like buttons,checkboxes, text fields, and so on. It canhave an honest-to-goodness menu barwith menu items. And it has all the littlewiodowing icons for whatever platformyou're 00, for minimizing, maximizing, anddosing me window.TheJFr.ame looks different depending onthe platform you're on, This is aJFrame onMacOSX:"If I see one morecommand-line app,you're fired.""6 60File Panlc ~ Devl a l e'"t c1lc\c me-"@ choose meMaking a GUI is easy:• Make a frame (0 JFrame)JFrame frame = new JFrame () ;Put wldge1's it1 the wh,dow~ ~Once you have aJFrame, you can putthings (widgets') in it by adding themto theJFrame. There are a ton ofSwingcomponents you can add; look for themin rhe javax.swing package. The mostcommon include]Button,JRadioBuHon,JCheckBox,jLabel,jList,jScroIIPane,JSlider,JTextArea,]TextFie1d. and]Table. Most are really simple to use, butsome (likeJTable) can be a bit morecomplicated.@)Make a widget (button, text field , etc.)JButton button = new JButton ("clicJc ms");• Display it C9ive it a size and make iT visible)frame.setsize(300,300);frame.setvisible(true);354 ch apte r 12


geWng QuiYour first &UI: a button Ottafrattteimport javax.swinq.*;public class SimpleGuil { ~public static void DlAi.n (String£] &rgll) ( ~ a.....e ar-d a~ ",a'tt. a Y cb-\Ol.~~r.ame frame :: new JFrame () ; ~ rc" ('/0'" Ul'l ~aS$ tne hv-cbm t,o~JButton hutton '" new JButton ("click meN) ; tM W~ '(0" ....,al'l~ 0l'I the hLet's see what happens when we run It:%java SimpleGuilWhoa! That's aReally Big Rutton.The button fills all theavailable space in the frame.Later we'll learn to controlwhere (and how big) thebutton is on the frame.you are here) 355


user Interface eventsJut ttothh1g happetts whett Iclick it...That's not exactly true. When you press the button it shows that~pressed'or 'pushed in' look (which changes depending on theplcttfonn look and feel, but it always does something to show whenit's being-pressed).The real question is, "How do I get the button to do somethingspecific when the user clicks it?"We need two things:~ A method to be called when the userclicks (the thing you want to happen asa result of the button click).@ A way to know when to triggerthat method. In other words, a wayto know when the user clicks thebuttonlQ: Willa button look like aWindows button when you run onWlndows7i\.: If you want it to. You canchoose from a few~look andfeels~-c1asses in the core librarythat control what the interface lookslike. In most casesyou can choosebetween at least two different looks:the standard Java look and feel, alsoknown as Metal, and the native lookand feel for your platform.The MacOSX screens in this book use eitherthe as x AquQlook and feel, or theMeta/look and feel.Q: Can I make a program looklike Aqua all the tJme7 Ellen whenIt's runnIng underWindows7A: Nope. Not all look and feelsare available on every platform. Ifyou want to be safe,you can eitherexplicitly set the look and feel toMetal, so that you know exactly whatyou get regardless of where the appis running, or don't specify a lookand feel and accept the defaults.When the user clicks, we wantto know.We're interested in the usertakes-action-on-a-buttonevent.Q: 1heard Swing was dog-slowand that nobody uses It.A: This was true in the past,but Isn't a given anymore . On weakmachines, you might feel the pain ofSwing. But on the newer desktops,and with Java version 1.3 and beyond,you might not even notice thedifference between a Swing GUI anda native GUI.Swing Is used heavilytoday, in all sorts of applications.358 chap ter 12


getting gui&ettit1g a user evetttImagine you want the text on the button tochange from cuck meto I've been clicked whenthe user presses the bltton. First we can write amethod that chang51' the text of the button (aquick look.Jhr.ougfi the API will show you themethod):public void changelt() (button. setText("I' va bean clickedl");First, the button needs to knowthat we care.~C'f \l~, I ta--e aW• ...,~t. haffe¥\S -to yt»-Iyour code Ir>But nowwhat? How will we know when thismethod should run? How will we know when thebuttonis clidred?Injava, the process of getting and handling auser event is called event-handling. There aremany different event types inJava, althoughmost involve GUI user actions. If the user clicksa button, that's an event. An event that says-The user wants the action of this button tohappen." Ifit's a "Slow Tempo" button, the userwants the slow-tempo action to occur. Ifit's aSend button on a chat client, the user wants thesend-roy-message action to happen. So the moststraightforward event is when the user clickedthe button, indicating they want an action tooccur.With buttons, you usually don't care about anyintermediate events like button-is-being-pressedand button-is-being-released. What you want tosa)' to the button is, "I don't care how the userplays with the button, how long they hold themouse over it, how many times they change theirmind and roll off before letting go, etc.Just teDmewhen the usermeans business!In other words,don't call me unless the user clicks in a way thatindicates he wants the darn button [0 do what itsays it'll dol"Second, the button needs a wayto call us back when a buttonclickedevent occurs.1) How could you tell a button object that youcare about Its events? That you're a concernedlistener?2) Howwillthe button call you back? Assumethat there's no way for you to tell the button thename of your unique method (changeltOl.Sowhat else can we use to reassure the button thatwe have a specific method It can call when theevent happens? (hint:think Pet)you are here) 351


event listenersIf you care about the button's events,"'1W.i~iM"''''''''''''''IIiiII''''''-ii1thatsays,ClI'm~or your events."A listener interlace is the bridge between the',istener (you) and event source (the button).JTheSwing GUI components are event sources. In Java terms,an event source is an object that can tum user actions (dicka mouse, type a key, close a window) into events. And likevirtually everything else in lava, an event is represented as anobject. An object ofsome event class. Ifyou scan th rough thej ava.aWl.event package in the API, you 'I) see a bunch of eventclasses (easy to spot-they all have Event in the name). You'llfind MouseEvent, KeyEvent, '-\'indowEvent, ActionEvent, andseveral others.\lJhen you imPlement alistener interface, you. givethe hutton a way to callyou hack. The interface iswhere the call-hack methodis declared.An event source (like a button) creates an event object when theuser does something that matters (like clickthe button). Mostof the code you write (and all the code in this book) will receiveevents rather than create events. In other words, you'lJ spendmost of your time as an event listenerrather than an event source.Every event type has a matching listener interface. Ifyou wantMouseEvents, implement the MouseListener interface. WantWindowEvents? Implement WindowListener. You get the idea.And remember your interface rules-e-tc implement an interfaceyou declare that you implement it (class Dog implements Pet) ,which means you must write implementation methodsfor everymethod in the interface.Some interfaces have more than one method because theevent itself comes in different flavors. If you implementMousel.istener, for example, you can get events formousef'ressed, mouseReleased, mouseMoved, etc . Each ofthose mouse events has a separate method in the interface.even though they all take a MouseEvent. Ifyou implementMousel.istener, the mousePressedO method is called when theuser (you guessed it) presses the mouse. And when the user letsgo, the mouseReleased() method is called. So for mouse events,there's only one event object; Mouseliveru, but several differentevent methods, representing the different types of mouse events.


getting guiHow the listener and sourcecommunicate:"Button, please add me toyour Jist of listeners and callmy actionPerformedO methodwhen the user clicks you.""OK, you're an ActionListener,so I know how to call you backwhen there's an event -- I'll callthe actionPerformedO methodthat I knowyou have."",'"'0'"o~·.10ActionListenef'(0 11...r"S)The ListenerIf your class wants to know abouta button's ActionEvents,youim plement the ActionLlstenerinterface.The button needs toknow you're Interested, so youregister with the button by calling ItsaddActionLlstener(this} and passing anActionListener reference to It (In this case,youare the ActIonListener so you passthis).The button needs a way to call youback when the event happens, so it callsthe method in the listener Interface. As anActionUstener, you must Implement theinterface's sole method, actlonf'erformedt).The compiler guarantees It.The Event SourceA button is a source of ActionEvents,so it has to know which objects areinterested llsteners.The button has anaddActionUstenerO method to giveInterested objects (listeners) a way totellthe button they're interested.When the button'saddAetionLlstenerO runs (becausea potential listener invoked it), thebutton takes the parameter (areference to the listener object) andstores it in a list. When the user clicksthe button, the button 'fires'the eventbycal/Jng the actionPerformedOmethod on each listener In the list.you are here ~ 359


getting eventsGetting a button's ActionEvent• Implement the ActionListener interface•I) Register with the button (tell it youwant to listen for events)• Definethe event-handling method (implementthe actionPerformedO method from theActionListener interrface)public static void main (String[] args)SimpleGuilB qui = new SimpleGuilB();quLgoO;


getting guillsfetters, Sources, attd EvettfsFor most of your steUar Java career, yO'll will not be the source\ofevents.J~=\er how much you/ci yourself the center ofyour socialGet used to it. Your~ to be a goodlistener.(Which. ifyou do it sincerely, can improve your social life.)As a listener, my job is toImplement the interface,register with the button, andprovide the event-handling.As an e.vent source, my job is toaccept rt9istrations (from listeners),get events from the. user. andcall the listener's event-handlingmethod (when the user clicks me)CbSource SENDSIIthe eventListener GETS theeventHey, what about me? rm a player too, youknowI As an event object, I'm the argumentto the event call-back method (from theinterface) end myjob is to carry data about'ke event back to the listener.Event objectHOLDS DATAabout the eventyou are here) 361


event handlingQ: Why can't I be a source of events?..A..:You CAN.We just said that most of the timeyou'll be the receiver and not the originator of thee~nt (at least in the early days ofyour brilliant Javacare~(he events you might care aboutare'fi red' by classes in the Java API,and all you haveto do Is be a listener for them.You might, however,design a program where you need a custom event, say,StockMarket Event thrown when your stock marketwatcher app finds something It deems Important. Inthat case, you'd make the StockWatcher object be anevent source, and you'd do the same things a button(or any other source) does-make a listener interfacefor your custom event, provide a registration method(addStockListener()), and when somebody calls It, addthe caller (a listener) to the list of listeners.Then, whena stock event happens, Instantiate a StockEvent object(another classyou'll write) and send It to the listenersIn your list by calling their stockChanged(StockEventev) method. And don't forget that for every event typethere must be a matching listener Interface (so you'llcreate a StockLlstener Interface with a stockChangedOmethod),Q: J don't see the Importanee of the event objectthat's passed to the event call-back methods. Ifsomebody calls my mousePressed method, whatother Info would I need?A: A lot of the time, for most designs, you don'tneed the event object. It's nothing more than a littledata carrier, to send along more info about the event.But sometimes you might need to query the event forspecific details about the event. For example, If yourmousePressedO method is called, you know the mousewas pressed. But what If you want to know exactlywhere the mouse was pressed? In other words, what Ifyou want to know the Xand Y screen coordinates forwhere the mouse was pressed?Or sometimes you might want to register the somelistener with multiple objects. An onscreen calculator,for example, has 10 numeric keys and since they all dothe same thing, you might not want to make a separatelistener for every single key.Instead, you mightregister a single listener with each of the 10 keys, andwhen you get an event (because your event call-backmethod is called) you can call a method on the eventobject to find out who the real event source was.Inother words, which key sent this event.Eachof these widgets (user Interface objects) are thesource of one or more events. Match the widgets withthe events they might cause. Some widgets might be asource of more than one event, and some events can begenerated by more than one widget.Widgetscheck boxtext fieldscrolling listbuttondialog boxradio buttonmenu ItemEvent methodswlndowClosing()action Perfonned()ItemStateChanged0mousePressed()keyTyped()mouseExlted()focusGalned()362 chapter 12


getting Qui&ettittg back to graphics...Now that we know a little about how events work (we'll learnmore later), let's get back to putting stuffon the screen.We'll spend a few minutes playing with some fun ways to getgraphic, before returning to event handling.Three ways to put things on your GUI:~etson Q frameAdd buttons, menus, radio buttons, etc.frame.getcont&ntPane() .add(myButton);The javax.swing package has more than a dozenwidget types.• Drow 2t> graphics on Q widgetUse a graphics object to paint shapes.graphics.fi110val(70,70,lOO,lOO) ;You can paint a lot more than boxes and circles;the Java2D API is full of fun, sophisticatedgraphics methods. ;'f '\.


making a drawing panelMake your ow., drawi.,g widgetIfyou want to put your own graphics on the screen, your bestbet is to make your own paintable widget, You plop that widgeton the frame.just like a button or any other widget, but when itshows up it will have your images on it. You can even make thoseimages move, in an animation, or make the colors on the screenchange every time you click a button."i~i~ofcake.Make a subclass of JPanel and override onemethod, palntComponentO.All ofyour graphics code goes inside the paintComponentOmethod. Think ofthe paintComponentO method as the methodcalled by the system to say, "Hey widget, time to paint yourself."Ifyou want to draw a circle, the paintComponentO method willhave code for drawing a circle. When the frame holding yourdrawing panel is displayed, paintComponentO is called and yourcircle appears. Ifthe user iconifies/minimizes the window, theJVM knows the frame needs "repair" when it gets de-iconified,so it calls paintComponentO again. Anytime the JVM thinks thedisplay needs refreshing, your paintComponentO method will becalled.One more thing, yflU never call this methodYfnl;T$e1j! The argumeotto this method (a Graphics object) is the actual drawing canvasthat gets slapped onto the realdisplay. You can't get this byyourself; it must be handed to you by the system. You'll seelater, however, that you can ask the system to refresh the display(repaint() ), which ultimately leads to pai ntComponent () beingcalled.J. lc."t~import java. awt. * i _ ¢(.o b~, ~ ~oI'import j avax . swing. *; ~•}364 chapter 12


getting guiFutt fhit1Qs to do itt paittfCotMpottet1fULet's look at a few more things you can do in paintflomponentj).The most fun, though, is when you start experimenting yourself.Try playing with the numbers, and check the API for classGraphics (later we'll see that there's even more you can do besideswhat's in the Graphics class).Dls~Gpublic void paintComponent (Graphics g) { rI~s 't.eY t~',\t ...a",t. ~....,ov'(Image image = new Imagelcon ("catzilla. jpqU) . getImage () ;JPaint a randomly-colored circleon a black backgroundpublic void paintComponant(Graphics g)g.fillReot(O,O,this.getWidth(),int red = (int) (Math.random() * 255);int green = (int) (Math.random() * 255);int blue = (int) {Math.random(} * 255);Color randomColor = new Color(red, green,g.setColor(randomColor);g.fillOval(70,70,lOO,lOO);~idrf 70 .f~t to pll(ds fro", fh J t:J00 .p, ~ke it 100 . t: t"tt, 70 trPlxds ~II. pl'l


drawing gradients with Graphics2D'ehit1d every good c.raphics referettceis a Oraphies!e object.\IThe argument to paintComponentO is declared as typeGraphics (java.awt.Graphics).pubU.c void pa..intcomponent(G:r:a.phiclI q) ( }So the parameter 'g' IS-AGraphics object. Which means itcouldbe a subclassofGraphics (because of polymorphism).And in fact, it is.The object referenced by the tg'parameter is adually aninstance ofthe Graphics2D class.Why do you care? Because there are things you can do witha Graphics2D reference that you can't do with a Graphicsreference. A Graphics2D object can do more than a Graphicsobject, and it really is a Graphics2D object lurking behind theGraphics reference.Remember your polymorphism. The compiler decides whichmethods you can call based on the reference type, not theobject type. Ifyou have a Dog object referenced by an Animalreference variable:Animal a = new Dog();You can NOT say:a.bark () iEven though you know it's really a Dog back there. Thecompiler looks at 'a', sees that it's oftype Animal, and findsthat there's no remote control button for barkr) in the Animalclass. But you can still get the object back to the Dog it really isby saying:Doq d "" (Doq) Aid.buk () ;So the bottom line with the Graphics object is this:If you need to use a method from the Graphics2D class, youcan't usethe the paintComponent parameter ('g') straightfrom the method. But you can cast it with a new Graphics2Dvariable.Graphics2D q2d B (Graphics2D) qi-Methods you can call on 8Graphics reference:drawlmageOdrawLlneOdrawPolygondrawRectOdrawOvalOfillRectOfillRoundRect()setColor()To cast the Graphlcs2D object toa Graphlcs2D reference:Graphics2D g2d = (Graphics2D) g;Methods you -can call ona Graphlcs20 reference:IiII3DRecl0draw3DRectOrotate 0scaleOsheerOtransformOselRenderingHlntsO(these are ~ot t.mr.pltf:t ",ethod lish,thetk the API .few ",ewe.>366 chapter 12


getting gui'ecause life"s too short to paint thecircle asolid color when there"s agradient blend waithtg for you.~ublic void IntComponent(Graphics g) (Graphic 2D q2d : (Graphics2D) g:~ tast it so 'Nt tar- tall ~ir-~ tha~~.iphiul.D roas b~ ~rarhits aocsr-'i.GradientPalnt gradient: new GradientPaint(70 ,70,Color.blue, 150,150, COlor.orange);st.rf:j r ~rtih 't ~. ~ ~~d;" ~h~ Poi~t s 4>Jor '''.9 poi,,/; s toJor~ this sets tht virboaI . 1. L .d' 1.. falPl~ urush to .ig2d. aetPaint (gradi.ent) : ~ra I~l;; Ilumd 0+ a solid lolorg2d.filloval(70,70,100,100);"'" 1\ OY\S " ~ i\\tht ~i\\O~~\(~:~~t~ \1:~eo (J'rIthe O~d\ ~I~. Lhe ~rddit"t). LL...l>Sh u.e- '{. Jyal"~''foVr~llc void paintComponent(Graphics q) (Graphics2D g2d = (Graphlcs2D) g;int red D (lnt) (Math .random() .. 255);int green: (int) (Math.random() .. 255);lnt blue e (lnt) (Math .random() .. 255);Color startColor = new Color(red, green, blue);red = (lnt) (Math . random () .. 255);green: (lnt) (Math.random() .. 255);blue: (lnt) (Math,random() * 255);Color endColor = new Color (red, green, blue) ;GradientPalnt gradient = new GradientPalnt(70,70,startColor, 150,150, endColor);q2d.setPaint(qradient);g2d.fillOval(70,70,100,100) ;you are here ~ 367


events and graphics,...-----EVENTS--------------,• To make a GUI, start with a window, usually aJFrameJFrame frame = new JFrame();• You can add widgets (buttons, text fields, etc.) totheJFrame using:frame. getcontentPane () .add(button);• Unlike most other components, the JFrame doesn't letyou add toit directly, so you must add to the JFrame'scontent pane.• To make the window (JFrame) display, you must give Ita size and tell it be visible:frama.setSize(300,300);frame.sBtVisihle(true);• To know when the user clicks a button (ortakes someother action on the user interface) you need to listen fora GUI event.• To listen for an event, you must register your Interestwith an event source.An event source Isthe thing (button,checkbox, etc.) that 'fires' an event based on userinteraction.• The listener Interface gives the event source a waytocall you back, because the Interface defines themethod{s) the event source will call when an eventhappens.• To register forevents with a source, call the source'sregistration method. Registration methods always takethe form of: add


getting guiWe catt get att evet1t.We catt paittt graphics.&ufcatt we paittt graphics when we get att evettt?Let's JOOk up an event to a change in our drawing panel. We'll make the circlechanle colors each time you click the button. Here's how the program flows:Start the appoThe frame is built with the two widgets(your drawing panel and a button). Alistener is created and registered withthe button. Then the frame is displayedand it just waits for the user to click.eThe user clicks the button and thebutton creates on event object andcalls the listener's event handler.e Theevent handler calls repaintO on theframe. The system calls paintCompone.ntOon the drawing panel.oVoila!A new color is painted becausepaintComponentO runs again, filling thecircle with a random color.you are here ~ 369


uilding a GUI framedo you put TWOthings on a frame?&Ullayouts: putti"g tttore thatt o.,ewidget Ott a frattteWe cover GUI layouts in the nextchapter, but we'll do aquickie lesson here to get you going. Bydefault, a framehas five regions you can add to. You can add only onethingto each region ofa frame, but don't panic! That one thingmight be a panel that holds three other things including apanel that holds two more things and ... you get the idea. Infact, we were 'cheating' when we added a button to the frameusing:------dd~u/t ~iOll-Given the pictures on page 351, write thecode that adds the buttonand the panel tothe frame.370 chapter 12


getting guiThe circle changes color each time youclick the button.import javax.awing.*;import java.awt.*;import java.awt.event.*; ~public class SimpleGui3C (implemants ActionListaner (JFrame frame;public static void main (String [] arqs)SimpleGu13C qui '" new SimpleGui3C():qui.go (J ;public void go() {frame '" new JFrame();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ;JButton button'" new JButton ("Change colors");button. addActionListener (this) ; ~ _MyDrawPanel drawPanel = new MyDrawPanel () ; Add tile two wid~e-b (b"iframe.getContentPane () . add{BorderLayout. SOUTH, button); ~/ k dl'ld d\"..w i,,~ r~l'Iel) toframe. 98tContentPane () .add(BorderLayout. CENTER, drawPanel); I( ~he two \"e~ iOf\.S cJ theframe. setSize (300,300) ;frame. setVisible (true) ;-tra"'e.class MyDrawPanel extends JPanel (public void paintComponent(GraphicB q) (/ / Code to 1Ul the oval wlth a random color/ / See page 347 for the codeyou are here) 371


multiple listeners/ Let's try itwith TWO buttons(The south button will act as it does now, simply calling repaint 00 theframe. The second button (which we'll stick in the east region) willchange the text on a label. (A label isjust text on the screen.)So .,ow we t1eed FOUR widgets-label will~o na-e- ~t>td __ awin~ panel ~oes~ in the tenu__toICK-t~n~in~b~ will ~o htreeAttd we tteed to getrwo eventsChange LabelUh-oh.Is that even possible? How doyou get two events when youhave only O11C actionPerfonnedOmethod?372 chapter 12


geWng guiHow do you get actio" eve"ts for two dlffere"t butto".,whe~ each butto" "eeds to do solttethi"Q dffferettt?iI-.• option oneImplement two actionPerformedO methods.--class MyGui implements ActionListener (II Iota of oode bere and then:publi~ void actionPerfo~d(ActionEventevent) (frame. repaint () ;public void actionPerformed(ActionEvent event) {label. setText ("That hurt! /I ) ;~ ~t. this is i"'possible'~ .Flaw: You can'ti You can't Implementthe same method twice In a Java class. It won't compile.And even if you could, how wou Id the event source know which of the two methods to call?• option twoRegister the same listener with both buttons.-class MyGui implements ActionLletaner (I I declare a bunch of instance variables berepubli~ void go() (II build quieolorButton ~ new JButeon():labelButton = new JButton() ;colorButton. addActionListener (th1e) ; ~ R.l!~isUr the ~",e lisU-"e"labelBut ton .addActionListener (this) ; l( 'NI8, b~ blottoruI I more qW. code here . ..public void actionPerformed(ActionEvant event) {if (event. gatSource () = colorButton) ( t, ab' ~d.frama .repaintO;~ G.~ t,nt l!'1l!'\tt. ~~8:Pnelee ( to ~i)\d ov-t. '01". "d lAStlabel.setText("That burt!/I); at~\\'( ~·,ye.ci It.. a Lto do­-lhd-t t.o dl!tid~ ",,"41~Flaw: this does work, but In moat cases It's not very 00. One event handlerdoing many different things means that you have a single method doing many different things.If you need to change how onesource is handled, you have to mess with everybody's eventhandler. Sometimes It is a good solution, but usually it hurts maintainability and extensibility.you are here. 373


multiple listenersHow do you get actio" evettts for two dffferettt butfotts,whett each buttott tteeds to do sotltethittQ differettt?• option threeCreate two separate ActlonListener classesalass MyGui (JFraIDe frame;JLabe.l label;void gui() (/ J code to instantiate the two listeners and reqister one1/ with the color button and the other with the label button)II clos. classclass ColorButtonLiatener implements ActionListaner {public void actionPer£ol:m8d (ActionEvent event) (frame. repaint () ;, WO'I\l wot"k! Tnis tlau dool'l't ha~t a ~e~tr'Cl'lU tptl\e 't~a"'t' variable o.f the M'1~\oi daucla.ss LabelButtonListener implements ActionLiatener (public void actionPerfo~(ActionEventevent) (la.bel.setText("Tha.t hurt!H);~ Proble...1n ° I has r° IS t.. au 1'0 re-tere'lt..e to the variable 'label'Flaw: these classes won't have access to the variables they needto act on, 'frame' and 'label'. You could fix Itbut you'd have to give each ofthelistener classes a reference to the main GUI class,so that Inside the aetlonPerformedOmethods the listener could use the GUI class reference to accessthe variables of the GUIclass. But that's breaking encapsulatIon, so we'd probably need to make getter methodsfor the g ul widgets (getFrameO.qetl.abelf), etc.). And you'd probably need to add aconstructor to the listener class so that you can pass the GUI reference to the listener atthe time the listener is Instantiated. And, well, it gets messier and more complicated.There hQS gotto be Qbetterwayl374 chapter 12


getting guiyou are here. 375


inner classesItttter class tothe rescue!You can have one class nested inside another. It's easy.Just make sure that the definition for the inner class isinside the curly braces of the outer class.Simple inner class:class MyOuterClassclass MylnnerClassvoid goO (){An inner class canuse aU tIle metltOJsand ,'at'ial)les of theouter class, evert till'lwi"atr ones,An inner class gets a special pass to use the outer class's stuff. Eventheprivate stuff. And the inner class can use those private variablesand methods of the outer class as if the variables and memberswere defined in the inner class. That's what's so handy about innerclasses---they have most of the benefits of a normal class. but withspecial access rights.TIle inner class getsto use tlto...e "ariahlesanJ metltOds justas if tile mctltoJ...and variables wel'CJeclat'eJ within tlu~inner class.Inner class using an outer class variableclass MyOuterClass {private int x;c1809 MylnnerClas8 (void go () {x = 42; ~}II close inne~ classII close outer class376 chapter 12


getting gUiA., f.,.,er class it1sfa.,ce tMust be tied toat1 outer class it1stat1ce*.---Remember, when we talk about an inner class accessingsomething in the outer class, we're really talking about anillstan~ of the inner class accessing something in an instance ofthe 0tler class. But which instance?Can dry arbitrary instance of me inner class access the methodsand ~'l-iables of any instance of me outer class? No!"-An inner object must be tied to a spec fie outer object onthe heap.An inner objectshares a specialbond with anouter object. "


Inner class instancesHow to "'ake an instance of an inner classIfyou instantiate an inner class from code wilhin an outer class, the instanceofthe outer class is the one that the inner object will 'bond' with. Forexample, if code within a method instantiates the inner class, the innerobject will bond to the instance whose method is running../'Code in an outer class can instantiate one of its own inner classes, in exactlythe same way it instantiates any other class... new MyInner ()class MyOuter {\!is a ro-i'laUn~~ t.\au t Jprivate int x; ~ \~fIU "aYiilb\~ ..,.MyInner inner '" n_ MyInnar 0 ;~ ~dkt dl\ instal'lU 0+ in11I"tt" dilSSepublic void doStuff () {inner .go () ; II _u. _.I .LL(} ~ ta il ...nnou 01\ "toniJ\l'l~ t.\auMyOuterclass MyInner {void goO {-2 ('4r"--_}II close inner class} II close outer classMyOuterSide bar---------------------,You can Instantiate an Inner Instance from code running outsidethe outer class, but youhaveto usea special syntax. Chances are you'll go through your entireJava life and neverneedto makean Innerclass from outside,but just In case you'reInterested...class Faa {:publie statie void mairl (String[] arqll) (MyOutA!llr outarObj '" new MyOutar () ;MyOuter .MyInner innerObj .. outarObj. new MyInner () iMyInner378 chapter 12


getting guiNow we can get the two-buttoncode workingpublic class TwoButtonsJFr) frame ;JL~ labAl;/~l i C static void main CStrinq[) arqs)TwoButtons qui = new TwoButtODS ();qui .go () ;Cllong. LaMIpublic void got) (frame = new JFrame();frame. setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE) ;(+,h J to t ḥeJButton labelButton = new JButton ("Change Label");~ .,..rttad ere ~assi,,~ .:o..ab O'/'llabelButton.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.JButton colorButton = new JButton ("Change Circle"); ~ t ḣe ilW~'ilcolorButton.addActionListener(n_ ColorLiStaMr () ) :label = new JLabel("I'm a label");MyDrawPanel drawPanel = new MyDrawPanel():TwoButtorlSobjectframs.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):e:class Lahelt.1atener ~l.amanta_ Ac~_~~ls~~!. (public void actionPerformed(ActionEvent event) (lab&l.setTaxt("Ouch! ") :) , ~ iPl"~ tldSS kPlowsII close inner class ilbowt 'Iabd'ColorListenerobjectIII close inner classyou are here ~ 379


Inner classesJa¥a·~ed'This weeks Interview:Instance of an Inner ClassHeadFirst: What makes inner classes important?Inner object: Where do I start? We give you a chance toimplement the same interface more than once in a class.Remember, you can't implement a. method more thanonce in a normalJava class. But using inner classes, eachinner class can implement the same interface, so you canhave all these diffemu implementations of the very sameinterface methods.HeadFirst: Why would you ever warn to implement thesame method twice?Inner object: Let's revisit GUI event handlers. Thinkabout it... if you want thru buttons to each have adifferent event behavior, then use three inner classes, allimplementing Actionl.istener-r-which means each classgets to implement its own acrionPerformed method.HeadFirst: So are event handlers the only reason to useinner classes?Inner object: Oh, gosh no . Event handlers are just anobvious example. Anytime you need a separate class, butstill want that class to behave as if it were part of anotherclass, an inner class is the best-and sometimes only-wayto do it.HeadFirst: I'm still confused here. If you want the innerclass to behave like it belongs to the outer class, why havea separate class in the first place? Why wouldn't the innerclass code just be in the outer classin the first place?Inner object: I just glIl.lt you one scenario, where youneed more than one implementation of an interface. Buteven when you 're not wing interfaces, you might needtwo different classes because those classes represent twodifferent tlting.s. It's good 00.HeadFirst: Whoa. Hold on here. I thought a big part of00 design is about reuse and maintenance. You know, theidea that if you have two separate classes, they can eachbe modified and used independently, as opposed to stuffingit all into one class yada yada yada. But with an inner class,you're still just working with one real class in the end, right?The enclosing class is the only one that's reusable andseparate from everybody else. Inner classes aren't exactlyreusable. In fact, I've heard them called "Reuselessuselessover and over again."Inner object: Yes it's true that me inner class is not asreusable, in fact sometimes not reusable at all, because it'sintimately tied to the instance variables and methods ofthe outer class. But it-HeadFirst: -which only proves my point! If they're notreusable, why bother with a separate class? I mean, otherthan the interface issue, which sounds like a workaroundto me.Inner object: As I was saying, you need to think aboutIS-A and polymorphism.HeadFirst: OK. And I'm thinking about them because...Inner object: Because the outer and inner classesmight need to pass differtm IS-A tests! Let's start with thepolymorphic GUI listener example. What's the declaredargument type for the button's listener registrationmethod? In other words, if you go to the API and check,what kind of thing (class or interface type) do you have topass to the addActionLstener() method?HeadFirst: You have to pass a listener. Something thatimplements a particular listener interface, in this caseActionListener. Yeah, we know all this. What's your point?Inner object: My point is that polymorphically, you havea method that takes only one particular rype. Somethingthat passes the IS-A test for Actionl.istener, But-andhere's the big thing-what if your class needs to be an IS­A of something that's a cum type rather than an interface?HeadFIrat: Wouldn't you have your class just extend theclass you need to be a part of? Isn't mat the whole pointof how subclassing works? If B is a subclass of A, thenanywhere an A is expected a B can be used. The wholepass-a-Dog-where-an-Animal-is-the-declared-type thing.Inner object: Yes! Bingo! So now what happens if youneed to pass the IS-A test for two different classes? Classesthat aren't in the same inheritance hierarchy?380 chapter 12


getting guiHeadFirst: Oh, weU you just,.. hrnmm. I think I'm gettingit. You can always implement more than one interface,but you can extend only one class. You can only be one kind\of IS-A when it comes to elmstypes .\'Inner object: Well done! Yes, you can't be both a Dogand a Burton. BUt if you're a Dog that needs to sometimesbe a Burton (in order to pass yourself to methodsthat take a Buuon), the Dog class (which extends Animalso it can't extend Burton) can have an inner class that actson the Dog's behalf as a Button, by extending Burton,and thus wherever a Button is required the Dog canpass his inner Button instead of himself. In other words,instead of saying x.takebunoruthis), the Dog object callsx.takeButton(new Mylnnerfluttoruj).HeadFirst: Can I get a clear example?Inner object: Remember the drawing panel we used,where we made our own subclass ofJPanel? Right now.that class is a separate, non-inner, class. And that's fine,because the class doesn't need sp ecial access to the instancevariables of the main GUI. But what if it did? What ifwe're doing an animation on that panel, and it's getting itscoordinates from the main application (say, based on somethingthe user does elsewhere in the GUI). In that case, ifwe make the drawing panel an inner class, the drawingpanel class gets to be a subclass of]panel, while the outerclass is still free to be a subclass of something else.HeadFirst: Yes I see! And the drawing panel isn't reusableenough to be a separate class anyway, since what it'sactually painting isspecific to this one GUI application.Inner object: Yes! You've got it!HeadFirst: Good. Then we can move on to the nature ofthe relatirmshi/J between you and the outer instance.Inner object: What is it with you people? Not enoughsordid gossip in a serious topic Like polymorphism?HeadFirst: Hey, you have no idea how much the public iswilling to pay for som e good old tabloid dirt. So, someonecreates you and becomes instantly bonded to the outerobject, is that right?Inner object: Yes that's right. And yes) some havecompared it to an arranged marriage. We don't have a sayin which object we're bonded to.HeadFirst: ALight, I'll go with the marriage analogy.Can you gel a divorce and remarry something else?Inner object: No, it's for life.HeadFirst: Whose life? Yours? The outer object? Both?Inner object: Mine. I can't be tied to any other outerobject. My only way out is garbage collection.HeadFirst: What about the outer object? Can it beassociated with any other inner objects?Inner object So now we have it. This is what you reallywanted. Yes, yes. My so-called 'mate' can have as manyinner objects as it wants.HeadFirst: Is that like, serial monogamy? Or can it havethem all at the same rime?Inner object: All at the same time. There, Satisfied?HeadFirst: Well, it does make sense. And let's nOIforget, it wasyou extolling the virtues of "multipleimplementations of the same interface", So it makes sensethat if the outer class has three buttons, it would needthree different inner classes (and thus three different innerclass objects) to handle the events. Thanks for everything.Here's a tissue.you are here) 381


Inner classesUshtg att itttter class for atthttatiottWe saw why inner classes are handy for event listeners, becauseyou get to implement the same event-handling method morethan once. But now we'Ulook at how useful an inner class is whenused as a subclass of something the outer class doesn't extend. Inotherwords. when the outer class and inner class are in differentinheritance trees]Our goal is to make a simple animation, where the circle movesacross the screen from the upper left down to the lower right,1.81'1••Q:Why are we learning aboutanimation here11 doubt ifI'mgoing to be making games.How simple animation works• Paint an object ot a particular x and y coordinateq.fillOval(20,50,lOO,100) ;~t2-0 piuls +r-0I'tI the lett,c;o ril(~ls ~r-0I'tI the top• Repaint the object at a differe'1! x and y coordinateg.fillOval(25,55,lOO,lOO) ;t2? piuls ~rOl'tl the lett, 97piuls kr-Of'Il -the iof~(the objett ""oved a littledOWJl a...d to the \"i~nt.>• Repeat the previous step with changing x and y valuesfor as long as the animation is supposed to continue.A:vou might not be makinggames.but you might becreatIng simulations, wherethings change over time to showthe results of a process.Or youmight be building a visualizationtool that, for example, updatesa graphic to show how muchmemory a program is using,or to show you how muchtrafflc is coming throughyour load-balancing server.Anything that needs to take aset of continuously-changingnumbers and translate them Intosomething useful for gettingInformatlon out of the numbers.Doesn't that all sound businesslike?That's Just theMofficialjustlflcatlon: of course.The realreason we're covering it here isJust because it's a simple wayto demonstrate another useof Inner classes. (And becausewe Justlike animation, and ournext Head First book Is aboutJ2EE and we know we can't getanimation in that one.)382 chapter 12


w\ we !eally want is something like...getting gui/tssMyDrawPanel extends JPanel {public void paintcomponent(Graphics g) {g.setColor(Color.orange);g.fillOval(x,y/100,lOO)i~eaL\I b",e Y'II"~&:~a'I~t. ilt,d\\ecl. -\:)Ie O"Iil ~d\~~er",t. \~~ your penCilBut where do we get the new x and ycoordinates?And who calls repaint()?Seeif you can design a simple solution to get the ball to animate from the top left of thedrawing panel down to the bottom right Our answer Is on the next page,so don't tumthis page until you're done!Big Huge Hint make the drawi ng panel an inner class.Another Hint don't put any kind of repeat loop In the palntComponentO method.Write your Ideas (or the code) here:you are here ~ 383


animation using an inner class~ complete simple animation code\)import javax.swing.*;import java.awt.*;public olass SimplQAnimation ~ ~yo,U IIOtiab\es ,,, t,hL",a\c.L t.'WC ,YIS ~ t,hL "" d"d 'Iint x = 70it ~ ",d'l'I ~V.\ daS1. (/f" l.i'f'Cktnt y :II 70; ~ ~d"~ ~ t.ht.public static void main (Strinq[] arqa) (SimpleAnimation qu.i = new Si.mpleAnimation ();qui .go () ;public void go() (JFrama frame '" MlW JFrame () ;lrame.setDefaultCloa8Operat!on(JFrama.EXIT_ON_CLOSE)iMyDrawPanel drawPanel = new MyDrawPanel () ;traMa.qetcontentpane() . add (dra wPane l ) ;frame.setSize(300,300);frame.setVis~le(true);for (int 1 - 0; i


u~. It didn't move••• it smeared.What di'~e. do wrong?There's one little flaw in the paintComponentOmethod.e e 6"--- -11--geWng guiWe forgot to erase what wasalready there! So we got trails.To fix it, all we have to do is fill in the entire panel withthe background color, before painting the circle eachtime. The code below adds two lines at the start of themethod: one to set the color to white (the backgroundcolor of the drawing panel) and the other to fill theentire panel rectangle with that color. In English, thecode below says, "Fill a rectangle starting at x and y of0(0 pixels from the left and 0 pixels from the top) andmake it as wide and as high as the panel is currently.~publio void paintComponent(Graphics q) (g.setColor(Color.white);g.fillRect (0 ,0, this . qatWidth 0 , this .qetHeigbtO);q.aetColor(Color.qreen); ~ 1lg. fUIOva.l (x,y, 40,40) ; ~etw;dt.h() ar,d 9dl+ti ~t()"'tthod$ il'lhtyoiUd r ~ drti"l-0I0I JPal'ItI.~ IJ : 'Sharpen yu peooIloptional.just for funlWhat changes would you make to the x and y coordinates to produce the animations below?(assumethe first one example moves in 3 pixel Increments)l[]Q x +3start2[][3finishstartfinish'DDstartfinishv--±Lxy--xv__startfinish'DOstartfinish'DDstartfinishxy--xy--xy--you are here ~ 385


Code Kit~en16 0 B•...§.~-----1beat tow ...let's make a music video. We'll use Java-generated ranJomgraphics that keep time with the music beats.Along tbe way we'll register (and listen lor) a new lund olnon-GUI event, triggered by the music itseLt.Reme>r>be-, this paH: is ,)11 orti-al. Bl>t we th irJc. i-t's 500 ptoplt who .ll'e I'tally tasyto i"'fl"~bllt still...)186 ch ap ter 12


getting guOK, maybe not a music video, but we wiUmakea program that draws random graphics on thescreen with the beat ofthe music. In a nutshell,the program listens for the beat ofthe musicand draws a random graphic rectangle with eachbeat.That brings up some new issues for us. So far,we've listened for only GUI events, but nowwe need to listen for a particular kind ofMIDIevent. Turns out, listening for a non-GUI event isjust like listening for GUI events: you implementa listener interface, register the listener with anevent source, then sit back and wait for the eventsource to call your event-handler method (themethod defined in the listener interface).The simplest way to listen for the beat of themusic would be to register and listen for theactual MIDI events, so that whenever thesequencer gets the event, our code will get ittoo and can draw the graphic. But... there's aproblem. A bug, actually, that won't let us listenfor the MIDI events we're making (the ones forNOTE ON ).So we have to do a little work-around. Thereis another tjpe of MIDI event we can listenfor, called a ControllerEvent. Our solutionis to register for ControllerEvents, and thenmake sure that for every NOTE ON event,there's a matching ControllerEvent fired atthe same 'beat'. How do we make sure theControllerEvent is fired at the same time? Weadd it to the trackjust like the other events! Inother words, our music sequence goes like this:BEAT I - NOTE ON, CONTROLLER EVENTBEAT 2 - NOTE OFFBEAT 3 - NOTE ON, CONTROLLER EVENTBEAT 4 - NOTE OFFand so on.Before we dive into the full program, though,let's make it a little easier to make and add MIDImessages/ events since in this program, we'regonna make a lot of them.What the music art programneeds to do:• Make a series of MIDI messages/events to play random notes on a piano(or whatever instrument you choose)• Register a listener for the events• Start the sequencer playing• Each time the listener's eventhandler method is called, draw arandom rectangle on the drawingpanel, and call repaint.We'll build it in three iterations:• Version One: Code that simplifies makingand adding MIDI events, since we'llbe making a lot of them.• Version Two: Register and listen forthe events, but without graphics.Prints a message at the command-linewith each beat.• Version Three: The real deal. Addsgraphics to version two.you are here ~ 387


Util~ method for evenls/At' easier way to 'Make'Messages / eVet1tsRight now, making and adding messages andevents to a track is tedious. For each message,we have to make the message instance (in thiscase, ShortMessage), call setMessageO, make aMidiEvent for the message, and add the eventto the track. In last chapter's code, we wentthrough each step for every message. Thatmeans eight lines of codejust to make a noteplay and then stop playingl Four lines to add aNOTE ON event, and four lines to add a NOTEOFFevenlShortM8ssage a = new ShortMessage();a.setNessage(144, 1, note, 100);MidiEvent noteOn :: new MidiEvant(a, 1);track. add (noteOn) ;ShortM8ssaqa b = new ShortMessage();b.setMessagB(128, 1, note, 100);MidiEvent noteOff = new Mid..iEvent(b, 16);track.add(noteOff);Things that have to happen foreach event:.. Make a message instanceShortMsssage Drst :: new SbortHessage();• Call setMessogeO with the instructionsfirst . setMessage (192, 1, instrument, 0)(I Make a MidiEvent instance for the messageMidiEvent noteOn '" new MidiEvent(first, 1);• Add the event to the tracktrack.add(noteOn);Let's build a static utility method thatmakes a message and returns a MidlEventpublic: static MidiEvant makeEvent(int comd, int chan, int one, int two, int tick) (MidiEvent event = null;try (ShortMessllgB a '" new ShortMess&ge () J'a.setMessag8(Comd, chan, one, two);event =new MidiEvent (a, ticJc);}catch(Exception e) { }return event;L LL L {a H ·di~'w ..t all~ yn"Yl'I "{;Ilt tVeT\"{; I~I\loaded lI.y 'With t.ht ... ess.a~()388 chapter 12


getting guiExatttple: how to use the new staticI\takeEvet1tO tttethodThere's no event handling or graphics here,just a sequence of 15notes that go up the scale. The point ofthis code is simply to learnhow to use our new makeEventO method. The code for the nexttwo versions is much smaller and simpler thanks to this method.import javax. sound.midi. * ;~ dOhit tot- et!J the i"'pot-tpublic class MiniMUsicPlayer1 {public static void main(String[] args) {try) a st,~t"t~Sequencer sequencer = MidiSystem.getsequencer 0 ; "- av.t (a"d eyt"sequencer.open(); L ~'"Sequence seq = new Sequence (Sequence. PPQ, 4); +- ...ake a se,\~nteTrack track = seq.createTrackO; ~ and a hatkfor (int i = 5; i < 61; i+= 4) {~ ...ake a b~nth 0+ events to ...ske the notes keel'~oin~ ~l' (~YOftl l'iano note .; to l'iano note bDtrack.add(makeEvent(144,1,i,100,i»;track.add(makeEvent(128,1,i,lOO,i + 2»;II end looptall ~r hew rr.akeEventO "'ethod to krr.essa~e ahd event th ",a e theMidiCveht rd;~rh:d /1'1 add the reslA/t (thethe tratk Th i,0rr. rr.akeEvehtW toNOTE . ese are ,.OTE ON att)sequencer. setSequence (seq); ~ ta . OFF a29) pairs ahdsequencer. setTempolnBPM(220) ; s rf. It r .....hih!Jsequencer.start();} catch (Exception ex) (ex.printStackTrace();}II close mainpublic static MidiEvent makeEvent(int comd, int chan, int one, int two, int tick) {MidiEvent event = null;try {ShortMessage a = new ShortMessage();a.setMessage(comd, chan, one, two);event = new MidiEvent(a, tick);} II close class}catch(Exception e) { }return event;you are here ~ 389


controller eventsimport javax.sound.Ulidi. *;public class MiniMuaicPlayer2public static void main(String[] args) (~n£MusicPlayer2 mini : new MiniMusicPlayar2();mini-goO ;Sequence seq = new Sequence (Sequence. PPQ, 4) ;Track track = s&q.createTrack();sequencer.setsequence(seq);sequencer.setTempoInBPM(220};sequencer.start() ;} catch (Exception ax)II closeI(~ -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'"public MidiEvent makeEvent (int cOJDd, int chan, int one, int two, int tick) (MidiEvent event .. null;try (ShortMassage a ~ new ShortNessage():a. BetM&ssage (comd, chan, on8, two);evant = new Micli.Event(a, tick);I catch (Exception e) I }return event:}II close classCode that's different from the previousversion is highlighted in gray. (and we'renot running it all within mainO this time)390 chapter 12


getting guiVersion Ihree: drawing graphics in thtte with the tltusicThis final version builds on version two by adding the GUI parts. We build aframe, add a drawing panel to it, and each time we get an event, we draw anew rectangle and repaint the screen. The only other change from versiontwo is that the notes play randomly as opposed to simply moving up thescale.The most important change to the code (besides building a simple GUI)is that we make the drawing panel implement the ControllerEventListenerrather than the program itself. So when the drawing panel (an inner class)gets the event, it knows how to take care ofitselfby drawing the rectangle.Complete code for this version is on the next page.The drawing panel inner class:CI ' a list.eYltV'Tht clV'a..,iYl~ ya Ylt 'sclass MyDrawPanel extends JPanel implements ControllerEventListenerboolean msg = false; t-- r'~Lsd: a .fla~ to .faist, a",d ..,~'" Stt itW 1;1"\Ot OI'Ily wht'" Wt g~t a", ~ve",t.public void controlChange(ShortMessage event) (msg = true; f..--..repaint () ;r- We ~ot a", ~vtnt, so w~ set the .flag totl"\Ot and tall l"~pai"'tOpublic void paintComponent{Graphics g) {if (msg) (~We hav~ to l.lS~ a .fla~ b~tal.lS~ OT»ER th·a",d w~ want to Dai",i ONL\/ h Lh Iln~sCllli~~~ t\"i~~~\" a \"tpainiO,r T w tn 1; ere S a OI'IvolJt\"EvtntGraphics2D g2 = (Graphics2D) g;int r = (int) (Math.random{) * 250);int gr = (int) (Math.random() * 250);int b = (int) (Math .random() * 250);g.setColor(new Color(r,gr,b»;int ht = (int) «Math.random() * 120) + 10);int width = (int) «Math.randomO * 120) + 10);int x = (int) «Math.random() * 40) + 10);int y = (int) ({Math.random() * 40) + 10);g.fillRect(x,y,ht, width);msg = false;} II close if} II close methodII close inner classTht I"est is tod~ to ~t"'t\"aiea \"andOlll tolO\" and paintaStllli-\"andolll \"tttan~lt .you are here ~ 391


MiniMusicPlayer3 codeimport j avax. sound.midi . * ;import java.io.* ;import javax.swing.*;import java.awt.*;public class Min1MusicPlayer3~}V~This is the complete code listing for VersionThree. It builds directoy on Version Two. Tryto annotate it yourself, without looking at theprevious pages.static JFrame f = new JFrame(~My First Music Video");static MyDrawPanel ml;public static void main(String[] args) (Min1MusicPlayer3 mini = new Min1MusicPlayer3();mini.goO;) / / close methodpublic void setUpGuiO (ml = new MyDrawPanel();f.setContentPane(ml) ;f .setBounds(30,30,300,300);f .setVisible(true) ;/ / close methodpublic void qo()setUpGui();try {Sequencer sequencer = MidiSystem.getSequencer();sequencer.open();sequencer.addControllerEventListener(ml, new int[] {127»;Sequence seq = new Sequence(Sequence.PPQ, 4);Track track = seq.createTrack() ;int r = 0;for (int i = 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 end loopsequencer.setSequence(seq);sequencer.start();sequencer.setTempoInBPM(120);} catch (Exception ex) {ex.printStackTrace() ;}/ / close method392 chapter 12


exercise: Who Am IWho am IPA bunch of Java hot-shots, in full costume, are playIng the party game-Whoam Ir They give you a clue, and you try to guess who they are, based onwhat they say. Assume they always tell the truth about themselves. Iftheyhappen to say something that could be true for more than one guy, thenwrite down all ios whom that sentence applies. Fill In the blanks next to thesentence with the names of one or more attendees.Tonight'sattendees:Any of the charming personalities from this chapter justmight show uplI got the whole GUI, In my hands.Every event type has one of these.The listener's key method.This method gives JFrame its size.You add code to this method but never call It.When the user actually does something, It's an __ .Most of these are event sources.I carry data back to the listener.An addXxxLlstener( ) method says an object is an __ .How a listener signs up.The method where all the graphics code goes.I'm typically bound to an Instance.The 'g' In (Graphics g), Is really of class.The method that gets palntComponent( ) roiling.The package where most of the Swingers reside.394 chapter 12


getting Quiimport javax.swing.*jimport java.awt.event.*;import java.awt.*;class InnerButtonBE the eomrilerThe Java nle on this page represents acomplete source t\le. Your jah is to playcompiler and detertrtine whether this filewill cOl1Ipile. Ifit won't co11IPile, hawwould you t'xx it, and ifit doescompile, what would it do?JFrame frame;Jautton bipublic static void main(String II args)InnerButtan qui = new InnerButton();guL go () ;}public void gal) {frame = new JFrame();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);b = new JButton(UA n ) ;b.addActionListener()j}frame.getContentPane().add(BorderLayout.SOUTH, b);frame.setSize(200,lOO);frame.setVisible(true)iclass BListener extends ActionListener {public void actionPerformed(ActionEvent e) {if (b.getText().equals(MAn» {b.setText(uBn);} else {b. setText (UA to) i}you are here ~ 395


getting guiWho am I?I got the whole GUI. in my hands.Every event type has one of these .JFramelistener interfaceThe listener's key method. actionPerlormed( )This method givesJFrame its size. setSize( )You add code to this method butnever call it. paintCompone.nt( )When the user actually doessomething, it's an __Most of these are event sources.I carry data back to the listener;An addXxxListener( ) methodsays an obj ect is an _eventswing componentsevent objectevent sourceHow a listener signs up. addActionListe.ner( )The method where all thegraphics code goes. paintComponent( )import javax.swing.*;import java.awt.event.*;import java.awt. *Jclass InnerButtonJFrame frame;JButton b;Once this codeis fixed, it willcreate a GUI witha button thattoggles betweenA and B when youclick it.public static void main(String [I args)InnerButton qui ~ new InnerButton():qui-go( I:public void go(l {frame = new JFrame();frame.setDefaultCloseOperation(JPrame.EXIT_ON_CLOSE) ;The addActionListener( )method takes a class thatimplements the Actionl.istenerinterfaceb = new JButton("A")jb. addActionLiBtener( lIiW JLlstettar( I )lI'm typically bound to an instance.The 's' in (Graphics g). isreally of this class.The method that getspaintCornponent( ) rolling.The package where most of theSwin ge rs reside.inner classGraphics2drepaint( )javax.swingframe.getContentPane() .add(BorderLayout.SOOTB, bl;frame.setSize(200,lOO)lframe.setVisible(true);class BListener hllpltJll8l1t1 ActionListener {public void actionPerformed(ActionEvent elif (b.getText().equals(UA"ll {b. BBtText (»B'") :else {b. setText (»A" IiActionListener is aninterface. interlacesare implemented, notextendedyou are here. 397


puzzle answerspool puzzleimport javax.swing.*;import java.awt.*;public class Animate {int x = 1;int y : 1;public static void main (String[] args) {Animate gui = new Animate ();guLgo() ;The Amazing. Shrinking, BlueRecta ngle.pUblic void go()JFrarne frame new JFrame( 1 jfrarne.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)jMyDrawP drawP =new MyDrawPOiframe.getcontentPane().add(drawP)jf rame.setSize( 500,270);frame.setViaible(true);for (int i = 0; i < 124; i- X++,Y++ ) {x-;drawP.repaintO;try {Thread.sleep(50);} catch(Exception ex) { }}class MyDrawP extends JPanel {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);}398 chapter 12


13 using swingWork on YourSwingSwing is easy. Unless you actually care where things end up on the screen. Swing codelooks easy,but then you compile it, run it, look at it and think- 'h~y, that's not supposed to gothere." The thing that makes it easyto code Is the thing that makes It hard to canuo/-thelayout Manager.Layout Manager objects control the size and location of the widgets in aJava GUJ. They do a ton of work on your behalf, but you won't always like the results.You wanttwo buttons to be the same size,but they aren't. You want the text field to be three inches long,but It's nine. Or one. And under the label instead of next to It. But with a tittle work, you can getlayout managers to submit to your will. In th is chapter, we'll work on our Swing and in additionto layout managers, we'll learn more about wIdgets. We'll make them, display them (where wechoose), and use them In a program. It's not looking 100 good for Suzy.this is a new chap te r 399


components and containersCamponent is the more correct term for what we've been calling a widget.The thingsyou put in a CUI. The things a usersees and interacts with. Textfields, buttons, scrollable lists, radio buttons, etc. are all components. Infact, they all extend javax. swing. JComponent.COlMpo.,etds can be nestedIn Swing, virtually all components are capable of holding othercomponents. In other words, you can siUkjust aboutanything into anythingelse. But most ofthe time, you'll add userinteractive components such asbuttons and lists into background components such as frames and panels.Although it's possible to put, say, a panel inside a button, that's prettyweird, and won't win you any usability awards.With the exception ofJFrame, though, the distinction between interactivecomponents and ba.ckground components is artificial. AJPanel. forexample, is usually used as a background for grouping other components,but even aJPanel can be interactive. Just as with other components, youcan register for theJPanel's events including mouse clicks and keystrokes.A widget is teduucal.lya Swing Com~ent._Almost every thingyou can stick in aGUI extends !romjavaLSWing.JComponent.Four steps to making a GUI (review)• Make a window (e JFrame)JFrame frama "" n_ JFrame () ;• Make a component (button, text field, erc.)JButton button - ne. JButton("click me U ) ;• Add the component to the frameframe. getContantPane () .add(BordarLayout. EAST • button);• Display it (give it a size and make it visible)frame.setsize(300,300);frame.setVisible(true)iPut interactive components:Into background components:...o~J?al\t\400 chapler 13


Layout MahagersA layout manager is aJava object associatedwith a particular component, almost always abackground component, The layout managercontrols the components contained within thecomponent the layout manager is associatedwith, In other words, ifa frame holds a panel,and the panel holds a button, the panel's layoutmanager controls the size and placement ofthe button, while the frame's layout managercontrols the size and placement ofthepanel. The button. on the other hand.doesn't need a layout manager because thebutton isn't holding other components.Ifa panel holds five things. even ifthosefive things each have their own layoutmanagers, the size and location ofthe fivethings in the panel are all controlled by thepanel's layout manager. If those five things,in tum, hold otherthings, thea those otherthings are placed according to the layoutmanager ofthe thing holding them.When we say hold we really mean add as in, aoanel holds a button because the button wasadded to the panel using something like:_IIIIII!IIII!!!II------~~,using swing~Panel.add(button);Layout managers come in several flavors, andeach background component can have its ownyout manager. Layout managers have theirwn policies to follow when building a layout,For example, one layout manager might insistthat all components in a panel must be the samesize, arranged in a grid, while another layoutmanager might let each component choose itsown size, but Slack them vertically. Here's anexample of nested layouts:JPanel panelA = new JPanel () ;JPanel panelB = new JPanel() ;panelB.add(new JButton("button 1"»;panelB.add(new JButton("button 2");panelB.add(new JButton("button 3"));panelA.add(panelB);Panel Ayou are here • 401


layout managersHow does the layout tttat1ager decide?Different layout managers have different policies for arrangingcomponents (like, arrange in a grid. make them all the same size,stack them vertically, etc.) but the components being layed out doget at least some small say in the matter. In general, the process oflaying out a background component looks something like this:A layout scenario:


using swingIhe Jig fhree layout tttat1agers:border; flo~ and box.BorderLayoutA BorderLayout manager divides a backgroundcomponent into five r~ions. You canadd only onecomponent per region to a background controlledby a BorderLayout manager . Components laid outby this manager usually don't get to have theirpreferred size. 9orderlayout Is the default layoutII\Qna~ for Q fromel\-------UI-----FlowLayoutA FlowLayout manager acts kind of like a wordprocessor, except with components instead ofwords. Each component is the size it wants to be,and they're laid out left to right in the order thatthey're added. with ·word-wrap" turned on. Sowhen a component won't tit horizontally, it dropsto the next "line" in the layout. FlowLayout Is thedefault layout mo~,. for a pone"BoxLayoutA BoxLayout manager is like FlowLayout in thateach component gets to have its own size, andthe components are placed in the order in whichthey're added. But. unlike FlowLayout. a BoxLayoutmanager can stack the components vertically (orhorizontally, but usually we're just concerned withvertically). It's like a FlowLayout but instead ofhaving automatic 'component wrapping', you can­insert a Sort of 'component return key' and forcethe components to start a new line.[ Jo0..-.1\ :§)(~ 0you are here) 403


order layoutru\---------BorderLayout caresabout five regions:east, west, north,south, and centerLet's add a button to the!!!!region:import javax. swing. * ; t' . \Alld.a...,t y.)t\(a¥import java.an. *; ~ BcKdlYLa'fOlO I' In.rpublic class Buttonlpublic static void ma.in (Strinq[l argos) IButtonl qui = new Buttonl () iqui-goO;public void go () ( .~ \}If. '"t.~iO"JFrame frame = new JFrame () ; SVf.C,I 'fJButton button = new JButton ("cliclc me"); ('frame. qetContentpane () .lldd(BorderLayout.EAST Iframe.Betsi~e(200/200);frame.setVisible(true);button) i~'f.tttII'.J.':V IraillBarllell----------,How did the BorderLayout manager come up withthis size for the button?eee --What are the factors the layout manage.r has toconsider?click meI ~ -Why isn't it wider or taller?1- - - ,j,404 chapter 13


using swingWatch what happens when we givethe button more characters•..public void go() (JFrame frame = new JFrame();JButton button = new JButton("c1ick like you mean it");!rame.getConcentPane() . add (Bor de r Layout . EAST, button);frame .setSize(200,200);frame.setVisible(true);ooo oyou are here ~ 405Since it's in the eastregion of a border layout,rll respect its preferred width. Butr don't care how tall it wants to be:it's ganna be as tall as the frame,because that's my policy.eee-a --,.click likeyou mean IIr"


order layoutLet's try a button in the NORTH regionpublic void go() (J~rame frame = new JFrame();.mutton button '" new .JButton ("There is no spoon... ");frame.getCohtentPane().add(BorderLayouL.~,button);frame.setSize(200,200);frame.setVisible(true);Now let's make the button ask to be ~II!!,How do we do that? The button is already as wideas it can ever be-as wide as the frame. But wecan try to make it taller by giving it a bigger font.pubLf c void go () ( ~.\\ ~o'(t.~ t,\.eJFrame frame = new JFrame () ; 'D\oll( ~O¥'\:. '01' .,.,.tJrl $~al.t.JButton button = new .mutton ("Click This! ") ;~ ...a"'t. -to a\\~ t.i,~ht..Font bigFont = new Font ("serif", Font. BOLD, 28); ~oY t,'nt'D\lt.torbutton.aetFont(bigFont);frame.getContentPane() .add(BorderLayout.NORTB, button);frame.setSlze(200,200);frame.setVisible(true);406 chapter 13


using swingI think rm getting it... if rm in eesr orwest, I get my preferred width but theheight is up to the layout manager. Andif rm in north or south, it's just theopposite-I get my preferred height, butnot width,But wltst happensin tlte center region?The center region gets whatever's leftl(except in one special case we'll look at later)public void go ()JFrame framenew JFrame();JButton east new JButton("East");JButton west new JButton("West H ) ;JButton north = new JButc:.on("North");JButton south = new JButton("South H ) ;JButton center = new JButton("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) ;frame.setsize(300,300);frame. setVisible (true) ;Le;e e =-;;;;;;;.;.;;; -d( North!~ei r----~e-,IO~),1\tiwidth·West C~nl~r £anaN:it.6. { South ~~-----_J.you are here ~ 407


flow layoutFlowLayout cares-about the flow of thecomponents:left to right, top to bottom, inthe order they were added.Let's add a panel to the east region:A JPanel's layout manager is FJowLayout, by default. Wnen we adda panel to a frame, the size and placement of the panel is stillunder the BorderLayout manager'scontrol. But anytning inside thepanel (in other words, components added to the panel by callingpanel. add (aComponent») are under the panel's FfowLayoutmanager's control. We'll start by putting an empty panel in the fl'"£lme'seast region, and on the next pages we'll add things to the panel.import javax.8winq.*;import java.awt.·;public class Panel1806-- --_..publio static void main (SuingIl llrgs) (Panell qui: new Panel1();qui. go () ;public void go () (JFrame frame :D new JFrame () ; ~Milkt. iht. pilPlt.1 ~yz so \lJt. tar. sJPanel panel = new JPanel () ; Yih-. '.1 '.1\ ee..... I"{; IS 0fI"Lllt. ;}...t.panel. setBackqround (Color. d&rkGray) i .frame. getContantpane () . add(BorderLayout. EAST,frams.setsize(200,200)iframe.setVisible(true) ipanel);408 chapter 13


using swingLet's add a button to the panelpublic void go() {Jframe frame = new Jframe();JPanel panel = new JPanel();panel.setBackground(Color.darkGray);JButton button'" new JButton ("shock me");th aYlt:\ aYld add -tht:Add t,hf~ 1:.0 e Y Cll'le\'s la'fOl>t ...ar.d~('f"Cll'le\ t.o t.'ne ~ya",e. -r-:~.!- a d t.ht: ~ya",e)srHo...,) l-Ot'Ihols the '0)" hol s -I:'ne yaYlel.J ~ I t. n>d'l\d~t:Y (bcordty toOYlpanel.add{button); ~ ~ a~OI>frame.getContentPane() .add(BorderLayout.EA$T, panel);frame.setSize(250,200);frame.setVisible(true);00controlscontrols ~The frame's8orderLayoutmanagerThe panel'sFlowLayout manageryou are he re . 409


flow layoutWhat happens if we add TWO buttonsto the panel?public void go ()JFrame frame new JFrame();JPanel panel new JPanel();panel.setBackground(Color.darkGray);-rwD'o...\:;\:P...sJButton button = new JButton ("shock me"); ~ .,.jjy.eJButton buttonTwo = new JButton("bliss"); Vpanel. add (button) ; -'-- add Bpanel. add (buttonTwo) ; ~ OT» to thl!: randframe.getContentPane() . add (BorderLayout.EAST,frame.setSize(250,200);frame.setVisible(true);panel);what we wanted:» :uceeewhat we got:.--=>~en your penCil~L_ _ . •If the code above were modified to the code below,what would the GUllook like?JButton button = new JButton("shock me");JButton buttonTwo = new JButton("bliss");JButton buttonThree = new JBu tton("huh?H);panel.add(button);panel.add(buttonTwo);panel.add(buttonThree);Draw what youthink the GUI wouldlook like If you ranthe code to the left.(Then try ltl)410 chapter 13


using swing[ Joo~c=::flf- 0BoxLayout to the rescue!It keeps componentsstacked, even if there's roomto put them side by side.Unlike FlowLayout, BoxLayout can force a'new line' to make the components wrap tothe next line, even If there's room for themto fit horizontally.But nowyou'll have to change the panel's layout mancger from thedefault FlowLayout to BoxLayout.public void got) {JFrame frame = new JFrame (l ; ...a,.a~C" to ~ a ~JPanel panel = new JPanel () ; C\\a e -t\oIe \a'fO'l"t. t-panel. setBackground (Color. darkGr:~iY\S~~ J 'rJo"..u~o~panel.s8tLsyout(new BoxLayout(panel, BoxLayout.Y_AXIS»;JButton button =- new JButton ("shock me");Jautton buttonTwo = new Jautt.on("bliss");panel .add(button);panel .add(buttonTwo);frame.getContentPane() .add(BorderLayout.EAST,frame.setSize(250,200);frame.setVisible(true);~T n~ Bo~yovt toMb-illk-th~ to"'POhblt if;s I ' huds to know.ihd whilh d)(i! to tlY'F~ O\.lt (i,~" B.~ pal'ltl)vertildl ~lH ~ we lASe Y_AXI~ +~ apanel) ;e eeyou are here ~ 411


layout managersQ: Howcome you can't add directly to a frame the wayyou can to a panel?A: A JFrame Is speciaI because it's where the rubbermeets the road In making something appear on the screen.Whll e aIIyour SWing components are pu re Java,aJFramehas to connect to the underlylng OSIn order to accessthedl splay.Think of the content pane as a 100% pure Java layerthat sits on top of the JFra me. Or thi nk of it as though JFrameis the window frame and the content pane Isthe...glass.Youknow, the window pane. And yo u can even swap the contentpane with your own JPanel,to make your JPanel the frame'scontent pane, using,myFrama .•etcontantpane(myPanel);Q: can Ichange the layout manager of the frame?What IfIwant the frame to use ftow Instead of border1A:The easiest way to do this Is to make a panel, buildthe GUI the way you want In the panel, and then make thatpanel the frame's content pane using the code In the prevlousanswer (rather than using the default content pane).Q: What IfIwant a different preferred size? Isthere asetSlzeO method for components1A:Yes, there Is a setSlzeO, but the layout managers willIgnore It. There's a distinction between the preferredsize ofthe component and the sizeyou want It to be.The preferredsize Is based on the size the component actually needs(the component makes that decision for Itself).The layoutmanager calls the component's getPreferredSlzeO method,and tho:method doesn't care If you've prevlouslycalledsetSlzeO on the component.Q:can't IJust put things where Iwant them? can Itumthe layout managers off?A:vep.on a component by component basis,you can callsetLayout(null) and then It's up to you to hard-codethe exact screen locations and dimensions. In the long run,though, It's almost always easier to use layout managers.• Layout managers control the size and location ofcomponents nested within other components.• When you add a component toanother component(sometimes referred 10 as a background cornporentbut that's not a technical distinction), the addedcomponent is controlled bythe layout manager ofthebackground componenl• Alayout manager asks components for theirpreferred size, before making a decision aboutthe layout. Depending on the layout manager'spolicies, it might respect atl, some, ornone ofthecomponent's wishes.• The BorderLayout manager lets you add acomponent to one offive regions. You must specifythe region when you add the component, using thefollowing syntax:add (BorderLayout. EAST, panel);• Wrth Bordertayout, components inthe north andsouth gettheir preferred heigh~ but not width.Components In the east and west get their preferredwidth, but not height The component inthe centergets whatever isleff over (unless you use pack () ).• The pack() method Is like shrink-wrap for thecomponents; It uses the full preferred size ofthecenter component, then determines the size oftheframe using the center as a starting point, buildingthe rest based on what's inthe other regions.• FlowLayout places components left to right. top tobottom, In the order they were added, wrapping toanew line ofcomponents only when the componentswon't fit horizontally.• RowLayout gives components their preferred size inboth dimensions.• BoxLayout lets you align components stackedvertically, even Ifthey could fit side-by-sida. UkeFlowLayout. BoxLayout uses the preferred size ofthe component inboth dimensions.• BorderLayout isthe default layout manager for aframe; FlowLayout Isthe default for a panel.• Ifyou want a panel to use something other than flow,you have tocall setLayout () on the panel.412 chapter 13


using swingPlayit1Q with Swittg colitpottetttsYou've learned the basics oflayout managers, so now let's try out afew of the most common components: a text field, scrolling text area,checkbox, and list, We won't show you the whole darn API for each ofthese, just a few highlights to get you started.JTextFleld.8 6 6At 1.D y·rah.W t.o\l>JI'I~1 ,,0 .dt'h ~Constructors~ W. ~af ts t'llt Y"'e~tyYtd 'HIIt: T'''~ (l.t'",,,JText:F1&1d field % n_ JTex.tField(20); ~e ~.,rl ~'t\d.J'TextField field: new JTAXtFi8ld(~Yournameff)iHow to use It• Get text out of itSystam.out.println(5eld.getTQXt());• Put text in itfield . 1I8 t Text ("whatever") ;field. lIetText("\\) i \ ~t .~\e\d"-- 'This t e.lI's• Get an ActionEvent when the user VOlA l,dll alSo l'e~isk .fpresses return or enter rtally 'N.1l'1t iD htar a~t ~iY evel'lh it yOlAl/.1tt- P'r't:~s d kty. I every ti ...e thefiald.addActionLiataner(myActionListener) i• Select/Highlight the text in the fieldfiald.aelectAll();• Put the cursor back inthe field (so the usercan just start typing)field. requeatFocua () ;you are here ~ 413


text areaJTextAreaUnlike JTextField, JTextArea can have more than one line of text. Ittakes Q little configuration to make one, because it doesn't come out ofthe box with scroll bars or line wrappi"9. To make a J'TextAr'e(] scroll, youhave to stick it in a ScroliPane. A ScroJiPane is an object that r'e(]11y lovesto scroll. and will take care of the text ereo's scrolli"9 needs.Constructor t r VJ ""ul'SVJ to ......JTaxtArea taxt mHow to use Itnew JTaxtArea(lO,20);• Make it have a vertical scroll bar only'- . \o..\)JeY't'c6 nC\~10 \,~ (~the Y'" ~~o. Ifj'o..\;,\,,)10 ""tal'S ~ l'S (~ -thC yrt6 ',IJCit &c~J~~o\\?a~ 4". ~~ st;~o\\ dt'.Mi~C a ~t It ~ ~,,~~ U'llt a 'ft.6JSarollPane IIc:roller - ne. JSc:rollPane (taxt) ; Tell the stroll pal\t io ,text.lIetLineWrap(true); ~ T",,"II 01\ line ~affi~ f a~ st\"ollba\" l&SC Oftysc:roller.aetvertiea1Sc:rol1BarPolicy(ScrollPaneConlitants.VERTlCAL SCROLLBAR AL~IIcroller.set8orizonta1Sc:rol1BarPolicy(Sc:rollPaneConatants.BORIZONTAL_SCROLLBAR_NEVER);• Append to the text that's in ittaxt.append("button cliaked H ) ;• Select/Highlight the text in the fieldtaxt.lIelectAll();• Put the cursor back in the field (so the usercan just start typing)text.requelltFocua() ;414 chapter 13


using swingJTextArea exampleimport jaYaX.swing.*;import java.art.*;import java.art.event.*;public class TaxtAreal implements ActionL~staner {"eee ~- ,.,~~ cHcJced .~- cHcJcedbut.ton ellekedz: -JTextArea text;}public static void main (String [] &rqs)TextAreal qui c new TextAreal();qui .go () ;0:- ~-~1'= - :public void go() (JFrame frame - new JFrame();JPanel panel = new JPanel () ;JButton button::; new JButton("Just Click It");button. addActionListener (this) ;text::; new JTaxtArea(lO,20);text.setLinewrap(true);r Just tUck It~JScrollPane scrollar ~new JScrollPane{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);public void actionPerformed(ActionEvent ev) (text.append("button clicked \n ");iI~t d new lihC: $0 B.c: w


check boxConstructorJCheckBoxJCheckBox check = new JCheckBox("Goes to 11");How to use It• Listen for an item event (when it's selected or deselected)check.addltemListener(this);.. Handle the event (and find out whether or not it's selected)public void itemstateChanged(ItemEvent ev)String onOrOff = "off";if (check.isSelected(» onOrOff = "on";System.out.println("Check box is " + onOrOff);., Select or deselect it in codecheck.setSelected(true);check.setSelected(false);O the re1atE}{l? "UUlD ~uesti9nsQ: Aren't the layout managersjust more trouble than they'reworth? If Ihave to go to all thistrouble, I might as well just hardcodethe size and coordinates forwhere everything should go.A: Getting the exact layoutyou want from a layout managercan be a challenge. But thinkabout what the layout manageris really doing for you. Eventheseemingly simple task of figuringout where things should go onthe screen can be complex. Forexample, the layout manager takescare of keeping your componentsfrom overlapping one another.In other words, it knows how tomanage the spacing betweencomponents (and between theedge of the frame). Sure you cando that yourself, but what happensif you want components to bevery tightly packed? You might getthem placed just right, by hand,but that's only good for your JVM!Why? Because the componentscan be slightly different fromplatform to platform, especially ifthey use the underlying platform'snative 'look and fee 1/, Subtle thingslike the bevel of the buttons canbe different in such a way thatcomponents that line up neatlyon one platform suddenly squishtogether on another.And we're still not at the really BigThing that layout managers do.Think about what happens whenthe user resizesthe window! Oryour GUI is dynamic, where componentscome and go. If you hadto keep track of re-Iaying out allthe components every time there 'sa change in the size or contents ofa background component...yikes!416 chapter 13


using swing~ListConstructorString [] H.atEntries '" ("a..lpha", "beta", \'ga:nmta", "delta","apailon", "zeta", "eta H , "theta "I;list'" new JLlst(liatEntrie.);How to use It• Make it have a vertical scrollbarJSerollPane acroller '" new JScrolIPane(liat) ;scroller.setVerticalScrol~Poliey(ScroIIPaneConstanta.VERTlCAL_SCROLL8AR_ALMAYS);acroller.setaorizontalScrollBarPolicy(ScrollPan8Constants.HORIZONTAL_SCROLLBAR_NEVER);panel.add(acroller);Set the number of lines to show before scrollingliat.setVisibleRowCount(4);• Restrict the user to selecting only ONE thing at a timelist.setselectionMode(ListSeleotioDModel.SrNGLE_SELECTION);Register for list selection eventslist.addListSelectionListenar(this);y~\\• Handle events (find out which thing in the list was selected~ / fllt. j" this i~ test.L TWIC~ J '10\> ooY\'t.¥*- t.ne e\la.'t.public void va.lueChanqed (ListselectionEvent lse) (E;" .if( Ilse.getValueIsAdjullting()) ( ~String selecUon ." (String) list. getSelectedValue 0 ; ~eiSdttudV~lueO ad:. I~SysteJD. out.println (lteleotion) ; _1. ~"rcwn.s a" Objett, Alist i 'f.li...iud to OYII" oL. • b' S:./ ~U"'''5 0 :,)etu.you are here. 417


Code KitchenThis part's optional We're ~ing the lull BeatBox, GUIand all In the Saving Objects chapter, we'll learn how tosave and restore drum patterns. FinallyI in the networlungchapter (Mak a Connedionl, we'U turn the BeatBox into awor~ing chat client.418 chapter 13


using swingMakit1Q the JeatJoxThis is the full code listing for this version ofthe BeatBox, with buttons for starting,stopping, and changing the tempo. The code listing is complete, and fullyannotated,but here's the overview:•Build a GUI that has 256 checkboxes (JCheckBox) that start outunchecked, 16 labels (JLabel) for the instrument names, and fourbuttons.•Register an ActionListener for each of the four buttons. We don'tneed listeners for the individual checkboxes, because we aren'ttrying to change the pattern sound dynamically (i.e. as soon as theuser checks a box). Instead, we wait until the user hits the 'start'button, and then walk through all 256 checkboxes to get their stateand make a MIDI track.•Set-up the MIDI system (you've done this before) including gettinga Sequencer, making a Sequence, and creating a track. We are usinga sequencer method that's new to Java 5.0, setLoopCount( ). Thismethod allows you to specify how many times you want a sequenceto loop. We're also using the sequence's tempo factor to adjust thetempo up or down, and maintain the new tempo from one iteration ofthe loop to the next.•When the user hits 'start', the real action begins. The event-handlingmethod for the 'start' button calls the buildTrackAndStartO method.In that method, we walk through all 256 checkboxes (one row ata time, a single instrument across all 16 beats) to get their state,then use the information to build a MIDI track (using the handymakeEventO method we used in the previous chapter). Once the trackis built, we start the sequencer, which keeps playing (because we'relooping it) until the user hits 'stop'.you are here ~ 419


BeatBox codeimport java.awt.*;import javax.swing.·;import j avax. sound.midi. . * ;import java.util.*;import java.awt.event.*;public elass BeatBox {JPanel mainPanel;ArrayListSequencer sequencer;Sequen~e sequence;Track track;JFrame theFrame ;~ The'S( dre ~e I\d"'CS ~ the i~""LlftIents, dS a Shi"'" an-dY, to'


using swingdownTempo . addActionLis tener (n_ MyDownTempoListener () ) ;buttonBox.add(dovnTempo);Box nameBox = new Box (80xLayout. Y_AX!S) ;for (int i = 0; i < 16; i++) {nameBox .add(new Label (i.nst..rumentNa.mes [i]» ;background. add (BorderLayout. EAST, buttonBox) ;background. add (80rd.erLayout.WEST, namaBox);theFrame .getcontentpane() . add (background) ;GridLayout grid = new GridLayout(16,16) ;grid. setVgap (1) ;grid. setHqap (2) ;mainPanel = new JPanel (grid) ;background. add (BorcierLayout. CEN"l'ER, mainPanel);for (int i = 0; i < 256; i++) {JCheckBox c = new JCheckBox();c.setselected(false);checkboxList.add(c);mainPanel.add(c) ;II end loopsetOpMidi();theFrame.setBounds(50,50,300,300);th9Frame.pac:k();theFrama.setVisible(true);I I elose methodpublic void ••t~~() {tz:y (sequencer = MidiSystem..getsequencer () ;sequencer. apan () ;sequence = n_ Sequence (Sequence.PPQ,4) ;track = eequence.creat8Track();sequencer.aetTampolnBPH(120);} catah(Exception e) (e.printStaakTrace();}II clos9 methodyou are here • 421


BeatBox codesequence .deleteTrack(track) ;track = sequence.createTrack();for (int i = 0; i < 16; i++)trackList = new int[16];int key = instruments[i); ~for (int j = 0; j < 16; j++ ) { ~ Do this ~OV" eath ~ the BE.ATS ~OV" this YOW3JCheckBox jc = (JCheckBox) checkboxList.get(j + (16*i» ;if ( jc.isSelected(» (trackList[j) = key;relse { Is t.he thetkbo"l. at. t.his beat. sdett.ed? I~ yes, fIAt.trackList[j) = 0;the key vall.le in this slot in the ayyay (the slot that.} Ye~esents this beaV. Otheywise, the inshWl'lent isI I close inner loopNOT slAffosed to flay at this beat, so set it. to Uyo·makeTracks (trackList) ; -,.-..::----- roY this i\'\StYWI'Ient., and ~OV" all Ib beats,track. add (makeEvent (176,1,127,0,16) ) ; ",ake eve"ts and add the", to the hadeII close outer~ We always want to ",alce SlAye that H,tye IS an event attrack. add (makeEvent (192,9,1,0,15) ) ; beat. IE. (it ~oes 0 to ,'S). OH,tywise, the 'BeatHo"l. ",i~httry ( not ~o the .flAil Ib beats be+oYe it staYts ovty·sequencer.setSequence(sequence);sequencer.setLoopCount(sequencer.LOOP_CONTINUOUSLY);sequencer.start();sequencer.setTempoInBPM(120) ;} catch(Exception e) {e.printStackTrace();}II close buildTrackAndStart methodpublic class ~!iI~~:£!DI~fM implements ActionListenerpublic void actionPerformed(ActionEvent a) (buildTrackAndStart();}II close inner class422 ch apter 13


using swingpublic class (mJ.HRa,~g~ implements ActionListenerpublic void actionPerformed(ActionEvent a) (sequencer.stop() ;}II close inner classpublic class r~EtItl=i!iij~jimplements ActionListenerpublic void actionPerformed(ActionEvent a) (float tempoFactor = sequencer.getTempoFactor() ;sequencer.setTempoFactor«float) (tempoFactor * 1.03»;}II close inner classublic class "'"".c"'!.'T) : : " * 9i ':mr ':~iil implements ActionListenerp :m% ",~ ,'.w,~ ,. ,."iI. , ,, . , , , ,,,, ,.A'public void actionPerformed(ActionEvent a) (float tempoFactor = sequencer.getTempoFactor();sequencer.setTempoFactor«float) (tempoFactor * . 97» ;}} II close inner classThe otheto il'll'leto dasslistel'letos tOt" the bl


exercise: Which Layout?Which code goes withwhich layout?Five of the slx screens below were made from oneof the code fragments on the opposite page. Matcheach of the five code fragments with the layout thatfragment would produce.o 6 SClesuJI~.G 606•o e e(wala ritesuJile5uj l424 chapter 13


using swingcode FragmentsJFrame frame = new JFrame();JPanel panel = new JPanel();panel. setBackground(Color.darkGray) ;JButton button = new JButton(~tesuji") ;JButton buttonTwo = new JButton(~watari") ;frame.getContentPane() .add(BorderLayout.NORTH,panel);panel.add(buttonTwo);frame.getContentPane() .add(BorderLayout.CENTER,button);GeJFrame frame = new JFrame() ;JPanel panel = new JPanel();panel.setBackground(Color.darkGray);JButton button = new JButton(~tesuji");JButton buttonTwo = new JButton(~watari") ;panel.add(buttonTwo) ;frame.getContentPane() .add(BorderLayout.CENTER,button);frame.getContentPane() . add (BorderLayout.EAST, panel);JFrame frame = new JFrame();JPanel panel = new JPanel () ;panel.setBackground(Color.darkGray);JButton button = new JButton(~tesuji");JButton buttonTwo = new JButton(~watari") ;panel.add(buttonTwo);frame.getContentPane() .add(BorderLayout.CENTER,button);JFrame frame = new JFrame();JPanel panel = new JPanel () ;panel. setBackground(Color.darkGray) ;JButton button = new JButton(~tesuji");JButton buttonTwo = new JButton(~watari") ;panel. add(button) ;frame.getContentPane() .add(BorderLayout.NORTH,buttonTwo) ;frame.getContentPane() .add(BorderLayout. EAST, panel);JFrame frame = new JFrame();JPanel panel = new JPanel() ;panel. setBackground (Color.darkGray) ;JButton button = new JButton(~tesuji");JButton buttonTwo = new JButton(~watari");frame.getContentPane() . add(BorderLayout. SOUTH ,panel) ;panel.add(buttonTwo) ;frame.getContentPane() . add (BorderLayout.NORTH,button) ;you are here; 425


puzzle: crosswordGtJI-Or~ss,.0You cando It.AaOS5 17. Shake It baby Down 13. Manager's rules1. Artist's sandbox 21. Lots to say 2. Swing's dad 14. Source'sbehavior4. Border's catchall 23. Choose many 3. Frame's purview 15. Borderbydefault5. Java look 25. Button's pal 5. Help's home 18. User's behavior9. Genericwalter 26. Homeof 6. Morefun than text 19. Inner's squeeze11. A happeningactionPerformed7. Componentslang 20. Backstage widget12.Apply awidget 8. Romulin command 22. Maclook15.JPanel's default 9. Arrange 24. Border's right16. Polymorphictest 10. Border's top426 chapter 1 3


using swing~ExerciSe Solutions~ JFrame frame .. Dew JFrame();V' JPanel panel C Dew JPanel () ;paDel.setBackground(Color.darkGray) ;JButtOD button = Dew JButton("tesuji H ) ;JButton buttonTwo .. new JButton (".auri N ) ;panel.add(buttonTwo) ;frame.getCoDtentPane() . add (BorderLayout. CENTER ,button) ;A JFrame frame = Dew JFrame () ;~ JPanel panel '" new JPanel Cl ;panel.setBaokqround(Color.darkGray) ;JButton button .. new JButton("tesuji N ) ;JButton buttonTwo .. new JButton("wauri N ) ;frame .getContentPane() .add(BordarLayout.NORTS,panel);panel. add (buttonTwo) ;frame .qetContentPane() .add(BorderLayout.CENTER,button);~ JFrame frame = new JFrame () ;..., JPanel panel" new JPanel{);panel.setBaekqround(Color.darkGray) ;JButton button = new JButton("tesuji H ) ;JButton buttODTwo = new JButton("watari") ;frame.qetContentPane() .add(BordarLayout.SOUTH,panel);panel.add(buttonTwo) ;frame. getContantpane () .add (BorderLayout. NORTH, button) ;o ~e e o.......JFrame frame '" n_ JYram. () ;JPanel panel = new JPanel () ;panel.aetBackground(Color.darkGray);JButtoD button'" new JButton("tesuji");JButton buttonTwo '" new JButton("watari H ) :panel .add(button):frame.qetConbentpane() .addlBordarLayout.NORTH,buttonTwo):frame.qetContentpane() .add(BorderLayout.EAST, panel);OJFrame frame = new JFr_ () :• JPanel panel .. n_ JPanel () :panel.a8tBackqround(Color .darkGray);JButton button = new JButton("taauji H ) ;JButton buttonTvo CI new JButton ("watari") ;panel . add (buttonTwo) :framo. qlltContantpane Cl •add (BordllLLayout. CENTE:R,button) ;frame . getContentPane () .addl80rderLayout.EAST, panel);you are here ~ 427


puzzle AnswerseaI-Or~ssz.o


14 serialization and file I/OSaving ObjectsObjects can be flattened and inflated. Objects have state and behavior.Behavior lives in the dOH, but state lives within each individual object. So what happens whenit's time to savethe state of an object? If you're writing a game, you're gonna need a SavelRestore Game feature .If you're writing an app that creates charts, you're gonna need a SavelOpen Filefeature. If your program needs to savestate/you can do It the hard way,interrogatingeach object, then painstakingly writing the value of each instance variable to a file, In aformat you create.Or,you can do Itthe easy 00 way-you simply freeze-dry/flatten/persistJdehydrate the object itself, and reconstltute/lnflate/restore/rehydrate It to get it back.But you'llstill have to do it the hard way sometimes, especially when the file your app saves has to be readby some other non-Java application, so we'll look at both In this chapter.this Is a new ch ap ter 429


saving objectsCapture the featYou have lots of options for how to save the state ofyourJava program. and what you choose will probablydepend on how you plan to use the saved state. Hereare the options we'll be looking at in this chapter.If your data will be used by only the Javaprogram that generated It:~ Use ~erializQtionWrite 0 tile that holds flattened (serialized)objects. Then have your program read theserialized objects from the file and inflate themback into living, breathing, heap-inhabiting objects.If your data will be used by other programs:@ Write a plain text file-Write a tile. with delimiters that other programs can parse,For example, a tab-delimited file that a spreadsheet ordatabase application can USe.These aren't the only options, ofcourse. You can save data in anyformat you choose. Instead of writing characters, for example,you can write your data as bytes. Or you can write out any kindofJava primitive as a Java primitive-there are methods to writeints, longs. booleans, etc. BUt regardless of the method you use,the fundamental lIO techniques are pretty much the same:write some data to something, and usually that something is eithera file on disk or a stream coming from a network connection.Reading the data is the same process in reverse: read some datafrom either a file on disk or a network connection. And ofcourseeverything we talk about in this part is for times when you aren'tusing an actual database.430 ch apter 14


Savl"Q StateImagine you have a program, say, a fantasyadventure game, that takes more than onesession to complete. As the game progTesses,characters in the game become stronger, weaker,smarter, etc.• and gather and use (and lose)weapons. You don't want to start from scratcheach time you launch the game-it took youforever to get your characters in top shape fora spectacular battle. So. you need a way to savethe state of the characters, and a way to restorethe state when you resume the game. And sinceyou're also the game programmer, you want thewhole save and restore thing to be as easy (andfoolproof) as possible.• Option oneWrite the three serializedcharacter objects to a fileCreate a file and write three serializedcharacter objects. The file won't makesense if you try to read it as text:-l.uGa.meoharaot-"'~ava/1anIJ8t:rIDSi [weapoQtNava/lang/8t:r'lDS;QBtlfUrl:I4java.Jant.8t:rln4;..uvA.i{Gzptbowt8wordtdUSUq- nt'l'rolluq-tbare h.Ilndabig IIDq- ztMagloiaDuq-tepeu.tInvialbWty•Option twoWrite a plain text fileCreate a file and write three Jines of text.one per character, separating the piecesof state with commas:80.mt,bow, lJWQrcl,dlUt8OO,Troll,bare banlb,big ur:18O,Megictln ,ape!h,lnviaibUityGameCharacter11'1 powerString typeWeaponD weaponsgelWeaponOusaWeaponOIncreasePower()II moreserialization and file 1/0Imagine youl1a-ve t 1 r.1 m"ee gameCllaract ers to sal'e...you are here ~ 431


saving objectsWrlti"Q aserialized object to afileHere are the steps for serializing (saving) an object Don't bothermemorizing all this; we'l1 go into more detail later in this chapter.o Make a FileOutputStreamWrlt~ the obj~ct r ..I 'o~h.1Yat-tc--- lL L' to L yt:-t&fY\UU ..I'a\"~ Ult: ODjt: ~ Uv vee dl'lUos.writeObject (characterOne) i it:---/. O:~, ~nayad:.t.yT'fIo, il~d ~nil"'~~",c,~"'''. Ios.writeObject (characterTwo); ~ ,./l'+tt-s thCJ'II to tnt: ~11t: N1~oB.writeObject(characterThree); ~e432 chapter 14


Pata lMoves itt streatMs frotM ot1e place to at1other.serialization and file I/OCO"t1ectio"strealMs represe)tta eOt1t1ectlot1toa source ordestlt1aflot1 (file,socket etc.) whilechal" streatMs- cat1't oot1"ecf Ot1their OW" 3"d tMustbe chal"ed toacot1t1ectfo" dna",.Thejava I/O API has amnection streams, that represent connections to destinations andsources such as files or network sockets, and chain streams that work only if chained toother streams.Often, it takes at least two streams hooked together to do something useful-one torepresent the connection and anotherto call methods on. \\Thy two? Because connectionstreams are usually too low-level. FileOutputStream (a connection stream), for example,has methods for writing byles. But we don't want to write byusl We want to write objects, sowe need a higher-level chain stream.OK, then why not have just a single stream that does exactly what you want? One that letsyou write objects but underneath converts them to bytes? Think good 00. Each classdoes onething well. File OurpurStreams write bytes to a file. ObjectOurputStreams turnobjects into data that can be written to a stream. So we make a FileOutputStream that letsus write to a file, and we hook an ObjectOutputStrearn (a chain stream) on the end ofit.When we call writeObject() on the ObjectOutputStream. the object gets pumped into thestream and then moves to the FileOutputStream where it ultimately gets written as bytesto a file.The ability to mix and match different combinations of connection and chain streamsgives you tremendous flexibilityl Ifyou were forced to use only a singlestream class, you'dbe at the mercy of the API designers. hoping they'd thought of everythitlgyou might everwant to do. But with chaining, you can patch together your own custom chains.is written toobject is flattened (serialized) object is written as bytes tois chained to011010010110111001011010010110111001ObjectOutputStreom(a choin stream)FileOutputStream(a connection stream)Fileyou are he re ~ 433


serialized objectsWhat really happens to a., objectwhet' itl serialized?o Object on the heapG Object serializedObjects on the. heap have state-thevalue of the object's instancevariables. These values make oneinstance of a class different fromanother instance of the same class.Serialized objects save the valuesof the instance variables. so thatan identical instance (object) can bebrought back to life on the heap.0010010101000110Foo myFoo = new Foo();myFoo .setwidth(37);myFoo.setBeight(70);434 chapter 14


serlallzatlon and file I/O-'ut what exactly IS att object~ state?What needs to be saved?Now it starts to get interesting. Easy enough to save the primitivevalues 37 and 70. But what ifan object has an instance variablethat's an object reference? What about an object that has fiveinstance variables that are object references? What if those objectinstance variables themselves have instance variables?Think about it. What part ofan object is potentially unique?Imagine what needs to be restored in order to get an object that'sidentical to the one that was saved. It will have a different memorylocation. ofcourse. but we don't care about that, All we care aboutis that out there on the heap. we'll get an object that has the samestate the object had when it was saved.Vi!iiJlj1 Iraill BarbellWhat has to happen for the Carobject to be saved in such a waythat It can be restored back to itsoriginal state?The Car object has twoInstance variables thatreference two otherobjects.Think of what-and how-youmight need to save the Car.And what happens ifan Engineobject has a reference to aCarburator7 And what's inside thenre 0 array object?What doe8 It take tosave a Car object?you are here. 435


serialized objectsWhen an object is serialized, all the objectsit refers to from Instance variables are alsoserialized. And all the objects those objectsrefer to are serialized. And all the objects thoseobjects refer to are serialized••• and the bestpart is, it happens automaticallylThis Kennel object has a reference to a Dog [] array object. TheDog [] holds references to two Dog objects. Each Dog object holdsa reference to a String and a Collar object. The String objectshave a collection of characters and the Collar objects have an intoWhen you save the Kennel, all of this ;s savedl~ -Serialization saves theentire object grapb..All objects reterencedby instance variables,starting with theobject being serialized./\ ·l:-~9[ ) arrcri o'o~436 chapter 14


If you want your class to be serializable,itMpletMet1t Serializableserialization and file 110The Serializable interface is known as a marker-or taginterface,because the interface doesn't have any methods to implement. Itssole purpose is to announce that the class implementing it is, well,serializable. In other words, objects of that type are saveable throughthe serialization mechanism. Ifany superclass ofa class is serializable,the subclass is automatically serializable even if the subclass doesn'texplicitly declare implements Serializable. (This is how interfaces alwayswork. If your superclass "IS-A" Serializable, you are too).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\\ -tal aSey\a\\~, ' lhc ' a'la,io yat.\l.aO;,C. so, ~'~\)\t 'S I'll" ,)import java.io.*; ~ SeYli e..d t.'nt i""'y~''1011' 'II ..public class Box implements Serializable......... ~ ../public void setWidth(int w)width = w;public void setHeight(int h}height = h;public static void main (String[] args) {Box myBox =new Box() ;myBox.setWidth(50};myBox.setHeight(20);))d \\~oo ,seYl to i ~i\C YId.,.,.C I ¥.e aCOY\'IItt.". ~ 'It. dot.s,", t. ",ilL10 ovtV'abo"s t.a" "nYO'"eue...l.io\llS.!r -r .t. e'Jl.Ists· \ "i"l' I d \\~oo·seY .1I "c'" ~i\t YId"'ctry { ~FileoutputStream fs = new FileOUtputStream("foo.ser") ;ObjectOUtputStream os = new ObjectOUtputStream(fs);os.writeObject(myBox); ~ Make ah Ob'ettoos.close () ; ......... thaihed to :J "tp"tstrea",catch(Exception ex) { the tOhhettioh stex.printSt&ckTrace(); Tell it to W\-'te 1 rea""Il::he objett.you are here. 437


serialized objectsSerialization is all or nothing.Can you imagine what wouldhappen If some of the object'sstate didn't save correctly?Eeewww! Thatcreeps me out just thinkingabout itl Like, what if a Dog comesback with rIO weight. Or no ears. Orthe collar comes back size 3 insteadof 30. That just can't be allowedlimport java.io.*;~ POI'IO obj~eL ea" b~ so-ializ..ed.public class Pond implements Serializable (" POl'ld has ont 'IN taTleeprivate Duck duck = new Duck(); ~ CIa ,.. D Ie.public static void llIain (Strinq[] arqs) {Pond myPond = new Pond();try (FileOutputstreAm fs : new FileOUtputStream("Pond.'ser");ObjectOUtputStream os : new ObjeotOutputStream (fs) ;. ..,e--. Whos . writ e Ob ) 8 c t (myPon d ) ; . bl.yo .... so-ia'i~ ""yPond ( Pos . close () ; obJuV, ih Dlotk i>\lU a ol'ldaui:o-....atit...i II 1.- . I'I~~ variablecatch(Exception ex) (ex .printStackTrace() ;va~iable, a vl. ,Either the entireobject graph isserialized correctlyor serialization fails.You can't serializea Pond object ifits Duck instancevariable refuses tobe senallzed (bynot implementingSeriafizable).y 3 c 't-\ serlall~d. . PO'PIO:to YWI ~t ",ai" I" dass438 ch ap ter 14


serialization and file 110It's hopeless,then? I'm completelyscrewed if the idiot whowrote the class for my instancevariable forgot to make itSerializable?Mark an Instance variable as transientIf It can't (or shouldn't) be saved. -Ifyou want an instance variable to be skipped by theserialization process, mark the variable with the transientkeyword.• import java.net.*:. t !o4i'r' "Otil'C. ~ class Chat implements Serializable {b-a.,.s~~iS ~aV"\a'o\tl O~~Il\~t.)I~ transient Strinq currentID;sa"t v'. 'I>S~ n.'" J ---~V"ia\i-z.abO"f\,~~ Strinq userNamejlI..SC'rNa ....e variable / / more codewill be saved as pari }o.f ~t. obJt.d:'s st.dtedUY"'9 st.\"laliz.aiiol'l.lfyou have an instance variable that can't be saved becauseit isn't serializable, you can mark that variable with thetransient keyword and the serialization process will skip rightover it.So why would a variable not be serializable? It could bethat the class designer simply /ClTgot to make the classimplement Serializable, Or it might be because the objectrelies on runtime-specific information that simply can't besaved. Although most things in thejava class libraries areserializable, you can't save things like network connections,threads, or file objects. They're all dependent on (andspecific to) a particular runtime 'experience'. In other words,they're instantiated in a way that's unique to a particular runofyoor program, on a particular platform, in a particularJVM. Once the program shuts down, there's no way to bringthose things back to life in any meaningful way; they have tobe created from scratch each time.you are here ~ 439


serialized objectstherelm-~?DUmb ~uest19n8Q: If serialization is so important,why isn't it the default for all classes?Why doesn't class Object implementSerializable, and then all subclasseswill be automatically Serializable.A: Even though most classeswill,and should, implement Serializable,you always have a choice. And youmust make a conscious decision ona c1ass-by-c1ass basis,for each classyou design, to 'enable' serializationby implementing Serializable.First of all, if serialization were thedefault, how would you turn it off?Interfaces indicate functionality, nota lack of functionality, so the modelof polymorphism wouldn't workcorrectly if you had to say/implementsNonSerializable"to tell the world thatyou cannot be saved.Q: Why would I ever write a classthat wasn't serializable?A: There are very few reasons,butyou might, for example, have a securityissue where you don't want a passwordobject stored. Or you might have anobject that makes no sense to save,because its key instance variables arethemselves not serializable, so there'sno useful way for you to make yourclass serializable.Q: If a class I'm using isn'tserializable, but there's no goodreason (except that the designer justforgot or was stupid), can I subclassthe 'bad'class and make the subclassserializable?440 cha pte r 14A: Yes! If the class itself isextendable (i.e. not final), you canmake a serializable subclass,and justsubstitute the subclass everywhereyour code is expecting the superclasstype. (Remember, polymorphismallows this.) Which brings up anotherinteresting issue: what does it mean ifthe superclass is not serializable?Q: You brought it up: what does itmean to have a serializable subclassof a non-serializable superclass?A: First we have to look at whathappens when a class is deserialized,(we'll talk-about that on the next fewpages). In a nutshell, when an objectis deserialized and its superclass is notserializable, the superclass constructorwill run just as though a new object ofthat type were being created. If there'sno decent reason for a class to notbe serializable, making a serializablesubclass might be a good solution.Q: Whoall just realizedsomething big•••if you make avariable 'transient~this means thevariable's value is skipped overduring serialization.Then whathappens to it? We solve the problemof having a non-serializable instancevariable by making the instancevariable transient, but don't we NEEDthat variable when the object isbrought back to life? In other words,isn't the whole point of serializationto preserve an object's state?A: Yes, this is an issue,butfortunately there's a solution. If youserialize an object, a transient referenceinstance variable will be brought backas null, regardless of the value it hadat the time it was saved.That meansthe entire object graph connected tothat particular instance variable won'tbe saved.This could be bad, obviously,because you probably need a non-nullvalue for that variable.You have two options:1) When the object is brought back,reinitialize that null instance variableback to some default state. Thisworks if your deserialized object isn'tdependent on a particular value forthat transient variable. In other words,it might be important that the Doghave a Collar, but perhaps all Collarobjects are the same so it doesn'tmatter if you give the resurrected Doga brand new Collar; nobody will knowthe difference.2) If the value of the transient variabledoes matter (say, if the color and designof the transient Collar are unique foreach Dog) then you need to savethekey values ofthe Collar and use themwhen the Dog is brought back toessentially re-create a brand new Collarthat's identical to the original.Q: What happens if two objects inthe object graph are the same object?Like, if you have two different Catobjects in the Kennel, but both Catshave a reference to the same Ownerobject. Does the Owner get savedtwice? I'm hoping not.A: Excellent question! Serializationis smart enough to know when twoobjects in the graph are the same.Inthat case,only one of the objects issaved,and during deserialization, anyreferences to that single object arerestored.


serlallzatJon and file 1/0Peserializatiot1= restorit1Q att objectThe whole point ofserializing an object is so that you canrestore it back to its original state at some later date, in adifferent 'run' of theJVM (which might not even be the sameJVM that was running at the time the object was serialized).Deserialization is a lot like serialization in reverse.oMake a FilelnputStreQtnFilelnputStream fileStream = newserializ.edJ,.e ~ the objectsObject one = os.readObject();Object two = os.readObject();Object three = os.readObject();e-cast the objectsyou are here, 441


deserlallzlng objectsWhat happe.,s durhtg deserializatio.,?When an object is deserialized, thejVM attempts to bringthe object back to life by making a new object on the heapthat has the same state the serialized object had at the time itwas serialized. Well, except for the transient variables, whichcome back either null (for object references) or as defaultprimitive values.· . r ~e JVM.\\ ~'(O-.l ell' eCJW:I~\his stty -.II \ d ~e dass.-:t ~\"d'" ea01101001object is read as bytesclass is found and loaded, savedinstance variables reassigned0110111001File__----~ 011010010110111001is read byFiJeInputStream(0 connection stream)is chained toObjectInputStream(a chain stream)Objecto The object is read from the stream.e The JVM determines (through info stored withthe serialized object) the object's class type.The JVM attempts t? find and load the object'sclass. If the JVM can't find and/or loadthe class, the JVM throws an exception andthe deserialization fails .A new object is given space on the heap, butthe serIalized obJeds constructor doesNOT runl Obviously, if the constructor ran, itwould restore the state of the object backto its original 'new' state, and that's not whatwe wont. We want the object to be restoredto the state it had when it was serialized, notwhen it was first created.442 chapter 14


serialization and file I/OG If the object has a non-serializable classsomewhere up its inheritance tree, theconstructor for that non-serializable classwill run along with any constructors abovethat (even if they're serializable). Once theconstructor chaining begins, you can't stop it,which means all superclasses, beginning withthe first non-serializable one, will reinitializetheir state.CD The object's instance variables are given thevalues from the serialized state. Transientvariables are given a value of null for objectreferences and defaults (0, false, etc.) forprimitives.:t1ere1lU'H ? 0DUmb ~uestl9n8Q:Whydoesn't the class get saved as part of the ob"ject? That way you don't have the problem with whetherthe class can be found.A: Sure,they could have made serialization work thatway. But what a tremendous waste and overhead. Andwhile it might not be such a hardship when you're usingserialization to write objects to a file on a local hard drive,serialization is also used to send objects over a networkconnection. If a class was bundled with each serialized(shippable) object, bandwidth would become a much largerproblem than it already is.For objects serialized to ship over a network, though, thereactually is a mechanism where the serialized object can be'stamped' with a URl for where its class can be found.Thisis used in Java's Remote Method Invocation (RMI) so thatyou can send a serialized object as part of, say, a methodargument, and if the JVM receiving the call doesn't havethe class,it can use the URl to fetch the classfrom thenetwork and load it, all automatically. (We'll talk about RMIin chapter 17.)Q:What about static variables? Are they serialized?A: Nope. Remember, static means "one per class"not"one per object" Static variables are not saved,and when anobject is deserialized, it will have whatever static variableits class currentlyhas.The moral : don't make serializable objectsdependent on a dynamically-changing static variable!It might not be the same when the object comes back.you are here ~ 443


serialization exampleSavit1g at1d restorit1g the gattte charactersimport java.io.*;public class GameSaverTest { Make sow-t tna~atte'rt-· ·public static void main(String(] axgs} {GameCharacter one = new GameCharacter(50, "Elf", new Strinq{] ("bow", "sword", "dust"});GameCharacter two =new GameCha.racter (200, "Troll", new String!1 {"bare hands" J "big ax"}) ;GameCharacter three =new GameCharacter(120, "Magician", new String[l ("spells", "invisibility"}) ;/ / imagine code that does things with the characters that might change their state valuestry {ObjectOutputStream 09 =new ObjectOutputstream (new Fileoutputstream ("Game. ser") );os.writeObject(one) ;os.writeQbject(two) ;os.writeQbject(three) ios. close () ;catch(IOExceptioD ex) (ex.printStackTrace() ;}one = null;two = null;three =null;Wt stt tnt... tD ""II so '\lit un't~ alUSS t.ht objttts 0l'I -\:he ht.af·Now \'"tad tht... balK j" +\'"0'" the tilt...~{ ~Objectlnputstream is = new Objectlnputstream(new Filelnputstream ("Game. ser")) ;Gamecharacter oneRestore = (GameCharacter) is. readObject () ;GameCharacter twoRestore = (GameCharacter) is. readObject () ;GameCharacter threeRestore =(GameCharacter) is. readObject () ;~ .t. oVlt.t4·System. out.println ("One' B type : \I + oneRestore. g8tType () ) ; Chtt'tt. -to see i \ ....Systern.aut .println ("Two's type : " + twoRestore. getType () ) ; ~System.out.println("Three's type: " + threeRestore .getTypeO) jcatch(Exception ex) (ex .printstackTrace();444 ch apter 14


serialization and file 110fhe G-atl1eCharacfer classimport java.io. t ;public class GameCharacter implements Serializable {int power;String type;String[] weapons;public GameCharacter(int p, String t, String[] w) {power =p;type =t;weapons =w;public int getPower ()return power;public String getType()return type;public String getWeapons () {String weaponList = "":for (int i =0; i < weapons. length; iff) {weaponList += weapons[i] + " ";}return weaponList;you are here " 445


saving objectsOl.jed Serialization)- You can save an objecfs state byserializJng the object.)- To serialize an object, you need an ObJectOutputStream (from thejava.lo package))- Streams are either connection streams orchain streams.. Connection streams can represent a connection toa source ordestination, typically afile, network socket connection, ortheconsole.)- Chain streams cannot connect to a source ordestination and mustbe chained toa connection (or other) stream.)- To serialize an object toa file, make a RleOuputStream and chain ~into an ObjectOutputStream... To serialize an object, call writeObject(theObject) on theObjectOutputStream. You do not need to call methods on theFUeOutputSlream.)- To be serialized. an object must Implement the Seriallzable interface.Ita superclass ofthe class Implements Serializabls, the subclass willautomatically beseria\lzable even If ~ does not speclfically declareimplements Seri8/1zable.)- When an object Isserialized, its entire oblect graph Isserialized. Thatmeans any objects referenced bythe serialized object's instancevariables are serialized, and any objects referenced bythoseobJects...and soon.• If any object in the graph Isnot serializable, an exception will bethrown at runlime, unless the Instance variable referring tothe objectIsskipped... Marie aninstance variable with the transient keyword if you wantserialization to skip that variable. The variable will be restored as null(for object references) ordefault values (for primitives).. • During deseriallzation, the class ofallobjects Inthe graph must beavailable tothe JVM.• You read objects In (using readObjeet()) Inthe order In which theywere originally written.• The retum type ofreadObjectO istype Object, so deserializedobjects must be cast to their real type.• Static variables are not serializedI Itdoesn't make sense to savea static variable value aspart of aspecific objecfs state. sInce allobjects of that type share only a single valu&-the one Inthe class.446 chapter 14


serialization and file I/OWriti"g a Strittg to afext FileSaving objects, through serialization, is the easiest way to save andrestore data between runnings ofa Java program. But sometimes youneed to save data to a plain old text file. Imagine yourJava programhas to write data to a simple text file that some other (perhaps non­Java) program needs to read. You might. for example, have a servlet(Java code running within your web server) that takes form data theuser typed into a browser, and writes it to a text file that somebody elseloads into a spreadsheet for analysis .Writing text data (a String, actually) is similar to writing an object,except you write a String instead ofan object. and you use aFileWriter instead ofa FileOurputStream (and you don't chain it to anObjectOutputStream).60,Elf,how, sword,dust200,Troll,ba.re ha.ndB,hlg ax120,Maglolan,spel1B,invisibilltyTo write Qserialized object:ObjQctOutputstream.vriteObject(someObject);To write QString:fileWriter. write ("My first String to save") jimportclass WriteAFile {public static void main (String[] args) {try {FileWriter writer =\/0 sb>~~d1'l\/t\\...L- t)I~ b- I t.a-u.~ . writer . write ("hello foo ! ") ; ~ Tht -.-iuO "'«hod ukII-$t. ~ ',1'1 a '(~... o'tJ... vl-''ri'a St.ril'l~es~.,.. "'t:.'J!'C'lv \1'1~ 1\writer. close () ; ~ Cl 'laSt'"1:. ....hCtl YO\l.'rt \0'2-.,I.t.~y-b 0'/1•.dO"ll)}catch(IOException ex) (ex.printStackTrace();you are here ~ 447


writing a text filefext File ExatMple; e-FlashcardsRemember those flashcards you used in school? Where youhad a question on one side and the answer on the back?They aren't much help when you 're trying to understandsomething, but nothing bears 'em for raw drill-and-practiceand rote memorization. When JfYU have to burn in afaa.Andthey're also great for trivia games.We're going to make an electronic version that has threeclasses:1) QuizCardBuilder. a simple authoring tool for creating andsaving a set ofe-Flashcards,2) QuizCardPlayer. a playback engine that can load aflashcard set and play it for the user.3) QuizCard, a simple class representing card data. We'llwalk through the code for the builder and the player, andhave you make the QuizCard class yourself, using this~QulzCardQuizCard(q, a)questionanswer18 0e Qvlz CMd",lIdo, IFI..Quullon:,Which university Is featured In thefilm -Good Will Huntlng~IJ,,~ ..An....r: IM.I.T. ~,,~II ~8 8e ()I~ card"-,f j"gelQuestion0gelAnswerQ,What happens If you calll:0bject.getPrimaryKeyO on asian bean's remote reference?I,-- - II( Wulc.id ) i- ;::( ShoW_, ), 10 LA)-~QulzCardBullderHas a File menu witk a ~SaveH option for savingthe current set of cards to a text file."- ~QulzCardPlayerHas a File menu with a "Load" option for loading aset of cards from a text fife.448 chapter 14


serialization and file 110Quiz Card 'uilder (code outli.,e)public class QuizCardBuilder {public void goO {/ / build an d display guiIMev- t.lassprivate class NextCardListener implements ActionListener {public void actionPerformed(ActionEven t ev) {/ / add the curr e nt card to the list and clear the text areasIlIlIev- dassprivate class SaveMenuListener imp lemen ts ActionListener {public void actionPerformed (ActionEvent ev) {/ / bring up a file dialog box/ / let the user name and save the setIlIlIev- dassprivate class NewMenuListener implements ActionListener {public void actionPerformed (ActionEvent ev) {II d ear out the card list, and dear out the text areasprivate void saveFIle(File file) {/ / iterate through the list of cards, and write each one ou t to a text file/ / in a parseable way (in oth er words , with clear separations between parts)Called by the Sa\leMell...L.istenev-;does the at.hal ~ i le WV"ibn~ .you are here ~ 449


Quiz Card Builder codeimportimportimportimportimportjava.util.*;java.awt.event. *;J, avax. swmq, . *;java.awt. *;j. ava . *i i o . ;public class QuizCardBuilderprivate JTextArea question;private JTextArea answer;private ArrayList car dLi st ;private JFrame frame;public static void main (String!] ar gs ) {QuizCardBuilder builder = new QuizCardBuilder();builder.go () ;public void got) {/ / build guif rame = new JFrame(uQuiz Card Builder");JPanel mainPanel = new JPanel();Font bigFont = new Font(Usanserif", Font.BOLD, 24);question = new JTextArea(6,20);question.setLineWrap(true);question.setWrapStyleWord(true);question.setFont(bigFont);JScrollPane qScroller = new JScro l l Pane (quest i on) ;qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL SCROLLBAR ALWAYS);qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);answer = new JTextArea(6, 20);answer.setLineWrap(true);answer.setWrapStyleWord(true);answer.setFont(bigFont);JScrollPane aScroller = new JScrollPane(answer);aScroller. setVerticalScrollBarPolicy (Scr ollPaneConstants.VERTICAL SCROLLBAR ALWAYS);aScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);JButton nextButton =new JButton(UNext Card");cardList = new ArrayList();JLabel qLabel = new JLabel(uQuestion:");JLabel aLabel = new JLabel(UAnswer:");mainPanel.add(qLabel);mainPanel.add(qScroller);mainPanel.add(aLabel);mainPanel.add(aScroller);mainPanel.add(nextButton);nextButton.addActionListener(new NextCardListener());JMenuBar menuBar = new JMenuBar();JMenu fileMenu = new JMenu(UFile");JMenultem newMenultem = new JMenultem( UNew");450 chapter 14


serialization and file I/OJMenultem saveMenultem = new JMenultem("SaveH)inewMenultem.addActionListener(new NewMenuListener());saveMenultem.addActionListener(new SaveMenuListener());tileMenu.add(newMenultem)ifileMenu.add(saveMenultem)imenuBar.add(fileMenu);frame.setJMenuBar(menuBarliframe.getContentPane() .add (BorderLayout. CENTER,frame.setSize(500,600) iframe.setVisible(true)ipublic class NextCardListener implements ActionListener (public void actionPerformed(ActionEvent ev) (QuizCard card = new QuizCard(question.getText(), answer.getText());cardList.add(card) iclearCard ();public class SaveHenuListener implements ActionLiatener (public void actionPerformed(ActionEvent ev) (QuizCard card = new QuizCard(question.getText(),cardList .add(card);answer .getText());-b CI'f\ t.n IS\) '0'1 b'>ed'Id\~ bo'1- r. ~ 'IS aOfle o>r't.bl\e>\a ...,\el \\'1 is HilS dS'f'se ~ C~! It. ~edpublic class NewManuListener implements ActiOnListen~f\\fpublic void actionPerformed(ActionEvent ev) (cardList.clear(liclearCard () iprivate void clearCard() (question.setText("")janswer.setText(KHl jquestion,requestFocuS()ic>:private void saveFile(File file) /e:-:try {BufferedWriter writer ~ new BufferedWriter(new FileWriter(file))i )for (QuizCard card: cardList) ( ~l! t.h.ai" d B~.f(l-edW\"ikwriter.write/card.getQuestion() + ...i")ij.s~t\" ~pdraud b \ "" " ..,,­add /. y a /", and ihbla IItW'lIt thardt.te-- ("\11")you are here. 451


writing fIlesfhe java.ioJiIeclassThejava.io.File class represents a file on disk, but doesn'tactually represent the contents of the file. What? Think ofa File object as something more like a pat/manuofa file(or even a directory) rather than The Actual File Itself.The File class does not, for example. have methods forreading and writing. One VERYuseful thing about a Fileobject is that it offers a much safer way to represent afile than just using a String file name. For example. mostclasses that take a String file name in their constructor(like FileWriter or FileInputStream) can take a Fileobject instead. You can construct a File object, verifythat you've got a valid path, etc. and then give that Fileobject to the FileWriter or FilelnputStream.A File object represents the nameand path of a file or directory ondisk, for example:JUsersJKathy/DataJGameFile.txtBut it does NOT represent, or giveyou access to, the data in the filelSome things you can do with B File object:.. Make a File object repr~ntlng anexisting tHeFile f =new File(~MyCode.txtUI j@ Make Q new directoryFile dir =new File("Chapter7 n l ;dir.mkdir () ;• List the contents of a directoryif (dir.isDirectory()I {String [1 dirContents = dir.list () ;for (int i =0; i < dirContents.length; iH) {System.out.println(dirContents[i]);8) Get the absolute path of Q file or directorySystem.out.println(dir.getAbsolutePath(»;I) Delete a file or directory (returns true Ifsuccessful)boolean isDeleted =f.delete()j452 chapter 14


serialization and file 1/0The beauty of buffersIf there were no buffers, It would be likeshopping without a cart. You'd have tocarry each thing out to your car. one soupcan or toilet paper roll at a time."Boulder"Stringis written toString is put into a bufferwith other StringsWhen the buffer ;s full. theStrings are all written toAspenDenver,... "Boulder H U~eD" •Aspen Denver Boulder Boulder"Denver"M is chained toBufferedWrlter(a chain stream thatworks with characters)FlleWrlter(a connection streamthat writes charactersas opposed to bytes)FileBufferedNriter writer =new BufferedKriter(new FileWriter(aFile))i~The cool thing about buffers is that they're much. more efficient thanworking without them. You can write to a file using FileWriter alone, bycalling write (someString), but FileWriter writes each and every thing youpass to the file each and every time. That's overhead you don't want orneed. since every trip to the disk is a Big Deal compared to manipulatingdata in memory. By chaining a BufferedWriter onto a FileWriter, theBufferedWriter will hold all the stuffyou write to it until it's full. Only whenthe buffer isfull will theFUeWriteractuallybetold to unite to thefile on disk.If you do want to send data beftn» the buffer is full, you do have control.Just Flush It. Calls La writer.flush () say. "send whatever's in the buffer, now! hyou are here) 453


eading filesReadittg frotH afext FileReading text from a file is simple, but this time we'll use a Fileobject to represent the file, a FileReader to do the actual reading,and a BufferedReader to make the reading more efficient.The read happens by reading lines in a while loop, ending the loopwhen the result ofa readl.inej) is null. That's the most commonstyle for reading data (pretty much anything that's not a Serializedobject): read stuffin a while loop (actually a while loop tesf),terminating when there's nothing left to read (which we knowbecause the result ofwhatever read method we're using is null) .What's 2 + 2?/4What's 20+22/42~ I ~ dthti"""~import java. io. * ; DO'I'I t dr~MyText.txtclass ReadAFile {pub1ic static void main (Strinq(J arqs) {A Fild(eadty ~ a f.ctr., t t· ..L. ,.tha b L' ~ oor, :ou-ea... i"ortry { ( yat , V1at (.OnnUts to a UlI.t .filtFile myFile = new File("MyText.txt");FileReader fileReader = new FileReader(myFile);BufferedReader reader =.'bIt t.o noldMakt a s.b-'Il'~ "a'(l" . Ii. tl-lt linc IS yeat4t.I-I Il't\t as '\,String line = null;while «line = reader.readLine(» != null) (System. out.println (line) ;}reader.close();catch(Exception ex) {ex.printStackTrace();454 chapter 14


serialization and file 1/0Quiz Card Player (code outli"e)public class QuizCardPlayer {public void goO {/ / build and display guiclass NextCardlistener implements ActionListener (public void actionPerformed(ActionEvent ev) {/ / if this is a question, show the answer, otherwise show next question/ / set a flag for whether we're viewing a qu estion or answer}}class OpenMenuListener implements ActionListener {public void actionPerformed(ActionEvent ev) {/ / bring up a file dialog box/ / let the user navigate to and choose a card set to openprivate void loadFile(File file) {/ / must bu ild an ArrayList of cards, by reading them fro m a text file/ / called from the OpenMenuListen er event handler, reads the file one lin e at a time/ / and tells the makeCardf) meth od to make a new card out of th e line/ / (one line in th e file holds bo th the question and an swer, separated by a "I")private void makeCard(String lineToParse) {/ / called by th e Ioadf'ile method, takes a lin e fro m the text file/ / and parses into two pieces-s-question and answer-and creates a new QuizCard/ / and adds it to th e ArrayList called CardListyou are here ~ 455


Quiz Card Player codeimportimportimportimportimportjava.util.*;java .awt.event.*;j avax . swi ng . *;java.awt. *;. ' * J aVa. 10 . ;public cl ass QuizCardPlayerprivate JTextArea display;pri vate JTextArea answer;private Arr ayLi s t car dLi st;privat e QuizCard currentCard;privat e int cur r ent Car dI ndex;private JFrame frame;privat e JButton nextButton;private boolean isShowAnswer;public static voi d main (String [] args) (QuizCar dPl ayer r eader = new QuizCardPlayer();reader.go();publi c void go()II build guiframe = new JFrame ("Quiz Card Player");JPanel mainPanel = new JPanel();Font bigFont = new Font("sanserif", Font.BOLD, 24);display = new JTextArea(lO, 20);display. setFont (bigFont);display. setLineWrap(true);display. setEditable(false);J ScrollPane qScroller = new JScrollPane(display);qScroller.setVerticalScr ollBarPolicy(ScrollPaneConstants.VERTICAL SCROLLBAR ALWAYS);qScroller.setHorizontalScrollBarPolicy (ScrollPaneConstants.HORIZONTAL SCROLLBAR NEVER);nextButton = new JButton("Show Ques t i on" ) ; --mai nPanel .add (qScro l l er ) ;mainPane l.add(nextButton);nextButton.addActionListener(new NextCardListener());JMenuBar menuBar = new JMenuBar();JMenu fileMenu = new JMenu("File");JMenuItem loadMenuItem = new JMenurtem ("Load card set");l oadMenultem.addActionListener(new OpenMenuListener());fileMenu. add (loadMenuItem) ;menuBar .add (fil eMenu) ;f r ame.setJMenuBar(menuBar);frame.getContentPane( ) .add(BorderLayout.CENTER, mainPanel);frame.setSi ze(640, 500);frame. setVisible(true) ;II close go456 chapter 14


serialization and file 110public class NextcardListaner implements ActionListener (public void actionperformed(ActionEvent eu) (if (isShowAnswer) (I I show the answer because they've seen the questiondisplay.setText(currentCard.getAnswer(») ;nextButton.setText(~Next Card");isShowAnswer = false;else {II show the next questionif (currentCardIndex < cardList.size(»)showNextCard();else III there are no more cards!display.setText(~Thatwas last card");nextButton.setEnabled(false);public class OpenManuLiatanar implements ActionListenerpublic void actionPerformed(ActionEvent ev) (JFileChooser fileOpen = new JFileChooser();~ fileOpen.showOpenDialog(frame);'loadFile(fileOpen.getSelectedFile(»:rcardList = new ArrayList();try (BufferedReader reader = new BufferedReader(newString line = null:while ((line = reader. readLine () ImakeCard(line) ;!= null) (Ireader.close();I)~lprivate void loadFile(File file) (Icatch(Exception ex) {System. out.println ("couldn't read the card file") iex.printStackTrace();II now t ime to start by showing the first cardshowNextCard() ;private void makeCUd(Stxing lineTOi'U88) ( I~Eat.h liYlt: o.f U1\.-t t..on-uyonds to • s i,,~leString () result = lineToParse .split ("I"); ~ .fl~hu...d blAt. 'foIt: h6\1e to yal"~ ~ -theQuizCard card = new QuizCard(result{Oj, resu.lt l Ll j r Iot:S'ti ~ d al\S'W£\'" as stf.lYab: yiet.e1, WecardList. add (card) ; ~ Otl ~, l'tO tthoa to b...eak +.heSystem. out i prIntLn ("made a card") j ~ the SU"I~ s.? I ... r.1L st.iIiI\( i'llto t'folO tokC'llS (oM. .,-« VIe '\\Iot 071arod 0YIe .t« -the .1\1"",£\'"), We'll look at tht:private void showNextCardO ( \itO ...dhod Of! the Ylt:1\.-t y,,~t,currentCard = cardList.get(currentCardlndex); ~currentCardIndex++;display.setText(currentCard.getQuestion();nextButton .setText("Show Answer");isShowAnswer = true;}I I close classyou are here ~ 457


parsing Strings with splitOParsittg with Strhtg splitCJImagine you have a flashcard like this:Saved In a question file like this:What is blue + yellow?greenclJ\S'fie\"WhB.t is blue + yellow?j greenWha.t 1B red + blue?jpurpleHow do you separate the question and answer?When you read the file, the question and answer are smooshedtogether in one line, separated by a forward slash"r (becausethat's how we wrote the file in the QuizCardBuilder code).String splitO lets you break a String Into pieces.The spJitO method says, "give me a separator, and I'll break out ellthe pieces of this String for you and put them in 0 String array:token 1separator468 chapter 14


serialization and file 1/0Q:OK,Ilook In the API and there are about fivemUllon classes In theJava.lo package. How the heck doyou know which ones to use?A..: The I/O API uses the modular 'chaining' concept sothat you can hook together connection streams and chainstreams (also called 'filter' streams) In a wide range ofcombinations to get Just about anyth Ing you couId wa nt .The chaIns don't have to stop at two levels; you can hookmultiple chain streams to one another to get just the rightamount of processing you need.Most of the t ime, though, you'll use the samesmaII handfu I of classes.If you're wrlting text flies,BufferedReader and BufferedWriter (chained to FlIeReaderand Fll eWriter) are pro bably all you need. If you're wrltingserialized objects, you can use ObJeetOutputStream andObJectlnputStream (chained to FllelnputStream andFileOutputStream).In other words, 90% of what you might typically do withJavaI/O can use what we've already covered.Q:What about the new I/O nlo classes added In 1.41A.: The [ave.nlo classesbring a big performanceimprovement and take greater advantage of nativecapabilities of the machine your program Is runn ingon. One of the key new features of nlo is that you havedirect control of buffers. Another new feature Is nonblockingI/O, which means your I/O code doesn't just sitthere, waItIng, if there's nothIng to read or write. Someof the existing classes (Including FllelnputStream andFlleOutputStream) take advantage of some of the newfeatures, under the covers.The nio classesare morecomplicated to use,however, so unless you really need thenew features, you might want to stick with the simplerversions we've used here. Plus,If you're not careful , nio canlead to a performance loss.Non-nlo I/O Is probably rightfor 90% of what you'll normally do, especially if you're Justgetting started In Java.But you canease your way Into the nlo classes, by usingFilelnputStream and accessing its channelthrough thegetChannelO method (added to FllelnputStream as ofversion 1.4).Make it. St.itkextRoses arefirst, violetsarenext.Redders and w,lters areonly for t .• To wrile a text file, start with a FileWrilerconnection stream.• Chain \he FileWriter toa BufferedWriter forefficiency.• AFile object represents a file ata particularpath, but does not represenl the actualcontents ofthe file.• With a File obiect you can create, traverse,and delete directories.• Mosl streams that can use a String filenamecan use a File object as well, and a FJle obiectcan be safer 10 use.• To read a text file, start with a FileReaderconnection stream.• Chain \he FileReader toa BufferedReader forefficiency.• To parse a text file. you need 10 be sure thefile is written with some way to recognize thedifferent elements.Acommon approach is touse some klnd ofcharacter to separate theindividual pieces.• Use the String splitO method 10 split a Stringupinto indiVidual tokens.AString with oneseparator will have two tokens, one on eachside of\he separator. The separator doesn~count asa token.you are here. 459


saving objectsVersio" IP: AJig Serializatio" &otchaNow you 've seen that I/O inJava is actually pretty simple, especially ifyou stick to the most common connection/chain combinations. Butthere's one issue you might really care about.Version Control is crucial!!fyou serialize an object, you must have the class in order todeserialize and use the object. OK, that's obvious. But what mightbe less obvious is what happens ifyou changethe classin themeantime? Yikes. Imagine trying to bring back a Dog object whenone ofits instance variables (non-transient) has changed from adouble to a String. That violatesJava's type-safe sensibilities in a BigWay. But that's not the only change that might hurt compatibility.Think about the following:•You write a Dog class10UOl1011 01 ". \1"'11010 1000010 ·· \ ,,~S\()Y\·v~~;~o10 Q 1taSS1010101~~~~~~~~O l ~;Ar;Dog.class•You serialize a Dog objectusing that classChanges to a class that can hurt deseriallzatlon:Deleting an instance variableChanging the declared type ofan instance variableChanging a non-transient instance variable to transientMoving a class up or down the inheritance hierarchyChanging a class (anywhere in the object graph) from Serializableto not Serializable (by removing 'implemen ts Serializable' from aclass declaration)Changing an instance variable to staticChanges to a class that are usually OK:Adding new instance variables to the class (existing objects willdeserialize with default values for the instance variables they didn'thave when they were serialized)Adding classes to the inheritance treeRemoving classes from the inheritance treeChanging the access level ofan instance variable has no affect onthe ability ofdeserialization to assign a value to the variableChanging an instance variable from transient to non-transient(previously-serialized objects will simply have a default value for thepreviously-transient variables)•You change the Dog class~~~i~ ~ \ . \D~: ~ : O ~ ~ ' : tlass >JeYSIO'l\Ol 010 1.; o ~~~o:~:o :H=12-~1. 0 1. 10 10Dog.c1ass•You deserialize a Dog objectusing the changed class10110110UOl ' "1010000101010 10 001.010 1C10 0001 1010o 00 11 01011. 0 1 10 10Dog.classt\a >Jeys',OYl 'ISss:H=12-~• Serailization fails!!The JVM says, "you can'tteach an old Dog new code".460 cha pte r 14


serialization an d file 110Usi.,g the serialVersio.,UIPEach time an object is serialized. the object (includingevery object in its graph) is 'stam ped' with a versionID number for the object's class. The ill is calledthe serialVersionUlD, and it's computed based oninform ation about the class structure. As an object isbeing deserialized, if the class has changed since theobject was serialized, the class could have a differentserialVersionUID, and deserialization will faill But youcan control this.If you think there Is ANY possibility thatyour class might evolve, put a serial versionID In your class.When Java tries to deserialize an object, it comparesthe serialized object's serialVersionUID with that of theclass the JVM is using for deserializing the object Forexample, ifa Dog instance was serialized with an ill of,say 23 (in reality a serialVersionUID is much longer).when theJVM deserializes the Dog object it will firstcompare the Dog object serialVersionUID with theDog class serialVersionUID. If the two numbers don'tmatch, rhejVM assumes the class is not compatiblewith the previously-serialized object, and you'll get anexception during deserialization.So, the solution is to put a serialVersionUIDin your class, and then as the class evolves, theserialVersionUID will remain the same and theJVMwill say. "OK, cool, the class is compatible with thisserialized object." even though the class has actuallychanged.This works ()1lly ifyou're careful with your classchanges! In other words. YQU are taking responsibilityfor any issues that come up when an older object isbrought back to life with a newer class .To get a serialVersionUID for a class, use the serialvertool that ships with yourJava development kit.When you think your classmight evolve after someone hasserialized objects from it•••@ Use. the serialver command-line too'to get the version ID for your clossCD Paste the output into your closspublic class Dog {private Strinq name;private int size ;/ / method code herelong .erialVersionOZD ­-6849194410154667110L;~ Be sure that when you make changes tothe closs, you take responsibility in yourcode for the consequences of the changesyou made to the clossl For example, besure that your new Dog closs can deal withan old Dog being deserialized with defaultvalues for instance variables added to thedoss after the Dog was serialized.you are he re ~ 461


Code Kitchen'* *Code KitchenLet's mak the BeatBox save andrestore our lavorite pattern462 chapter 14


serialization and file I/OSavinG a'eatJox patternRemember, in the BeatBox, a drum pattern is nothing more than a bunch ofcheckboxes. When it's time to play the sequence, the code walks through thecheckboxes to figure out which drums sounds are playing at each ofthe 16beats. So to save a pattern, all we need to do is save the state of the checkboxes.We can make a simple boolean array, holding the state ofeach of the 256checkboxes. An array object is serializable as long as the things in the array areserializable, so we'll have no trouble saving an array ofbooleans.To load a pattern back in , we read the single boolean array object (deserializeit), and restore the checkboxes. Most ofthe code you've already seen, in theCode Kitchen where we built the BeatBox GUI , so in this chapter, we look atonly the save and restore code.This CodeKitchen gets us ready for the next chapter, where instead ofwritingthe pattern to a file, we send it over the networkto the server. And instead ofloading a pattern in from a file, we get patterns from the server, each time aparticipant sends one to the server.Serializing a patternThis is an inner t\ass i'llSidet.he Beat.Bo~ zede.public class MySendListener implements ActionListener { l' \.,,, t.heIt. all happens ..,hen "he ~er " . spublic void actionPerformed (ActionEvent a) {~b~Hon and t.he Ad:ionE.'Ient. .{\res.boolean []checkboxState = new boolean[256]; t-- Ztarbooleatl array to hold t.hefor (int i = 0; i < 256; i++) {01" eath the'kbo~ .JCheckBox check = (JCheckBox)if (check.isSelected(» {checkboxState[i] = true;checkboxList.get(i); Walk t.hro~ h t.h(ArrayList. got e thetkbo~Listget t.he state thetkbo~s), atldadd it to t 0+ eath Otle, andhe boo/eatl array.try {FileOUtputStream fileStream = new FileOUtputStream(new File("Checkbox.ser"»;ObjectOUtputStream os = new ObjectOUtputStream(fileStream) ;os.writeObject(checkboxState);catch(Exception ex) {ex.printStackTrace();} II close methodII close inner classyou are here). 463


deserlallzlng the patternResfori.,g a Jea1tox patter"This is pretty much the save in reverse... read the boolean arrayand use itto restore the state of the GUI checkboxes, It all happens when the user hitsthe "restore" 'button.Restoring a patternpublic class MyReadInListener impleJDenta ActionLiatanerpubliC void actionPerfor.med(ActionEvent a)boolean [] checkboxState :;;;; null;try (FilelnputStream filaIn:;;;; new Filelnputstream(new File("Checkbox.aer"»;ObjectInputstream is • new ObjectInputStream(fileIn) ;checkboxState = (boolean []) is.readObject () ; t--- Rao -the s"",~'e ~jed: i". the kil~~eboolea" array> o"d ta1-t It W . 0catch (Exception ex) (ex.printstackTrac. () ; } boolea" arr0'i (Yl:1"etI'w. ytaoObjett\'"d~."s a yet ~a-.te ok ~e Ob}etfor (int i :;;;; 0; i < 256; i++) (JCb.eckBox check :::r (JCheckBox)if (eheckboxStatetill (ohaek.satsalected(trua) ;} elae (eheck.aetselected{false);aheokboxLillt.get(1) ;sequencer.stop();buildTrackAndStart();} I I close I118thodII close inner classrpen your penCiI-----------------,This version has a huge IImltatlonl When you hit the "serlatlzelt" button, ItserlaIIzes automatlcalIy,to a file named "Checkbox.ser" (which gets created If Itdoesn't exist) . But each time you save,you overwrite the previously-saved flIe.Improve the save and restore feature, by Incorporating a JFlleChooser so thatyou can name and save as many different patterns as you like, and loadlrestorefrom any of you r prevIously-saved pattern flies.464 chapter 14


serialization and file 110~yourpenCiican they he saved?Which ofthese do you think are,or should be,serlallzable? If not,why not? Not meaningful7Security rlsk7 Only works for the CUTrentexecution of the JVM?Make your best guess,without looking it up in the API.Object type Serlallzable? If not, why not?ObjectStringFileDateOutputStreamJFrameIntegerSystemVes I NoYes I NoYes I NoVes I NoYes I NoYes I NoYes I NoVes I NoWhars Legalil:lrclethe code fragmentsnat would compile (assuming:hey're with In a legaIdass).KEEP+­RIGHTFileReader fileReadar ~ new FileReader() iBufferedReader reader :: new BufferedReader (fileReader) ;FileC>utputStream f :: new FileOutputStream(new File ("roo. se.r") ) ;ObjectOutputstream 08 :: new ObjectOutputStream(f) ;BufferedReader reader:: new BufferedReader(new FileReade.r(file)) ;String line =null;whila (line • reader.readLine()) != null) (malcecard(line) ;ObjectInputStream is = new ObjectInputstream (new Fil&Outputstream("Game. ser")) ;GameCharacter oneAgain = (Gamecharacter) is.readObject();you are here ~ 465


exercise: True or FalseThis chapter explored the wonerful world ofJava 110. YourJob Is to decide whether eachof the following lID-related statements istrue or false.1. Serialization is appropriate when saving data for non-java programs to use.2. Object state can be saved only by using serialization.3. ObjectOutputStream is a class used to save serialized objects.4. Chain streams can be used on their own or with connection streams.5. A single call to writeObjectO can cause many objects to be saved.6. All classes are serializable by default.7. The transient modifier allows you to make instance variables serializable.8. Ifa superclass is not serializable then the subclass can't be serializable.9. When objects are deserialized, they are read back in last-in, first out sequence.10. When an object is deserialized, its constructor does not run.11. Both serialization and saving to a text file can throw exceptions.12. BufferedWriters can be chained to FileWriters.13. File objects represent files, but not directories.14. You can't force a buffer to send its data before it's full.]5. Both file readers and file writers can be buffered.16. The String splitO method includes separators as tokens in the result array.17. Any change to a class breaks previously serialized objects of that class.466 chapter 14


-CJu serialization and file 110o e lYlaonetsThis one's tricky, ~ we promoted it from an Exerciseto full Puzzle status.Reconstruct the code snippets to make a working Java program thatproduces the output listed below? (You might not need all of the magnets,and you may reuse a magnet more than once.)class DungeonGame implementsseriali'Zable {fos = newFileOutputstrearnFileOutputs t r e am ( "drr, ~s e r " ) ie.printStackTrace()iObjectlnputStream ois = newObjectlnputStream(fis);short getZ () {return Zi009.close ( ) :int geU() {return XiSystem.out.println(d.getX()+d.getY()+d.getZ())iFilelnputstream fis = new ubl i c int x = 3;FilelnputStream("dg.ser")j ransient long y = 4;private short z = 5;long getY() {return y;ois ,close ( ) ;class D ungeOnTest


exercise sol utions1. Serialization is appropriate when saving data for non:Java programs to use. False2. Object state can be saved only by using serialization. False3. ObjectOutputStream is a class used to save serialized objects. True4. Chain streams can be usedon their own or with connection streams. False5. A single call to writeObjectO can cause many objects to be saved. True6. All classes are serializable by default. False7. The transient modifier allows you to make instance variables serializable. False8. If a superclass is not serializable then the subclass can't be serializable. False9. When objects are deserialized they are read back in last-in, first out sequence. False10. When an object is deserialized, its constructor does not run. True11. Both serialization and saving to a text file can throw exceptions. True12. BufferedWriters can be chained to FileWriters. True13. File objects represent files, but not directories. False14. You can't force a buffer to send its data before it 's full. False15. Both file readers and file writers can optionally be buffered. True16. The String splitf) method includes separators as tokens in the result array. False17. Any change to a class breaks previously serialized objects ofthat class. False468 chapter 14


serialization and file 110class DungeonGame implements Serializable {public int x = 3;transient long y = 4:private short z = 5:int getX() {return Xj}long gety() {return Yj}short getZ() {return 2:}}class DungeonTest {public static void main(String [) args) (DungeonGame d = new DungeonGame{)jSystem.out.println(d'getX() + d.getY() + d.getZ{»jtry (Fit ~~ W1~ Help Es:apo\ java DungeonTest128}FileOutputStream fOB = new FileOutputStream{Udg.ser H ) :ObjectOutputStream oos = new ObjectOutputStream(foB)joos.writeObject(d);oos.close():FilelnputStream fis = new FilelnputStream(Udg.ser n ) :ObjectlnputStream ois = new ObjectlnputStrearn{fis):d = (DungeonGame) ois.readObject();ois.close();catch (Exception e) {e.printStackTrace()j)system.out.println(d.getX() + d.getY{) + d.getZ{»;you are here. 469


15 networking and threadsMake a ConnectionConnect with the outside world. Your Java program can reach out and touch aprogram on another machine. It's easy. All the low-level networking details are taken care of byclasses In the java.net library. One of Java's big benefits is that sending and receiving data overa network Is Just I/O with a slightly dIfferent connection stream at the end of the chain. If you'vegot a BufferedReader. you can read.And the BufferedReader could care less if the data cameout of a file or flew down an ethernet cable.In this chapter we'll connect to the outside worldwith sockets.We'll make cllentsockets.We'll make server sockets.We'll rnake clients and servers.And we'll make them talk to each other. Before the chapter's done, you'll have a fully-functional,multithreaded chat client. Old we just say multithreaded? Yes, now you will learn the secret ofhow to talk to Bob while simultaneously listening to Suzy.this is a new chap ter 471


tbo)(. chatYou're working on a computer game .You and your teamare doing the sound design for each part of the game.Using a 'chat' version of the Beat 'Box, your team cancollaborate-You can send a beat pattern along withyour chat message, and everybody in the Beat BB:O"~C:h:a:t__-:r~~~;si~~~@~c::~~;1getS .i~ So yO,u don't just get to rtad\ thde othder. .. ""'\


networking and threadsChat Program OverviewThe Client has toknowahoutthe Server.The Server has toknowabout ALL the Clienti.How it Works:Client Co Client connects to the serverClient AG The server makes aconnection and adds the clientto the list of participantse Another client connectso Client A sends a message tothe chat serviceClient AClient B---- ~---.Client A~V~, I'd lik~ to l.o9I~t- to tht t~ stHite"Who took ~ lava liMf__---1My OOhtl fServerServer-~~I ~ .I ~. '.-Servero The server distributes themessage to ALL participants(including the original sender)Client AClient BServeryou are here ~ 473


socketconnecllonsThe three things we have to learn to get the client working are :1) How to establish the initial connection between the client and server2) How to send messages UJ the serverS) How to receive messagesjrom the serverThere's a lot of low-level stuff that has to happen for these things to work. But we'relucky, because the Java API networking package (java.net) makes it a piece of cakefor programmers. You'll see a lot more GUI code than networking and I/O code.And that's not all.Lurking within the simple chat client is a problem we haven't faced so far in thisbook: doing two things at the same time. Establishing a connection is a one-timeoperation (that either works or fails). But after that, a chat participant wants tosend outgoing messages and simultaneously receive incoming 7TU'.SSages from the otherparticipants (via the server). Hmmmm... that one's going to take a little thought, butwe'll get there injust a few pages.o ConnectClient connects to the server byestablishing a Socket connection.• SendClient AClient sends a message to the serverMa~ a sotlcd:. l.mIPlettiO'll toJ~I>.lbt.r.rO; .if.rort c;oooe ReceiveClient AClient gets a message from the server474 chapter 15Client A


Make a ttetwork Socket cotntectiottTo connect to another machine, we need a Socket connection.A Socket (java.ner.Socket class) is an object that representsa network connection between two machines. What's aconnection? A relationship between two machines. where twopieces of software know about each other. Most importantly,those two pieces ofsoftware know how to communicatewitheach other. In other words . how to send bits to each other.We don't care about the low-level details, thankfully, becausethey're handled at a much lower place in the 'networkingstack'. Ifyou don't know what the 'networking stack' is, don'tworry about it. It's just a way of looking at the layers thatinformation (bits) must travel through to get from aJavaprogram running in aJVM on some OS, to physical hardware(ethernet cables, for example). and back again on some othermachine. Somebody has to take care ofall the dirty details.But not you. That somebody is a combination of O~pecificsoftware and theJava networking API. The part that you haveto worry about is high-level-make that v~ high-level-andshockingly simple. Ready?Socket chatSocket= new Socket(~196.164.1.103H,lr:ci r t1S ~or the sa-vt:rnetworking and threadsTo make a Soc"ketconnection, you needto know~thingsabout the server: %0it is, and which portits running OILIn other words,IP address and TCPport l11U1lher.7 Port 1l""'ba­5000);ClientASocket connection means the two machines haveinforztlation about each other, including networllocation (IP address) and TCP port.you are here ~ 475


well-known portsArep port Is Just a ttutltber.A16...bit ttutMber that identifiesaspecific prograttt Ott the server.Well-known TCP port numbersfor common server applicationsYour internet web (HTTP) server runs on port 80. That's astandard. Ifyou've got a Telnet server, its running on port23. FTP? 20. POP3 mail server? 110. SMTP? 25. The Timeserver sits at 37. Think ofport numbers as unique identifiers.They represent a logical connection to a particular piece ofsoftware running on the server. That's it. You can't spin yourhardware box around and find a TCP port. For one thing,you have 65536 ofthem on a server (0 - 65535). So theyobviously don't represent a place to plug in physical devices.They're just a number representing an application.Without port numbers, the server would have no way ofknowing which application a client wanted to connect to.And since each application might have its own uniqueprotocol, think ofthe trouble you 'd have without theseidentifiers. What ifyour web browser, for example, landedat the POPS mail server instead ofthe HTTP server? Themail server won 't know how to parse an HTTP request! Andeven ifit did, the POPS server doesn't know anything aboutservicing the HTTP requestWhen you write a server program. you'll include code thattells the program which port number you want it to nul on(you'll see how to do this in Java a little later in this chapter).In the Chat program we're writing in this chapter. we picked50DD.Just because we wanted to. And because it met thecriteria that it be a number between 1024 and 65535. WhyI024? Because 0 through 1023 are reserved for the wellknownservices like the ones we just talked about,And ifyou 're writing services (server programs) to run ona company network, you should check with the sys-adminsto find out which ports are already taken. Your sys-adminsmight tell you, for example, that you can't use any portnumber below, say, 3000. In any case, ifyou value your limbs,you won't assign port numbers with abandon. Unless it'syour home network. In which case youjust have to check withyour kids.AseY"'er" l.4... helVe "p to b&5~bdiHf"r'etlt serve- apps 'nIIInil'\~~ per" pori:.The TCPporttuU1lbers frOttl 0to 1023are reserved for well­"known services. Don'tuse them for your ownserver programs!'"The chat server we'rewriting uses port5000. We just }tie"ked atuU1lber between 1024and 65535.'Well, you might be able 10 use one ofthese.bul the sys-adrnln whereyouwork will probably kill you.476 chapter 15


networking and threadsQ: How do you know the portnumber of the server program youwant to talk to 7A.: That depends on whether theprogram is one of the well-knownservices.If you're trying to connectto a well-known service, like the oneson the opposIte page (HTIp' SMTP,FTP,etc.) you can look these up onthe Internet (Google "Well-KnownTCP Port"). Or ask your friendlyeighborhood sys-adrnin.But if the program isn't one of thewell-known services,you need tofind out from whoever Is deployingthe service. Ask him. Or her.Typically,if someone writes a network serviceand wants others to write clients forit, they'll publish the lP address, portnumber, and protocol for the service.~or exampie, if you want to write aclient for a GO game server, you canvisit one of the GO server sites andfind Information about how to write aclient for that particular server.IP address is like specifying aparticular shopping moll, soy,"Flatirons Marketplace"or number is like naminga specific store, soy,"Bob's CD Shop"Q: Can there ever be more thanone program running on a singleport7 Inother words, can twoapplications on the same server havethe same port number7A.: Nol If you try to blnd a prog ram:0 a port that Is already in use,you'llget a BindException. To bind a program:0 a port just means starting up aserver application and telling It to runa particular port. Again, you'll learn~ o re about this when we get to theserver part of this chapter.OK,you got a Socket connection.The client and theserver know the IP address and Tep port number foreach other. Now what1 How do you communicateover that connection11nother words, how do youmove bits from one to the other? Imagine the kinds ofmessages your chat client needs to send and receive.ClientServeryou ar e here ~ 477


eading from a socketTo read data frotH aSocket use aSufferedReaderTo communicate over a Socket connection, you use streams.Regular old I/O streams.just like we used in the last chapter. Oneof the coolest features injava is that most of your I/O work won'tcare what your high-level chain stream is actually connected to. Inother words, you can use a BufferedReaderjust like you did whenyou were writing to a file, the difference is that the underlyingconnection stream is connected to a Socket rather than a File!oLTM forl:. ,",""g~b-.IMake a Socket connection to the server / t.\It ~ "",",ht:r ~(K oU'rSocket chatSocket ~ new Socket("127.0.0.1", 5000);"-.. /27.0.o.J i$ t.he Make an InputStreamReader chained to the Socket'slow-level (connection) input stream\-.ii,n 'foU kno-.l+.hat "000 ish~t.1\OU -.I~ TOL ~ 'fou t.hat ~t:r.z: 'N~ds J +f.~ I~:d~~~ tor '11~lhoti .. ." ~ Ulis 'oIh ) I.lI t.od~ i.s... . ) 'nS~Vtt- bI Yot. r~ tub "")\11\9 01\. You01\ d .sjI\SI~ rt. ~ you.r tJ tI )\d-aIOtlt "'clth. 'bI dndrr>e.e Make a BufferedReader and readIBufferedReader reader = new BufferedReader (stream) iString message = reader.readLine();1L. &oH~(dReAdt:r b:> ~~ d 1 - tnt 10-.1-Chai" V'C' d ( nit\-. was t\-.ai"t 'UJ,.. .\• ..l.)\"ovtSb-ta""Rea~_ w AJ. ~'r()7f\ tr.( ~I 1: S"t.Tta'" -.It 'J"'''( \('


networking and threadsfo write data to aSocket use aPrh1tWriterWe didn't use PrintWriter in the last chapter, we used BufferedWriter. We havea choice here, but when you're writing one String at a time, PrintWriter is thestandard choice. And you'll recognize the two key methods in PrintWriter,printO and println() IJust like good 01' System.out,o Make a Socket connection to the serverSocket chatSoeket = new Soeket("127.0 .0.1",e Make a PrintWrlter chained to the Socket's low-level(connection) output streamPrintWriter writer = new PrintWrit8r(chatsocket.qetoutputStream(»;Ie ~ (print) something. 1I 0 ods a I\tfoI \ ,roe aT.' L Jowriter.println("messaqe to send"); ~rrl"U" a .writer.print("another message"); ~rri"t() cl.~"" iu. l ~t ClIO ~ ..,\\at it. se..o.s·-tht "CW \I"t.·characters----+~I .message..."PrintWriterbytes to serverI~ 011010011chained to '----_--ISocket's outputstream (we don't needto know the actual class)you are here) 479


writing a clientfhe PailyAdvieeCliet1tBefore we start building the Chat app,let's start with something a little smaller.The Advice Guy is a server program thatoffers up practical, inspirational tipsto get you through those long days ofcoding.We're building a client for The AdviceGuy program, which pulls a messagefrom the server each time it connects.What are you wailing for? Who kncwswhat opportunities you've missedwithout this app.o ConnectClient connects to the server and gets aninput stream from itThe Advice GuyClienteReadClient reads a messQge from the server480 chapter 15Client A


networking and threadsPailyAdviceCliet1t codeThis program makes a Socket, makes a BufferedReader (with thehelp of other streams), and reads a single line from the serverapplication (whatever is running at port 4242).import java.io.*;import java .net.*;~r_.,.-L is in ,o"a.nt1:.L-_~ tlass ;:,Q


socketconnecUonsTest your memory of the streams/classes for reading and writing from aSocket.Try not to look at the opposite pagelTo read text from a Socket:.. - - .,!\\'serverClient'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'/erTo send text to a SocketClient'M"iWdraw ill the thaill o-f sttUMS the t1ibltlAStS to smd ~i"5 to the ~verrpen your pencU------------------.Fill In the blanks:What two pieces ofInformation does the client need in order to make aSocket connection with a server?Which TCP port numbers are reserved for'well-known services'like HTTPand FTP7TRUE or FALSE: The range of valid TCP port numbers can be representedby a short primitive?482 chapter 15


networking and threadsWrifittg a sitttple serverSo what's it take to write a server application?Just acouple ofSockets. Yes, a couple as in two. A ServerSocket,which waits for client requests (when a client makes anew Sockett) and a plain old Socket socket to use forcommunication with the client.How it Works:o Server application makes a ServerSocket, on a specific portSarverSocket serverSock: new S&rV8rSocket(4242);This starts the server application listeningfor client requests comingin for port 4242.~~~~. ) ...\e Client makes a Socket connection to the server applicationSocket sock = new Socket ("190 . 165. 1 . 103" , 42(2); SD",,~~et.Clie.nt knows the IP address and port number(published or given to him by whomeverconfigures the server app to be on that port)rs::~~ ~.......~ ~'II'':~ ;';;; ~'.,.....le Server makes a new Socket to communicate with this clientSocket sock = serverSock.accept();The acceptO method blocks (just sits there) whileit's waiting for a c1ie.nt Socket connection. When aclient finally tries to connect, the method returnsa plain old Socket (on a different port) that knowshowto communicate with the dient (i.e.. knows theclient's IP address and port number). The Socket is onCl different port than the ServerSocket, so that theServerSocket can go back to waiting for other clients.you are here. 483


writing a serverPailyAdviceServer codeThis program makes a ServerSocket and waits for client requests. When it getsa client request (i.e. client said new Sockett) for this application), the servermakes a new Socket connection to that client. The server makes a PrintWriter(using the Socket's output stream) and sends a message to the client.( Ley t.hese St.yiYl~Ye",e",v I dbimport java.io.*;weye wov-d-wYa""N 'fimport java.net.*;t.he lode editov-· e.veYehit. Yet.~yYI iYl t.he ",I(ldlubl ' 1 D'l Ad' S ,. 0'" t.his atta'f r 1"1...' I) 1p ac c ass aa, y va.ce erver dail'f advile lO"'CS n O't a .:>"YlYI~ . '?String[] adviceList = {"Take smaller bites", "Go for the tight jeans. No they do NOTmake you look fat.", "One word: inappropriate", "Just for today, be honest. Tell yourboss what you *really* think", "You might want to rethink that haircut."};public void go() (try)} II close goPrintWriter writer = new PrintWriter(sock.getOutputStream(»;St~ing ad~ice = ge~vice(); ~wrJ.ter .p r J.nt l n (advJ.ce); ~ 1'I0W we ~ th Sotwriter. close () ; . ~ ...ake d P ~ W. ket lOlll'lettiol'l to the t1iel'lt toSystem.out.println(advice); advile 1'"11, I'"T'Uhl'" dl'ld selld it (pt"il'ltlI'lO> a Stl'"il'lQI ...tssa~t. tl'l we dost th Sotk-1. b Jwe re dOl'lt with this ll' 1. e q tta~tItl'll:,catch{IOException ex) (ex.printStackTrace();private String getAdvice() {int random = (int) (Math.randomO * adviceList.length);return adviceList[random] ;public static void main(String[] args) (DailyAdviceServer server = new DailyAdviceServer();server.go{) ;484 chapter 15


networking and threads,.,JIBrain BarbellHow does the serverknowhowtocommunicate with the dlent?The client knows the IPaddress and portnumber of the server,but how is the serverable to make a Socket connection with theclient (and make Input and output streams)?Think about how / when / where the servergets knowledge about the client.therelare~~DUmb ~uestl9ns~: The edvlce server code on the oppositepage has IJ VERY serious limitation-it lookslike It can handle only one client at a tlmel.A: Yes,that's right. It can't accept a requestfrom a client untllit has finished with thecurrent c/lent and started the next Iteration ofthe infinite loop (where It sits at the acceptOcall until a request comes In, at which time Itmakes a Socket with the new client and startsthe process over again).Q.: Let me rephrase the problem: how canyou make a server that can handle multipleclients concurrently??? This would neverwork for a chat server,for Instance.A: Ah,that's simple, really. Use separatethreads, and give each new client Socket to anew thread. We're just about to learn how todo that!• Client and server applications communicate over a Socketconnection.• ASocket represents a connection between two applicationswhich may (or may not) berunning on two different physicalmachines.• Aclient must know the IPaddress (or domain name) andrcp port number of the server application.• Arcp port isa 16-bi1 unsigned number assigned toaspecific server application. TCP port numbers allow differentclients toconnect tothe same machine but communicatewith different applications running on that machine.• The port numbers from 0 through 1023 are reserved for'well-known services' Including HTTP, FTP, SMTP, etc.• Aclient connects to a server bymaking a Server socketSocket 9 = new Socket(~127.0.0.1n, 4200);• Once connected, a client can getInput and output streamsfrom the socket. These are low-level 'connection' streams.9ock.getInputstream();• To read text data from the server, create a BufferedReader,chained to an InputStreamReader. which Ischained to theinput stream from the Socket.• InpulStreamReader Isa 'bridge' stream that takes inbytes and converts them totext (character) data. Irs usedprimarily toact asthe middle chain between the high-levelBufferedReader and the low-level Socket input stream.• To write text data tothe server, create a PrintWriter chaineddirectly tothe Socket's output stream. Call the prin~) orprinUnO methods to send Strings tothe server.• Servers use a ServerSocket that waits forclient requests ona particular port number.• When a ServerSocket gets a request it 'accepts' the requestbymaking a Socket connection with the client.you are here ~ 485


a simple chat clientWritit1g a Chat Cliet1fWe'll write the Chat client application in two stages. First we'llmake a send-only version that sends messages to the server butdoesn't get to read any of the messages from other participants(an exciting and mysterious twist to the whole chat roomconcept).Then we'll go for the full chat monty and make one that bothsends and receives chat messages.Version One: send-onlyCode outlinepublic class SimpleChatClientAJTextFleld outqoing;PrintWrieer writer;Socket sock;public void go() (II make gui and regist8r a listener with the send buttonI I call the setOpNetworkiDg () methodprivate void setOpNetworking () (II make a Socket, then malc.e a PrintWriterII assign the PrintWriter to writer instance variablepublic class SendButtonListener implements ActionLiatenerpublio void actionPer£ormed(ActionEvent ev) (II get thil text from the text field andII send it to the server using the writer (a PrintWritar))II close SendButtonLiatener inner classII close outer class486 chapler 15


networking and threadsimport java.io.*;import java.net.·;import j avax. swing. • ;import:. java.awt.· ;import java.awt.event.";publio class SimpleChatClientAJTextField outgoing;Pr:intWriter writer;Socket sock;public void go ()JFrame frame ~ new JFrame(nLudierously Simple Chat elientH);JPanel mainPanel = new JPanel () ;outgoing = new JTextField(20);JButton sendButton = new "Button ("sand") ;sendButton.addActionListener(new SendButtonListener(»;mainPanel.add(outgoing);mainPanel.add(sendButton) ;frame. getcontentPane () . add (Bord.erLayout. CENTER I mainPa.nel);setUpNetworking():frame.setSize(400,500):frama.setViaible(true);II close go W~'re lI.Sjh~ Iota/host soy~ ld" ~ the tlitntpriv~ ~id aetUpNetworkinq () { tL"an $tl"V& 011 one "'dthineBock = new Socket(U127.0.0.1 H , 5000); -n " L • u'.I'I\clk.e the SotkdI nil IS wn(Y' .. _ ..writer = new PrintWriter (sock .getoutputstream(»; ,..d the PY;l'Itw.,.itev (its t.dUedSystem. out.println ("networking establiBhed f H ) : t.he 01.) ....~od .,.i~ht bC~o'feCAtch (IOException ex) ( d:Oft'\ il'l ~c aff ~UP8x.printSt&cxTrace() ; u~a~ ~• II close setUpNetworkingpublic class SendButtonLiBtener implements ActionListener (public void actionPerformed(ActionEvent .v) (try (writer.println(outqoing.getText(»;writer.flush();catch (Exception ex) (ex.printstackTrace{);Ioutgoing. setText (U") ;outgoing.requestFocua() ;}II close SendButtonListener inner claas/'Jow we cfttlodlly do the W'rit.in~ .Re"'e...be__, the W'rif.t.,. is thained tothe il'l\'1"t ~Cd'"whehtveY wc do cf rriPltll'lO, it ~oaoveY the )ltt.W


improving the chat clientVersion Two: sec:,n:d~_o:;:::;;;;;;;;;~~~~~~and receive _T~e Strllt\" sends il ftltssa5e to alltlltllt pariitipallts. as ~ CIs tJ,eftlessa~t is rtl.eived by thc ~VCT.When,a t1ieflt s.e"ds d "'tssa5c, itdoes" t afPeal'" i" the il\tOfloi"5ftleUil5e display area \Antil the$.Crllel'" $.Cl'ods it to eVt\"yt:n.e.IlhInk A...~o.,'&SU 1---~ ..-Big Question: HOW do you get messages from the server?Should be easy; when you set up the networking make an input stream as well(probably a BufferedReader). Then read messages using readl.ine/).Blgger Question: WHEN do you get messages from the server?Think about that. What are the options?• Option One: Poll the server every 20 secondsPros: Well, it's do-ableCons: How does the server know what you've seen and what you haven't? The serverwould have to store the messages, rather thanjust doing a distribute-and-forget each timeit gets one. And why 20 seconds? A delay like this affects usability, but as you reduce thedelay, you risk hitting your server needlessly. Inefficient.• Option Two: Read something In from the server each time the usersends a message.Pros: Do-able, very easyCons: Stupid. Why choose such an arbitrary time to check for messages? What ifa user isa lurker and doesn't send anything?488 chapter 15• Option Three: Read meSAages as soon as they're sent from the serverPros: Most efficient, best usabilityCons: How do you do you do two things at the same time? Where would you put this code?You'd need a loop somewhere that was always waiting to read from the server. But wherewould that go? Once you launch the CUI, nothing happens until an event is fired by a CUIcomponent.


networking and threads.In Java you really CANwalk and chew gum atthe same time.Multithreading In JavaYou know by now that we'regoing with option three.We want something to run continuously,checking for messages from the server,but without iruerrupting the users ability tointeract with the CUI.'So while the user ishappily typing new messages or scrollingthrough the incoming messages, wewant something behind the scenesto keepreading in new input from the server.That means we finally need a new thread.A new, separate SlackWe want everything we did in the Send­Only version (version one) to work thesame way, while a new process runs alongside that reads information from theserver and displays it in the incoming textarea.Well, not quite. Unless you have multipleprocessors on your computer, each newJava thread is not actually a separateprocess running on the OS. But it almostfeels as though it is.Java has multiple threading bu ilt rightinto the fabric of the language. And it's asnap to make a new thread of execution:Thread t = new Thread() ;t.start () ;That's it. By creating a new Thread object,you've launched a separate threadojexecution, with its very own call stack.Exceptfin" one problem.That thread doesn't actually do anything,so the thread "dies" virtually the instantit's born . When a thread dies, its newstack disappears again. End of story.So we're missing one key componentthethread's job. In other words, we needthe code that you want to have run by aseparate thread.Multiple threading in Java means wehave to look at both the threadand the jobthat's ron by the thread. And we'll alsohave to look at the Thread class in thejava.lang package. (Remember. java.langis the package you get imported forfree, implicitly,and it's where the classesmost fundamental to the language live,including String and Systern.)you are here ~ 489


threads and ThreadJava has tMultiple threads but o.,lyone Thread classWe can ralk about threadwith a lower-case ' t' and Threadwith a capital 'T'. When you see thread, we're talkingabout a separate thread ofexecution. In other words,a separate call slack. When you see Thread, think ofthe Java naming convention. What, inJava, starts with acapital letter? Classes and interfaces. In this case. Threadis a class in thejava.lang package. A Thread objectrepresents a thread. oj execution; you'll create an instance ofclass Thread each rime you want to start up a new threadof execution.i\ theead is a separate'Lhr'eud ofexecution'.r[1 othet; words. a1l'}Jal'alc call slack.J\'-rhrcad is a Javaclass that represenha thh!uJ.1'0 111ake a Lhread.l1mkl\ a ThI\\ud.!hreadThreadThreadvoid joinOvoid slartOslatlc void sleepOmain threadanother threadstarted by the codeA. thread [lower-case 't") is a separate thread of execution.That means a separate call slack . Every Java applicationstarts up a main thread-the thread that puts themainO method on the bottom of the stack. TheJVMis responsible for starting the main thread (and otherthreads, as it chooses, including the garbage collectionthread ). As a programmer, you can write code to startother threads of your own .java.lang.ThreadclassThread (capital "I") is a class thatrepresents a thread of execution.It has methods for starting athread.joining one thread withanother, and putting a thread tosleep. (It has more methods; thesearejust th e crucial ODes we needto use now).490 chapter 1 5


networking and threadsWhat does it ttteat1 to have tMore thattot1e call stack?With more than one call Slack, you get the appearance of havingmultiple things happen at the same time. In reality. only a truemultiprocessor system can actually do more than one thing at atime, but with Java threads, it can appearthat you're doing severalthings simultaneously. In other words, execution can move backand forth between stacks so rapidly that you feel as though all stacksare executing at the same time . Remember,java isjust a processrunning on your underlying OS. So first,Java itselfhas to be 'thecurrently executing process' on the OS. But onceJava gets itsturn to execute, exactly what does theJVM run? Which bytecodesexecute? Whatever is on the top afthe currently-running stacklAnd in 100 milliseconds. the currently executing code might switchto a different method on a different stack.One ofthe things a thread must do is keep track of which statement(of which method) is currently executing on the thread's stack.It might look something like this:o The JVM calls the malnO method.public static void main (String[l args) (main threadmain() starts a new thread. The mainthread is temporarily frozen while the newthread starts running.Runnable r = new MyThreadJob()j~Thread t = new Thread(~ YOl,t'1! le;l'lI~hdtt.start 0 ; -this ...~~. .c.siDog d :: new Dog () j d ...o.,.ellt... III Jt.startC)mainOmain threaduser thread Ae The JVM switches between the newthread (user thread A) and the originalmain thread, until both threads complete.main threadx.goOrunOuser thread Ayou are here. 491


launching a threadHow to launch a new thread:o Make a Runnable object (the thread's job)Runnable threadJob = new My~Jnnable()jRunnable is an interface you'll learn about on the next page.You'll write a class that implements the Runnoble interface,and that class is where you'll define the work that a threadwill perform. In other words, the method that will be runfrom the thread's new call stacke Make a Thread object (the worker) andgive it a Runnable (the job)Thread myThread = new Thread(threadJob) jPass the new Runnable object to the Thread constructor.This tells the new Thread object which method to put onthe bottom of the new stack-the Runnable's runO method.Q Start the ThreadmyThread.start()jNothing happens until you call the Thread'sstartO method. That's when you go fromhaving just a Thread instance to having a newthread of execution. When the new threadstarts up. it takes the Runnable object'srunO method and puts it on the bottom ofthe new thread's stack.rul'10492 chapter 15


networking and threadsEvery fhread tteeds ajob to do.AtMethod to put Ott the ttew thread stack.Runnah]e is to aThread what ajoh is toaworker. ARunnahleis the joh athread issupposed to run.ARunnah]e holds themethod that goes onthe bottom of the newthread's stac"k: ru.n().A Thread object needs ajob. Ajob the thread will run when thethread is started. Thatjob is actually the first method that goes on ~. ts 01\\'1 ()I\ethe new thread's stack, and it must always be a method that looks ~\ . -\:.t.Yht.e de 11\ ~lYI i-tS 31'1like this: I"e 1\""",,3 e\.II\ '10. Y~O. {R.t"'t.\~ e~YG\essI L..A Iy..,.b It. '10 00 ',s. y~'o It. '" :rpublic void run (} ( "'~ ~t. "'~ LI -t. 'fld'1.)II code that will be run by the new thread il'l~ht.t SO l'IVt. i-t. i" ,,"3Lhty ,/0'" \.., \~ ~"t:\,How does the thread know which method to put at the bottom ofthe slack? Because Runnable defines a contract. Because Runnableis an interface. A thread'sjob can be defined in any class thatimplements the Runnable interface. The thread cares only that youpass the Thread constructor an object of a class that implementsRunnable.When you pass a Runnable to a Thread constructor, you're reallyjust giving the Thread a way to get to a runt) method. You're givingthe Thread itsjob to do.you are here. 493


Runnable interlacefo tttake ajob for your thread,itMpletMet1t the Rut1"able iMterfacepublic clus MyRunnable ~I..-nt:apublic void go ()doMore();public void doMOre() (SYllItem.out.prll\tln("top 0' the stack");class ThreadTetlter { R \:II i"std"U ;"to ~e I'C'O/Pass -the "ew ,,


networking and threadsThe three states of a new threadThread t= new Thread(r);NEWRUNNABLE\ \ / / /


thread statesTypical runnableJrunning loopTypically, a thread moves back andforth between runnable and running,as theJVM thread scheduler selects athread to run and then kicks it backout so another thread gets a chance.RUNNABLE~RUNNING~Sent bock to runnableso another thread coohave a chanceA thread can be madetemporarily not-runnableTIle thread scheduler can move arunning thread into a blocked state,for a variety of reasons. For example,the thread might be executing codeto read from a Socket input stream,but there isn't any data to read. Thescheduler will move the thread outofthe running state until somethingbecomes available. Or the executingcode might have told the thread toput itself to sleep (sleepO). Or thethread might be waiting because ittried to call a method on an object,and that object was 'locked', In thatcase, the thread can't continue untilthe object's lock is freed by the threadthat has it.All ofthose conditions (and more)cause a thread to become temporarilynot-runnable,RUNNABLERUNNINGsIUfi ...~ waiti"9 .feN'


networkIng and threadsfhe fhread SchedulerThe thread scheduler makes all the decisions aboutwho moves from runnable to running. and about when(and under what circumstances) a thread leaves therunning state. The scheduler decides who runs, and forhow long, and where the threads go when the schedulerdecides to kick them out of the currently-running state.You can't control the scheduler. There is no API forcalling methods on the scheduler. Most importantly,there are no guarantees about scheduling! (There are afew almose-guarantees. but even those are a little fuzzy.)The bottom line is this: do not baseyour program'$rorrectness Q1l theschedulerworkingin a particular way!The scheduler implementations are different fordifferentJVM's, and even running the same programon the same machine can give you different results.One ofthe worst mistakes new Java programmersmake is to test their multi-threaded program on asingle machine, and assume the thread scheduler willalways work that way, regardless of where the programruns.So what does this mean for write-once-run-anywhere?It means that to write platform-independentJava code,your multi-threaded program must work no matter howthe thread scheduler behaves. That means that you can'tbe dependent on, for example, the scheduler makingsure all the threads take nice, perfectly fair and equalturns at the running state. Although highly unlikelytoday, your program might end up running on aJVMwith a scheduler that says, ~OK thread five, you're up,and as far as I'm concerned, you can stay here untilyou're done, when your run () method completes."The secret to almost everything is sleep. That'sright, sleep. Putting a thread to sleep, even for a fewmilliseconds. forces the currently-running thread toleave the running state, thus giving another thread achance to run. The thread's sleepO method does comewith oneguarantee: a sleeping thread will not becomethe currently-running thread before the the length ofits sleep time has expired. For example, ifyou tell yourthread to sleep for two seconds (2,000 milliseconds),that thread can never become the running thread againuntil sometime afterthe two seconds have passed.The"fhreadscheduler makes allthe decisions aboutwho runs and whodoesn't. lIe usuallymakes the threads taketurns, nicely. Butthere's no guaranteeabout that. lIe mightlet one thread runto its heart's contentwhile the otherthreads 'starve'.you are here ~ 497


thread schedulingAn example of how unpredictable thescheduler can be...Running this code on one machine:Produced this output:public class MyRunnable implements Runnablepublic void run()qo() ;public void go ()doMore() ;public void dOMOre() (System.out.printin("top 0' the stack");java Th~eadTestDriveback in maintop 0' the stack~(j.va T l-~;::",adT·c~i:.DJ.--;_ ' . · ' ctop 0' the stackback in mainjava ThreadTestDrivetop 0' the stackback in mainclass ThreadTestDrive {public static void main (String[] args) (Runnable threadJob = new MyRunnable () ;Thread myThread = new Thread (thraadJob) ;myThread.start();,...... '.....java Th~eadTestnrivetop 0' the stackback in mainj a v atop 0'T h r e a dT e s ~ D r 1 v ethe stackback in mainjava T h r R a d TQs t D ~ ~ ~ ~top 0' the stackback in mainJava ThreadTestDr1veback in maintop 0' the stack498 ch apter 15


networking and threadsHow did we end up with different results?Sometimes it runs like this:maIn0starts thenew threadThe scheduler sendsthe main thread outofrunning and backtorunnable, sothatthe new thread canrun.The scheduler tetsthe new threadrun to completion,printing out "top 0'the stack"The new thread goesaway, because itsrunOcompleted. The mainthread once againbecomes the runningthread, and prints 'backInmain"main threadmain threadnew threadtimetimeyou are here . 499


socketconnecUons:t1erelare~Dumo "C.UesU9nSQ.: I've seen examples that don't use a separateRunnable Implementation, but Instead Just make asubclass of Thread and override the Thread's runOmethod.That way,you call the Thread's no--argconstructor when you make the new thread;Thread t = new Thread(); 1/no RunnableA: Yes, that Is another way of making your ownthread, but think about it from an 00 perspective.What's the purpose of subclassing? Remember thatwe're talking about two different things here-theThread and the thread'slob. From an 00 view, thosetwo are very separate activities, and belong in separateclasses. The only time you want to subclass/extendthe Thread class,Is if you are making a new and morespecific type ofThread.ln other words, ifyou think ofthe Thread as the worker, don't extend the Thread classunless you need more specific worker behaviors. But Ifall you need Is a new lob to be run by a Thread/worker,then Implement Runnable In a separate,job-specific(not worker-specific) class.This is a design Issue and not a performance orlanguage Issue.It's perfectly legal to subclass Threadand override the runO method, but It's rarely a goodIdea.Q.: Can you reuse a Thread object? Can you give Ita new Job to do and then restart It by calling startOagaln7A: No. Once a thread 's runO method has completed,the thread can never be restarted . In fact, at thatpoint the thread moves Into a state we haven't talkedabout-dead. In the dead state, the thread hasfinished Its runO method and can never be restarted.The Thread object might stili be on the heap, as aliving object that you can call other methods on (Ifappropriate), but the Thread object has permanentlylost its 'threadness'. In other words, there Is no longer aseparate call stack, and the Thread object Is no longera thread. It's Just an object, at that point, like all otherobjects.But, there are design patterns for making a pool ofthreads that you can keep using to perform differentjobs. But you don't do It by restartlng() a dead thread.• Athread with a lower-case 't'isa separate thread ofexecution in Java.• Every thread In Java has its own call stack.• AThread with a capital 'T is the java.lang.Threadclass. AThread object represents a thread ofexecution.• AThread needs ajob to do.AThread's job isaninstance ofsomething that Implements the Runnableinterface.• The Runnable Interface has just a single method, runO.This isthe method that goes on the bottom ofthe newcall stack. Inother words. it isthe first method to run Inthe new thread.• To launch a new thread, you need a Runnable to passtothe Thread's constructor.• Athread IsIn the NEW state when you haveinstantiated aThread object but have not yet calledstartO.• When you start a thread (by calling the Thread object'sstartO method), anew stack Is created, with theRunnable's runO method on the bottom ofthe stack.The thread isnow inthe RUNNABLE state, waiting tobe chosen torun.• Athread issaid 10 be RUNNING when the NM'sthread scheduler has selected it tobe the currentlyrunningthread. On a single-processor machine, therecan beonly one currently-running thread.• Sometimes a thread can be moved from the RUNNINGstate to a BLOCKED (temporarily non-runnable) state.Athread mighl be blocked because it's waiting for datafrom a stream. orbecause It has gone tosleep, orbecause Itiswaiting for an object's lock.• Thread scheduling Isnot guaranteed towork in anyparticular way, so you cannot be certain that threadswlll take tums nicely. You can help influence tum-lakingby putting your threads to sleep periodically.500 chapter 15


networking and threadsPutti.,g· athread to sleepOne of the best ways to help your threads take turns isto put them to sleep periodically. All you need to dois call the static sleepO method, passing it the sleepduration, in milliseconds.For example:Thread.sleep(2000);will knock a thread out of the nmning state, andkeep it out ofthe runnable state for two seconds.The thread can't become the running threadagain until after at least two seconds have passed.A bit unfortunately, the sleep method throws anInterruptedException, a checked exception, so allcalls to sleep must be wrapped in a try/catch (ordeclared), So a sleep call really looks like this:try (Thread,sleep(2000) ;catch(InterruptedException ex) (ax.printStackTrace() ;Put your thread to sleepifyou want to he surethat other threads get achance to run."When the thread wakesup. it always goes bac"kto the runnah]e stateand waitS for the threadscheduler to choose itto run again.Your thread ",;11 probably neverbe interrupted [Tomsleep; the exception is in the API to support a threadcommunication mechanism that almost nobody uses inthe Real World. But, you still have to obey the handleor declare law, so you need to get used to wrapping yoursleepO calls in a try/catch.Now you know that your thread won't wake up before thespecified duration, but is it possible that it will wake upsome time afterthe 'timer' has expired? Yes and no. Itdoesn't matter, really, because when the thread wakesup, it always goes bcuk to the rusmable stare!The threadwon't automatically wake up at the designated time andbecome the currently-running thread. When a threadwakes up, the thread is once again at the mercy ofthe thread scheduler. Now, for applications that don'trequire perfect timing, and that have only a few threads,it might appear as though the thread wakes up andresumes running right on schedule (say, after the 2000milliseconds). But don't bet your program on it.you are here ~ 501


using Thread.sleep()Usittg sleep to tttake our prograttt",ore predictable.Remember our earlier example that kept giving us differentresults each time we ran it? Look back and study the codeand the sample output. Sometimes main had to wait until thenew thread finished (and printed "top o' the stack"), whileother times the new thread would be sent back to runnablebefore it was finished, allowing the maio thread to come backin and print out "back in main", How can we fix that? Stopfor a moment and answer this question: "Where can you puta sleept) call, to make sure that "back in main" always printsbefore "top 0' the stack"?We'll wait while you work out an answer (there's more thanone answer that would work).Figure it out?public class MyRunnable implements Runnable (public void run() (go() ;Thi~ is wh.rt. we. WGl'It-a l.or.siskt. (Katy0+ fYint. st.at.~enh'File Ed~ Window Help SnoozeBunonJava ThreadTestDriveback in maintop 0' the stack.: i a v a ThreadTestDriveback in maintop 0 ' the stackjavu ThreadTestDriy~back in maintop 0' the stackjava ThreadTestDriveback i n maintop 0' the stackjava ThreadTestDriveback in maintop 0 ' the stackpublic void go ()Uy (Thread••leep(2000);catch(Ifttarrupt.eclException ex) (ex.pr1ntStackTrace();...,. J. ,", ."public void dOMOre() (System. out.prinUn ("top 0'the stack");class ThreadTestDrive (public static void mAin (String[] arqs)Runnable theJob - new MyRunnable();Thread t::: new Thread(theJob);t.start () ;Systam.out.println(~back in main");}502 chapter 15


Maki.,g a.,d sfarti.,g two threadsThreads have names. You can give your threads a name ofyour choosing, or you can accept their default names. But thecool thing about names is that you can use them to tell whichthread is running. The following example starts two threads.Each thread has the samejob: run in a loop. printing thecurrently-running thread's name with each iteration.networking and threadspublic class RunThreads implements Runnable (~\t i,..st;ll'tt.·public static void main(String[J arqa) ( ..... Ma\(t O'f\t RIl'l'ol"3RunThreads runner '" nitW RunThreads () ;Thread alpha = new Thread (runner); ~ Mcl~ two th'r,edtb, with tht 1,I>"t R""Ylable (theThread beta '" new Thread(runner); ~ .alpha. setName ("Alpha thread");Scl"'e Job--...,e II t:a1k ...~t about t.he "-two th..-t.adsbeta. 88tName ("Beta thread"); ~ and O?Ie R"""\dblt. In a +tvJ ra~es).alpha . 8 tart () ; ~Na",t. the tht"edds.beta.start(); ~ start the tht"t.clds.LL ""-'A" ~is \00f1~t.h ~vtao \fIi\\ YIlYl V\~~-Jpublic void run () { . L' it. 1'0",1: e.)l.h tu"t.·P"r\Yl~'''~ 'Vfor (int i = 0; i < 25; i++) { 1String threadName K Thread. currentThread () .getName();Syatam.out.println(threadName + " is running");What will happe.,?Wlll the threads take turns? Will you see the thread namesalternating? How often will they switch? With each iteration?After five iterations?You already know the answer: we don't knowlIt's up to thescheduler. And on your as, with your particularJVM, onyour CPU, you might get very different results.Running under asx 10.2 (Jaguar), with five or feweriterations, the Alpha thread runs to completion, thenthe Beta thread runs to completion. Very consistent. Notguaranteed. but very consistent.But when you up the loop to 25 or more iterations, thingsstart to wobble. The Alpha thread might not get to completeall 25 iterations before the scheduler sends it back torunnable to let the Beta thread have a chance.File Ed ~ WindOW H~p C&ntaunAlpha thread is runningAlpha thread is runningAlpha thread is runningBeta thread is runningAlpha thread is runningBeta thread is runningBeta thread is runningBeta thread is runningBeta thread is runningBeta thread is runningBeta thread is runningBeta thread is runningBeta thread is runningBeta thread is runningBeta thread is runningBeta thread is runningBeta thread is runningBeta thread is runningBeta thread is runningAlpha thread is runningyou a re here . 503


aren't threads wonderful?UtM, yes. There IS adark side.fhreads ca., lead to co.,curre.,cy 'issues:Concurrency issues lead to race conditions. Race conditionslead to data corruption. Data corruption leads to fear... youknow the rest.It all comes down to one potentially deadly scenario: two ormore threads have access to a single object's daia: In otherwords, methods executing on two different stacks are bothcalling, say, getters or setters on a single object on the heap.It's a whole 'left-hand-doesn't-know-what-the-right-handis-doing'thing. Two threads, without a care in the world,humming along executing their methods, each threadthinking that he is the One-True Thread. The only onethat matters. After all, when a thread is not running, and inrunnable (or blocked) it's essentially knocked unconscious.When it becomes the currently-running thread again, it doesn'tknow that it ever slopped.504 chap ter 15


networking and threadsMarriage in Trouble.Can this couple be saved?Next, on 8 very special Dr.Steve Show[Transcript from episode #42)Welcome to the Dr. Steve show.We've got a story today that's centered around the top two reasons whycouples split up-finances and sleep.Toctaor's troubled pair, Ryan and Monica.,share a bed and a.bank account. Butnot for longifwe can'tfind a solution. Theproblem? The classic 'iiwo people-one bank account" th:1ng.Here's how Monica desoribed it to me:"RiYan and I agreed t.hat neither crus will overdraw the checkl.ng account.So the procedure 1S, whoever wants to withdraw money must check thebalance in the account beiore rnak1ng the withdrawal. It all seemed sosimple. But suddenlywe're bouncing checks and gettinghitwith overdraft.fees II thought it wasn't possible, I thought our procedure WBE safe. But thenthis happened:Ryan needed $50, so he checked the balance in the account,and saw that it WW3 $100. No problem. So, he plans towithdrawthe money. But first he faI1B asleepIAnd that's where I come in, while ~'s still BEleep, andnow Iwant to withdraw $100. I check the balance, andit's $100 (because !Wan's st1ll asleep and ha.sn'tyet madehis withdrawal), so I think, no problem. So I make thewithdrawal, and agatn no problem. But then Ryan wakes up,completes h1s withdrawal, andwe're suddenly overdrawn! He didn'teven knowthat he fell asleep, so he justwent ahead and completed histra.nsaot1on without checking the balance again. You've got to help us Dr.SteveI"Is there a solution? .Are they doomed? We can't stop Ryan from fa.lllngasleep, but canwe make sure that Monica can't get her hands on the bankaccount until after he wakes up?Take a moment and tb.1n.k about that while we go to a.commercial break.you are here. 505


Ryan and Monica codeThe Ryatt at1d Mottica proble'lt itt codeThe following example shows what can happen when twothreads (Ryan and Monica) share a singleobject (the bankaccount).The code has two classes, BankAccount, andMonicaAndRyanJob. The MonicaAndRyanjob classimplements Runnable, and represents the behavior that Ryanand Monica both have--checking the balance and makingwithdrawals. But of course, each thread fulls asleep in betweenchecking the balance and actually making the withdrawal.The MonicaAndRyanJob class has an instance variable of typeBankAccount., that represents their shared account.The code works like this:BankAccountintbalancegelBalance()withdrawORunnableTIIIIRyanAndMonlcaJobBankAccount accountrunOmakeWithdrawal0• Make one Instance of RyanAndMonlcaJob.The RyanAndMonicaJob class is the Runnable (the job to do),and since both Monica and Ryan do the same thing (checkbalance and withdraw money), we need only one instance.•RyanAndMonicaJob theJob::: new RyanAndMonica.Job 0 ;Make two threads with the same Runnable(the RyanAndMonicaJ ob instance)Thread one::: new Thread (theJob) ;Thread two = new Thread (theJob) ;• Name and start the threadsone.setName(~Ryan"l;two . setN8IJle ("Monica") ;one .start() ;two. start 0 ;• Watch both threads execute the runO method(check the balance and make a withdrawal)In the runO method, doexactly what Ryan andMonica would do-checkthe balance and, ifthere's enough money,make the withdrawal.This should protectagainst overdrawing theaccount.Except••• Ryan andMonica always fallasleep ~r theycheck the balance butbefore they finish thewithdrawal.One thread represents Ryan.the other represents Monica.Both threads continually check the balance and then make awithdr


networking and threadsThe Ryat1 at1d MOt1ica exalltpleclass BankAccount { L tarts ltIith aprivate int balance = 100; ~~__~ Tne attov.rI'; s'oa\aY\l.e ok fI OO .public int getBalance()return balance;}public void withdraw(int amount) {balance = balance - amount;public class RyanAndMonicaJob implements Runnable {private BankAccount account = new BankAccount();public static void main (String [] args) {RyanAndMonicaJob theJob = new RyanAndMonicaJob (); ~ frlsta .Thread one = new Thread (theJob) ; ~ r.t1ai:e the ~"r.tldble (-ob)Thread two = new Thread (theJob) ; +-- Make two .Lh d ~~I-eas ' .one. setName ("Ryan") ; job. nat ' ~IVlr.g eath thl-ead thtwo. setName ("Monica") ; alloLir.t . "'ear.s both thl-eads will b e ~"'e R"htldbleone. start() ;Ir.stahle val-iabl e ir. the R e alleSSlh !} the Onetwo. start() ;"r.tldble tlass.public void run ( ) {for (int x = 0; x < 10; x++) {makeWithdrawl (10) ;if (account.getBalance() < 0) {System.out.println("OVerdrawn!");tn\'"ead loo\'s t.nYO\l.~narid t.\'"·le sIYl t.ne yv.YlO .",e+.h od 'tltIitn eat.n it.e\'"atioYl' AHe\'" t.~~to make a 1tI,t.nd\'"a ltla 'DalaYlte oY\l.e a~aiYl to see IltIit.nd\'"altla\, 'It. t.net.ks t.net.he attOv."t. is ol/eV'dya ltl".ehetk the attov.Ylt. bala"t.e, aYld it t.heYe~s Ylot. IS} e"ov.~h mOrle~, we j\lSt. f\'"int. a ",essa~e . I theY~ t.e. , . . Venov. h, ltIe ~o to sleef, t.hen ltIake v.? a"d t.OWIf epr1;rate v01d makeW1 thdrawal (1nt amount) { ~ 't.hdv-altlal, '\lSt like R'fan did.1f (account.getBalance () >= amount) { t.he WI JSystem.out.println(Thread.currentThread() .getName() + " is about to withdraw");try {System.out.println (Thread. currentThread() .getName() + " is going to sleep");Thread.sleep(500);} catch(InterruptedException ex) {ex.printStackTrace(); }System.out.println (Thread. currentThread() .getName() + " woke up.");account.withdraw(amount);System.out.println (Thread. currentThread() .getName() + " completes the withdrawl");}else {System.out.println("Sorry, not enough for" + Thread.currentThread() .getName(»;We p"i iha b"hlh of D>oiht staLse h l'hi' UhoIeh\;S so we tar.e w ae; s appehih!} as it l-"hS.Lyou are here ~ 507


!"Cyan ana MOniCa OUtput:, .FlI& EdllWindow Help VI£llRyan is about to withdrawRyan is going to sleepMonica woke up.Monica completes the withdrawlMonica is about to withdrawMonica is going to sleepRyan woke up .Ryan completes the withdrawlRyan is about to withdrawRyan is going to sleepMonica woke up.Monica completes the withdrawlMonica is about to withdrawMonica is going to sleepRyan woke up.Ryan completes the withdrawlRyanis about to withdrawRyan is going to sleepMonica woke up.Monica completesSorry, not enoughSorry, not enoughSorry, not enoughSorry, not enoughSorry, not enoughthe withdraw1for Monicafor Monicafor Monicafor Monicafor MonicaR~'an woke up.Ryan completes the withdrawlOverdrawn'Sorry, not enough for RyanOverdrawn!Sorry, not enough for RyanOverdrawn!Sorry, not enough for RyanOverdrawn!The makeWithdrawalO methodalways checks the balancebefore making a withdrawal,but stili we overdraw theaccount.Here's one scenario:Ryan checks the balance, sees thatthere's enough money, and then fallsasleep.Meanwhile, Monica comes in and checksthe balance. She, too, sees that there'senough money. She has no Idea thatRyan Is going to wake up and complete awithdrawal.Monica falls asleep .Ryan wakes up and completes hiswithdrawal.Monica wakes up and completes herwithdrawal. Big Probleml In between thetime when she checked the balance andmade the withdrawal, Ryan woke up andpulled money from the account.Monica's check of the account wasnot valid, because Ryan had alreadychecked and was stili In the middle ofmaking a withdrawal.Monica must be stopped from gettingInto the account until Ryan wakes up andflnishes his transaction. And vice-versa.508 chapter 15


networking and threadsThey need a lock for account access!The lock works like this:~ There's a lock associated with the bonkaccount transaction (checking the balanceand withdrawing money). There's onlyone key, and it stays with the lock untilsomebody wants to access the account.fThe bank accounttransaction isunlocked whennobody Is usingthe account.When Ryan wants to access the bankaccount (to check the balance and withdrawmoney), he locks the lock and puts the keyin his pocket. Now nobody else can accessthe account, since the key is gone.When Ryanwants to accessthe account, hesecures the lockand takes the key.Ryan keeps the key in his pocket until hefinishes the trQl\SQctlon. He has the onlykey, so Monica can't access the account(or the checkbook) until Ryan unlocks theaccount and returns the key.Now, even if Ryan falls asleep ofter hechecks the balance, he has a guaranteethat the balance will be the some when hewakes up, because he kept the key while hewas asleep!fWhen Ryan Isfinished, heunlocks the lockand returns thekey. Now the keyis available forMonica (or Ryanagain) to accessthe account.you are here ~ 509


using synchronizedWe t1eed the IttakeWithdrawal () tttethodto rut1 as otte atomic thit1Q.We need to make sure that once a thread enters themakeWithdrawal() method, it must be allowed tofinisb the methodbefore any other thread can enter.In other words, we need to make sure that once a thread haschecked the account balance, that thread has a guarantee that it canwake up and finish the withdrawal before any other thread can check theaccount balance!Use the synchronized keyword to modify a method so that onlyone thread at a time can access itThat's how you protect the bank accountl You don't put a lock onthe bank account itself; you lock the method that does the bankingtransaction. That way. one thread gets to complete the wholetransaction, start to finish . even if that thread falls asleep in themiddle of the methodISo if you don't lock the back account, then what exactly is locked? Isit the method? The Runnable object? The thread itself?We'll look at that on the next page. In code, though, it's quitesimple-just add the synchronized modifier to your methoddeclaration:The synchronizedkeyword means thata thread needs a keyin order to access thesynchronized code.To protect your data(like the bank account),synchronize themethods that act onthat data.private synchronized void makeWithdrawal(int amount) {if (account.getBa1ance () >= amount) {Syetam.out.println(Thread.current'l'hreadO .q4ItNameO + " is about to withdraw");try (System. out.println (Thread.currentThread() .getName() + ~ 1s going to sleepll);Thread.s1eep(SOO) ;} eatch(InterruptedException ex) (e.x.printStackTraoeO; ISystem. out.println (Thread. ourr8ntThread () . gatName 0 + " wob up. ") ;aocount..withdraw (amount) ;System. out.println (Thr8ad. currentThread 0 .qetNlUll80 + " completes the withdraw1"};else (System. out.print1n ("Sorry, not enough for" + Thread. currentThread () .getN~(»;(Nou ~or 'f0'0l ph'fsil.s-s.avvy \"~ad~ : 'f~' !he t.onv~ntion of I&S;,,~ the 'oIcwl! 'at-.il.' hcY~ does 1\0-1: \"e.flutthe 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.he1.0JIU'j(t 0+ threads or tta"sal.i;iOt\1. ~t'(, it's Mt OUR ~vtrltOl\ . l.f WE \IItl"t i.... t.haY~e, 'Wt'd appl'ft4t isc\'lhC'r~'s Ul\l.crt


networking and threadsUshtg at1 objeet~lockzvery object has a lock. Most of the time, thek is unlocked, and you can imagine a virtual. sitting with it. Object locks come into playIy when there are synchronized methods.\n en an object has one or more synchronizedethods, a thread can enter a syrn:hroniz.ed-ethod onlyif the thread can getthe key io theJ,ject's wckJHey, this object'stakeMonevO method issynchronized. I need to getthis object's key before Ie locks are not per method, theyar e per object. If an object has two-nchron ized methods, it does notsimply mean that you can't have twothreads entering the same method, Iteans you can't have two threads entering) of the synchronized methods.Think about it. [fyou have multiplemethods that can potentially act on anobj ect's instance variables, all those methodsneed to be protected with synchronized.The goal ofsynchronization is to protectcritical data. But remember, you don't lock thedata itself, you synchronize the methods thataccess that data.So what happens when a thread is crankingthrough its call stack (starting with the nm()method) and it suddenly hits a synchronizedmethod? The thread recognizes that it needsa key for that object before it can enter themethod. It looks for the key (this is all handledby theJVM; there's no APT in java for accessingobject locks), and if the key is available. thethread grabs the key and enters the method.From that point forward, the thread hangs onto that key like the thread's life depends onit. The thread won 't give up the key until itcompletes the synchronized method. So whilethat thread is holding the key, no other threadscan enter any ofthat object's synchronizedmethods, because the one key for that objectwon 't be available.Every Java object has a Iocl.AIocR has only one 'key. .Most of the tiJtle, the IocR isunlocked and nobody cares.But ifan ohject hassynchronized methods, athread can enter one of thesynchronized methods ONLYifthe "key for the object's Ioc"kis available. In other words.only ifanother thread hasn'talready grahbed the one "key.you a re he re. 511


synchronization mattersfhe dreaded "Lost Update NprobleiMH ere's another classic concurrency problem, that comes from the database world. It'sclosely related to the Ryan and Monica story, but we'll use this example to illustrate a fewmore points.The lost update revolves around one process:Step I : Get the balance in the accountint i = balance;Step 2: Add 1 to that balancebalance = i + 1;The trick to showing this is to force the computer to take two steps to complete the changeto the balance. In the real world, you'd do this particular move in a single statement:balance++;But by forcing it into twosteps, the problem with a non-atomic process will become clear.So imagine that rather than the trivial "get the balance and then add I to the currentbalance" steps, the two (or more) steps in this method are much more complex, andcouldn't be done in one statement.In the "Lost Update" problem, we have two threads, both trying to increment the balance.class TestSync implements Runnable {private int balance;public void run()for(int i = 0; i < 50; i++) {increment 0 ;System.out.println("balance is " + balance);public void increment() {int i = balance;balance = i + l;~ H~ r~ 's ih~ trlAtial pari! w .additlQ / 1- . ~ Il'ltr~ "" ~ ll't ih I IJ 1:0 whai~ v~r ih I ~ oa alll~ byTIME WE READ IT ( ~ va lA ~ o.f balal'll~ was AT THEih ~ CURREAM- I . )ra h ~r ihall addil'lQ /1 h 1-." I va lA ~ IS J 1:0 W a~V~rpublic class TestSyncTest {public static void main (String[] args) {TestSync job = new TestSync();Thread a = new Thread(job);Thread b = new Thread(job) ;a.startO;b.startO;512 chapter 15


networking and threadsLetJs rut1 this code...Thread A runs for awhilePut the value of balance into variable i.Balance is O. so ; is now O.Set the value of balance to the result of i + 1.Now balance Is 1.Put the value of balance Into variable i.Balance Is 1, so I is now 1.Set the value of balance to the result of I + 1.Now balance Is 2.Thread B runs for awhilePut the value of balance into variable I.Balance Is 2, so i is now 2.Set the value of balance to the result of I + 1.Now balance Is 3.Put the value of balance Into variable i.Balance Is 3, so I is now 3.(now thread B is sent back to runnebte,before It sets the value ofbalance to 4]Thread A runs again, picking up where. it left offPut the value of balance Into variable I.Balance Is 3, so I is now 3.Set the value of balance to the result of I + 1.Now balance Is 4.Put the value of balance Into variable I.Balance Is 4, so I Is now 4.Set the value of balance to the result of I + 1.Now balance is 5.Thread B runs again, and picks up exactly where it left offlSet the value of balance to the result of I + 1.Now balance Is ~ ~II. "·\\t~S..n __ead A",ydat.ed It. to 1:), blOt.\'\0,", B ta...e bdl.\( alia ~Ul'fea0\'\ to!> o.f t.he "fdat.e A....ade,as it A's "'fdclU IIt"'~ hcll1't\'\ea.We lost the last updatesthat Thread A madelThread B had preViouslydone a 'read' of the valueof balance, and when Bwoke up, It Just kept goingas If It never missed a beat.you are here. 513


synchronizing methodsMake the ittcretttettt() tMethod atotttic.Syttchrottize it!Synchronizing the incrernenu) method solves the "LostUpdate" problem, because it keeps the two steps in the methodas one unbreakable unit.public synchronized void increment() {int i-balance;balance = i + 1;}Once a thread entersthe method, we haveto make sure that allthe steps in the methodcomplete (as oneatomic process) beforeany other thread canenter the method.Q..: Sounds like It's a good Idea to synchronizeeverything,Just to be thread-safe.J\: Nope, it's not a good Idea. Synchronization doesn'tcom e fOT free. FIrst, a synchronized method has a certai namount of overhead. In other words, when code hits asynchronized method, there's going to be a performance hit(although typically, you'd never notice It) while the matter ofHIs the key avallabl e7"Is resolved.Second,a synchron Ized met hod can slow you r prog ramdown because synchronization restricts concurrency. Inother words, a synchronized method forces other threads toget in line and walt their turn.This might not be a problemIn your code, but you have to consider It.Third, and most frightening, synchronized methods can leadto deadlockl (Seepage 516.)A good rule of thumb Is to synchronize only the bareminimum that should be synchronIzed. And In fact, youcan synchronize at a granularity that's even smaller thana method. We don't use it In the book, but you can use thesynchronized keyword to synchronize at the more finegrainedlevel of one or more statements, rather than at thewhole-method level.514 chapter 15


networking and threads• Thread A runs for awhileAttempt to enter the incrementO method.The method is synchronized, so get the key for this objectPut the value of balance into variable i.Balance is 0, so i is now 0.Set the value of balance to the result of i + 1.Now balance is 1.Return the key (it completed the incrementO method).Re-enter the incrementO method and get the key.Put the value of balance into variable i.Balance is 1, so i is now 1.[now thread A is sent back to runnable, but since it has notcompleted the synchronized method, Thread A keeps the key]• Thread B is selected to run, Attempt to enter the incrementO method. The method issynchronized, so we need to get the key.The key is not available.[now thread B is sent into a 'object lock not available lounge]• Thread A runs again, picking up where it left off~ (remember, it still has the key).~ Set the value of balance to the result of i + 1.Now balance is 2.Return the key.[now thread A is sent back to runnable , but since ithas completed the incrementO method, the threaddoes NOT hold on to the key]• Thread B is selected to runIAttempt to enter the incrementO method. The method issynchronized, so we need to get the key.This time, the key IS available, get the key.Put the value of balance into variable i.[continues to run...]you are here ~ 515


thread deadlockThe deadly side ofsyttchronizatiottBe careful when you use synchronized code, because nothingwill bring your program to its kn ees like thread deadlock.Thread deadlock happens when you have two threads, both ofwhich are holding a key the other thread wants. There's no wayout of this scenario, so the two threads will simply sit and wait.And wait. And wait.Ifyou're familiar with databases Or other application servers,you might recognize the problem; databases often have alocking mechanism somewhat like synchronization. But areal transaction management system can sometimes deal withdeadlock. It might assume, for example, that deadlock mighthave occurred when two transactions are taking too long tocomplete. But unlikeJava, the application server can do a"transaction rollback" that returns the state of the rolled-backtransaction to where it was before the transaction (the atomicpart) began.Java has no mechanism to handle deadlock. It won't even knowdeadlock occurred. So it's up to you to design carefully. Ifyoufind yourselfwriting much multithreaded code, you mightwant to study ".Java Threads" by Scott Oaks and Henry Wongfor design tips on avoiding deadlock. One of th e most commontips is to pay attention to the order in which YOUl' threads arestarted.All it takes fordeadlock are twoobjects and twothreads.A simple deadlock scenario:Thread A enters asynchronized methodof object foo, and getsthe key."I faaThread A goes tosleep, holding thetoo key.1"..., -rThread B enters asynchronized methodof object bar, and getsthe key. ifI barThread B tries to entera synchronized methodof object too, but can'tget that key (bacauseA has It). B goesto the waiting lounge.until the Ioo key isavailable. B keeps thebar key.tooThread A wakes up (stlllholding the (00 key)and tries to enter asynchronized method onobject bar, but can't getthat key because B hasIt. A goes to the waiting1 lounge, until the bar key Isavailable (it never will bel)Thread A can't run untilit can get the bar key,but B is holding the barkey and B can't run until Itgets the tookey thai A Isholding and...516 chapter 15


-networking and threads• The static Thread.sleepf) method forces a thread to leave therunning state for atleast the duration passed tothe sleep method.Thread.sleep(200) puts a thread tosleep for 200 milliseconds.• The sleepO method throws achecked exception (InterruptedExceptionl,so all calls to sleept) must be wrapped in a try/catch. ordeclared.• You can use sleepO tohelp make sure all threads geta chance torun,although there's no guarantee that when a thread wakes up it'll go totheend ofthe runnable line. Itmight for example, go right back to the front.In most cases, appropriately-timed sleepO calls are all you need to keepyour threads SWitching nicely.• You can name a thread using the (yet another surprise) setNameOmethod. All threads get adefault name, but giving them an explicl1 namecan help you keep track ofthreads. especially if you're debugging withprint statements.• You can have serious problems with threads if two ormore threads haveaccess tothe same object on the heap.• Two ormore threads accessing the same object can lead todatacorruption if one thread, for example, leaves the running slate while stiliinthe middle ofmanipulating an object'scritical state.• To make your objects thread-safe, decide which statements should betreated as one atomic process. In other words, decJde which methodsmust run 10 completion before another thread enters the same methodon the same object.• Use the keyword synchronized tomodify amethod declaration,when you want toprevent two threads from entering that method.• Every object has a single lock, with asingle key forthat lock. Most ofthetime we don't care about that lock; locks come into play only when anobject has synchronized methods.• When a thread attempts toenter a synchronized method, the threadmust get the key for the object (the object whose method the threadIs trying torun). If the key Is not available (because another threadalready has it), the thread goes Into a kind ofwaiting lounge. until ttre keybecomes available.• Even Ifan objecl has more than one synchronized method, there isstillonly one key. Once any thread has entered asynchronized method onthat object, no thread can enter any other synchronized method on thesame object This restriction lets you protect your data by synchronizingany method that manipulates the data.you are here ~ 517


final chat clientNew and itltproved SitltpleChafClienfWay back near the beginning of this chapter, we built the SimpleChatClient that could sendoutgoing messages to the server but couldn't receive anything. Remember? That's how wegot onto this whole thread topic in the first place, because we needed a way to do two thingsat once: send messages to the server (interacting with the GUI) while simultaneously readingincoming messages from the server, displaying them in the scrolling text area.import java.io.*;import java.net.*;import java.util.*;import javax.swing.*;import java.awt.*;import java.awt.event.*;public class SimpleChatClientJTextArea incoming;JTextField outgoing;BufferedReader reader;PrintWriter writer;Socket sock;public static void main (String[] args) {SimpleChatClient client = new SimpleChatClient();client. go 0 ;Yes, there really IS anend to this thapter.Blott not yet...public void go ()JFrame frame new JFrame(~Ludicrously Simple Chat Client");JPanel mainPanel = new JPanel() ;incoming = new JTextArea(lS,SO);incoming.setLineWrap(true);incoming.setwrapStyleWord(true) ;incoming.setEditable(false);JScrollPane qScroller = new JScrollPane(incoming) ;qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL SCROLLBAR ALMAYS) ;qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);outgoing = new JTextField(20);JButton sendButton = new JButton(~Send");sendButton.addActionListener(new SendButtonListener(»;mainPanel. add(qScroller) ; We're startin~ a thmainPanel.add(outgoing); / lotSinli a hew ' nlew read,. 1 dd(dB ) s. J Inner t: ass asmaJ.nPane . a sen utton; ,;he Rlothnabl (- b)+setUpNetworking () ; thl"ead. Th eit ,o~ th~s. f' e l"ead sJob ISl;O l"ead 1'rOft> the stl"vel"'sSOlk~t streaft>, disrlayih~any 11,~Oft>ih~ ft>essa~es in theframe .getContentPane 0 . add (BorderLayout. CENTER, mainPanel); Sll"o In~ teXt area.frame.setSize(400,SOO);frame .setVisible(true);ii close go518 ch apter 15


networking and threadsprivate void setUpNetworking() {tty {sock = new Socket("127.0.0.1 H , 5000);:J:nputStreamReader streamReillder = new InputStreamRaader(sock.getInputStream();reader ~new BufferedReader(streamReader);writer = new PrintWriter(sock.getoutputStream(); tn· tSystam.out.prinUn ("networking established") ; I • ~e sot.Krt to ~et. e 'dYl'\,lSil\~catch(IOException ex) ( Wt.'rc 141 :{ strca".s. We ""crt. al yea '1 crax.printStackTrAce () ; alld 0Il-lf" stY to strUi to 1:.ht. ~ J) t.M. oJ:.YI't. J ea.", tnt. il\flot sb-u'" soI I close setUpNet:working \,,,rt f\CI'fl we'r( ,v.1;J Jthat ther I'L he ~t.Y.W\ts53¥S ",'r0W\ ~~Yc.ld ea.... ~et.public class SendButtonListener implements ActionLietenerpublic void actionPerfo~(ActionEventev) {try (writer.prinUn(outgoing.getText(» ;writer.llush() ;cateh(Exception ex) (ex.printStackTr8ce() ;}outgoing.setText("");outgoing.requestFocus() ;}II close inner cl~sslex.priilt:StaCJC'1'rac.n;}II close outer classyou are here. 519


chat server codeIJ _..Readj-"a"eCade ., fhe really really sltttple Chat ServerYou can use this server code for both versions of the Chat Client, Every possibledisclaimer ever disclaimed is in effect here. To keep the code stripped down to thebare essentials, we took out a lot of parts that you'd need to make this a real server.In other words, it works, but there are at least a hundred ways to break it. Ifyouwant a Really Good Sharpen Your Pencil for after you 've finished this book, comeback and make this server code more robust.Another possible Sharpen Your Pencil, that you could do right now, is to annotatethis code yourself. You'll understand it much better ifyou work out what'shappening than if we explained it to you. Then again, this is Ready-bake code,so you really don't have (0 understand it at all. It's herejust to support the twoversions of the Chat Client.import java.io.*;import java.net.*;import java.util.* ;public class VerySimpleChatServerArrayList clientOUtputStreams;public claS8 ClientBandler implements Runnable (BufferedReader reader;Soc:ket sock;public: ClientBandler (Socket clientSocket) {try (sock = clientSocket;InputStreamReader isReader :: new InputStreamReader (sock . getlnputStream () ) ;reader:: new BufferedReader (isRl!!lader) ;• catch(Exception ex)) II close constructor(ex .printStackTrace();)public void run () {String message;try (while «(message = reader.readLine(» !a null)System.out.println("raad " + message) ;tellEveryone(message);• II close whilecatch(Excaption ex)) 1/ close runII close inner class(ex .printStackTr4l:e();)520 chapter 15


networtOng and threadspublic static void main (String[] args)new VerySimpleChatServer().go();public void ge() (clientOutputSt.reams ;; Dew ArrayList 0 ;try (ServerSocket serverSock;; new SarverSocket(5000);wh.i.le(true) (Socket clientsocltet = servarSoclt.aCC8pt () ;Pr1.ntwrlter writer"" new PrintWriter(clientSoaket.qetoutputStream();clientOutputst.relUD8. add(writer) ;Thread t = new Thread(new ClientHandler(clientsoOket»;t.start () ;System.out.pr1.ntln("get a connection H ) icatch (Exception ex) (ax.printStackTrace();• II close gopublic void tel~one(Str1.ngmessage)Iterator it = cliantoutputStreama.iterator();while(it.hasNaxt(» (try (PrintWriter writer ;; (Printwrlter) it.naxtO;writer.println(message) iwritar .fluBh () ;catch (Exception ex) {ex.printstacltTrace();II end whileIII close tellEveryooeclose classyou are here. 521


synchronlzaUon questions:t1erel~~DumlJ ~uesti9nsQ.: What about protecting staticvariable state 7 Ifyou have staticmethods that change the static variablestate, can you stili use synchronization7A.: Yesl Remember that staticmethods run against the classand notagainst an Individual instance ofthe class.So you might wonder whose object's lockwould be used on a static method? Afterall, there might not even be any instancesof that class.Fortunately, Just as eachobject has Its own lock- each loaded classhas a lock. That means that If you havethree Dog objects on your heap, you havea total of four Dog -related locks.Threebelonging to the three Dog Instances,and one belonging to the Dog class Itself.When you synchronize a static method,Java uses the lock of the class itself. So Ifyou synchronize two static methods In asingle class,a thread will need the classlock to enter either of the methods.Q..: What are thread prlorltlesll'Yeheard that's a way you can controlscheduling.A.: Thread priorities might helpyou Influence the scheduler, but theystili don't offer any guarantee. Threadpriorities are numerical values that tellthe scheduler (If It cares) how Important athread Is to you.In general, the schedulerwill kick a lower priority thread out of therunning state If a higher priority threadsuddenly becomes runnable ,But...onemore time, say It with me now,"thereIs no guarantee.» We recommend thatyou use priorities only if you want toInfluence performance,but never, everrely on them for program correctness.Q.: Why don't you just synchronizeall the getters and setters from theclass with the data you're trying toprotect? Like, why couldn't we havesynchronlzed Just the checkBalanceOand wlthdrawO methods from classBankAccount. Instead of synchronizingthe makeWlthdrawalO method fromthe Runnable's class?A: Actua lIy, we should havesynchronized those methods, to preventother threads from accessing thosemethods In other ways.We didn't bother,because our example didn't have anyother code accessing the account.But synchronizing the gettersand setters (or in this casethecheckBalanceO and wlthdrawO) isn'tenough.Remember, the point ofsynchronization Is to make a speciflcsection of code work ATOMICALLY. Inother words, It's not Just the individualmethods we care about, It's methodsthat require more than one step tocompletel Think about lt.jf we had notsynchronized the makeWlthdrawalOmethod, Ryan would have checked thebalance (by calling the synchronizedcheckBalanceOl, and then Immediatelyexited the method and returned the keylOf course he would grab the key again,after he wakes up, so that he can callthe synchronized withdrawO method,but this still leaves us with the sameproblem we had before synchronizationlRyan can check the balance, go to sleep,and Monica can come in and also checkthe balance before Ryan has a chance towakes up and completes his withdrawal.So synchron izing all the accessmethodsIs probably a good Idea, to preventother threads from getting in, but youstili need to synchronize the methodsthat have statements that must executeas one atomic unit.522 chapter 15


networking and threadsCode KitchenCvber BeatBox( Start )( Stop )( Tempo Up )( Tempo Down )( sendlt )dance beatAndy: groove #2Chris: groove2 revls&dNigel: dance beatThis is the last version ol the BeatBox!It connects to a simple MusicServer so that you cansend and receive heat patterns witlt other cUents.The code is really long, so tite complete listing isarluaUy in AppenJix A.you are here. 523


exercise: Code MagnetsCode MagnetsA work ing Javaprogram Is scrambled up on the fridge. Canyou add the code snippets on the next page to the emptyclasses below, to make a working Java program that producesthe output listed ? Some of the curly braces fell on thefloor and they were too small to pick up, so feel free to add asmany of those as you needlpublic class TestThreads {class ThreadOneclass Accum {class ThreadTwoBonus Question: Why do you think we used themod ifiers we did In the Accum class?524 chapter 15


Code Magnets, continued..networking and threadsThread one ~new Thread(tl)isystem.out.printlo(Utwo u+a.getCount())i} oatoh(InterruptedExceptiOn ex) { } ThreadTwO t2new ThreadTWO()ireturn counte icounter += add::::- new Th read(t2);implements Runnable (Accum aAccum.getAccum():public static Accum getAccurn() {} catch(InterruptedException ex) { }private static Accurn anew Accurn( ) iprivate int co unter 0:public voida.updatecounter(l);forti t n x=O: x < 99İ X++) ( implements Runnable (public int getCount() (a.updateCounter(lOOO)ireturn a;System.out.printl O("one "+a .getCount(»;for(int x=o; x < 98' two.start()i, x++) (public static void main(String (I args) (public void runt) ( private Accum() { } Thr e adOne tl = new ThreadO ne():you are here ~ 525


exercise solutionspUblic clasa TestThreada {}pUblic static void main(String [] args) {}ThreadOne tl '" new ThreadOne()jThreadTwo t2 '" new ThreadTwo();Thread one ~Thread two cone.start() ;two.start() ,new Thread(tl);new Thread(t2);public static Accurn getAccum() {return a;}/,~~ il sUb/')i~".uJ t.\ass to.t.t........class Accum {private static Accum a =: new AccUDI ( ) ;private int counter =: OJ}private Accurn() { } r-- to. rri"~ ~~public void updateCounter(int add) {counter += add;}public int getCount() {return counterj}class ThreadOne implements Runnable {}Accum a =:Accum.getAccum()jpublic void run() {}for(int xeO; x < 98; x++) {}a.updateCounter(lOOO);try {Thread.sleep(50)j} catch(InterruptedException ex) { }system.out.println(None u+a.getCount())jThreads from two different classes are updatingthe same object in a third class, because boththreads are accessinga single instance of Accum.The line of code:private static Accum a=new Accum(); creates astatic instance of Accum (remember static meansone per class), and the private constructor inAccum means that no one else con makean Accumobject. These two techniques (private constructorand static getter method) used together, createwhat's known as a 'Singleton' - an 00 pattern torestrict the number of instances of an objectthat can exist in an application. (Usually, there'sjust a single instance of a Singleton-hence thename), but you can use the pattern to restrict theinstance creation in whatever way you choose.)class ThreadTwo implements Runnable {}Accum a =Accum.getAccum()jpublic void run() {}for(int x=:O; x < 99; x++) {}a.updateCounter(l)jtry {Thread.sleep(50);} catch(InterruptedException ex) { }System,out.println(~twou+a.qetCount())j526 chapter 15


•Near-miss at the Airlocknetworking and threadsThis morning's meeting was focusedon the controlsystems for the orbiter's airlocks.As the finalconstructionphases were nearing their end, the number of spacewalks wasscheduledto increasedramatically, and trafficwas high both in and out of the ship'sairlocks. "Good morning Sarah", said Tom, "Your timing is perfect, we're just startingthe detailed design review.""As you all know", said Tom,"Each airlock is outfittedwith space-hardenedGUIterminals, both inside and out Whenever spacewalkersare entering or exiting the orbiterthey will use these terminals to initiatethe airlock sequences." Sarah nodded,"Tom canyou tell us what the method sequences are for entry and exit?" Tom rose,and floated to thewhiteboard., "First, here's the exit sequence method's pseudocode",Tom quicklywrote on theboardorbiterAirlockExitSequence()verifyPortalStatus();pressurizeAirlock();openlnnerHatch();confinnAirlockOccupied () ;closelnnerHatch() ;decompressAirlock();openOuterHatch();confirmAi r lockVacated () ;closeOuterHatch();"To ensure that the sequence is not interrupted, we have synchronizedall of themethodscalled by the orbiterAirlockExitSequence() method",Tom explained. "We'd hate tosee a returningspacewalkerinadvertentlycatch a buddy with his space pants down!"Everyonechuckled as Tom erased the whiteboard, but something didn't feel rightto Sarah and it finally clicked as Tom began to write the entry sequence pseudocode on thewhiteboard, "Wait a minute Tom!", cried Sarah. ''1 think we've got a big flaw in the ex.itsequence design, let's go back and revisit it, it could be critical!"Why did Sarahstop the meeting? What didshe suspect?you are here ~ 527


puzzle answers•Whatdid Sarah know?Sarah realized that in order to ensure that the entire exitsequence would run without interruption theorbiterAi r lockExitSequence ( ) method needed tobe synchronized. As the design stood, it would be possiblefor a returning spacewalker to interrupt the Exit SequencelThe Exit Sequence thread couldn't be interrupted in themiddle of any of the lower level method calls, but it couldbeinterrupted in between those calls. Sarah knew that the entiresequence should be run as one atomic unit, and ifthe a rbiterAirlockExitSequence ( ) method was synchronized, itcould not be interrupted at any point.528 chapter 15


16 collections and genericsDatastructuresSorting is a snap in Java. You have all the tools for collect ing and manipulatingyour data without having to write your own sort algorithms (unless you're reading this rightnow sitting in your Computer Science 101 class,in which case, trust us-you are SO going to bewriting sort code while the rest of us Justcall a method In the Java API). The Java CollectionsFramework has a data structure that should work for virtually anything you'll ever need to do.Want to keep a list that you can easily keep adding to? Want to find something by name?Wantto create a list that automatically takes out all the duplicates? Sort your co-workers by thenumber of times they've stabbed you in the back? Sort your pets by number of tricks learned?It 's all here...this is a new chapter 529


sorting a listfracki"Q SOt1g popularity 0., your jukeboxCongratulations on your new j ob----managing the automatedjukebox system at Lou's Diner. There's no Java inside thejukebox itself, but each time someone plays a song, thesong data is appended to a simple text file.Your job is to manage the data to track song popularity,generate reports, and manipulate the playlists, You're notwriting the entire ap~omeof the other software developer/waiters are involved as well. but you're responsible for managingand sorting the data inside thejava app. And since Lou has a thingagainst databases, this is strictly an in-memory data collection. Allyou get is the file thejukebox keeps adding to. Your job is to take itfrom there.You've already figured out how to read and parse the file, and so faryou've been storing the data in an ArrayList.SongLlst. txtPink Moon/Nick DrakeSomersault/Zero 7Shiv& Moon/Prem JoshuaCircles/BTDeep Channel/Afro CeltsPassenger/HeadmixListen/Tahiti 80Challenge #1Sort the songs in alphabetical orderYou have a list ofsongs in a file. where each linerepresents one song, and the title and artist areseparated with a forward slash. So it should be simpleto parse the line, and put all the songs in an ArrayList.Your boss cares only about the song titles, so for nowyou can simply make a list thatjust has the song titles.But you can see that the list is not in alphabeticalorder... what can you do?You know that with an Arrayl.ist, the elements arekept in the order in which they were inserted into thelist, 50 putting them in an ArrayList won't take care ofalphabetizing them, unless... maybe there's a sortj)method in the ArrayList class?530 chapter 16


Here's what you have so far; without the sort:impo4t java.util.*;import java.io.*;collections with genericspUblic class JukeboxlArrayList songList :public static void main (String ()new Jukeboxl() . ge ( ) ;new ArrayList() iargs 1 Ipublic void go() I ~getSongs();System.out.println(songList);. 1: Y'tilO the t 'lle il"dNot.hi,,~ syet."lill he....e..J~oo ~a-- eat" \il'le·void gatSonqa () t.a\\ -\:.he ilod$of..~O '"try {File file new File("SongList.txt H ) ;BufferedReader reader = new BufferedReader(new FileReader(file»:String line = null;whi Le « line= r e ader , readLine () ! = null) (addSong(line);catch(Exception ex) (ex.printStackTrace();rThe tiddSonCi...d j th 1 "'eiJ..od \\/orh .(J... -J.. Ln. e I/O thdpU JIISf likl! i~1! /.I "~"t; Ild$ both th tifl....--yOk b... k "i'l


ArrayList API~ut the ArrayList class does NOr have asartO tMethod!When you look in Arrayl.isr, there doesn't seem to be any method related to sorting.NaJking up the inheritance hierarchy didn't help either-it's clear that y()U can't call a sortnethod on the ArrayList.~ -C;. -::T~ A;ii'iVUit (Jiiii 2 Pli"tfOOii sr 5:0)~i:i)11ern +lf~ h It P : 1/JavLS u n . rom /J1n / l . S . O ' docs /&pl / ln cltx .h lm l••• ... 1• ..,., AW..I.1a.aC~ !IDt>nu t.n.es fltJa> !hi> USl all ~ ~ dcm


collections with genericsr do see a collection classcelled TruSe.t... and the docssCI>! that it keeps your datasorted. r wonder if r should beusing a TreeSet inste.ad of anArrayList ...o oArrayLisf is.!Q1the ot1ly collectiot1Although ArrayList is the one you'll use most often,there are others for special occasions. Some of the key .collection classes include:D 't 'NcKY'f C1nOl>t b-'tl~Of' ~ese oth~ Ol'Iest.o \eClyY\ '\I 0 il'l-toyiaht "0... · We ~c ,1._~ TreeSet...~e o~il~ a \iH:le C1~'Keeps the elements sorted and prevents duplicates... HashMapLet's you store and access elements as namelvalue pairs.~ L1nkedLlstDesigned togive better performance when you insert ordeleteelements from the middle ofthe collection. (In practice, anArrayUst isstill usually what you want.)~ HashSetPrevents duplicates inthe collection, and given an element, canfind that element inthe collection qulcldy.~ L1nkedHashMapLike aregular HashMap, except it can remember the order inwhich elements (name/value pairs) were Inserted, orit can beconfigured to remember the order In which elements were lastaccessed.you are here ~ 533


Collectlons.sortOYou could use a freeSet. ..Or you could use the Coliectiotts.sortCl tttethodlfyou put all the Strings (the song titles) into a TreeSet instead ofan ArrayList, the Strings would automatically land in the right place,alphabetically sorted. Whenever you printed the list, the elements wouldalways come out in alphabetical order.And that's great when you need a set (we'lltalk about sets in a few minutes) or whenyou know that the list must au.vays staysorted alphabetically.On the other hand, ifyou don't need thelist to stay sorted. TreeSet might be moreexpensive than you need-every timeyouinsertinto a Treeset; the TreeSet has to takethe time tofigure out where in 1M treethe newelement mustgo. With ArrayList, inserts canbe blindingly fast because the new elementjust goes in at the end.lava.utll.collectionspublicstatic void copy{Ust destination.List source)publicstatic Ust emptyUst()publicstatic void flll(List IIstToFill, ObjectobjToFillltWrth)public static Int trequency(Collection c, Object0)publicstatic void reverse{Ust list)/I many more metQ: But you CAN add something to anArrayListat a specific Index Instead of just at-~the end-there's an overloaded addll methodthat takes an Int along with the element to addSo wouldn'fft be slower than Inserting at the end1A: Yes, It's slower to insert something in an ArrayLlstsomewhere otherthan at the end. So using the 0 verloadedadd(lndex, element) method doesn't work as quithe add(element)-which puts the added elemeBut most of the time you use ArrayLists, you won't need to putsomething at a specific Index.publicstatic void rotate(Ust list, lnt distance)Q: Isee there's a L1nkedllst class,sowouldn't that be better fordoing Inserts somewhere In the middle1 At least if Iremember my DataStructures class from college...A: Yes, good spot. The LinkedLlst can be quicker when you Insert orremove something from the middle, but for most applications, the differencebetween middle inserts Into a Linkedllst and ArrayList is usually not enoughto care about unless you're dealing with a huge number of elements. We'lllook more at L1nkedLlst In a few minutes.publicstatic void shuffle(Ust list)publicstatic~ sOrt{L\stlistV. ;~. II". Ohiect oIdVal, Object newVal)publicstatic boole.ij" ,,,,,,... !here IS a sor!() Meihod I-1ft !he Collet-t;ofts tlass. I! hkesa Lis! ' and' Slftte ArrayListi"'ple_e...i.s !he Lis! .....ter+ate,ArrayLis! IS-A Lis!. Thanks!o polyMorphisM, y~ tan pass a...ckly as calling~rayList to a Me!hod d ,nt at the end. to ta et aredIce List534 chapter 16


collectlons with genericsAddit1g Coliectiot1s.sortU to the Jukebox codeimpo r t j ava . ut i l . *;import java . i o . T ;pub l i c c l as s J u keb oxlArrayList songList = new ArrayList();public s t a t i c voi d ma i n (String [] a r gs) (ne w Jukebox1 () . go ();The Collections.sortOlllethod sorts a list ofStriPgs alphabetically.pub lic voi d got)ge r-Song s () ;r1t.aVt. CoI\et:b~System. out . prin t l n (s ongLi st) ; ~ ~~~et\


sorting your own objectsJut now you Meed SOMQ objects,not just shttple Stri"Qs.Now your boss wants actual Song class instances in the list, notjustStrings, so that each Song can have more data. The new jukeboxdevice outputs more information, so this time the file will have fourpieces (tokens) instead ofjust two.The Song class is really simple, with only one interesting featuretheoverridden toStringO method. Remember, the toString()method is defined in class Object, so every class inJava inherits themethod. And since the taStringO method is called on an objectwhen it's printed (System,out.println (an Object) ), you shouldoverride it to print something more readable than the defaultunique identifier code. When you print a list. the toStringOmethod will be called on each object.class Song (String title;fString artist;String rating;String bpmiSongUstM0r2.txtPink Moon/Nick Drake/5/80Somersault/Zero 7/4/84Shiva Moon/Prem Joshua/6/120Circles/BT/5/110Deep Channel/Afro Celts/4/120Passenger/Headmix/4/l00Listen/Tahiti 80/5/90Song(String t, String a, String r, String b) (title = t;artist =' a; The va~i.ables a.-t all sd. i"rating = r; the l.or\strl.ll.i« wher> thebpm = b rI\ew ~,,~"is l.~eated ,pUblic String getTitle()return title;public String getArtist()return artist;public String getRating(}return rating;public String getBpm()return bpm;public String toString ()return title;536 chapter 16


Changing the Jukebox code to use Songsinstead of Stringscollections with genericsYour code changes only a little-the file I/O code is the same,and the parsing is the same (String.splitf) ). except this timethere will be Jourtokens for each song/line, and all four will beused to create a new Song object. And of course the ArrayListwill be of type instead of.import j ava . uti l . * ;import java.io.*;L A.rra'JL.ist cJ SoY\~Chan~e ~ an f\ J 'Stv:ln~.objetts Insteadpublic c l a s s JUkebOX~ ~ArrayList songList = new ArrayList();publi c static v o i d mai n(Stri ng[ ] args) (new J ukebox3() . g o () ;}pub l i c void ge() {g e tSongs() ;Syste m. o u t . println( s o ng Li s t) ;Collect i o n s .sort(songLi s t ) ;Sys tem . out.pri ntl n (songLis t ) ;}void getSongs ()try {Fi le file new File{"SongLi s t . t xt H ) ;BufferedReader r e ader = ne vi Buffe r e d Re ade r (ne w FileReader (file ) ) ;St r i ng line = nul l ;while « Line> r e a d e r . rea dLine ()) ! ~o null) (a dd Song (line ) ;catch (Exception e x)e x .pri ntStackTrac e () ;vo id addSeng(String lineTeParse) {St ring [ ] t okens = lineTo Pa r s e . split("/");Song nextSonq = new Sonq(tokens[O] , tokens[l], tokens [2] , tokens[3]);songList.add(nextSong);you are here ~ 537


Collections.s0 rtOIt WOt1~t cotMpi Ie!Something's wrong... the Collections class clearly shows there's asort/) method, that takes a List.ArrayList is-a List, because ArrayList implements the List interface,so... it should work .But it doesn't!The compiler says it can't find a sort method that takes anArrayl.istc'Songo, so maybe it doesn't like an Arrayl.ist ofSongobjects? It didn't mind an ArrayList. so what's theimportant difference between Song and String? What's thedifference that's making the compiler fail?%javac Jukebox3.javaJukeboK3 .java:15 : cannot find symbolsymbol method sort(java.util.ArrayList


collections with genericsWID I have no idea how toread the method declarationon this. It says that sortOtakes a List~T) . but what isn And what is that big thingbefore the return type?o ofhe sortO tMethod declaratiot'sortpublic: at.4t~ fUl.teDd: eome:rllbl&


generic types&et1erics ",eat1s ",ore type...safetyWe'lljust say it right here-virtually all of the code you writethat dealswith genericswill becollection-related code. Although generics can be usedin other ways, the main point ofgenerics is to let you write type-safecollections. In other words, code that makes the compiler stop youfrom putting a Dog into a list ofDucks.Before generics (which means beforeJava 5.0), the compiler couldnot care less what you put into a collection, because all collectionimplementations were declared to hold type Object. You could putanything in any ArrayList; it was like all ArrayLists were declared asArrayList.ArrayList••••~ ~ ~ ~And come OUT as a reference oftype ObjectwIth generics. you cancreate type-safe collectionswhere more probleltlS arecaught at compile-timeinStead of runtil1le.wIthout generics. thecompiler would happily letyou put aPumplin into anArrayLiSt that was supposedto hold only Cat objects.WITH genericsObjects go IN as a reference toonly Fish objectsArrayListAnd come out as areference oftype Fish540 ch apter 16


Learning genericsOfthe dozens of things you could learn about generics, there arereally only three that matter to most programmers:collections with generics• Creating instances of generified classes (like ArrayList)When you make an ArrayList, you have to tell it the typeofobjects you'll allow in the list,just as you do with plainold arrays.new ArrayList()• Declaring and assigning variables of generic typesHow does polymorphism really work with generictypes? Ifyou have an ArrayList referencevariable, can you assign an ArrayList to it? Whatabout a List reference? Can you assign anArrayList to it? You'll see ...List songList =new ArrayList()• Declaring (and invoking) methods that take generic typesIfyou have a method that takes as a parameter, say, anArrayList ofAnimal objects, what does that really mean?Can you also pass it an ArrayList ofDog objects? We'lllook at some subtle and tricky polymorphism issues thatare very different from the way you write methods thattake plain old arrays.(This is actually the same point as #2, but that shows youhow important we think it is.)void foo(List list)x.foo(songList)Q.: But don't Ialso need to learn how to create my OWN genericdasses? What if Iwant to make a class type that lets peopleinstantiating the class decide the type of things that class will use?A.: You probably won't do much of that. Think about it-the APIdesigners made an entire library of collections classescovering most ofthe data structures you'd need, and virtually the only type of classesthatreally need to be generic are collection classes. In other words, classesdesigned to hold other elements, and you want programmers using it tospecify what type those elements are when they declare and instantiatethe collection class.Yes, it is possible that you might want to create generic classes, but that'sthe exception, so we won't cover it here. (But you'll figure it out from thethings we do cover, anyway.)you are here ~ 541


generic classesUsing generic CLASSESSince ArrayList is our most-used generified type, we'llstart by looking at its documentation. They two key areasto look at in a generified class are:1) The class declaration3) The method declarations that let you add elementsUnderstanding ArrayList documentation(Or, what's the true meaning of "E"?)Thinl of "E" as a stand-in for"-the type of elem.ent you wantthis collection to hold andreturn." (E is for Elenent.)- -public class ArrayList extends AbstractList.:implements List .. , {The t'tfe (the lJal~ of


collections with genericsUsit1Q type parattteters with ArrayListTHIS code:ArrayList thisList = newMeans ArrayLlst:. . . {public boolean addlE 0)/ / more codeIs treated by the complier as:public class ArrayList extends AbstractList . .. {public boolean add(Strinq 0)/ / more codeIn other words, the ~E~ is replaced by the realtype (also called the type parameter)that you use when you create the Arrayl.ist, And that's why the add0 methodfor ArrayList won't let you add anything except objects of a reference type that'scompatible with the type of ~E ". So ifyou make an ArrayList, the add0method suddenly becomes add(String 0). !fyou make the ArrayList of type Dog,suddenly the addt) method becomes add(Dog 0).Q: Is"E"the only thing you can put there18ecause the docs for sort used "1'':'•••A: You can use anything that's a legal Java Identifier. That means anything that youcould use for a method or variable name will work as a type parameter. But the conventionIs to use a single letter (so that's what you should use), and a further convention IS touse MT" unless you're specIfically wrltlng a collection class,where you'd use ME" to representthe "type of the Element the collection will hold"you are here ) 543


generic methodsA generic class means that the class declaration includes a typeparameter. A generic method means that the method declarationuses a type parameter in its signature,You can use type parameters in a method in several different ways:• Using atype parameter defined Inthe class declarationpublic class ArrayList extends AbstractList ... (public boolean addlE 0)\/OII"~"-../ t- ......" ~ fh ~E»When you declare a type parameter for the class, youcan simply use that type any place that you'd use arealclass or interface type. The type declared in themethod argument is essentially replaced with the typeyou use when you instantiate the class,tllr~dyb t bl d:fi"td :~;tl~:rhet.4~ it'stht lltlU.--• Using atype parameter thatwas NOT defined Inthe class declarationpublic void t&keThing(ArrayList~list)Ifthe class itself doesn't use a type parameter, you can stillspecify one for a method, bydeclaring it in a really unusual(but available) space-before the return type, This method saysthat T can be "any type ofAnimal",rr...." ~ be»&t we~~rliel" i" the ...efh ~~ we ~1~hOAod dtlJdrd~544 chapter 16


collections with genericsWait ... that can't be right. If youcantake a list of Animol, why don't youjust SAY that? What's wrong with justtoke ThIng{AtTayUst~ Animal;) list)?HereJs where It gets weird...This:public void takeThing(ArrayList list)Is NOT the same as this:public void takeThing(ArrayList list)Both are legal, but they're diffmmtlThe first one, where is part of the methoddeclaration. means that any Arrayl.ist declared ofa type that isAnimal, or one of Animal's subtypes (like Dog or Cat), is legal.So you could invoke the top method using an ArrayList,ArrayList, or ArrayList.But... the one on the bottom, where the method argument is(Arr.tyList list) means that only an Arr.tyListis legal. In other words, while the first version takes an Arrayl.isrofany type that is a type ofAnimal (Animal, Dog, Cat, etc.),the second version takes Qnly an Arrayl.Jst of type Animal. NotArrayList, or ArrayList but only ArrayList.And yes, it does appear to violate the point of polymorphism.but it will become clear when we revisit this in detail at the endof the chapter. For now, remember that we're only looking atthis because we're still trying to figure out how to sortO thatSongList, and that led us into looking at the API for the soru)method, which had this strange generic type declaration.For now, all you need to krww is that the synt.ax of the top uersionis legal, and that it meansyou can pass in a ArrayListobject1'nstantiated as Animal or anyAnimal subtype.And now back to our sortt) method...you are here. 545


sorting a SongThis still doesn'texpla in why the soM methodfailed on an ArrayList of Songsbut worked for an ArrayList ofStrings...Remember where we were...i mpor t java.util .*;import java.io.*:public class Jukebox3 (ArrayList songList = new ArrayList() ipUblic static void main{String{ ) args) (new Jukebox3{) .go();IpUblic void go() (getSongs();Sys t em.out. pr i nt l n (s ongLi s t );System.out.println(songList);}void getSongs ()try (File file new File("SongList.txt H ) ;Buf feredReader r e ade r = new BufferedReader (new FileReader (file) );String line ~ null;while ((line= reader.readLine{» != null) (addSong{line);Icatch (£xception ex) (ex.printStackTrace();)void addSong(String lineToParse) (String!) tokens = lineToParse.split("/");Song nextSong = new Song (tokens [01 , tokens[l], tokans[2] , tokens[3]);songList.add(nextSong);546 chapter 16


collections with genericsRevisiti.,g the sortt) tltethodSo here we are, trying to read the sortt) method docs to findout why it was OK to sort a list ofStrings, but not alist ofSong objects. And it looks like the answer is'''The sortO method can take only listsof Comparable objects.Song is NOT a subtype ofComparable, so you cannot sortothe list of Songs.At least not yet.•.L... ~ ~ OoVi i,;;;;;;.. $(·L :.1.-"~"""lIHJ ' /""""I_" I "" /'''''__1':01public static


the sortt) method't1 get1erics, "extet1ds Nttteat1S"extet1ds ~ itttpletttet1ts NTheJava engineers had to give you a way to put a constrainton a parameterized type, so that you can restrict it to, say, onlysubclasses ofAnimal. But you also need to constrain a type toallow only classes that implement a particular interface. Sohere's a situation where we need one kind ofsyntax to workfor both situations-inheritance and implementation. In otherwords, that works for both extends and implements.And the winning word was... extends. But it really means "is-a",and works regardless ofwhether the type on the right is aninterface or a class.COMrarable is an in-ttr.fate, sothisR~l...l...y reads, "T Ml.tSt be a t'tre t,hatiMrleMents the COMrarable in-ttrfate .~public static


Fittally we kttow whatl wrottQ...The SOtt


the Comparable interfacefhe "eYl, itltproved, cotltparable SO"Q classWe decided we want to son by title, so we implement the corn pareTo()method to compare the title of the Song passed to the method againstthe title ofthe song on which the compareToO method was invoked.In other words, the song running the method has to decide how itstitle compares to the title of the method parameter.Hmmrn... we know that the String class must know about alphabeticalorder, because the sortj) method worked on a list ofStrings. We knowString has a compareTaO method. 80 why notjust call it? That way, wecan simply let one title String compare itself to another, and we don'thave to write the comparing/alphabetizing algorithm!class Song implementsString titIe;String artist;String rating;String bpm;Comparable {public int compareTo(Song s) {return title.compareTo(s.getTitle(»;)IAsv.ally t.~~se ,.,..;tt,h...\lIt't't sfetl.f'ii~ the t'fYe t1a-tt~e i "le... e"h,,~ dciss tal> be (.Oft\ra--ed a~"'IJI,S+"This ecihS that. ~,,~ objed:.s ta" be t.OMr a -- ed -toot.hel" ~~ objet.b, f~ t~e r~--fose tJ sorti~ .,--- The soortO ",dhod ~ds a So,,~ to i.e-ya--eTof.).J..,. -to see how that ~~ t.o...ya __es to t~ Sol'l~ O'/'lwhith the ...dhoa was ,,,yoked.Sonq(String t,title = t;artist = a;rating = r;bpm = b;String a, String r, String b) (public String getTitle()return titie;public String getArtist()return artist;public String getRating()return rating :public String getBpm () {return bpm;%java Jukebox3(Pink Moon, Somersault, Shiva Moon, Circles, DeepChannel, Passenger, Listen][Circles, Deep Channel, Listen, Passenger, PinkMoon, Shiva Moon, Somersault]public String toString()return title;)550 chapter 16


collections w ith genericsWe catt sortthe list, but...There's a new problem-Lou wants two different views of the song list,one by song title and one by artist !But when you make a collection element comparable (by having itimpl ement Comparable), you get only one chance to implement thecompareToO method. So what can you do?The horrible way would be to use a flag variable in the Song class,and then do an if test in compare'Ior) and give a different resultdepending on whether the flag is set to use title or artist for thecomparison.But that's an awful and brittle solution, and there's something muchbetter. Something built into the API for just this purpose-when youwant to SOrt the same thing in more than one way.That's not good enough.Sometimes r want it to sortby artist instead of title.Look at the Collections class API again. There's asecond sortO method-and it takes a Comparator.._-Collections Oava 2 Platform SE 5.0) ----. _.--~ flle:IIIUsers/kathyIPublic/docs/apl/lndex.hlml 0.. Google Js Jellyvislon. Inc Collect ion s ...form SE 5.0) Caffelnated ...d Brain Day Brand Noise DIva Marketing »--- static 8LngletoAKaP(K key, V value) ~--1 lllGtic ~(Li5t list)~per T»void according to the 1UJlUTal ordering of its elements.Returns an immutable map,mapping only the ~specified key to the specified value.:oJ,-- Sorts the specified list into ascending order,sarlO ~~od is o'Jev-\oad ed -to\ llt;~ BOrt. (List list, COlnD8f"lftor


the Comparator interfaceUshtg a custOtlt CotltparaforAn element in a list can compare itselfto another ofits own type in only one way. using its compareTo(}method. But a Comparator is external to the elementtype you're comparing-it's a separate class. Soyou canmake as many ofthese as you like! Waut to comparesongs by artist? Make an ArtistComparator. Sort by beatsper minute? Make a BPMCornparator.Then all you need to do is call the overloaded sortt)method that takes the List and the Comparator that willhelp the sortt) method put things in order.The sortO method that takes a Comparator will use theComparator instead of the element's own compareTo(}method, when it puts the elements in order. In otherwords, ifyour sortt) method gets a Comparator, it won'teven call the compareToO method of the elementsin the list. The sortf) method will instead invoke thecompareO method on the Comparator.So, the rules are:Java.util.Comparatorpublic interface Comparatorint compare(T aI, T 02);Ifyou pass aeomparator to thesortO method. the sort order isdetermined by the comparatorrather than the elements owncompareToO method.~ Invoking the one-argument sort(L1st 0) methodmeans the list elemenfs compareToO methoddetennlnes the order. So the elements Inthe listMUST Implement the Comparable Interface.~ Invoking sort(Llst 0, Comparator c)means thelist elemenfs compareToO method will NOT becalled, and the Comparators compare{) methodwill be used Instead. That means the elementsInthe list doNOT need to Implement theComparable Interface.Q.: So does this mean that Ifyou have a class thatdoesn't Implement Comparable, and you don't have thesource code, you could stili put the things In order bycreating 8 Comparator7A: That's right.The other option (if It's posslble) would beto subclass the element and make the subclass implementComparable.552 chapter 16Q.: But why doesn't ~very class Implli!mentComparable1A: Do you really believe that everything can be ordered?If you have element types that Just don't lend themselves toany kind of natural orderIng, then you'd be misleading otherprogrammers If you implement Comparable. And you aren'ttaking a huge risk by not Implementing Comparable, sincea programmer can compare anything in any way that hechooses using his own custom Comparator.


collections with genericsUpdatiMQ the Jukebox to use a COlMparaforWe did three new things in this code:1) Created an inner class that implements Comparator (and thus the rompare()method that does the work previously done by romjJrue'Ib()).2) Made an instance ofthe Comparator inner class.3) Called the overloaded sortt) method. giving it both the song list and theinstance ofthe Comparator inner class.Note: we also updated the Song class tcString() method to print both the songtitle and the artist (It prints title: artist regardless of how the list is sorted.)i mpo r t java.util. ";imporc java.io.·;public class JukeboxS (ArrayList songList = new ArrayList();public static void main(String[ ] args) {new Jukebox5 () .go();class Artistcompare implements Comparatorpublic int campare(Song one, Song twO) (return one.qatArtist () . compareTo (two.g8tArtist (» ;~ni~ bet.OI'/I!1 i} Sh-i",~ (tne artirt)pUblic void got) {getSongs();System.out.println(songLi s t);Collections.sort(songList);System.out.println(songList);~ Make a~ i~Ylt.t: ~ theArtistCompare artistCompare:: new ArtistCompare () ; C--y.lrat.m- IMer t.lau.Collections. sort (songList, artisbCompare);System.out .println(SongLis t J ;void getSongs() {II rIo code herevoid addSong(String l ineToParse} {II parse line an d add co song listNote: we've made sort-by-title the default sort. bykeeping the compareToO method In Song use thetitles. But another way to design this would be toImplement both the title sorting and artist sorting asinner Comparater classes, and not have Song ImplementComparable at all.That means we'd always use the twoargversion of Collections.sortl).you are here ~ 553


collectJons exerciseimportpublic class SortMountains {LinkedList '------- mtn new LinkedList, ()iclass NameCompare {public int cOmpare(MouDtain one, Mountain two) {return}class HeightCompare {pubLi.c int compare (Mountain one, Mountain two) {}return ( );}public static void main(String [J args) {new SortMountain().go():}public void got) {mtn.add(new Mountain(ULongs", 14255»;mtn.add(new Mountain(UElbert", 14433»imtn.add(new Mountain(nMarOOn M , 14156»imtn.add(new Mountain(UCastle", 14265»;System.out.println(Uas entered:\n" + mtn);NarneCornpare nc = new NarneCompare();Reverse EngineerAssume this code eXiStS inII Single !1le. Your joh istonil in the hlankS So thethe program will create theoutput shawn.Note: answers are at the end ofthe chapter,System.out.println(uby narne:\nn + mtn);HeightCompare he = new HeightCompare();}}System.out.println(nby height:\nn + mtn)iclass Mountain {Output:}}}{{File EdH WIndow Hel ThlsOne'sFor8ob%java SortMountainsas entered:[Longs 14255, Elbert 14433, Maroon 14156, castle 14265]by name:lCastle 14265, Elbert 14433, Longs 14255, Maroon 14156)by height:[Elbert 14433, Castle 14265, Longs 14255, Maroon 14156]554 chapter 16


~ your penCil fiTI-in-the-blankscollections with genericsFor each of the questions below, fill in the blankwith one of the words from the "possible answers"list, to correctly answer the question. Answers areat the end of the chapter.Given the following compilable statement:Possible Answers:Comparator,Comparable,compareTo( ),compare( ),yes,noCollections.sort(myArrayList);1. What must the class of the objects stored in myArrayList implement?2. What method must the class ofthe objects stored in myAr r a yLi s t implement? _3. Can the class of the objects stored in myArrayList implement bothComparator AND Compa rable?Given the following compilable statement:Collections . sort(myArrayList, myCompare);4. Can the class ofthe objects stored in myArrayList implement Comparable?5. Can the class ofthe objects stored in myArrayList implement Comp a r a t o r ?6. Must the class of the objects stored in myArrayList implement Comparable? _7. Must the class of the objects stored in myArrayList implement Comparator? _8. What must the class ofthe myCompare object implement?9. What method must the class of the myCompare object implement?you are here ~ 555


dealing with duplicatesUh"'oh. fhe sorting all works, but now we have duplicates...The sorting works great, now we know how to son on both title (using the Song object'scompareToO method) and artist (using the Comparator's compare0 method). But there'sa new problem we didn't notice with a test sample of the jukebox text file-the sorted listcontainsduplicates.It appears that the dinerjukeboxjust keeps writing to the file regardless ofwhether thesame song has already been played (and thus written) to the text file. The SongListMore.txtjukebox text file is a complete record of every song that was played, and might contain thesame song multiple times.SongllstMore.txtPink Moon/Nick Drake/5/80Somersault/Zero 7/4/84Shiva Moon/Prem Joshua/6/120Circles/BT/5/110Deep Channel/Afro Celts/4/120Passenger/Headmix/4/100Listen/Tahiti 80/5/90Listen/Tahiti 80/5/90Listen/Tahiti 80/5/90Clrcles/BT/5/110556 chap ter 16


We t1eed aSet-it1stead of a ListFrom the Collection API, we find three main interfaces, List, Set, andMap. ArrayList is a List, but it looks like Set is exactly what we need.collections with generics~ LIST· when sequence mattersCollections that know about Index posfflon.Usts know where something is in the list Youcan have more than one element referencingthe same objeelList~ SET· when uniqueness mattersCollections that do notaI/ow duplicates.Sets know whether something isalready in the collection.You can never have more than one element referencingthe same object (or more than one element referencingtwo objects that are considered equal-we'lIlook atwhatobject equality means ina moment).Set~ MAp· when finding somethIng bykeymattersCollections that use key-value pairs.Maps know the value associated with a given key. Youcan have two keys that reference the same value, but youcannot have duplicate keys. Although keys are typicallyString names (so that you can make name/value propertylists, for example),a key can be any object.Mapyou are here ~ 557


the collections APIThe Collectiot1 API (part of it)Notice that the Map interface doesn'tactually extend the Collection interface,but Map is still considered part of the"Collection Framework" (also knownas the "Collection APr). So Maps arestill collections, even though they don'tincludejava.utilCollection in theirinheritance tree.(Note: this is not the completecollection API; there are otherclasses and interfaces, butthese are the ones we caremost about)SortedSet(Interface)/'/'Set(Interface).", ,,,r,,I,I,II,,II-IIII\, ,\III, ,I,Collection(interface)IList(interface)-r; l\'".I \, ,\III ,, \IIII, \, ,II, \I ,I ,r., , ,",,,,," ,,,,"TreeSet LinkedHashSet HashSet ArrayList LlnkedLlst Vector.-------- KEy-------.T.T.,extendsimplementsimplementation classinterfaceMa~l dOY\'+' ~'ll.u"d '(\"00>\jiIVel...·h l.Collet -!:.i Ol'l, b..+."thl'f)ve lVII tol'llidll"ldMapto b~ ~il..-t of the "(Interface) "tolled:.iOl'1 ~\'"el ...twetrkIi" Java. ~o a Ma~ is-r; 1\' ., ... still Ye{~ed to ell aI , ,, ,\ ,,,, tolled:.iol'\'I ,I \SortedMap ,\ ,r ,,,,,,I (Interface) ,I.,I, ,,,I, •I,/ '//\TreeMap IIHashMap"'-----.".LinkedHashMap •IHashtable558 chapter 16


Using a HashSet instead of ArrayListWe added on to the Jukebox to put the songs in a HashSet. (Note: we left out someoftheJukebox code, but you can copy it from earlier versions. And to make it easierto read the output, we went back [Q the earlier version of the Song's toStringOmethod, so that it prints only the title instead of title and artist.)collections with genericsi mp o r t j a v a . ut i l . ~ ;: mp or t j a va . i o . * ;ub l i c class J u ke box 6 {ArrayLi st s ong Li s t = ne w ArrayList (l ;~I I ma i n me t hod e c . ~p ublic vo i d go () ( L L . A... d L: +.We die!..'+. t.ha)\~e ~d$ofI~(), so I+' s1:.i1l y"Vl 1;he $O,,~ ," a" -- y LSg e t S o n g s();~)S ys t e m. ou t . p r i n t l n (s ong Li s t );Coll e c t i o n . s o r (s o ngLis t ) ;Syst e m. ou t . p r i n t l n (s ongLi s t );HashSet songSet = new HashSet();songSet.addA11(songList);System.out.println(songSBt);II get So ng s () and a dd Son g () methods~~e we t.__eah a "ew l1asl-.SctV',wameW-iz.ed t.D hold .so..~A~te-- ~iYl~t.\-Ie A----a'fLi!lCh'j -title).The &f. didr/f. help!!We still have all ih~ dl.lplitaus!(A"d it. lost. ih soV't. o...de...",ne" we y"t t.ne list iYlto a\1as~t. 1 blat. we'll WcifY'I a~t.that tm~ latey··JAHe... ~\l.Ui",~ it.into a }lash&t.a"a Y'"i,,-tiYl~ tnt:~a1~ (we dia",'teall sor\:.O a~a;n) .you are here) 559


object equalityWhat tttakes two objects equal?First . we have to ask-what makes two Song referencesduplicates? They must be considered equal. Is it simply tworeferences to the very same object, or is it two separate objectsthat both have the same Lilli?This brings up a key issue: reference equality vs. object equality.). Reference equalityTwo references, one object onthe heap,Two references tIlat refer tothe same object onthe heap are equal. Period. Ifyou call the hashCodeQ method onboth references. you'll get tile same result Ifyou don't override tilehashCode() method, tile default behavior (remember, you inheritedthis from class Object) isthat each objecl will gel aunique number(most versions ofJava assign ahashcode based on the objecfsmemory address on the heap, so no two objects will have the samehashcode).Ifyou want toknow iftwo references are really referring tothe sameobject. use the == operator. which (remember) compares the bits inthe variables. Ifboth references point tothe same object. the bits willbe Identical.If two objects foo and bar areequal, foo.equa's(bar' must be'rue, and both foo and bar mustreturn the same value fromhashCode(J. For a Set to treattwo objects as duplicates, youmust override the hashCodeOand equals() methods inheritedfrom class Object, so that youcan make two different objectsbe viewed as equal.Songif (faa -- bar) {II both references are referringII to the same object on the heap). Object equalityTwo references, twoobjects onthe heap, butthe objects are considered meaningfully equivalentIfyou want to treat two different Song objects as equal (forexample ifyou decided thaI two Songs are the same if they havematching title variables), you must override both the hashCodeOand equalsO methods inherited from class ObjecLAs we said above,ifyou don Yoverride hashCodeO, the defauhbehavior (from Object) is to give each object aunique hashcodevalue. So you must override hashCodeO to be sure that twoequivalent objects return tile same hashcode. But you must alsooverride equalsO so that ifyou call non either object. passing inthe other object, always returns tnn.if (foo.equa18(bar) &&Songfoo.bashCode() .. bar.hashCode(»)II both references are referring to either aII a single object , or to two objects that are equal560 chapter 16


collections with genericsHow aHashSet checks for duplicates: hashCode() at'd equals()When you put an object into a Hashset, it uses theobject's hashcode value to determine where to putthe object in the Set. But it also compares the object'shashcode to the hashcode ofall the other objects inthe Hash Set, and ifthere's no matching hashcode,the HashSet assumes that this new object is not aduplicate.In other words, if the hashcodes are different, theHashSet assumes there's no way the objects can beequal!So you must override hashCode0 to make sure theobjects have the same value.But two objects with the same hashCodeO might notbe equal (more on this on the next page). so iftheHashSet finds a matching hashcode for two objectsoneyou're inserting and one already in the set-theHashSet will then call ooe of the object's equalsr)methods to see if these hashcode-matched objectsreally are equal.And if they're equal, the HashSet knows that theobject you're attempting to add is a duplicate ofsomething in the Set, so the add doesn't happen.You don't get an exception, but the HashSer's add 0method returns a boolean to tell you (ifyou care)whether the new object was added. So ifthe addOmethod returns false, you know the new object was aduplicate ofsomething already in the set,I need to knowif your hashcodevalues are the same.Your hashcodesare the some, but oreyou REALLY equal?eqUaJs( bar)you are here ~ 561


overriding hashCodeO and equalst)The So.,g class with overridde.,hashCodeU a.,d equals()class Song impleme n t sSex-i og t i d e ;String artist ;St.ri ng rating;String bpm;Cornp e r eb Le-cSonq> {. t.h t. Btl, is a S-\:.vincypublic boolean equals (Object aSong) ( The qR~AT neWS IS a -Jd, n eQl>d\~OL . \la~e ell' O~t.Y""IO \Song s :: (Song) aSong i el\'lei S't.... \,,~s 'II to do is aslt. onereturn getTitle () .equals (s . getTitie () ) il;;--' ",ct,hod. ,S:' all 'H, ~~t.t. ot.heY ~n~' ~ ·btl,·title it It s t.'\"


collections with genericsO tbere1EU"er\l? 0umo ~uesfj9n8Q: How come hashcodes can be the sameeven Ifobjects aren't equal7A..: Hash5ets use hashcodes to store the elementsin a way that makes it much faster to access.If you try to find an object in an ArrayList by givingthe ArrayList a copy of the object (as opposed toan index value), the ArrayList has to start searchIngfrom the beginning, looking at each element inthe list to see if it matches. But a Hash5et can findan object much more quickly, because it uses thehashcode as a kind of label on the "bucket''whereIt stored the element. So If you say, "I want youto find an object in the set that's exactly like thisone..." the Hash5et gets the hashcode value fromthe copy of t he Song you give it (say, 742), andthen the HashSet says, MOh, I know exactly wherethe object with hashcode 11742 is stored ...: and itgoes right to the #742 bucket.This isn't the whole story you get in a computerscience class,but it 's enough for you to use Hash­Sets effectively. In reality, developing a good hashcodealgorithm is the subject of many a PhD thesis,and more than we want to cover In this book .The point Is that hashcodes can be the samewithout necessarily guaranteeing that the objectsare equal, because the -hashing algorithm" used Inthe hashCode() method might happen to returnthe same value for multiple objects.And yes,thatmeans that multiple objects would all/and in thesame bucket In the HashSet (because each bucketrepresents a single hashcode value), but that 's notthe end of the world. It might mean that the Hash­Set is Just a little less efficient (or that it's filledwith an extremely large number of elements), butif the HashSet finds more than one object in thesame hashcode bucket, the HashSet will simplyuse the equalsO method to see If there's a perfectmatch . In other words, hashcode values are sometimesused to narrow down the search,but to findthe one exact match, the HashSet still has to takeall the objects in that one bucket (the bucket forall objects with the same hashcode) and then callequalsO on them to see if the object it's looking foris In that bucket.yo u are here ~ 563


TreeSets and sortingAt1d ifwe wat1t the set to staysorted, we've got TreeSet-TreeSet is similar to HashSet in that it prevents duplicates. But it also keeps the list sorted. Itworksjust like the sortt) method in that if you make a TreeSet using the set's no-arg constructor, theTreeSet uses each object's compareToO method for the sort. But you have the option of passinga Comparator to the TreeSet constructor, to have the TreeSet use that instead. The downside toTreeSet is that if you don't needsorting, you're still paying for it with a small performance hit. Butyou'll probably find that the hit is almost impossible to notice for most apps.import java . ut il. * ;impo r t j ava . io . *;public class JukeboxS {Arra yList songListi nt val ;ne w Ar rayLi s t () ;publ i c s t a t i c vo i d main (St r ing [ ] a r gs ) {new Jukebox8 () . go ();L' L ad ~ \tashSet.L ' L - TYeeSe" IYlSU; +.0p ublic void go () { IYlstaYl-i,au; a T eSet tOYlstylOt I YgetSongs () ; Ca\\iYl~ the Ylo-a;? Y\ he SoYlC?J o'ojett sSystem.out.print l n (s ongL i s t) ; ( WleaYlS the;)tWl:th~e ~OY the soYt;.Col l e c t i ons . s o r t (songList) ; t.OWIyayeT L_ )J ' a Co",yClYClW Y 'System. out . pr intl n (songList) ;t.O"'\d halle yClsselA IYITreeSet songSet = new TreeSet(); (WesongSet.addA11(songList);~Sys t.em, out .println (songSet ) ; ~e 'al'l aAdd all the SOI'l~s .froll\ the l+ashSetlAS l h~ ~d~ ,110. (Or we 'olAld have added t heSOI'l~S Il'Id 1v1d"'1l1y lASil'\~ sOI'\~et.add() ' lAStthe way we added SOI'l~S t;, the Arra~Li st.)voi d ge t Songs () {try {File file = new Fi le (" Song ListMore.txt ") ;Buffer e dRea de r r e ade r = new Buf fere dRea de r (ne w FileRe ade r (file»;String l i ne = null ;whi l e ( (li ne= r e a der.readLi ne (» != null) {addSong (line) ;c a t ch(Exc ept i on ex ) {e x . pr i nt St a c kTr a c e () ;vo i d a ddSong (String line ToPa rse ) {String[ ] tokens = lineToPars e . split (" /" ) ;Song nextSong = new Son g (tokens[ O] , t oke ns [l ], toke ns [2] , t ok ens [3 ] ) ;s on gList . a dd (nextSong ) ;


collections with genericsWhat you MUSf kttow about freeSet. ..TreeSet looks easy, but make sure you really understand what you need todo to use it. We thought it was so important that we made it an exercise soyou'd have to think about it. Do NOT turn the page until you've done this.We mean it.V your pencilLook at this code.ReadIt carefully, thenanswer the questionsbelow. (Note: thereare no syntax errorsIn this code.)import java.util.-;public class TestTree {public static void main (String[] arqs) (new TestTree() .go():public void go() {Book bi = new Book ("Bow cats Work") ;Book b2 new Book ("Remix your Body") ;Book b3 = new Book("Finding Emo");TreeSet tree = new TreeSet() ;tree . add(hl) ;tree . add (b2) ;tree. add (1:13) :Systam.out.println(tree):class Book (String title;public Book(String t) {title = t;1).What Is the result when you compile this code?2). If It compiles, what Is the result when you run the TestTree class73).lf there is a problem (either compile-time or runtime) with this code, how would you fix It7you are here ~ 565


how TreeSets sortfreeSet elettte.,ts MUSf be cotttparableTre eSet can't read the programmer's mind to figure out how theobject's should be sorted. You have to tell the TreeSet how.To use a TreeSet, one of thesethings must be true:)- The elements inthe list must be of a type thatimplements ComparableThe Book class on the previouspage didn't implement Comparable, so itwouldn't work atruntime. Think about it, thepoor TreeSet's sole purpose in life istokeepyour elements sorted, and once again-ithadno idea how to sort Book objects! Itdoesn't failatcompile-time, because the TreeSet addOmethod doesn't take a Comparable type,TheTreeSet addO method takes whatever typeyou used when you created the TreeSet. Inother words, ifyou say new TreeSetOthe addO method isessentially add{Book). Andthere's no requirement that the Book classimplement Comparable! But itfails atruntimewhen you add the second element tothe set.That's the first time the set tries to call one ofthe object's compareToO methods and ... can't.OR)- You use the TreeSet'soverloaded constructorthat takes a ComparatorTreeSet works a lotlike the sortOmethod-you have a choice ofusing theelement'scompareToO method, assumingthe element type implemented theComparable interface, OR you can usea custom Comparator that knows howtosort the elements in the set. To use acustom Comparator, you call the TreeSetconstructor that takes a Comparator.c lass Book implements ComparableString title;publi c Book(String t ) {t itle = t ;}public int compareTo(Object b)Book book = (Book) b;return (title.compareTo(book.title»;public class BookCompare implements Comparator{public int compare(Book one, Book two) {return (one.title.compareTo(two.title» ;clas s Te s t {public void go ( ) {Book b l new Book("How Cats Work") ;Boo k b 2 = ne w Book ("Remix your Body" };Boo k b 3 = new Book("Fi ndi ng Emo");BookCompare bCompare = new BookCompare();TreeSet tree = new TreeSet(bCompare);tree . add(new Book( "How Cats Work" ) ;tree . add(new Book("Fi n ding Emo");t r e e . a d d (new Boo k ("Remix your Body" ) ;System.out.pri ntl n(tree) ;566 chaptert fl


We~ve See" Lists and Sets~ "OW we~11 use a Mapcollections with genericsLists and Sets are great, but sometimes a Map is the best collection (nor Collectionwith a capital "Cn-remember that Maps are part ofJava collections but they don'timplement the Collection interface).Imagine you want a collection that acts like a property list, where you give it a nameand it gives you back the value associated with that name. Although keys will often beStrings, they can be any Java object (or, through autoboxing, a primitive).MapEach element in a Map is actuallyTWO objects-a !!ey and a value.You can have duplicate values, butNOT duplicate keys.Map exampleimport java.util.~;pUblic class Te stMappublic s t at i c void main(S t r i ng [ a r gs ) {BashMap scores = new Ba.ahMap0 ;scores.put ("Kathy" / 42); A-- Use Plot() j'f>$~Cld 0+ ddO rP t ( " B t" 343)·"""" -L 1_1. Cl J Clnd now o-tscores.l.Olor1eU er, , 11; WI


generic typesFit1all't back to get1ericsRemember earlier in the chapter we talked about how methodsthat take arguments with generic types can be ... weird. And wemean weird In the polymorphic sense. If things start to feelstrange here.just keep going-It takes a few pages to really tellthe whole story.We'll start with a reminder on how arrayarguments work,polymorphically, and then look at doing the same thing withgeneric lists. The code below compiles and runs without errors:Here's how It works with regular arrays:import java.util .*;If a method argument is an arrayof Animals, it will also take anarray of any Animal subtype.In other words, if a method isdeclared as:void loo(AnimalU a) { }Assuming Dog extends Animal,you are free to call both:loo(anAnimalArray);foo(aDogArraY)ipUblic class TestGenericsl (public static void main (String(] args)new TestGenericsl() .go () ;public void got) {Animal[] animals ~ (new Dog() I new Cat(), new Dog()};Dog[] dogs: (new Dog(), new Dog(), new Dog()};~takeAnimals (animals) ;D~tlat'"e ,a"d tl'"~t.e a D~ attay,takeAnimals (dogs) ;


collections with genericsUsing polYtMorphic argulMenfs at'd genericsSo we saw how the whole thing worked with arrays, but will it workthe same way when we switch from an array to an ArrayList? Soundsreasonable, doesn't it?First, let's try it with only the Animal Arrayl.ist. We madejust a fewchanges to the go 0 method:Passing In just ArrayListpublic void gel) tArrayList animals = new ArrayList () janima ls.add(new Dog());ani mal s. add (new Cat (»); ~ We hdve t.o add Ol'\e af. d ti ....e sinte theyc'sanimals. add (new Dog () ) ;ShoYUkt S'ft'Ul)( like thet"c is .for drTay lY~or..takeAnimals (animals) ;


polymorphism and generics~ut will it work with ArrayList


collections with genericsAnd rm supposed to be OK with this? Thattotally screws my animal simulation where theveterinary program takes a list of any type ofanimal. so that a dog kennel can send a list of dogs,and a cat kennel can send a list of cats... nowyou're saying I can't do that if I use collectionsinstead of arrays?What could happet1 if it were allowed ...Imagine the compiler let yOIl get away with that, It let you pass anArrayList


arrays vs, ArrayUslsWait a minute... if this is why they won't Ie.tyou pass a Dog ArrayList into a method thattakes an Animal ArrayList-to stop you frompossibly putting a Cat in what was actually a Dog list.then why does it work with arrays? Don't you havethe same problem with arraysl Can't you still adda Cat object to a Dog[) ?Array types are checked again at... runtime, but collection type checkshappen only when you compile-Let 's say you doadd a Cat to an array declared as Dog[l (an array thatwas passed into a method argument declared as Animal[], which is aperfectly legal assignment for arrays) .public void got) {Dog[] dogs: {new Dog() ,new Dog(). new Dog()}:takaAnima1s(d~public void takeAniJDals (Animal [1 animals) (animals [0]= new cat();~ W~ pvt. a PI(W Celt. il'lto d D~ arra~. Thetc,..piley allowed it, beta\l1( it kl'lows thatIt compiles, but when we run it:'t01A ",i~ht. have passed a Cdt. an"ely cfr Al'Iill'lalarra't to the ,..et.hod, so to th~ to",pile\'" itwas possible that. -Chis was O~.Whew! At. leost theJVNl stopftd it.572 chapter 16


Wouldn't it be dreamy if there werea way to still use polymorphic collectiontypes as method arguments, so that myveterinary program could take Dog listsand Cat Iist$? That way I could loop throughthe lists and call their immunizeO method,but it would still have to be safe so that youcouldn't add a Cat in to the Dog list. But Iguess that's just a fantasy...


generic wildcardsWildcards to the rescueIt looks unusual, but there is a way to create a method argument thatcan accept an ArrayList ofany Animal subtype. The simplest way is touse a wildcard-added to theJava language explicitly for this reason.public void takeAnirnals (ArrayLiot in your declaration, the compiler won 't letyou do anything that adds to the listl


collections with genericsAlternate syntax for doing the salMe thingYou probably remember that when we looked at the sortf) method,it used a generic type, but with an unusual format where the typeparameter was declared before the return type. It'sjust a different wayofdeclaring the type parameter, but the results are the same:This:public void takeThing(ArrayList list)Does the same thing as this:public void takeThing(ArrayList


e the complier.exerciseBE the ~omri1er,advan~eJYour job Is to play complier and determine which ofthese statements would compile. But some of thlscode wasn't covered in the chapter, so you need towork out the answers based on what you DID learn,applying the rrules" to these new situations. Insome cases, you might have to guess,but thepoint is to come up with a reasonable answerbased on what you know so far.(Note: assume that this code is within a legal classandmethod.)Compiles?[JArrayList dogsl :new ArrayList()io ArrayList animalsl = new ArrayList


collectlons with genericsimport java.util.*;public class SortMountains {LinkedList( Mountain> mtn new LinkedList(Mountain> ();class NarneCompare Implements Comparator {public lnt compare(Mountain one, Mountain two) {return one.name.compareTo(two.name):&lUfion 1;tl the ~evergeEngineer" sh.arren ~reise,}class BeightCompare Implements Comparator {public int compare(Mountain one, Mountain two) {return (two.height - one. height) ;}}public static void main(String [)new SortHountain().go():}public void go() {mtn.add(new Mountain(ULongs U, 14255»:mtn.add(new Mountain(UElbert'", 14433);mtn.add(new Mountain(UMaroon u , 14156»;mtn.add(new Mountain(UCastle U , 14265»:}System.out.print1n(Uas entered:\n'" + mtn);NarneCompare nc = new NarneCompare();Collectlons.sort(mtn. nc).System.out.println(Uby name:\n'" + mtn);HeightCompare hc = new HeightCompare()iCollectlons.sort(mtn, he);Systern.out.prlnt1n(Uby height:\n Hargs)~( D"\c! 'to\>. " '"~ ~,;.~" I;," ;,"of)l.t "na" e ;)");~ D~C~NDIN~ .se~lIC>l.t? "+ mtn);::lass Mountain {String name:Int height;Mountaln(String n, Int h) {name = n;height = hi}public String toString( ) {return name + .. .. + height;}Output:FlIe Edit Window Hel 1l1lsOne'sFor8ob'l;java Sortl'buntainsas entered:[Longs 14255, Elbert 14433. Maroon 14156, Castle 14265)by nan'e:[Castle 14265, Elbert 14433, Longs 14255, Maroon 14156]by height:(Elbert 14433, Castle 14265, Longs 14255, Maroon 14156)you are here. 577


f111-in-the-blank solutionPossible Answers:Comparator,Comparable,compareTo( )Jcompare( ),yes,noGiven the following compilable statement:Collections.sort(myArrayList);L What must the class of the objects stared in myArrayList implement?Comparable2. What method must the class of the objects stored in myArrayList implement? compareTo( )3. Can the class of the objects stored in myArrayList implement bothComparator AND Comparable?yes---"------Given the following cornpilable statement:Collections.sort(myArrayList, myCompare) i4. Can the class ofthe objects stored in myArrayList implement Comparable?---'V'-e_S _5. Can the class of the objects stored in myArrayLis t implement Camparator?--'y'-e5 _6. Must the class of the objects stored in myArrayLis t implement Comparable? no- ------7. Must the class of the objects stored in myArrayList implement Compa r a t.o rj', ---!..lnox- _8. What must the class of the myCompare object implement?9. What method must the class of the myCompare object implement?Comporatorcomparee)578 chapter 16


collections with genericsCompiles?[JArrayList dogsl = new ArrayList();o ArrayList anim&ld ::: new ArrayList () ;)if List list :::new ArrayList () jo ArrayList dogs ::: new ArrayList () ;o ArrayList animals = dogs;J!I List dogList = dogs;~ArraYListobjects = new ArrayList();~ List ObjList = objects;o ArrayList objs = new ArrayList() ;you are here ~ 579


17 package, jars and deploymentRelease Your CodeIt's time to let go. You wrote your code. You tested your code.You refined your code.You told everyone you know that if you never saw a line of code again, that'd be fine. But in theend, you've created a work of art. The thing actually runsl But now what? How do you give It toend users? What exactly do you give to end users? What if you don't even know who your endusers are? In these final two chapters, we'll explore how to organize, package, and deploy yourJava code.We'll look at local, semi-local, and remote deployment options Including executablejars, JavaWeb Start, RMI, and Servlets.ln this chapter, we'll spend most of our time on organizingand packaging your code-things you'll need to know regardless of your ultimate deploymentchoice. In the final chapter, we'll finish with one of the coolest things you can do In Java. Relax.Releasing your code Is not saying goodbye. There's always maintenance...this Is a new ch apter 581


Java deploymentPeployi"Q your applieatio"What exactly is a Java application? In other words,once you're done with development, what is it that youdeliver? Chances are, your end-users don't have a systemidentical to yours. More importantly, they don't have yourapplication. So now it's time to get your program in shapefor deployment into The Outside World. In this chapter,we'll look at local deployments, including ExecutableJarsand the part-local/'part-remote technology calledjava WebStart. In the next chapter, we'll look at the more remotedeployment options, including RMI and Servlets,ExecutableJarDeployment options100% Local Combination 100% RemoteCD LocalThe entire application runs on theend-user's computer, as a stand-alone,probably GU!, program, deployed asan executable JAR (we'll look at JARin a few pages.)I1i'\~Combination of local and remoteThe application is distributed with aclient portion running on the user'slocal system, connected to a serverwhere other parts of the applicationare running.@ RemoteThe entire Java application runs on aserver system, with the client accessingthe system through some non-Javameans, probably a web browser.AJava program is abunchof classes. That's theoutput of your development.The real 'f,Uestion is whatto do with those classeswhen you're done.What arethe advantages anddisadvantages of delivering yourJava program asa local,standaloneapplicationrunning onthe end-user's computer?What arethe advantages anddisadvantages of delivering yourJava program as web-basedsystem where the userInteractswith a web browser, and theJava code runs as servlets on theserver?But before we really get into the whole deployment thing,let's take a step back and look at what bappens when you'vefinished programming your app and you simply want to pullout the class files to give them to an end-user. What's reallyin that working directory?682 chapter 17


package, jars and deploymentItMagitte this scettario...Bob's happily at work on the final pieces of his cool newJava program. After weeks of being in the "I'mjustone-compile-away"mode, this time he's reallydone. The program is a fairly sophisticatedCUI app. but since the bulk ofit is Swingcode. he's made only nine classes of hisown.At last, it's time to deliver the program to theclient. He figures all he has to do is copy thenine class files. since the client already hastheJava API installed. He starts by doing an1s on the directory where all his files are...eoWhoa! Something strange has happened. Instead of 18files (nine source code files and nine compiled classfiles), he sees 31 files, many ofwhich have very strangeo names like:Account$FileListener.classChart$SaveListener.classand on it goes. He had completely forgottenthat the compiler has to generate class filesfor all those inner class CUI event listenershe made. and that's what all the strangelynamedclasses are.Now he has to carefully extract all the classfiles he needs. Ifhe leaves even one of them OUI,his program won't work. But it's tricky since hedoesn't want to accidentally send the clientone of his source code files, yet everything isin the same directory in one big mess.you are here ~ 583


organizing your classesSeparate source code at'd class filesA single directory with a pile ofsource code and class files is amess. It turns out, Bob should have been organizing his filesfrom the beginning, keeping the source code and compiledcode separate. In other words, making sure his compiled classfiles didn 't land in the same directory as his source code.1M key is a combination ofdirectury stTudure organizatUm and the-d compiler option.But r thought I didn't havea choice about putting the clossfiles in with the source files.When you compile,they just gothere. so what do I do?There are dozens ofways you can organize your files, and yourcompany might have a specific waythey want you to do it. Werecommend an organizational scheme that's become almoststandard. though.With this scheme, you create a project directory, and insidethat you create a directory called source and a directory calledclasses. You start by saving your source code (java files) intothe source directory. Then the trick is to compile your codein such a way that the output (the .class files) ends up in theclassesdirectory.And there's a nice compiler flag, -d, that lets you do that.Compiling with the -d (directory) flag%cd Mypr~je~t/s~urce%javac -d .. /classes)'\Running your code~cdtells -tht lo"'pi/tr to lot. thtlo"'piled lode (llats. ~, ). to th " .oFi est;. , t tla1S.ts: di~ettoryab Ohe dired:A'ry lop clndbellk dow" a6 'i (' I.:JG n 1'ro", OlelLlrrent w(l\"k;l'I~ dil'tttory.By using the -d flag, youget to decide which directory thecompiled code lands in, rather than accepting the default of /rclass files landing in the same directory as the source code. rTo compile all the Java files in the source directory, use: til YOWl' ....ai"Oroo.. htt't •OIl"%javac -d .. /c1asses *. java ::~;~:ooo'oMyProject/classes'\.%j ava Mini rlOlI ~Ol.lr pr03r-


Put your Java itt aJAR-package, jars and deploymentAJAR file is a Java ARchive . It's based on the pkzip file format, and it lets you bundleall your classes so that instead ofpresenting your client with 28 class files, you handover just a singleJAR file. lfyou're familiar with the tar command on UNIX, you'llrecognize thejar tool commands. (Note: when we sayJAR in all caps, we're referringto the archive jilt. When we use lowercase, we're referring to the ja-r toolyou use tocreateJAR files.)The question is, what does the client Mwith theJAR? How do you get it to run?You make the JAR executable.An executableJAR means the end-user doesn't have to pull the class files out beforerunning the program. The user can run the app while the class files are still in theJAR. The trick is to create a manifest file, that goes in theJAR and holds informationabout the files in theJAR. To make aJAR executable. the manifest must tell theJVMwhuh. class has the main() method!Making an executable JAR•Make sure all of your class files are inthe classes directoryWe're going to refine this in a few pages, butfor now. keep all your class files sitting in thedirectory named 'classes'.•Create a manifest.txt file that stateswhich class has the malnO methodMake Q text file named manifest.txt that has aone line:dO\'l't ,,~t t\lt .t.lassMain-Class: MyApp 0(- on tht ",dPress the return key after typing the Main­Class line, or your manifest may not workcorrectly. Put the manifest file into the "closses"directory.manifesLtxtMyApp.dass•Run the Jar tool to create a JAR filethat contains everything in the classesdirectory I plus the manifest.%cd MiniProject/class8s'jar -cvmf .manifest.txt appl.jar *.classOR'jar -cvmf manifest.txt appl.jar MyApp.classCIflPl .JarmanifesLtxtno SO\O..tt.toOt Cja~d)in the "JARyou are here) 585


executable JAR100% Local Combination 100% RemoteRUt1t1it1g (executi.,g) the JARJaVli (thejVM) is capable of loading a class from aJAR, and callingthe main () method of that class. In fact, the entire application canstayin theJAR Once the ball is rolling (i.e., the main () methodstarts running), theJVM doesn't care where your classes comefrom, as long as it can find them. And one of the places thejVMlooks is within any JAR tiles in the classpath. U it can seeaJAR, theJVM will look in th3tJAR when it needs to find and load a class.Most 100% local Javaarrs are deployed asexecutable JAR files.r0 :~(:':r-':"-' :_:~..,.::l"'l l. ' . ~ -"appl .jarDepending on how your operating system is configured, youmight even be able to simply double-click theJAR file to launchit. This works on most flavors of Windows, and Mac OS X. Youcan usually make this happen by selecting the JAR and tellingthe OS to "Open with...~ (or whatever the equivalent is on youroperating system) .---------- Dffin~~estiQnsQ: Why can't IJust JAR up an entire directory?A.: The JVM looks inside the JARand expects to findwhat It needs right there. It won't go digging Into otherdirectories, unless the class Is part of a package, and eventhen the JVM looks only In the directories that match thepackage statement7Q: What did you jU5t say?A:You can't put your class flies Into some arbitrarydirectory and JARthem up that way . But If your classesbelong to packages, you can JARup the entire packagedirectory structure. In fact, you must. We'll explain all this onthe next page, so you can relax.586 chapter 17


Put your classes itt packages!So you've written some nicely reusable class files, and you 'veposted them in your internal development library for otherprognmmers to use. While basking in the glow ofhavingjust delivered some of the (in your humble opinion) bestexamples of00 ever conceived. you get a phone call. Afrantic one. Two ofyour classes have the same name asthe classes Fredjust delivered to the library. And all hell isbreaking loose out there, as naming collisions and ambiguitiesbring development to its knees.And all because you didn't use packages! Well, you did usepackages, in the sense of using classes in the Java API that are,of course, in packages. But you didn't put your own classesinto packages, and in the Real World, that's Really Bad.We're going to modify the organizational structure from theprevious pages.just a little, to put classes into a package. andto JAR the entire package. Pay very close attention to thesubtle and picky details. Even the tiniest deviation can stopyour code from compiling and/or running.Packages prevettf class ttattte co"fllctsAlthough packages aren'tjust for preventing name collisions,that's a key feature. You might write a class named Customerand a class named Account and a class named ShoppingCan.And what do you know, halfofall developers working inenterprise e-comrnerce have probably written classes withthose names. In an 00 world, that's just dangerous. Ifpart ofthe point of00 is to write reusable components, developersneed to be able to piece together components from avariety of sources, and build something new out of them.Your components have to be able to 'play well with others',including those you didn't write or even know about,Remember way back in chapter 6 when we discussed howa package name is like the full name ofa class, technicallyknown as the fully-qualified name. Class Arra yList is reallyjava.utiLArrayList, ]Button is really javax.swingJButton, andSocket is really java.net.Socket. Notice that two of those classes,ArrayList and Socket, both have java as their "first name".In other words. the first pan of their fully-qualified namesis "java". Think of a hierarchy when you think of packagestructures, and organize your classes accordingly.package, jars and deploymentPackage stnJcture of the J QVQ API for:java.textNumberFormatjava.utiI.ArrayListjava.awt.fJowLayoutjava.awt.event.ActionEventjava.net.Socketjavatext~et• / a~NumberFormat uti! /'"AnayUslI '" Socket:~' : I t ~ event~:'~:: \FlowlayoutActionEventWhat does tkls picture look like toyou? Doesn't It look Q whole lot likea directory hlercrc.hyiyou are here ~ 587


package narnlnqPrevettfittg package ttalMe cottflictsPutting your class in a package reduces the chances of namingconflicts with other classes, but what's to stop two programmersfrom coming up with identical pa~kagenames? In other words,what's to stop two programmers, each with a class named Account,from putting the class in a package named shopping.customers?Both classes, in that case, would still have the same name:shopping.customers.AcwuntSun strongly suggests a package naming convention that greatlyreduces that risk-prepend every class with your reverse domainname. Remember, domain names are guaranteed to be unique.TWodifferent guxs can be named Bartholomew Simpson, but rwodifferent domains cannot be named doh.com.pachges can prevent nameconfhcts. but only ifyouchoose araclage namethat's gtlaranteed to heunicrue, The hest way todo that is to preface yourpachges with your reversedomain name.com.headfirstbooks.Book~f' epallc.j~( J\o}",c \.. t..\6~ ,..6""Reverse domain package names588 chapter 17


package, jars and deployment_put your class in a package:se a package name're using com.headflrstjava as ourpie. The class name is PackageExercise,se the fully-qualified name of the class is now:.headfirstjavQ. PackageExercise.You _~!i.t put a classinto a directorystructure that matchesthe package hierarchy.Q package statement in your classbe the first statement in the sourcefile, above any import statements. Thereweonly one package statement per sourcefile, so all classes In Q SOlJrce tile must- the same package. That includes inneres, of course.import javax.swing.*ipublic class PackageExercise {II life-altering code hereSet Up a matching directory structure: - s not enough to say your class is in a package,ler ely putting a package statement incode. Your class isn't truly in a package-jl you put the class in a matching directoryture. So , if the fully-qualified class name. om.hea dfirst java.PackageExercise, youput the PackageExercise source code in atory named neadflrstjaVQ, which must be in..'rectory named com.: - . possible to compile without doing that, butus-it's not worth the other problems'II have. Keep your source code in a directoryt ur e that matches the package structure,. you'll avoid 0 ton of painful headaches down- road.lOUOllOUOlIOIO\ C-o~lelOlOlD)010 10111)\01111\Ol~lal0I~OI(1U1 .0 •PackageExerclse.classcomheacfflrstjavaLorI""l'\l.N ......U, \ _.'".­~ct'-t4,.6


compile and run with packagesCotttpilittg at'd ruttttinQ with packagesWhen your class is in a package, it's a little trickier to compile andrun. The main issue is that both the compiler and]VM have to becapable of f nding your class and all ofthe other classes it uses.For the classes in the core API, that's never a problem.Java alwaysknows where its own stuffis. But for your classes, the solutionof compiling from the same directory where the source files aresimply won't work (or at least not reliably). We guanotee, though,that ifyou follow the structure we describe on this page, you'll besuccessful. There are other ways to do it, but this is the one we'vefound the most reliable and the easiest to stick to.Compiling with the -d (directory) flagsta '" tht ~yt.f diytt~'t! Do NO! ~dJ Oo...m%cd MyProject/source ~ il\J tht. dirtt,1:.t*-y ...,h~t tht. jd~il tIlt IS,%javac%javac.>-d .. /01a8s8surJs tAe loto.pHer it> t t.h.to",piled lode (tlau ll:s) e'~it> .the tI~ dirtt.ky,~he rillhi patkd esfr~ Yes. it k_~To compile all the java files in the com.headfirstjavapackage, use:-d .. /classescam/beadfirstjava/*.javato...piles ev(;'ry /' (.file ' 1. · . SOlorte .\Ava>'I' UlIS d,ret.U>ry .r:Running your code com com%cd MyProject/classes%java cam.headfirstjava.PackaqeExeroiseheadf1f$f/8heacfflIOIlOl.10 no J'0110001 10001 01PackagaExercl8&.classPackageExe~S8~ava590 chapter 17


fhe ...dflag is eve" cooler tha" we saidCompiling with the -d £lag is wonderful because not only does itlet you send your compiled class files into a directory other thanthe one where the source file is, but it also knows to pllt the classinto the correct directory structure for the package the class is in.But it gets even better!Let's say that you have a nicedirectory structure all set up for yoursource code. But you haven't setup a matching directory structurefor your classes directory. Not aproblem! Compiling with-d tells the compiler to notjust put your classes intocorrect directory tree, but tothe directories if they don'tThe -d flag tells the complier,"Put the class into Its packagedirectory structure, using theclass specKled after the -d asthe root directory. But... If thedirectories aren't there, createthem first and then put the classIn the right place!"com'ldPackageExercrse.javapackage, jars and deployment~: Itried to cd Into thedirectory where my main classwas, but now the JVM says It can'tfind my c1assl But It's rightTHEREIn the current directorylA: Once your class is in apackage, you can't call it by its'short' name. You MUST specify,at the command-line, the fullyqualifiedname of the class whosemainO method you want to run.But since the fully-qualified nameIncludes the package structure,Java insists that the class be in amatching directory structure. So ifat the command-line you say:%java com.foo.Bookthe JVM will look in its currentdi rectory (and the rest of Itsclasspath), for a directory named"corn:It will not look for a classnamed Boole. until It has founda directory nomed"com" with adirectory Inside named ufoo': On Iythen will the JVM accept that itsfound the correct Book class. If itfinds a Book class anywhere else,it assumes the class isn't in theright structure, even if it isl TheJVM won't for example, look backup the directory tree to saY,"Oh,1can see that above us is a directorynamed com, so this must be theright package..."you are here ~ 591


JARs and packagesMakit1g at1 executable JAR with packagesWhen your class is in a package, the package directory structuremust be inside theJAR! You can'tjust pop your classes in theJAR the waywe did pre-packages. And you must be sure that youdon't include any other directories above your package. Thefirst directory of your package (usually com) must be the firstdirectory within the JAR! Ifyou were to accidentally include thedirectory above the package (e.g. the "classes" directory), theJARwouldn't work correctly.Making an executable ,JAR•Make sure all of your class files arewithin the correct package structure,under the classes directory.• Create a manifest.txt file that stateswhich class has the mainO method,and be sure to use the fully-qualifiedclass namelMake 0 text file named manifest.txt that hasasingle line:Main-Class: com.headfirstjava.PackaqaExercisetoll0'10UII 'IhelldtIn:tfM• .... ·· ~ll:",0\·,umanl1ast.lxtPut the manifest tile into the classes directory•Run the Jar tool to create aJAR filethat contains the package directoriesplus the manifestThe only thing you need to include is the 'com'directory, and the entire package (and all classes) t.~ is ~t, I_Iwill go into the JAR. AI\ '1~ ~"~...oAI1 ~d "Iou IIt.0fP' o,y totV'" I'. .t. 1'Sed MyProject/claasea .t ~et. tvt,......f\:),i\l,~ '" I. pcdcEx.jor ........-%jar -cvm£ manifest.txt packEx.jar comPaclalgeExerclM.dua592 chapter 17


package, jars and deploymentSo where did the tMat1ifest file go?Why don't we look inside theJAR and find out? From thecommand-line, thejar tool can do more thanjust create and run aJAR You can extract the contents ofaJAR (just like 'unzipping' or'unrarring').Imagine you've put the packExjar into a directory named Skyler;jar commands for listing and extractingG) List the contents of aJAR% jarMcrA./NF I'.- 'com ~_Iheadflrstjavl@ Extract the contents of Q% cd Skyler% jar -xf packEx.jarJAR (l.e. unJar)MANIFEST.MFMANIFEST.MFIO\ UlLO lib '~ \I t:l00\ 1~00\ 01PackageExerclse.c1assMETA-INF stands for 'metainformation'. The jar tool createsthe META-INF directory aswell as the MANIFEST.MF file.Tt also takes the contents ofyour manifest file, and puts itinto the MANIFEST.MF file. So,your manifest file doesn't go intothe JAR, but the contents of itare put into the 'real' manifest(MANIFEST.MF).yo u are here ~ 593


organizing your classesGiven the package/directory structure In thispicture,figure out what you should type at thecommand-line to compile, run, create a JAR, andexecute a JAR. Assume we're using the standardwhere the package dIrectory structure starts justbelow source and classes.In other words, the sourceand classes directories are not part of the package.manlfesttxtCompile:%cd source%javac_COWlCOWl1CIUOlO UO'J '• U •_lO.., ..Foot.classFoof.javaRun:%cd%java__C~QteQ JAR%cd_Bonus question:What's wrong with the package name?,-----------------Execute aJAR'cd_%_---------------594 chapter 17


package, jars and deploymentQ.: What happens If you tryto run an uec:utable JAR. andthe end-user doesn't have JavaInstalled?A: Nothing will run, sincewithout a JVM,Java code can'trun.The end-user must have JavaInstalled.Q: How can I g@t Javainstalled on the end-user'smachine?Ideally, you can create a customInstaller and distribute It alongwith your application. Severalcompanies offer Installer programsranging from simple toext remely powerluI.An InstaIlerprogram could, for example, detectwhether or not the end-userhas an approproprlate versionof Java Installed, and If not,Install and conflgure Java beforeInstalling your application.Instalishleld,lnstaIlAnywhere,and DeployDlrector all offer JavaInstaller solutions.Another cool thing about someof the Installer programs Is thatyou can even make a deploymentCD-ROM that Includesinstallers for all major Javaplatforms, so...one CD to rulethem all. If the user's running onSolarls, for example, the Solarlsverslo n of Java is insta lied. OnWindows, the Windows, verslon,etc. If you have the budget,this is by far the easiest way foryour end-users to get the rightversion of Java Installed andconflgured.• Organize your project so that your source code and class files are not inthe same directory.• Astandard organization structure is to create a project directory, and thenput asource directory and aclasses directory inside the project directory.• Organizing your classes into packages prevents naming collisions withother classes. if you prepend your reverse domain name on to the front ofa class name.• To put aclass inapackage, put apackage statement atthe top ofthesource code file, before any import statements:pac:kage com. wicJcedlysmart;• To be inapackage, aclass must be in a directory structure thet exactlymatches thepackage structure. For aclass, com.wlckedlysmarlFoo.the Foo class must be in adirectory named wickedlysmart. which Is in adirectory named com.• To make your compiled dassland inthe correct package directorystructure under the classes directory, use the -d compiler flag:% cd source%javac -d .. / claues aom/wicJcedlysmart/l1'oo. java• To run your code, cdto the classes directory, and give the fully-quallfiedname ofyour class:.. cd classes% java com.wickedlyamart.l1'oo• You can bundle your classes into JAR (Java ARchive) flies. JAR isbasedon the pkzip fonnal.• You can make an executable JAR file byputting amanifest Into the JARthat states which class has the malnO method. To create amanifest file,make a text file with an entry like the following (for example):Main-Class: com.wicJcedlysmart.FOO• Be sure you hitthe return key atter typing the Main-elass line, oryourmanifest file may not work.• To create a JAR file. type:jar -cvfm manifest. txt MyJar. jar com• The entire package directory structure (and only the directories matchingthe package) must be Immediately Inside the JAR file.• To run an executable JAR file, type:java -jar MyJar . jaryou are here. 595


wouldn't it be dreamy...596 chapler 17


ExecutableJar100% Local--- Web StartJava Web Start100% RemoteWith Java Web Start (JWS), your application is launched for thefirst time from a Web browser (get it? Web Starf) but it runs as astand-alone application (well, almost), without the constraints of thebrowser. And once it's downloaded to the end-user's machine (whichhappens the first time the user accesses the browser link that startsthe download), it stays there.Java Web Start is, among other things, a small Java program that liveson the client machine and works much like a browser plug-in (theway, say, Adobe Acrobat Reader opens when your browser gets a .pdffile) . ThisJava program is called the Java Web Start 'helper app',and its key purpose is to manage the downloading, updating, andlaunching (executing) ofyOUTJWS apps,WhenJWS downloads your application (an executableJAR), itinvokes the main0 method for your app. After that, the end-user canlaunch your application directory from theJWS helper app withouthaving to go back through the Web page link.But that's not the best part. The amazing thing aboutJWS is itsability to detect when even a small part ofapplication (say, a singleclass file) has changed on the server, and-without any end-userintervention-download and integrate the updated code.There's still an issue , ofcourse, like how does the end-user getJavaandjava Web Start? They need both-Java to run the app, andJavaWeb Stan (a small Java application itself) to handle retrieving andlaunching the app. But even tluu has been solved. You can set thingsup so that if your end-users don't haveJWS. they can downloadit from Sun. And if they do have JWS, but their version ofJava isout-of-date (because you've specified in yourJWS app that youneed a specific version ofJava), theJava 2 Standard Edition can bedownloaded to the end-user machine.Best ofall, it's simple to use. You can serve up aJWS app much likeany other type ofWeb resource such as a plain old HTML page or aJPEG image. You set up a Web (HTML) page with a link to yourJWSapplication, and you're in business.In the end, yourJWS application isn't much more than anexecutableJAR that end-users can download from the Web.package, jars and deploymentEnd-users launch aJavaWeb Start app by cliclingon a lin1 in a Webpage. But once the aprdownloads. it runs outsidethe browser, justlike anyother stand-alone Javaapplication. Infact, aJava Web Start app is justan executable JAR that'sdistributed over the Web.you are he re ~ 597


Java Web StartHow .Java Web Start worksG) The client clicks on a Web page linkto your JWS application (0 .jnlp file).The Web page linkClic:kWeb br-o'NSt"r-give me MyApp.jnlp"® The Web server (HTTP) gets the. request and sends back a .Jnlp file(this Is NOT the JAR).The .jnlp file is an XML document thatstates the name of the application'sexecutable JAR file,Java Web Start (a small 'helper app'on the client) is started up by thebrowser. The JWS helper app readsthe .jnlp file, and asks the server forthe MyApp.jar file.-give me MyApp.jar"@ The Web server 'serves ' up therequested .jar file.Java Web Start gets the JAR andstarts the oppUcation by calling thespecified malnO method (just like anexecutable JAR).Next time the user wants to run this opp. he canopen the Java Web Start application and fromthere launch your app. without even being online.--598 chap ter 17


The .j"lp filepackage, jars and deploymentTo make aJava Web Start app, you need to Jnlp (Java NetworkLaunch Protocol) file that describes your application. This is thefile theJWS app reads and uses to find yourJAR and launch theapp (by calling theJAR's main0 method), A jnlp file is a simple ,XML document that has several different things you can put in, .~ -t~e 'yoat:but as a minimum, it should look like this: ~ ye ~o~ s~et.l l~e seY"e~ ·, -tal"'s 'II ~ L~~ 'IS O'f\ 'ye v51'f\~, G10ase :\:,a.n- s'\- :t so 'lie 10 \~e (.0 e y'fle S \ot.a\~OS I \" yOV' 'lieJ 'II~eye 'f~\Ii -tnls O'f\ o'J'y "\1,1.0.0. . -tn\S 'fIO~\G,.f ' e -\:.tS-\:."'V'~L .1, ado ytsS L L sey"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'"/ . This ",eanS the lOSer tan Yl/in 'f0l/il'" r . ottl' e~ . ted ~ the internet. -t he lOSer I ~ \n ,~t:~::;~~e a\Atomatit-l/ifdahn~ teahye wont work. This says that YOI/il'" al'l' needs lIel'"sion 1.3 ~ ot Jalla, oY ~reate\".~ne tlatl'le/oiher JAo 0+t:,. eXef·l " 1"; es as w /I 1.L 1. " . 010 tI'Iip'hi hever. SOlltld d . e •


deploying with JWSSteps for making and deployinga Java Web Start appMake an executable JARfor your application.0MyApp.Jar~ Write a .Jnlp file.MyApp.jnlp® Place your JAR and .jnlpfiles on your Web server.@) Add a new mime type to your Web server.application/x-java-jnlp-nleThis causes the server to send the .jnlp file with thecorrect header, so that when the browser receivesthe Jnlp file it knows what it is and knows to startthe JWS helper app.Create Q Web page with a linkto your .jnlp file~ .....I~.....~--:MyJWSApp.hbnl


package, jars and deployment,,.LOOk at the sequence of events below,and 2.pIacethem in the order In which theyoccur In a JWS application.3.__-~--:::;':::-;;;-v!heWeb server sends a JAR\he Web browser starts uptheJWS helper appthe Web server sendstiJe to the browseruser dicks a Web page Itnlileto!he JWS helper apper requests a .jnlpfilefrom the Web serverthe JWS helper app invokesthe JAR's malnO method4.5,6.7.dlim~estJonsQ.: How IsJava Web Start dl~rentfrom an applet1A:Applets can't live outside of a Web browser. An applet isdownloaded from the Web as part of a Web page rather thansimply from a Web page. In other words, to the browser, the appletIsJust like a JPEG or any other resource. The browser uses either aJava plug-In or the browser's own built-In Java (far less commontoday) to run the applet. Applets don't have the same level offunctionality for things such as automatic updating, and they mustalways be launched from the browser. With JWS applications, oncethey're downloaded from the Web, the user doesn't even have tobe usIng a browser to relaunch the application locally. Instead,the user can start up the JWS helper app, and use It to launch thealready-downloaded application again.Q..: What are the security restrictions of JWS1A: JWS apps have several limitations Including beingrestricted from reading and writing to the user's hard drive. But...JWS has Its own API with a special open and savedialog box sothat, with the user's permission, your app can save and read Itsown flies In a speclaI, restricted area of th e user's drive.,--BULlO POINTS ­•Java Web Start technology lets you deploy astand-alone client application from the Web.• Java Web Start includes a 'helper app' that mustbe installed on the client (along with Java).•AJava Web Start (JWS) app has two pieces:an executable JAR and a .jnlp file.• A.jnlp file isa simple XML document thatdescribes your JWS application. It includestags for specifying the name and location oftheJAR, and the name ofthe class with the mainOmethod.• When a browser gets a .jnlp file from the server(because the user clicked on a link tothe .jnlpfile), the browser starts upthe JWS helper app.•The JWS helper app reads the .jnlp file andrequests the executable JAR from the Webserver.• When the JWS gets the JAR, it invokes themainO method (specified in the .jnlp file).you are he re ~ 601


exercise: True or FalseWe explored packaging, deployment, and JWSin this chapter. Your job is to decide whethereach of the following statements is true or false.1. TheJava compiler has a flag, -d, that lets you decide where your .class files should go.2. AJAR is a standard directory where your .class files should reside.3. When creating aJava Archive you must create a file calledjar.mf.4. The supporting file in aJava Archive declares which class has the main() method.5. JAR files must be unzipped before the jVM can use the classes inside.6. At the command line, Java Archives are invoked using the -arch flag.7. Package structures are meaningfully represented using hierarchies.8. Using your company's domain name is not recommended when naming packages.9. Different classes within a source file can belong to different packages.10. When compiling classes in a package, the -p flag is highly recommended.11. When compiling classes in a package, the full name must mirror the directory tree.12. Judicious use of the -d flag can help to assure that there are no typos in your class tree.13. Extracting aJAR with packages will create a directory called meta-info14. Extracting aJAR with packages will create a file called manifest.mf.15. TheJWS helper app always runs in conjunction with a browser.16. JWS applications require a .nlp (Network Launch Protocol) file to work properly.17. AJWS's main method is specified in itsJAR file.602 chapter 17


package, jars and deployment~U1Il1Ilar)'-Or~ss 7-.0Anything in the bookIsfairgame for thisonelAaossDown6.Won'ttravel 26. Mine isunique 1. Pushy widgets 16.Who's allowed 30. 110 cleanup9. Don't split me 27. GUl's target 2.__ of my desire 19. Efficiency expert 31. MUll-nap10. Release-able 29. Java team 3. 'Abandoned'moniker 20. Early exit 34. Trigmethod11. Got the key 30. Factory 4. A chunk 21. Commonwrapper 36. Encaps method12. VOgang 32. Forawhile 5. Math not trlg 23. Yes or no 38. JNLP format15. Flatten 33. Atomic It 8 6. Bebrave 24. Java jackets 39.VB's final17. Encapsulated returner 35. Good asnew 7. Arrangewell 26. Not behavior 40. Java branch18. Shipthis one 37. Pairsevent 8. Swing slang 28. Socket's suite21 . MakeIt so 41.Wheredo I start 11.I/O canals22. I/O sieve 42 A little firewall 13.Organized release25. Diskleaf 14. Not for an instanceyou are here ~ 603


exercise solutions,.2.3.4.5.6.7.the Web server sends a.jnlpfile 10 the browsertheWeb browser starts upthe JWS helper app\ \he NJS helper app requests'\ lheJARfl\eI the Web server sends a JAR ILli/e 10 the JWS helper appIthe JWS helper app Invokes ItheJAR's mal nO methodTrueFalseFalseTrueFalseFalseTrueFalseFalseFalseTrueTrueTrueTrueFalseFalseFalse1. TheJava compiler has a flag, -d, that lets you decide where your .class files should go.2. AJAR is a standard directory where your .class files shouJd reside.3. When creating a Java Archive you must create a file calledjar.mf,4. The supporting file in aJava Archive declares which class has the mainO method.5. JAR files must be unzipped before thejVM can use the classes inside.6. At the command line, Java Archives are invoked using the -arch flag.7. Package structures are meaningfully represented using hierarchies.8. Using your company's domain name is not recommended when naming packages.9. Different classes within a source file can belong to different packages.10. When compiling classes in a package, the -p flag is highly recommended.II. When compiling classes in a package. the full name must mirror the directory tree.12. Judicious use of the -d flag can help to assure that there are no typos in your tree.13. Extracting aJAR with packages will create a directory called meta-inf,14. Extracting aJAR with packages will create a file called manifestmf.15. TheJWS helper app always runs in conjunction with a browser.16. ]WS applications require a .nlp (Network Launch Protocol) file to work properly.17. A]WS's main method is specified in itsJAR file.604 chapter 1 7


~UtIltIlary-Or~55t. Oyou are here ~ 605


18 remote deployment w it h RMIDistributedComputingBeing remote doesn't have to be a bad thing. Sure,things areeasieT whenall the parts of your application are in one place, in one heap, with one JVM to rule them all. Butthat's not always possible. Or desirable. What If your application handles powerful computations,but the end-users are on a wimpy little Java-enabled device? What if your app needs datafrom a database, but for security reasons, only code on your server can access the database?ImagIne a big e-commerce back-end, that has to run within a transaction-management system?Sometimes, part of your app must run on a server, while another part (usually a client) mustrun on a different machine. In this chapter, we'll learn to use Java'samazingly sImple RemoteMethod Invocation (RMI) technology. We'll also take a quick peek at Servlets, Enterprise JavaBeans (EJB) ,and JInl, and look at the ways In wh Ich EJB and JInl depend on RMI.We'll end thebook by writing one of the coolest thi ng s you can make In Java,a universal servicebrowser.th is is a new chapter 807


how many heaps?..RMlapp100% LocalCombinationMethod calls are always betweeKtwo objects OK the sattte heap.So far in this book, every method we've invoked has been onan object running in the same virtual machine as the caller.In other words, the calling object and the callee (the objectwe're invoking the method on) live on the same heap.class Foo {void go ()Bar b = new Bar();b.doStuff() jpublic static void main (String [] args) (Faa f = new Foa()jf .go () ;In most applications, when one objectcalls a method on another, both objectsare on the same heap. In other words,both are running within the same JVM.In the code above, we know that the Foo instancereferenced byfand the Bar object referenced by bareboth on the same heap, run by the sameJVM. Remember,the jVM is responsible for stuffing bits into the referencevariable that represent how togetto an object on theheap.TheJVM always knows where each object is, and how Laget to it. But the JVM Can know about references on onlyits own heap! You can 't, for example, have aJVM runningon one machine knowing about the heap space ofaJVMrunning on a differentmachine. In fact, aJVM running onone machine can't know anything about a differentjVMrunning on the samemachine. It makes no difference iftheJVMs are on the same or different physical machines;it matters only that the twoJVMs are, well, two differentinvocations of the JVM.608 chapte r 18


emote deployment with RMIWhat if you wattt to ittvoke 8 'Method Ottatt object rutttthtg Ott another tH8chitte?We know how to get information from one machine to anotherwithSockets and I/O. We open a Socket connection to anothermachine, and get an Ourputfitream and write some data to it.But what if we actually want to call a method on something runningin another machine... anotherJVM? Of course we could always buildour own protocol, and when you send data to a ServerSocket theserver could parse it, figure out what you meant, do the work, andsend back the result on another stream. What a paia, though. Thinkhow much nicer it would be to just get a reference to the object on ~ ~t.1 lovtSthe other machine, and call a method. yO-.lC"hl, ~I.. ...~n 'b\C)t.o t ...I»'tṇ "V'~ t.O\t.~abo'f\S~......Imagine two computers...IJVM~Little__'--'- ~Big has something Little wants.C~ute-l0~er.---'CJ~r.=a~~~..::::15L-' '--- I CJ l-J C-.l L-J L..J L--o;'I --" l ..\l · ULittle wants to send some data to Big, so that Big can do theheavy ~ruting.Little wants simply to call a method...Bigdouble doCalcUsingDatahase(CalcNumbers numbers)and get Lack the result.But how can Little get a relerence to an object on Big?you are here' 609


two objects, two heapsObject AI rut,.1i.,g 0., Little, wa.,ts to calla tttethod 0., Object ~ ru.,.,it1g Ot1 Jig.The question is, how do we get an object on one machine(which means a different heap/]VM) to call a method onanother machine?doCalcUsi ngDatabase.O~~~Jut you can't do that.Well, not directly anyway. You can't get a reference tosomething on another heap. Ifyou say:Dog d = ???return value~- -~ e-..,,~-.- ...... '- ..-.11 _'--, -,Whatever d is referencing must be in the same heap space asthe code running the statement,But imagine you want to design something that will useSockets and I/O to communicate your intention (a methodinvocation on an object running on another machine), yetstill feel as though you were making a local method call.In other words. you want to cause a method invocation on aremote object (i.e., an object in a heap somewhere else) J butwith code that lets you pretend that you're invoking a methodon a local object. The ease ofa plain old everyday methodcall, but the power of remote method invocation. That's ourgoal.That's what RM1 (Remote Method Invocation) gives you!But let 's step back and imagine how you would design R.i\1I ifyou were doing it yourself. Understanding what you'd have tobuild yourself will help you learn how RMl works .610 chapter 18


emote deployment with RMIA design for remote method callsCreate four things: server, client,server helper, client helper• Create client and server apps. The server app is theremote service that has an object with the methodthat the client wants to invoke.Client heapCreate client and server 'helpers'. They'll handle 011the low-level networking and I/O details so your clientond service can pretend like they're in the same heap.Server heapyou are he re> 611


client and server helpersfhe role of the 'helpers"The 'helpers' are the objects that actually do the communicating.They make it possible for the client to adas though its calling amethod on a local object. In fact, it is. The client calls a method onthe client helper, as if the clienthelper were the actual service. The clienthelper is a frrorjfor theReal Thing.In other words, the client object thinks it's calling a method onthe remote service, because the client helper is pretendingto beth e service objeel. Pretendingto bethe thingwith the met/wd the clientwants 10 call!But the client helper isn't really the remote service. Although theclient helper ruts like it (because it has the same method that theservice is advertising), the client helper doesn't have any oftheactual method logic the client is expecting. Instead, the clienthelper contacts the server, transfers information about the methodcall (e.g., name of the method, arguments, etc.), and waits for areturn from the server.On the server side, the service helper receives the request fromthe client helper (through a Socket connection), unpacks theinformation about the call, and then invokes the real method onthe real service object. So to the service object, the call is local. It'scoming from the service helper, not a remote client.The service helper gets the return value from the service. packs itup, and ships it back (over a Socket's output stream) to the clienthelper. The client helper unpacks the information and returns thevalue to the client object.Your client object gets toact llke it's making remotemethod calls. But whatit's r!!llY doing is callingmethods on aheap-local'proxY object that handlesall the low-level details ofSockets and streams.Server heap612 chapter 18


emote deployment with RMIHow the method call happens• Client object calls doBigThingO on the client helper objectSe~r heap• Client helper packages up information about the call(arguments, method name,etc.) and ships it over thenetwork to the service helper.Client heapI"client wonts to call a method"Server heap• Service helper unpacks the information from the client helper,finds out which method to call (and on which object) andinvokes the real method on the real service ob]ect.- -Client heap I"client wants to coli a method"you are here ~ 613


RMI helper objectsJava RMI gives you the cliet1t at1dservice helper objects!In Java, RMJ builds the client and service helperobjects for you, and it even knows how to make theclient helper look like the Real Service. In otherwords. RMI knows how to give the client helperobject the same methods you want to call on theremote service.Plus, RMI provides all the runtime infrastructure tomake it work, including a lookup service so that theclient can find and get the client helper (the proxyfor the Real Service).With RMI. you don't write any of the networkingor I/O code yourself. The client gets to call remotemethods (i.e. the ones the Real Service has) justlike normal method calls on objects running in theclient's own 10ca1JVM.Almost.There is one difference between RMI calls and local(normal) method calls. Remember that even thoughto the client it looks like the method call is local,the client helper sends the method call across thenetwork. So there is networking and I/O. And whatdo we know about networking and I/O methods?They're risky!They throw exceptions allover the place.So, the client does have to acknowledge the risk. Theclient has to acknowledge that when it calls a remotemethod. even though to the client it's just a local callto the proxy/helper object, the call ultimaJely involvesSockets and streams. The client's original call is local,but the pro"]' turns it into a remote call. A remote callJUSt means a method that's invoked on an object onanotherJVM. HQ11J the information about that callgets transferred from oneJVM to another dependson the protocol used by the helper objects.With RMI. you have a choice of protocols: JRMP orIIOP,JRMP is RMJ's 'native' protocol, the one madejust for Java-ta-Java remote calls. nop, on the otherhand. is the protocol for CORBA (Common ObjectRequest Broker Architecture), and lets you makeremote calls on things which aren't necessarilyJavaobjects. CORBA is usually much more painful thanRMI, because ifyou don't have Java on both ends,there's an awful lot of translation and conversion thathas to happen.But thankfully, all we care about isJava-to-Java, sowe're sticking with plain old. remarkably easyRMl.In RMI, the client helper is a 'stub'and the server helper is a 'skeleton'...Client heapServer heap614 chapter 18


emote deployment with RMIMaking the Remote ServiceThis is an overview of the five steps for making the remoteservice (that runs on the server). Don't worry, each step isexplained in detail over the next few pages.ServerD!!Step one:Make a Remote InterfaceThe remote interface defines the methodsthat a client can call remotely. It's whatthe client will use as the polymorphic classtype for your service. Both the Stub andactual service will implement this!Step two:Make a Remote ImplementationThis is the class that does the Real Work.It has the real implementation of theremote methods defined in the remoteinterface. It's the object that the client~~~~~~.Step three:Generate the stubs and skeletons using rmicThese are the client and server 'helpers'.You don't have to create these classes or everlook at the source code that generates them.It's all handled automatically when yourun the rmic tool that ships with yourJavadevelopment kit,Step four:Start the RMI registry (rmiregistry)The nniregistry is Jike the white pages ofaphone book. It's where the user goes to gelthe proxy (the client stubv'helper object).Step five:Start the remote serviceYou have to get the service object up and running.Your service implementation class instantiates aninstance of the service and registers it with the RMIregistry. Registering it makes the service available forclients.MyRemotelmpl_Stub.class101101­Jtl 1...10'e " IIbOt. HI001 OlMyRemotelmpLSkel.classyou are he re . 615


a remote interfaceStep one: Make a Remote InterfaceExtend java.rmLRemoteRemote is a 'marker ' interface, which means it has no methods. It hasspecial meaning for RMI, though, so you must follow this rule. Noticethat we say 'extends' here. One interface is allowed to extend anotherinterface.public interface MyRemoteMyRemote.javaDeclare that all methods throw a RemoteExceptionThe remote interface is the one the client uses as the polymorphic typefor the service. In other words, the client invokes methods on somethingthat implements the remote interface. That something is the stub, ofcourse, and since the stub is doing networking and I/O, all kinds ofBadThings can happen. The client has to acknowledge the risks by handlingor declaring the remote exceptions. Ifthe methods in an interfacedeclare exceptions, any code calling methods on a reference of that type(the interface type) must handle or declare the exceptions.t , ~ . . ' av,H'",iimport java. rmi . *; ~ th~ R~",oh '"n;c;Y ate'S ,,,J 'public interface MyRemote extends Remote {public String sayHello() throws}Be sure arguments and return values are primitives or SerializableArguments and return values ofa remote method must be either primitiveor Serializable, Think about it. Any argument to a remote method has tobe packaged up and shipped across the network, and that's done throughSerialization. Same thing with return values. Ifyou use primitives, Strings,and the majority of types in the API (including arrays and collections),you'll be fine. Ifyou are passing around your own types,just be sure thatyou make your classes implement Serializable.publicsayHello() throws RemoteException;"'- This r-et;...rn vc1/~e is ~onna be shirredwire +\'"0'" the serve\" batk toover ~hethe ~"ent, so it lrIl.tSt be Se\"ializable.Thats how ar~s and \"et~rn valf.tt:s ad:;ratka~ed ~r and Sent , J


emote deployment with RMIStep two: Make a Remote Implementation--1~ .......";i _- 0• Implement the Remote interfaceYour service has to implement the remote interface-the onewith the methods your client is going to call.public class MyRemoteImpl extends UnicastRemoteObjectpublic String sayHello() {~return "Server says, 'Hey'''; Th~ t~n-riler will n-ake SlAre that} rIAlie In-r1en-el'lteo all the n-ethods/ / more code in class t~.om the intel-fate '/OIA ir..r1er..el'lt. Il'I} IS tase, there s ol'lly Ohe.MyRemotelmpl.java{• Extend UnicastRemoteObjectIn order to work as a remote service object, your object needs somefunctionality related to 'being remote'. The simplest way is to extendUnicastRemoteObject (from thejava.rmi.server package) and let thatclass (your superclass) do the work for you.public class MyRemoteImpl implements MyRemote {• Write a no-arg constructor that declares a RemoteExceptionYour new superclass, UnicastRemoteObject, has one little problem-itsconstructor throws a RemoteException. The only way to deal with this isto declare a constructor for your remote implementation,just so that youhave a place to declare the RemoteException. Remember, when a class isinstantiated, its superclass constructor is always called. Ifyour superclassconstructor throws an exception, you have no choice but to declare that L thO 'l'ly'our constructor also throws an exception. ,/o\A dOl'l't halle to yv-".al'l~ I:i ~- 1 t toY- YoIA JV-S" l'Ie..~Publ i c U.rRemoteImpl ( ) the t.01'lS rv.t., ~hat "OIAr slAfert.lass6"6:t wa" to det. are"I L ,t.~trv.t.tor throws al'l euefvOTI.• Register the service with the RMI registryNow that you've got a remote service, you have to make it available toremote clients. You do this by instantiating it and putting it into the RMIregistry (which must be running or this line ofcode fails). When youregister the implementation object, the RMI system actually puts the stub inthe registry, since that's what the client really needs. Register your serviceusing the static rebind() method ofthejava.rmi.Naming class. . M",e (that t.I\el'ts tal' ~ttry ( q\ve ~o\Ar serv.lt.et~ ~\str~) al'd re~\ster ItRemote service = new RemoteI 1 () ; ~ \otnit.R~IIl'Ire~\:t:; . W'hel'l ~o\A b.\"dthethewltn e . t. RMI sways t.he serv,u o'r~ .,- servit.e obJe~_, Lhe stlAb \l' the re~istr~·'---'" stlAb al'd flA';> "you are here. 617


Step three: generate stubs and skeletonsG) Run rmic on the remote implementation class(not the remote: Interface)The rrnic tool, that comes with thejava softwaredevelopment kit, takes a service implementation andcreates two new classes. the stub and the skeleton.It uses a naming convention that is the name ofyour remote implementation, with either _Stub or_Skeleton added to the end. There are other optionswith rmic, including not generating skeletons,seeing what the source code for these classes lookedlike, and even using llOP as the protocol. The waywe're doing it here is the way you'll usually do it.The classes will land in the current directory (i.e.whatever you did a cd to). Remember, rmicmustbe able to see your implementation class, so you'llprobably run rmic from the directory where yourremote implementation is. (We're deliberately notusing packages here, to make it simpler. In the RealWorld, you'll need to account for package directorystructures and fully-qualified names).MyRemotelmpl_Stub.classlClnO).10 liO Io U 6001 \ 0OO~ 0)MyRemotelmpCSkel.classStep four: run rmiregistry(1) Bring up a terminal and start the rmlre:gistry.Be sure you start it from a directory that has accessto your classes. The simplest way is to start it fromyour 'classes' directory.Step five: start the serviceCDBring up another terminal and start your serviceThis might be from a main0 method in your remoteimplementation class. or from a separate launcher class.In this simple example. we put the starter code in theimplementation class, in a main method that instantiatesthe object and registers it with RMl registry.618 chapter 18


emote deployment with RMIComplete code for the server sideThe Remote interface:The Remote service (the implementation):public MyReIDoteImpl () throws RemoteException { Ipublic static void main (String[] args) (try (MyRemote service = new MyR8moteImpl();~Naming.rebind("Remote Hella H I service);catch (Exception ex) { ~ M.ike the rt....oU ob· t I , Iex.printStacltTrace () ; 'r"'irt4ish-y'd· 1., :Je~"1.~e" b"'d it to -theJ _I"~ Ult S'td{;H':. N· bJ\d"'t yOIA l-e9;su ..- it:. lA"d . t ...'''?,.....e i"dO. The"ted to look it. "d · 1., t"r r~ he 1I


getting the stubHow does the client getthe stub~?The client has coget the stub object, since that's the thing theclient will call methods on. And that's where the RMI registrycomes in. The client does a 'lookup', like going to the white pagesofa phone book, and essentially says, "Here's a name, and I'd likethe stub that goes with that name."~Remote)loolcllpO is a statit l\'ltihod o-tthe Na",i~ tlass\tNaming.lookup("rmi://127.0.0 .1/Remotel' ~\ '1011 hil'lt to t..ut it. to tht 'f0\l.'" host. l\il",e 0'" /Pi"u...tate, siYlle t.he loolc'-r addytsS ~oes heye...ethod ret.'-Yl'I$ t'ffe Objett..Bello");Server• Client does Q lookup on the RMI registryNaminq.lookup("rm1://127.0.0.1/Ramot:8 Bello");• RMI registry returns the stub object(as the return value of the lookup method) and RMIdeserializes the stub automatically, You MUST havethe stub class (that rmic generated for you) on theclient or the stub won 't be deserialized,• Client Invokes Q method on the stub, asthough the stub IS the real service620 chapter 18


How does the client get the stub class?Now we get to the interesting question. Somehow, someway, theclient must have the stub class (that you generated earlier usingrmic) at the time the client does the lookup, or else the stub won 'tbe deserialized on the client and the whole thing blows up. In asimple system, you can simply hand-deliver th e stub class to theclient.There's a much cooler way, though, although it's beyond thescope of this book. Butjust in case you're interested, the coolerway is called "dynamic class downloading". With dynamic classdownloading, a stub obj ect (or really any Serialized object) is'stamped' with a URL that tells the RMI system on the clientwhere to find the class file for that object. Then, in th e process ofdeserializing an object, ifRMI can't find the class locally, it usesthat URL to do an HTTP Get to retrieve the class file. So you 'dneed a simple Web server to serve up class files, and you'd alsoneed to change some security parameters on the client. There area few other tricky issues with dynamic class downloading, but that'sthe overview.remote deployment wit h RMIComplete client codeI~ The Na...ih9 dass (.f .. . *. < re...ire3ist r look c: ~ 01n 9 theimport Java.rnu.. , J'ava . Y lop) IS'n t he·r..., patkagepublic class MyRemoteClient {public static void main (String[] args)new MyRemoteClient() .go();J. t ht V' t~isty~ as ~'/Y tpublic void go () \t t.o.,.,es Ol/.t 't ~«~tt t ht t.asr: O'oy:.t.t, so dontry {\I-MyRemote service = (MyRemote) Naming .lookup(~rmi://127.0.0.1/RemoteHello");String s = service . sayHello () ; Y d 1-. 7 '\ L-010 nee "Ule IP address a c1 t.he "artie ~ed VIIt or hosw...e VI I L ' d Lhe stV'vit.tSystem.out.println(s); \ ~Vld V'CUly\ ~catch (Exception ex) { It looks j lASt like a Iex.printStackTrace (); tall! (E'lt.tept it 1 9 '" ~ r old "'cthodRe...oteE 'lt.tept io~ 1AS at now/edse theyou are here ; 621


RMI class filesJe sure each lMachhte has the classfiles it "eeds.The top three things programmers do wrong with RMI are:1) Forget to start rmiregistry before starting remote service(when you register the service using Nammg.rebindt), thenniregistry must be running!)2) Forget to make arguments and return types serializable(you won't know until runtime; this is not something thecompiler will detect.)3) Forget to give the stub class to the client.,gclientDo,,'t +cn-5tt, tilt zhe..+'uses the i"te~~att to tallMethods the st.",b. Tntclie"t JVM "eeas the si",btla~, b~ the tliO'lt "eveYrete",s to the shb classi.- toae. Tbe tlit"t. alwaysv.ses the ve...o{:e i"ktate,as thou5h the l"t"'oteiPlttrk.lte WERE. t.heatb.al yC"'oU: objttt.llUJln,lIilUO""lo U CIO


emote deployment with RMI~n yoor penCilW:~$J~1.Look at the sequence of events below, and 2.place them in the order in which theyoccur in a Java RMI application.3.-The--SlU-b-se-n-;ds-:th~e::--:m::e:;\h;;:od~call totheserverThe clIent does a lookuthe RMI RegistryThe RMI registry IsstaThe client gets Ihe slub fromIhe RMI regIstryThe diem invokes 8'mon the stubate service (remoteimplementation) isinstantiated4.s.6.7.,---- IUUR POINTS~• An object on one heap cannot geta normal Javareference 10 an object on a different heap (which meansrunning on a different NM)• Java Remote Method Invocation (RMI) makes it seem likeyou're calting a method on a remote object (l.e. an objectina different JVM), but you aren't• When a client calls a method on a remote object, theclient is really calling a method on a proxy of the remoteobject. The proxy is called a 'stub'.• A stub isa client helper object that takes care of the lowlevelnetworking details (sockets, streams, serialization,etc) bypackaging and sending method calls to theserver.• To build a remote service (in other words, an object thata remote client can ultimately call methods on), you muststart with a remote Interface.• Aremote Inlerface must extend the java.rml.RemoteInterface. and all methods must declareRemoteException.• Your remote service implements your remote Interface.• Your remote service should extend UnicastRemoleObject.(Technically there are other ways 10 create a remote object,but extending UnicaslRemoteObject isthe simplest).• Your remote service class must have a constructor,and the constructor must declare a RemoleException(because the superclass constructor declares one).• Your remote service must beinstantiated, and the objectregistered with the RMI registry.• To register a remote service, use the staticNaming.rebind('Service Name", servicelnstance);• The RMI registry must be running on the same machineasthe remote service, before you try 10 register a remoteobject with the RMI registry.• The client looks up your remote service using the staticNaming.lookup{'rmi:/IMyHostNameJServiceName");• Almost everything related to RMI can throw aRemoteException (checked bythe compiler). ThisIncludes registering orlooking upa service In the relgstry,and a/lremote method calls from the client tothe stub.you are here. 623


usesfor RMIYeah, but who really uses RMI?I use itfor serious B-to-B,e-commerce backends,running on J2EEtechnology. I624 chapter 18


emote deployment w ith RMI100% Local Combination 100% RemoteWhat about Servlets1Servlets are Java programs that run on (and with) an HTfP web server. When a dient uses aweb browser to interact with a web page, a request is sent back to the web server. If the requestneeds the help of a Java servler, the web server runs (or calls, if the servlet is already running)the servlet code. Servlet code is simply code that runs on the server, to do work as a result ofwhatever the client requests (for example, save information to a text file or database on theserver). If you're familiar with eGl scripts written in Perl, you know exactly what we're talkingabout. Web developers use CGJ scripts or servlets to do everything from sending user-submittedinfo to a database, to running a web-site's discussion board.And evenserolets can use RMI/By far, the most common use ofJ2EE technology is to mix servlets and EJBs together, whereservlets are the client of the EJB. And in that case, theserulet is using RJ1IlI to talk to theEJBs.(Although the way you use RM1 with EJB is a little different from the process wejust looked at.)1 Client fills out a registration form and clicks 'submit',The HTTP server (i.e. web server) gets the request, sees thatit's for a servlet, and sends the request to the servlet,Web Browser(client)-client requests RegisterServlet"Web ServerServlet (Java code) runs, adds data to the database,composes a web page (with custom info) and sends it back tothe client where it·displays in the browser.Web Browser(client)................"client requests Register5ervlet"Web Server........"heres a confirmation page"conflnn.htmlyou are here. 625


very simple servletStep for making and running a servletG) Find out where your servlets need to be placed.For these examples, we'll assume that you already have a web serverup and running, and that it's already configured to support servlets,The most important thing is to find outexactly where your servletclass files have to be placed in order for your server to 'see' them. Ifyou have a web site hosted by an ISP, the hosting service can tell youwhere to put your servlets.just as they'll tell you where to place youreGI scripts.Web Sel"Ver® Get the servlets.jar and add It to your c10sspathServlets aren't part of the standardJava libraries; you needthe servlets classes packaged into the servlets.jar file. You candownload the servlets classes fromjava.sun.com, or you can getthem from yourJava-enabled web server (like Apache Tomcat, atthe apache.org site). Without these classes, you won't be able tocompile your servlets.servlals.Jar® Write a servlet closs by extending HttpServletA servlet isjust aJava class that extends HttpServlet (from thejavax.servlet.http package). There are other types ofservlers youcan make, but most of the time we care only about HttpServlet.UUOt;16 U~ Io U 0Cl61 1C1Ql)l OIMyServletA.cJasspublic class MyServletA extends Htt:pServlet { ... }@ WrIte an HTML page that invokes your servletWhen the user clicks a link that references your servlet, the webserver will find the servlet and invoke the appropriate methoddepending on the HITP command (GET, POST. etc.)~MyPage,htmlThis is the most amazing servlet.@ Make your servlet and HTML page Qvallable to your serverThis is completely dependent on your web server (and more specifically,on which version ofJava Servlets that you're using). Your ISPmay simply tell you to drop it into a "Servlets" d irectory on yourweb site. But ifyou're using, say, the latest version ofTomcat. you'llhave a lot more work to do to get the servlet (and web page) intothe right location. (Wejust happen to have a book on this too .)Web Server~. \"~l 1-, "~-.~ - .JI'" '-- - .' :' I, :1·.·. " ,. :',- -,I •.I ;, -:::-,'626 chapter 18


servlets and JSPD therel&rH ? "ume ~uestl9ns• Servlets are Java classes that run entirely on(and/or within) an HTIP(web) server.• Servlets are useful for running code on theserver as a result ofclient interaction withaweb page. For example, if a client submitsinformation inaweb page form, the servlet canprocess the information, add ittoa database,and send back a customized, confirmationresponse page.• To compile a servlet, you need the servletpackages which are inthe servlets.jar file. Theservlet classes are not part ofthe Java standardlibraries, so you need todownload the servlets.jarfrom java.sun.com orget them from a servletcapableweb server. (Note: the Servlet libraryis included with the Java 2 Enterprise Edition(J2EE))• To run a servlet, you must have aweb servercapable ofrunning servlets, such as the Tomcatserver from apache.org.• Your servlet must be placed ina location that'sspecific toyour particular web server, so you'llneed tofind that out before you trytorun yourservlets. If you have a web site hosted byan ISPthat supports servlets, the ISP will tell you whichdirectory to place your servlets in.• Atypical servlet extends HttpServlet andoverrides one ormore servlet methods, such asdoGetO ordoPostO.• The web server starts the servlet and calls theappropriate method (doGetO, etc.) based on theclient's request.• The servlet can send back a response by gettinga PrintWriter output stream from the responseparameter ofthe doGetO method.• The servlet 'writes' out an HTML page, completewith tags).Q.: What's a JSP, and how does it relate to servlets7A: JSPstands for Java Server Pages. In the end, the web serverturns a JSPinto a servlet, but the difference between a servlet anda JSPis what YOU (the developer) actually create.With a servlet,you write a Java classthat contains HTML in the output statements(if you're sending back an HTML page to the client). But with aJSP, it's the opposite-you write an HTML page that contains Javacode!This gives you the ability to have dynamic web pages where youwrite the page as a normal HTML page, except you embed Javacode (and other tags that"trigger" Java code at runtime) thatgets processed at runtime. In other words, part of the page iscustomized at runtime when the Java code runs .The main benefit of JSPover regular servlets is that it's just a loteasier to write the HTML part of a servlet as a JSPpage than towrite HTML in the torturous print out statements in the servlet'sresponse. Imagine a reasonably complex HTML page, and nowimagine formatting it within println statements. Yikes!But for many applications, it isn't necessary to use JSPs becausethe servlet doesn't need to send a dynamic response, or theHTML is simple enough not to be such a big pain. And, there arestill many web servers out there that support servlets but do notsupport JSPs, so you're stuck.Another benefit of JSPs is that you can separate the work byhaving the Java developers write the servlets and the web pagedevelopers write the JSPs. That's the promised benefit, anyway.In reality, there's still a Java learning curve (and a tag learningcurve) for anyone writing a JSP, so to think that an HTML web pagedesigner can bang out JSPs is not realistic. Well, not without tools.But that's the good news-authoring tools are starting to appear,that help web page designers create JSPs without writing thecode from scratch.Q.: Is this all you're gonna say about servlets? After such ahuge thing on RMI7A: Yes. RMI is part of the Java language, and all the classes forRMI are in the standard libraries. Servlets and JSPs are not part ofthe Java language; they're considered standard extensions. Youcan run RMI on any modern JVM, but Servlets and JSPs require aproperly configured web server with a servlet "container': This isour way of saying,"it's beyond the scope of this book." But you canread much more in the lovely HeadFirst Servlets& JSp'628 chapte r 18


emote deployment with RMIJust for fUt1, lets tMake the Phrase-O-Maticwork as aservletNow that we told you that we won'tsay any more about servlets, we can'tresist servletizing (yes, we am verbifyit) the Phrase--O-Matic from chapter 1.A servlet is stilljustJava. AndJava codecan call Java code from other classes.So a servlet is free to call a method onthe Phrase-O-Matic. All you have to dois drop the Phrase-O-Matic class intothe same directory as your servlet, andyou 're in business. (The Phrase-O­Matie code is on the next page) .Try mynew web-enabledphrase-o-matic and you'llbe a slick talker just likethe boss or those guys inmarketing.import java.io.*;import javax.servlet.- ;import javax.servlet.http.*;public class KathyServlet extends BttpServlet {public void doGet (HttpServletRequest request, BttpServletResponse response)throws ServletException, IOExceptionString title = "PhraseOMatic has generated the following phras8. H ;response. setcontentType ("text/html") ;PrintWriter out = respons8.getWriter();I -l.t4\\ ",~od1 QI'\out.printl.n(\\"); 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 theou t .print l n ("l '" ..,.t, a e}out .println("" + title + " " ) ; P~ya1(OMdtiC. tlau (()f'I the ne Y ~out.prlntln("" + Phr&seOMatic.makePhrass());out.println(~make another phraseH);out.println ("") ;out. close () ;you are here ~ 629


Phrase-O-Matic codePhrase-O-Matic code, servlet-friet1dlyThis is a slightly different version from the code in chapter one. In theoriginal, we ran the entire thing in a mainO method, and we had to rerunthe program each time to generate a new phrase at the command-line. In thisversion, the code simply returns a String (with the phrase) when you invokethe static makePhrase0 method. That way,you can call the method from anyother code and get back a String with the randomly-composed phrase.Please note that these long String[] array assignments are a victim ofwordprocessinghere-don't type in the hyphens! Just keep on typing and let yourcode editor do the wrapping. And whatever you do, don't hit the return key inthe middle ofa String (i.e. something between double quotes).public class PhraseOMatic {public static String makePhrase()II make three sets of words to choose fromString[] wordListOne = {"24/7","multi-Tier","30,OOO foot","B-to-B","win-win","frontend","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", "focused","leveraged", "aligned", "targeted", "shared", "cooperative", "accelerated"};String[] wordListThree = {"process", "tipping point", "solution", "architecture","core competency", "strategy", "mindshare", "portal", "space", "vision", "paradigm", "mission"};II find out how many words are in each listint oneLength = wordListOne.length;int twoLength = wordListTwo.length;int threeLength wordListThree.length;II generateint randlint rand2int rand3 =three(int)(int)(int)random numbers, to pull random words from each list(Math.randomO * oneLength);(Math .randomO * twoLength);(Math.randomO * threeLength);II now build a phraseString phrase = wordListOne[randl] + " " + wordListTwo[rand2] + " " +wordListThree[rand3] ;II now return itreturn ("What we need is a " + phrase);630 ch apter 18


emote deployment with RMIRMI is great for writing and running remote services. Butyou wouldn't run something like an Amazon or eBay on RMIalone. For a large, deadly serious, enterprise application, youneed something more. You need something that can handletransactions, heavy concurrency issues (like a gazillionpeople are hitting your server at once to buy those organicdog kibbles), security (notjust anyone should hit yourpayroll database), and data management. For that, you needan enterprise applil;atUm server.In java, that means a java 2 Enterprise Edition 02EE) server.AJ2EE server includes both a web server and an EnterpriseJavaBeans(EJB) server, so that you can deploy an applicationthat includes both servlets and EJBs. Like servlets, EJE isway beyond the scope of this book, and there's no way toshow "just a little" EJE example with code, but we wiU takea quick look at how it works. (For a much more detailedtreatment ofEJE, we can recommend the lively Head FirstEJB certification study guide.)An EJB server adds abunchofservices that you don't getwith straight RMI. Thingslike transactions, security.concurrency. databasemanagement. and networ"king.An EJB server steps intothemiddle ofan RMI call andlayers in all ofthe services.EJ'Bserver:.-_---\-,--.- ..... '.This is only a small paM of the E,JB picture.!you are here ~ 831


a little J InIFor our final trick... alittle JiniWe love jini. We think]ini is pretty much the best thing in Java. IfE]B is RMIon steroids (with a bunch ofmanagers), Jini is RMI with wings. PureJava bliss.Like the EJB material, we can't get into any oftheJini details here, but ifyouknow RMI, you're three-quarters ofthe way there. In terms of technology,anyway, In terms of mindset, it's time to make a big leap. No, it's time to fl>'.Jini uses RMI (although other protocols can be involved), but gives you a fewkey features including:Adaptive discoverySelf-healing networksWith RMT, remember, the client has to know thename and location ofthe remote service. Theclient code for the lookup includes the IP address orhostnarne ofthe remote service (because that's wherethe RMI registry is running) and the logical name theservice was registered under.But withjini, the client has to know only one thing: theinterface implemented by the service! That 's it.So how do you find things? The trick revolves aroundjini lookupservices. jini lookup services are far more powerfuJ and flexible thanthe RMI registry. For one thing,jini lookup services announce themselves to thenetwork, automatically. When a lookup service comes online, it sends a message (using IPmulticast) out to the network saying, "I'm here, if anyone's interested."But that's not all. Let's say you (a client) come online after the lookup service has alreadyannounced itself, you can send a message to the entire network saying, "Are there anylookup services out there?"Except that you're not really interested in the lookup service itself-you're interested inthe services that are registered with the lookup service. Things like RMI remote services,other serializablejava objects, and even devices such as printers, cameras, and coffeemakers.And here's where it gets even more fun: when a service comes online, it will dynamicallydiscover (and register itself with) any Jini lookup services on the network. When theservice registers with the lookup service, the service sends a serialized object to be placedin the lookup service. That serialized object can be a stub to an RMT remote service, adriver for a networked device, or even the whole service itself that (once you get it fromthe lookup service) runs locally on your machine. And instead of registering by name, theservice registers by the interfacei: implements.Once you (the client) have a reference to a lookup service, you can say to that lookupservice, "Hey, do you have anything that implements Scienuficf'alculator?" At that point,the lookup service will check its list of registered interfaces. and assuming it finds amatch, says back to you, "Yes I do have something that implements that interface. Here'sthe serialized object the ScientificCalculator service registered with me."632 chapter 18


emote deployment with RMIAdaptive discovery i" actio"@) Jini lookup service is launched somewhere on the network, andannounces itself using IP multicast.machIne on the networksomewhere ...another machine on the network•An already-running Jini service onanother machineasks to be registeredwith this newly-announced lookupservice .It registers by capability,rather than by name. In other words,it registers as the service interlace itimplements.It sends a serialized objectto be placed in the lookup service.Registerme os somethingthat implementsScientificCaJculator. Here's aserialized object that representsmy service. Send it toanybody who asks...machine on the networksomewhere...another machine on the networkyou are here . 633


adaptive discovery in JiniAdaptive discovery itt actio", co"thtued ...®A client on the network wantssomething that implements theScientificColculator interface.It hasno idea where (or if) that thing exists,so it asks the lookupservice.another machineon the networkmachine on the networksomewhere...another machine on the network@ The lookupservice responds, since it does have somethingregistered as a ScientificCalculator interface.machine on the networksomewhere ...another machine on the network634 ch apter 18


Self...healit1Q t1etwork it1 actio"eA Jini Service has asked to register with the lookup service. The lookupservice responds with a "leese". The newly-registered service must keeprenewing the lease, or the lookup service assumes the service has goneoffline. The lookup service wants always to present an accurate pictureto the rest of the network about which services are available.remote deployment with RMIanother machineon the networkmachine on the networksomewhere .. ,another machine on the network® The service goes off line (somebody shuts it down), so it fails torenew its lease with the lookup service. The lookup service drops it.machine on the networksomewhere...another machine on the networkyou are here ~ 635


universal service projectFhtal Project: the Ut1iversal Service browserWe're going to make something that isn'tjini-enabled, but quite easily could be.It will give you the flavor and feeling ofJini, but using straight RMI. In fact themain difference between our application and aJini application is how the service isdiscovered. Instead of the Jini lookup service, which automatically announces itself andlives anywhere on the network, we're using the RMI registry which must be on the samemachine as the remote service, and which does not announce itself automatically.And instead of our service registering itselfautomatically with the lookup service, wehave to register it in the RMl registry (using Naming.rebind()).But once the client has found the service in the RMI registry, the rest of the applicationis almost identical to the way we'd do it inJini. (The main thing missing is the kasethatwould let us have a self-healing network ifany of the services go down .)The universal service browser is like a specialized web browser, except instead of HTMLpages, the service browser downloads and displays interactiveJava GUIs that we'recalling uniuersal services.RMIBrowserChoose a ~Ite k'f'ol'l\ thelist The RMI TC"'oU: W"\IiUhas a ~~\IiteList.O...cthod -th.it ~N:Js batK thislist. o-t SCT\litcs.WheJI +.hc \!Sa' ~Ieth OYIC,-the tl,eJIt. asks .f0\'" thead;\oIG1 scrvitc cDil.eRolli,,~Da'l0fneWccK J e+.tJ tobe ~t batlt. ~'f'0ft\ the RMIyt"'oU: W"\/itc.636 chapter 18


emote deployment w ith RMIHow it works:CI ient starts up anddoes a lookup on theRMI registry forthe service called"Service.Server", andgets back the stub.Service Browser(client)ServerClient calls getServiceListO on the stub. The ServiceServerreturns an array of servicesServIce Browser(client)-- "getServiceListO·Server~=="OK, here's an array of services"• Client displays the list of services in a GUIService Browser(client)Serveryou are here. 631


universal service browserHow it works, continued...•User selects from the list, so client calls the get5erviceOmethod on the remote service. The remote service returns aserialized object that is an actual service that will run insidethe client browser.'getService(selectedSl/ctServer'OK, here 's the service-• Client calls the getGuiPanelO on the serialized service object itjust got from the remote service. The GUI for that service isdisplayed inside the browser, and the user can interact with itlocally. At this point , we don't need the remote service unless/untilthe user decides to select another service.Service Browser(client)638 chapter 18


..,remote deployment with RMIThe classes and interfaces:interface Servlce.Server Implements RemoteA regular old RMI remote interlace for the remote service (theremote service has the method for getting the service list andreturning a selected service).Servlc9ServergelServicesUslOgelServlceO• class ServlceServerImpl Implements 5ervlceServerThe actual RMI remote service (extends UnicastRemoteObject).Its job is to instantiate and store a/l the services (the thingsthat will be shipped to the client), and reg ister the server itself(ServiceServerImpJ) with the RMI registry.ServlceServerlmplgelServicesListOgelServiceO3' class ServlceBrowserThe client. It builds a very simple GUI, does a lookup in the RMIregistry to get the Service5erver stub, then calls a remote method onit to get the list of services to display in the GUI list .ServlceBrowsermainOInterface ServiceThis is the key to everything. This very simple interface has just onemethod, getGuiPanelO . Every service thot gets shipped over to theclient must implement this interface. This is what makes the whole thingUNIVERSAL! By implementing this int erface, a service can come overeven though the client has no ideo what the actual class (or classes)are that make up that service. All the client knows is that whatevercomes over, it implements the Service interface, so it MUST hove agetGuiPanelO method.The client gets a serialized object as a result of callinggetService(selectedSvc) on the Service5erver stub, and all the clientsays to that object is, "r don't know who or what you are, but I DOknow that you implement the Service interface, so I know I can callgetGuiPanelO on you. And s ince getGuiPanelO returns a JPanel, rll justslap it into the browser GUI and start interacting with itlclass Dic£5ervice implements ServiceGot dice? If not , but you need some, use this service to roll anywherefrom 1 to 6 virtual dice. for you.S&lVlcegetGuiPaneJO,. , ., . .~'"..." "I I, , ., , , , ./ I ....: DiceServlce.... gelGulPanelO., r------... . . . . . .. .. ...class MlnlMusicService implements Service,,Remember that fabulous little 'music video' program from the firstGUI Code Kitchen? We've turned it into a service, and you can play it r----'-----~over and over and ove.r until your roommates finally leave.DayOfTheWeekServlcegelGuiPanelO• class DayOfTheWukSuviu Implements SuvlceWere you born on a Friday? Type in your birthday and find out.MlnlMuslcServlcegelGulPanelOyou are here. 639


universal service codeinterface ServiceServer (the remote interface)import java.rmi.*;public interface ServiceServer extends Remote (Object[] getServiceList () throws RemoteException;Service getService(Object serviceKey) throws RemoteException;public interface Service extends Serializable {public JPanel getGuiPanel();640 chapter 18


emote deployment with RNass ServiceServerlmpl (the remote Implementation)java.rm.i.*;java.util.*;java. rm.i.server. • ;\ RM\ 'l"'f\tl'l\tn~bOt'lA\"\O'I'",apublic class ServiceServerImpl extends UnicastRemoteObject implements ServiceServerBashMap serviceList;public ServiceServerImpl ()setUpServices() ;throws RemoteException I. 'b aliu 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,nIprivate void setUpServices () ( . _"\ ~e.YV~t.es...nIV(;,'~serviceList = new BashMap();service.List.put("Dice Rolling Service", new DiceService();servlceList.put ("Day of the Week Service" I new DayOfTheWHkService () ) ;serviceLlst.put("Visual Music Service", new MiniMusicService()); .u~L\..6 KyVit.e.~ (the. at~~I\..K"""1MaKe. V'" t t\olc.'" '''1v> v>c.ro'oy:tb) a~ flo' sh"',,,~ I\il ....e (-to'!"~as\olMa~J WIth athe. 'KC'/ ).public Object£] getServiceList () { Client. t.alts .1, . .S tern t . tl ('" te") "UlJS In oraet- f.o Q....L /•.L f'ys .. ou . ~rl.n. n an r6ltlO; display in the bro ;)Cl: a Ib~ O't s~viles f.oreturn servJ..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; one We~ il'lSiae) by "'dkin9 a!:rrd ~:f .(eva. th~h ii: has S&-il'l~sj.. the lf~lhN!ap. We ,'Y JlI.St the i(EYS t.h~f. a"eJI f.W


ServlceBrowser codeclass ServlceBrowser (the client)import java.awt.·iimport javax. swing. * i~rt java.rmi.*iimport java.awt.event.*;public class SarviceBrowsarJPanel mainPanel;JComboBox serviceList;ServlceServer server;public void buildGUI () (JFrame frame = new JFrame(~RMI Browser H ) ;mainPanel D new JPanel();frame .geteontentPane () . add (BorderLayout.CEN'rEll, mainPanel);.~ lQOku.\,'-e'nis Method o~s -e'n~ \~~iteL.irtO .~j.ot[] ••~i~~.M;:dd:'~:~::::~~t;~\_ ~servlceList = new JCombo80x (services) ; JCorr-bo~ (the \~~ . n~ cJ eat'n thi~ ',,, the oYTd'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 chapter 18


emote deployment with RMIObject[] getServicesList() {Object obj = null;Object[] services = null ;try {obj = Naming .lookup(~rmi://127 .0.0.1/ServiceServer");)catch(Exception ex) {ex.printStackTrace() ;} ~server = (ServiceServer) obj;try {Cast the stlAb to thso that we tall tall e ~".o~e illtertate type~e ervlteListO Oil it 'services = server.getServiceList() ; ~__catch(Exception ex) {ex.printStackTrace() ;return services;~d:.set'viteLis·W ~ives lAS the at't'ay 0+ Objetts,-Chat we display in the JCoMboBo'/C. tOt' Hie lASet' toselett tt'OI'l\.class MyListListener implements ActionListener {public void actionPerformed(ActionEvent ev) {public static void main(String[] args)new ServiceBrowser() .buildGUI();}you are here. 643


DiceService codeclass DiceService (a universal service, implements Service)import javax.swing.·;import java.awt.event.*;import java.io.*;public class DiceService implements Service (JLabel label;JComboBox numOfDice;e e e-lUIl l flD'VrlttDlullolll"9_. - -~fT.1Wl'=SHpublic JPanel getGuiPanel() (JPanel panel = new JPanel () ;JButton button = new JButton("Roll 'em!");String[] choices = {"I", "2", "3", "4", "5 H } ;numOfDice = new JComboBox(ohoices) ;label = new JLabel ("dice values here");button.addActionListener(new Rol1EmListener(»;panel. add (numOfDice) ; ftt:r' th .panel. add (button) ;St:r:i: i f..t:C»Il'",POl"idl'rt ",tthod! nt: ",eihod 0+ tht:panel. add(label) ; thil S~i~t: : a~e--;_ v'e 07It: t.he dibrt's 901\1Id ~II whtrlreturn panel; .....a t ·.1' SZ}tua and loaded. yrAJ, u" do whdiel\ In tne ~t:u:jlliPa"eJO eihod I vty y04l.JPal'u~" $(I it bioi/as tht: at.t.:~1 d" J as II~n~ ~s you retur" a- Ilt-ro,~ '-JUt.public class RollEmListenar implements ActionListener {publiC! void aotionPerfo:rmed(ActionEvent ev) {/ I roll the diceString diceOutput = "";String selection = (String) numOfDice . get5electedItem() :int numOfDiceToRoll = Integer.parselnt(selection) ;for (int i = 0; i < numOfDiceToRoll; i++) (int r = (int) ((Math. random () * 6) + 1);diceoutput += (" " + r);)label. setText (diceOUtput) ;~arpen your penCilThink about waysto improve the DiceService.Onesuggestion:using what you learnedIn the GUI chapters,makethe dice 9raphicaI.Use a rectangle, and draw theappropriate number of circles on eachone,correspondIngto the roll for that particular die.1---1 • •644 chapter 18


class MlnlMusicService (a universal service, implements Service)import j avax . sound.midi... ;import java.io.*;import javax.sving.*;illlport java.art.*;illlport java.awt.event.*;In


MiniMuslcServlce codeclass MiniMusicService, continued••.public MidiEvent makeEvent(int comel, int chan, int one, int two, int tick) {MidiEvent event = null;try (ShortMessage a = new ShortMessage();a.setMessage(comel, chan, one, two);event = new MidiEvent(a, tick);}catch(Exception e) { }return event;class MyDrawPanel extends JPanel implements ControllerEventListenerII only if we got an event do we want to paintboolean mag = false;public void controlChange(ShortMessage event) {msg = true;repaint 0 ;public Dimension getPreferredSize()return new Dimension(300,300);public void paintComponent(Graphics g) {if (msg) {Graphics2D g2 = (Graphics2D) g;int r = (int) (Math.random() * 250);int gr = (int) (Math.random() * 250);int b = (int) (Math.random() * 250);g.setColor(new Color(r,gr,b»;int ht = (int) «Math.random() * 120) + 10);int width = (int) «Math.random() * 120) + 10);int xint y == (int) «Math.randomO * 40) + 10);(int) «Math.random() * 40) + 10);g .fillRect(x,y,ht, width);mag = false;} II close if} II close method} II close inner classII close class


emote deployment with RMIclass DayOfTheWeekService (a universal service, Implements Service)import javax.swing.-;import java.awt.event.·;import java.awt.* ;import java.lo.·;import java.util.* ;import java.text. • :,.e 9:" ............D.rroln......s-w.. ~-.. , .... ~I...0., I F .~ ~ ..,.... j l OOI Ipublic class DayOfTheWeekServicEl implements Service (JLabel output:Labe1 ;JComboBox month;JTextFleld day;J'l'extField year;public. JPanel qetGuiPanel () (JPanel panel "" new JPanel () ;JButton button"" new JButton(~Do it!");button.addAetionListener(new DoltListener(»;outputLabel. "" new .JLabel ("date appearll he.ra") ;DateFormatsymbols dataStuff = new DateFonaatsymbols () ;month = new JComboBox(dateStuff.g8tMOnthll{»;day"" new JTextField(8);year ;: new J'l'extField (8) :JPanel inputpanel ;: new JPanel (new Gr iciLayout (3 ,2) ) ;inputPane1.add(new JLabel ("Month") ;inputpanel.add(month);inputPanel . add (new JLabel ("Day") ) ;inputPanel.add(day);inputPanel. add{new JLabel ("Year"» ;inputPanel.ac1d(year) ;panel. add(inputpanel) :panel .add(button);panel.add(outputLabel);return panel;public class DoItLlstener implements A.ctionLilltener J O\l "etd Cl ....e....i"devpublic void aotionPerformed(ActionEvent &V) ( R ~O" to t'hayUY 10 -\:.t:'1 ~~t.t,,~ ""o'r\t.~int monthNum == month.getselectedIndexO; ; h "",,'olY a",d d 6 t. ho""e"'lY,Hlnt dayNum • Integer.paraeInt (day. qatTextO ); n\ ~e is t\'~"'t\~ ~\; ~\ass- Aho. theint yearNum :: Integer.parselnt (year. getTaxt ()f) ; \) 11 u.st. it. lASt>the Ca IoU 1 tt.i~'1 a fott.ernCalendar 0 • Calendar.qetInst&nce () ; et.4\tDa~f~t \~d \"~,,t ",,-l:.,c •set (Calendar. MONTH J monthN\DJl): ~""'f~ t,nt dw t"''''' fc. set (Calendar. DAY_OF_MONTH I dayNum); CIfc.set (Calendar. YEAR, yearNum):Date date :: c.qetTime () ;String dayOfWeelt ;: (new SimplaDataFor:JUt ("EEEE N ) ) • format (date) :outputLabel . setText (dayOfW&elt) ;you are here ~ 647


the end... sort ofCongratulations!You made it to the end.Of course, there's stili the two appendices.And the Index.And then there's the web site•••There's no escape, really.648 hapter 18


Appendix A:*Final Code Kitchen*Chris: groove2 revisedNIgel: dance beatFinaLLy, the complete version 01 the BeatBox!It connects to a simple MusicServer so that you cansend and receive beat patterns with other clients.this is a new appendix 649


final BeatBox codeFinal BeatBox client programMost of this code is the same as the code from the CodeKitchens in the previouschapters, so we don't annotate the whole thing again. The new parts include:GUI - two new components are added for the text area that displays incomingmessages (actually a scrolling list) and the text field.NETWORKING - just like the SimpleChatClient in this chapter, the BeatBox nowconnects to the server and gets an input and output stream.THREADS - again, just like the SimpleChatClient, we start a 'reader' class thatkeeps looking for incoming messages from the server. But instead of just text, themessages coming in include TWO objects: the String message and the serializedArrayList (the thing that holds the state of all the checkboxes.)import java.awt.* ;import javax.swing.*;import java.io.*;import javax. sound.midi . *;import java.util.*;import java.awt.event.*;import java.net.*;import javax.swing.event.*;public class BeatBoxFinalJFrame theFrame;JPanel mainPanel ;JList incomingList;JTextField userMessage;ArrayList checkboxList;int nextNum;Vector listVector = new Vector() ;String userName;ObjectOUtputStream out;ObjectInputStream in;HashMap otherSeqsMap new HashMap();Sequencer sequencer;Sequence sequence;Sequence mySequence = null;Track track;String[] instrumentNames = {~Bass Drum", ~Closed Hi-Hat", ~Open Hi-Hat","AcousticSnare", ~Crash Cymbal", ~Hand Clap", ~High Tom", ~ H i Bongo", ~Maracas", ~Whistle",~Low Conga", ~Cowbell", ~Vibraslap", ~Low-mid Tom", ~High Aqogo", ~Open Hi Conga");int[] instruments = {35,42,46,38,49,39,50,60,70,72,64,56,58,47,67,63);650 appendi x A


publicnewappendix A Final Code Kitchenstatic void main (String[] args) (BeatBoxFinal() .startUp(args[O]); II args[O] is your user ID/screen namefI\ l .f \J0~V- stv-eeYl Yla",e·""----- AdO. a t..o",....aYlo-liYle a v-~ ~",e Yl1;. ov- Ipublic void startup(String name) {userName = name;II open connection to the servertry (Socket sock = new Socket("l27 .0.0.l", 4242);c I ' 01 'ava 0eatBo'l-f=iYlal thef=lash...'/.cl....ye· ID j [}out = new ObjectOutputStream(sock.getOUtputStream(»;in = new ObjectInputStream(sock.getInputStream(»;Thread remote = new Thread(new RemoteReader(»;remote .start 0 ;catch(Exception ex) (System.out.println("couldn't connect - you'll have to play alone.") ;}setupMidi 0 ;buildGUI () ;II close s tartUppublic void buildGUI () ~lA.1 tode, YlothiYl~ Yle-." hev-etheFrame = new JFrame("Cyber BeatBox");BorderLayout layout = new BorderLayout() ;JPanel background = new JPanel(layout) ;background.setBorder(BorderFactory.createEmptyBorder(10,10,10,10»;checkboxList = new ArrayList() ;Box buttonBox = new Box(BoxLayout.Y_AXIS);JButton start = new JButton("Start");start.addActionListener(new MyStartListener(»;buttonBox.add(start);JButton stop = new JButton("Stop") ;stop.addActionListener(new MyStopListener(»;buttonBox.add(stop);JButton upTempo = new JButton("Tempo Up");upTempo.addActionListener(new MyUpTempoListener(»;buttonBox.add(upTempo);JButton downTempo = new JButton("Tempo Down") ;downTempo.addActionListener(new MyDownTempoListener(»;buttonBox.add(downTempo) ;JButton sendlt = new JButton("sendIt");sendlt.addActionListener(new MySendListener(»;buttonBox.add(sendIt);userMessage = new JTextField();you are here ~ 651


final BeatBox codebuttonBox.add(userMessage):Box namaBox ::; new Box(BoxLayout. 'i_AXIS) ifor (int i = 0; i < 16; i++) {nameBox. aeld(naw Label (i.nst%UmentNames [i]» ;background.. add(Bord.erLayout . EAST ,background.. add (Bord.erLayout.WEST,buttonBox) inameBox);theFrame.qetContentpane () . add. (background) ;GridLayout grid'" new GridLayout(16,16);grid. aetVgap (1) ;grid.setHqap(2):mainPanel '" new .Ji'anel (grid) :background. add (BorderLayout. CENTER, UlA1nPanel);for (int i '" 0; i < 256; i++) (JCheckBox c '" new JCheck.Box () ;c .setse1ected(false);checkboxList.add.(c) ;DIlU.nPanel. add. (c) ;II end looptheFrAmQ.aetBounds(50,50,300,300);theFrAmQ .pack () ;theFrame.setVisible(true);II close buildGUIpublic void. setUpMidi ()try (sequencer IS MidiSystem.getSequencer () isequencer.open();sequence IS new sequence (Saquence.PPQ,4) ;track '" sequance.areateTrack();sequencer.setTempolnBPM(120);catch (Exception e) (e .printstackTrace () ;)II close setUpMldi652 appendix. A


appendix A Final Code Kitche npublic void buildTrackAndStart() {ArrayList trackList = null ;sequence.deleteTrack(track);track = sequence.createTrack();for (int i = 0; i < 16; i++) {trackList = new ArrayList();II this will hold the instruments for eachh the t..het.k'ooi-t S'0 'fIo\k i\'\~ thY"o~ t t to a\'\?J",M 0 kO,t.kSJtel oYlO .,..aYYMi~~ ,chl/~ Ylt koY" .o. Lto «jtt "flt l C\'\0 ",okiYl~ the . 1~ 1r;,. ACTL.:'! oSi"i\'\stv-",,,,e\'\t ~. • o\e1'o, b",t It IS ~)< L oY"el/iol.lS. et,,\1 ..0"', L Y"eteY" "IP ,T\oils 'S yY" 'r . t.hay"eY"s, so L' a ~aiYl.. the yyel/lOI.lS L LL f' "'\\ ei-y\aYlo"IOYl'fIoS 1\'\ • to ~e" "fie -tfor (int j = 0 ; j < 16; j++) { Code~ltt..he\'lSJCheckBox jc = (JCheckBox) checkboxList.get(j + (16*i»;if (jc.isSelected(» (int key = instruments[i];trackList.add(new Integer(key»;else {trackList.add(null);II because this slot should be empty in the track}} II c lose inner l oo pmakeTracks{trackList);} II c lose outer l ooptrack.add(makeEvent{192,9,1,0,15»; II - so we always go to full 16 beatstry {sequencer.setSequence(sequence);sequencer . setLoopCount (sequencer. LOOP_CONTINUOUSLY) ;sequencer.start();sequencer.setTempolnBPM{120);} catch(Exception e) {e.printStackTrace();}} II close metho dpublic class MyStartListener implements ActionListenerpublic void actionPerformed(ActionEvent a) {buildTrackAndStart() ;} II c lose actionPer f o rmedII close inner classpublic class MyStopListener implements ActionListenerpublic void actionPerformed(ActionEvent a) (sequencer . stop () ;} II c l ose a c t ionPerformedII close inner c lasspublic class MyUpTempoListener implements ActionListenerpublic void actionPerformed(ActionEvent a) {float tempoFactor = sequencer.getTempoFactor();sequencer.setTempoFactor«float) (tempoFactor * 1.03»;} II close acti onPerf o rmedII c l ose inner c l assyou are here . 653


final BeatBox codepublic class MyDownTempoListener ~lements ActionListenerpublic void actionPerformed(ActionEvent a) {fioat tempoFactor = sequencer.getTempoFactor();sequencer.setTempoFactor«fioat) (tempoFactor * .97»;public class MySendListener implements ActionListener (public void actionPerformed(ActionEvent a) {II make an arraylist of just the STATE of the checkboxesboolean[] checkboxState = new boolean[256] ;for (int i = 0; i < 256; i++) {JCheckBox check = (JCheckBox)if (check.isSelected(» {checkboxState[i] = true;}} II close l oopString messageToSend = null;try {out.writeObject(userName + nextNum++ + ". " + userMessage.getText(» ;out.writeObject(checkboxState);catch(Exception ex) {System.out.println("Sorry dude. Could not send it to the server.") ;}userMessage.setText("");} II cl ose action Pe r f or medII c l ose i nne r cl a s spublic class MyListSelectionListener implements ListSelectionListenerpublic void valueChanged(ListSelectionEvent le) {if (!le.getValueIsAdjusting(» {String selected = (String) incomingList.getselectedValue();if (selected != null) (II now go to the map, and change the sequenceboolean[] selectedState = (boolean[]) otherSeqsMap.get(selected);changeSequence(selectedState);sequencer.stop();buildTrackAndStart();}II close valueChangedII cl ose i nne r class654 appendix A


public class RemoteReader implements Runnable {boolean[] checkboxState = null;String nameToShow = null ;Object obj = null;public void rune) {try {while«obj=in.readObject(» != nul l ) {System.out.println("got an object fromSystem.out.println(obj .getClass(»;String nameToShow = (String) obj ;checkboxState = (boolean[]) in.readObject();otherSeqsMap.put(nameToShow, checkboxState) ;listVector.add(nameToShow) ;incomingList.setListData(listVector) ;} I I close whi l ecatch(Exception ex) {ex.printStackTrace();}I I close runII close inner classappendix A Final Code KitchenW~~II a ~esS4(deseriaJi~) {h~t: ill, lIIe read~~ssage alld.L e 1110 ob iet L (t hetkb. ,;he Arra c: rs thethe JL~~ stau vallAesf~ Ids+, 0+ Boo/eall. JC to~p .L I'l tidd ·.L JIS a 1;111 U Ohen,;. Add' I,; 1;00+ the!:;ts p thil'l.9: 'lOlA k 1 11 9 to a JListfashioned Adata !Vetto :~p a VettorJList to rrayLisi) a ; 't. an oJd_.for wh t lAse thai. Ve~k hen t~1J t hpublic class MyPlayMineListener implements ActionListener { a to display' .L as it's SOIA epublic void actionPerformed(ActionEvent a) { III ,; h~ lisi.. rt~i f (mySequence != null) {sequence = mySequence;}} II close actionPerformedII close inner classpublic void changeSequence(boolean[]for (int i = 0; i < 256; i++) {JCheckBox check = (JCheckBox)i f (checkboxState[i]) {check.setSelected(true) ;else {check.setSelected(false) ;}II c l ose l oopI I close change SequenceII restore to my originalpublic void makeTracks(ArrayList list)Iterator it = list. iterator();for (int i = 0; i < 16 ; i++) {Integer num = (Integer) it.next();if (num != null) {int numKey = num.intValue() ;track.add(makeEvent(144 ,9 ,numKey, 100, i» ;track.add(makeEvent(128,9,numKey,100, i + 1»;}} I I close loopI I close makeTracks()This Ift~thod is tailed h tsO lftethin~ .ft-Olft th I'i ~ he lASer selettscheckboxSta~,n~ the patter:;;.fh e /NI'j1hf;[)/ATE.LYe one .. ey selet ted.checkboxList.get(i) ;All the MIDI sh H is ~uttl~was in the yYe'JiolAS 'Jet-Slon.the SaMe as it._ - - - - - - - - -you are here. 655


final BeatBox codepublic MidiEvent makeEvent(int comd, int chan, int one, int two, int tick) {MidiEvent event = null;try {ShortMessage a = new ShortMessage();a. setMessage (comd, chan, one, two);event = new MidiEvent(a, tick);}catch (Exception e} { } \i~e the last ~e'f"si()'l\·return event;Not\\'''~ "eVl· J~t} II close rnakeEvent} II c l os e c l a s s~yourpenCiiWhat are some of the ways you can improve this program?Here are a few ideas to get you started :1) Once you select a pattern, whatever current pattern was playing is blownaway. If that was a new pattern you were working on (or a modification ofanother one), you're out of luck.You might want to pop up a dialog box thatasksthe user if he'd like to savethe current pattern.2) If you fail to type in a command-line argument, you just get an exceptionwhen you run it! Put something in the main method that checks to see ifyou've passed in a command-line argument. If the user doesn't supply one,either pick a default or print out a message that saysthey need to run itagain, but this time with an argument for their screen name.3) It might be nice to have a feature where you can click a button and itwill generate a random pattern for you.You might hit on one you really like.Better yet, have another feature that lets you load in existing 'foundation'patterns, like one for jazz, rock, reggae, etc. that the user can add to.You can find existing patterns on the Head First Java web start.656 appen dix A


appendix A Final Code KitchenFinal BeatBox server programMost of this code is identical to the SimpleChatServer we made in theNetworking and Threads chapter. The only difference , in fact, is that this serverreceives, and then re-sends, two serialized objects instead of a plain String(although one of the serialized objects happens to be a String).import java.io.*;import java.net.*;import java.util.*;public class MusicServerArrayList clientOutputStreams;public static void main (String[] args) {new MusicServer() .go();public class ClientHandler implements Runnable {ObjectlnputStream in;Socket clientSocket;public ClientHandler(Socket socket) (try {clientSocket = socket;in = new ObjectlnputStream(clientSocket.getlnputStream(»;catch(Exception ex)} II close construct or(ex.printStackTrace();}public void run {} {Object 02 = null;Object 01 = null;try {while ((01 = in.readObject(» != null) (02 = in.readObject();System.out.println("read two objects") ;tellEveryone(01, 02);I I close whilecatch(Exception ex)I I close runII c los e inne r c lass(ex.printStackTrace();}you are here ~ 657


final BeatBox codepublic void qo() {clientOutputStreams = new ArrayList();try {ServerSocket serverSock = new ServerSocket(4242);while (true) {Socket clientSocket = serverSock.accept();ObjectOutputStream out = new ObjectOutputStream(clientSocket.qetOutputStream(»clientOutputStreams.add(out);Thread t = new Thread(new ClientHandler(clientSocket»;t. start() ;System.out.println("qot a connection");}}catch(Exception ex) {ex.printStackTrace();}II close gopublic void tellEveryone(Object one, Object two)Iterator it = clientOutputStreams.iterator();while(it.hasNext(» {try {ObjectOutputStream out = (ObjectOutputStream) it.next();out.writeObject(one) ;out.writeObject(two) ;}catch(Exception ex) {ex.printStackTrace() ;}II close t e l l Everyone} I I close class658 appendix A


Appendix BThe Top Ten Topics that almost made it into the Real Book...We covered a lot of ground,and you're almost finished with this book. We'll miss you, but beforewe let you go, we wouldn't feel right about sending you out Into JavaLand without a little morepreparation. We can't possibly fit everything you'll need to know Into this relatively small appendix.Actually, we did originally Include everything you need to know about Java (not already covered bythe other chapters), by reducing the type point size to .00003. It all fit, but nobody could read It. So,we threw most of it away,but kept the best bits for this Top Ten appendix.This really Is the end of the book. Except for the Index (a must-read I).this is a new appendix 659


it manipulation#10 Bit ManipulationWhy do you care?We've talked about the fact that there are 8 bits in a byte,16 bits in a short, and so on. You might have occasion toturn individual bits on or off. For instance you might findyourself writing code for your newJava enabled toaster,and realize that due to severe memory limitations, certaintoaster settings are controlled at the bit level. For easierreading, we're showing only the last 8 bits in the commentsrather than the full 32 for an int).Bitwise NOT Operator: ...This operator 'flips all the bits' of a primitive.int x = 10;x = -x;The next three operators compare two primitives on a bitby bit basis, and return a result based on comparing thesebits. We'll use the following example for the next threeoperators:int x = 10;int y = 6;Bitwise AND Operator:II bits are 00001010II bits are now 11110101II bits are 00001010II bits are 00000110This operator returns a value whose bits are turned on onlyif bothoriginal bits are turned on:int a = x «y; II bits are 00000010Bitwise OR Operator:This operator returns a value whose bits are turned on onlyif either of the original bits are turned on:int a = x I y; II bits are 00001110Bitwise XOR (exclusive OR) Operator: AThis operator returns a value whose bits are turned on onlyif exactly oneof the original bits are turned on:&The Shift OperatorsThese operators take a single integer primitive and shift (orslide) all of its bits in one direction or another. Ifyou wantto dust off your binary math skills,you might realize thatshifting bits left effectively multiplies a number by a power oftwo, and shifting bits right effectively divides a number by apower of two.We'll use the following example for the next three operators:int x = -11; II bits are 11110101Ok, ok, we've been putting it off, here is the world'sshortest explanation of storing negative numbers, andtwo's complement. Remember, the leftmost bit of an integernumber is called the sign bit. A negative integer number inJava always has its sign bit turned on (i.e. set to 1). A positiveinteger number always has its sign bit turned 011(0). Javauses the two's complement formula to store negative numbers.To change a number's sign using two's complement, flip allthe bits, then add 1 (with a byte, for example, that wouldmean adding 00000001 to the flipped value).Right Shift Operator: »This operator shifts all of a number's bits right by a certainnumber, and fills all of the bits on the left side with whateverthe original leftmost bit was.The sign bit does notchange:int y = x »2; II bits are 11111101Unsigned Right Shift Operator: »>Just like the right shift operator BUT it ALWAYS fills theleftmost bits with zeros. The sign bit mightchange:int y = x»> 2; II bits are 00111101Left Shift Operator: «Just like the unsigned right shift operator, but in the otherdirection; the rightmost bits are filled with zeros. The sign bitmightchange.int y = x «2; II bits are 11010100int a = x A y; II bits are 00001100660 appendix B


appendix B Top Ten Reference#9 ImmutabilityWhy do you eare that Strlt1i!..are 1"''Mutable?When yourJava programs start to get big. you 'llinevitably end up with lots and lots ofString objects.For security purposes, and for the sake ofconservingmemory (remember yourJava programs can run onteeny Java-enabled cell phones), Strings in java areimmutable. What this means is that when you say:String s = "0";for (int x :: 1; x < 10; x++) (8 = S + Xi)What's actually happening is that you're creating tenString objects (with values "0", "01", "012 ", through"0123456789") . In the end s is referring to the Stringwith the value "0123456789", but at this point thereare ten Strings in existenceIWhenever you make a new String, theJVM puts itinto a special part of memory called the 'String Pool'(sounds refreshing doesn't it.?). If there is alreadya String in the String Pool with the same value, theJVM doesn't create a duplicate, it simply refers yourreference variable to the existing entry. TheJVM canget away with this because Strings are immutable; onereference variable can't change a String's value outfrom under another reference variable referring tothe same String.The other issue with the String pool is that theGarbage Collector doesn't go there. So in our example.unless by coincidence you later happen to make aString called "01234", for instance, the first nineStrings created in our forloop willjust sit aroundwasting memory.Why do you care that Wra2!.ers areIt"",utable?In the Math chapter we talked about the two mainuses of the wrapper classes:• Wrapping a primitive so it can pretend to be anobject.• Using the static utility methods (for example,Integer.parselnt ()).It's important to remember that when you create awrapper object like:Integer iWrap :: new Integer(42);That's it for that wrapper object. Its value will alwaysbe 42. There is no settermethodfor a wrapper object.You can, of course, refer iWrapto a different wrapperobject, but then you'll have two objects. Once youcreate a wrapper object, there's no way to changethe value of that objectlRoses orered. .Strln ' Violets oreblue.11Sar.'mmutobf, .e, 'NfDppe,s are too.How does this save memory?Well, ifyou're not careful, it dcesn 't! But ifyou understandhow String immutability works, than youcan sometimes take advantage of it to save memory.Ifyou have to do a lot ofString manipulations (likeconcatenations, etc .), however, there is another classStringBuilder, better suited for that purpose. We'lltalk more about StringBuilder in a few pages.you are here ~ 661


assertions#8 AssertionsWe haven't talked much about how to debug yourJavaprogram while you 're developing it. We believe thatyou should learnjava at the command line, as we'vebeen doing throughout the book. Once you're aJavapro, ifyou decide to use an IDE*, you might haveother debugging tools to use. In the old days, whena java programmer wanted to debug her code, she'dstick a bunch ofSystem .out.println( ) statementsthroughout the program, printing current variablevalues, and "I got here" messages, to see ifthe flowcontrol was working properly. (The ready-bake codein chapter 6 left some debugging 'print' statementsin the code.) Then, once the program wasworkingcorrectly, she'd go through and take aU those System .out.println( ) statements back out again. It wastedious and error prone. But as ofJava 1.4 (and 5.0),debugging got a whole lot easier. The answer?AssertionsAssertions are like Systern.out.println ( ) statementson steroids. Add them to your code as you wouldadd println statements. Thejava 5.0 compilerassumes you 'll be compiling source files that are 5.0compatible, so as ofJava 5.0, compiling with assertionsis enabled by default.At runtime, ifyou do nothing, the assert statementsyou added to your code will be ignored by theJVM,and won't slow down your program. Butifyou tell theJVM to enable your assertions, they will help you doyour debugging, without changing a line of codeISome folks have complained about having to leaveassert statements in their production code, butleaving them in can be really valuable when yourcode is already deployed in the field. !fyour clientis having trouble, you can instruct the client to runthe program with assertions enabled, and have theclient send you the output. Ifthe assertions werestripped out ofyour deployed code, you'd neverhave that option. And there is almost no downside;when assertions are not enabled, they are completelyignored by thejVM, so there's no performance hit toworry about.How to make Assertions workAdd assertion statements to your code wherever youbelieve that something must be true. For instance:assert (height> 0);II if true, program continues normallyII if false, throw an AssertionErrorYou can add a little more information to the stacktrace by saying:assert (height> 0) : "height = " +height + "weight = " + weight;The expression after the colon can be any legalJava exp ression that resolves to a non-null value. Butwhatever you do . don't create assertions that cJumge anobjed's stale! Ifyou do, enabling assertions at runtimemight change how your program performs.Compiling and running withAssertionsTo compilewilh assertions:javac TestDriveGame.java(Notice that no command line options werenecessary.)To run with assertions:java -ea TestDriveGame'" IDE SlaDW for Integrated Development Environmentand includes tools such as Eclipse, Borland'sjbuilder, orthe open source NetBeans (netbeans.org).662 appsnuix B


appendix B Top Ten Reference#7 Block ScopeIn chapter 9, we talked about how local variableslive only as long as the method in which they'redeclared stays on the stack. But some variables canhave even shorterlifespans. Inside ofmethods, weoften create blocks of code. We've been doing thisall along, but we haven't explicitly talkedin terms ofblocks. Typically, blocks ofcode occur within methods,and are bounded by curly braces {}. Some commonexamples ofcode blocks that you'll recognize includeloops (jar, while) and conditional expressions (like ifstatements).+,nod b\ot.\I.Let's look at an example: s-tarl. ~ -tne ,.,evoid doStuff () {~ J t.o the e"tiYe ",ethod, /_ lotal vayiable stofe"Lnt; x = 0; ~~ ~ 1 f blotk a"d '1 isfor (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 both i\'l st°fe1'0 fYOD e"', IH- e\'lQ o.f the tor loop blotkIn the previous example, y was a block variable,declared inside a block, and y went out ofscope assoon as the for loop ended. Your java programs willbe more debuggable and expandable ifyou use localvariables instead ofinstance variables, and blockvariables instead oflocal variables, whenever possible.The compiler will make sure that you don't try to usea variable that's gone out of scope, so you don't haveto worry about runtime meltdowns.you are here • 663


linked invocations#6 Linked InvocationsWhile you did see a little of this in this book, we tried to keep our syntax as clean andreadable as possible. There are, however, many legal shortcuts inJava, that you'll no doubtbe exposed to, especially if you have to read a lot code you didn't write. One of the morecommon constructs you will encounter is known as linked invocations. For example:StringBuffer sb = new StringBuffer("spring");sb = sb.delete(3,6) .insert(2,"umme") . de l e t e Ch a r At (l ) ;System.out.println("sb = " + sb);II result is sb = summerWhat in the world is happening in the second line of code? Admittedly, this is a contrivedexample, but you need to learn how to decipher these.1 - Work from left to right.2 - Find the result ofthe leftmost method call, in this case sb. delete (3, 6) . If youlook up StringBuffer in the API docs, you'll see that the delete () method returns aStringBuffer object. The result of running the delete () method is a StringBuffer objectwith the value "spr".3 - The next leftmost method (insert () )is called on the newly created StringBufferobject "spr". The result of that method call (the insert () method), is alsoa StringBufferobject (although it doesn't have to be the same type as the previous method return), and soit goes, the returned object is used to call the next method to the right. In theory, you canlink as many methods as you want in a single statement (although it's rare to see more thanthree linked methods in a single statement). Without linking, the second line of code fromabove would be more readable, and look something like this:sbsbsbsb.delete(3,6);sb.insert(2,"umme");sb.deleteCharAt(l);But here's a more common, and useful example, that you saw us using, but we thoughtwe'd point it out again here. This is for when your main0 method needs to invoke aninstance method of the main class, but you don't need to keep a reference to the instance ofthe class. In other words, the main0 needs to create the instance onlyso that main0 caninvoke one of the instance's methods.class Faa {public static void main (String [] args) [L L we do,,'t. ea-e ab~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, so we l.\Ol'l I'"t,he rOO r.: ~,. t.t. +.0 a ye-teyel'lt.e·void go () t.he l'Iew rOO 0 ~e}I I here's what we REALLY want. ..664 appendix B


appendix B Top Ten Reference#5 Anonymous and Static Nested ClassesNested classes come In many flavorsIn the GUl event-handling section ofthe book, we started using inner (nested) classes as asolution for implementing listener interfaces. That's the most common, practical, and readableform of an inner class-where the class is simply nested within the curly braces ofanotherenclosing class. And remember, it means you need an instance of the outer class in order to getan instance of the inner class, because the inner class is a member ofthe outer/enclosing class.But there are other kinds ofinner classes including staticand arwnymous. We're not goinginto the details here, but we don't want you to be thrown by strange syntax when you see it insorneone's code. Because out ofvirtually anything you can do with theJava language, perhapsnothing produces more bizarre-looking code than anonymous inner classes. But we'll start withsomething simpler--static nested classes.Static nested classesYou already know what static means-s-something tied to the class, not a particular instance. Astatic nested class looksjust like the non-static classes we used for event listeners, except they 'remarked with the keyword static.public class FooOuter (class Barlnnervoid saylt() {System. out.printin ("method of a)}static inner class");class Test (publ ic s t atic voidfaa. sayIt () ;Static nested classes are more like reguJar non-nested classes in that they don't enjoy a special relationshipwith an enclosing outer object. But because static nested classes are still considered a member oithe enclosing/outer class, they still get access to any private members of the outer class... but only theonesthat arealso statu. Since the static nested class isn't connected to an instance of the outer class, itdoesn't have any special way to access the non-static (instance) variables and methods.you are here ~ 665


when arrays aren't enough#5 Anonymous and Static Nested Classes, continuedThe diHerenee between nested and InnerAnyJava class that's defined within the scope of another class is known as a rI£SU:d class. Itdoesn't matter ifit's anonymous, static. normal, whatever. Ifit's inside another class, it'stechnically considered a nested class. But non-statu nested classes are often referred to as innerclasses, which is what we called them earlier in the book. The bottom line : all inner classes arenested classes, but not all nested classes are inner classes.Anonymous inner classesImagine you 're writing some GUI code, and suddenly realize that you need an instanceof a class that implements ActionListener. But you realize you don't have an instance of anActionl.istener, Then you realize that you also never wrote a class for that listener. You have twochoices at that point:1) Write an inner class in your code, the way we did in our GUI code, and then instantiate itand pass that instance into the button's event registration (addActionListenerO) method.OR2) Create an anonymous inner class and instantiate it, right there.just-in-time. Litera11y rightwhere YlJU are at the pmnt you need the listeneror,jed. That's right, you create the class and theinstance in .the place where you'd normally be supplyingjust the instance. Think about that fora moment-it means you pass the entire cla.sswhereyou'd normally pass only an instance into amethod argumentl}666 appendix 8


access levelsappendix B Top Ten Reference#4 Access Levels and Access Modifiers (Who Sees What)Java has four access levels and three access modifiers. There are only three modifiers becausethe default (what you get when you don't use any access modifier) is one of the fouraccess levels.Access Levels (in order of how restrictive they are, from least to most restrictive)public ~ rlAblit ....eans any cede anywhere tan aUess the flAblit th in~ (bythin~' we ....ean tlass, I/ariable, ....ethod, tonstrlAttor, eUJ.protected "''-:- - - froutud works jlAst like detalAlt (tode in the sa....e fatka~e has auess), EXCEPT italso allows slAbtiasses olAtside the fatka~e to inherit the yrotetud thin~.default ~detalAlt aUess ....eans that only cede within the sa....e fatka~e asthe tlass with the detalAlt thin~ tal'l aUess the detalAlt th in~.private ~ fril/at e ....eans that ol'lly tode withil'l the same dass tal'l aUess the yril/ate thin~.Keef il'l mil'ld it means fril/au to the tlass, not fril/ate to the objett. One D~tal'l see al'lother D~ objett's fril/au shU, blAt a Cat tan't see a D~'s yril/aus.Access modifierspublicprotectedprivateMost of the time you'll use only public and private access levels.publicUse public for classes, constants (static final variables) , and methods that you'reexposing to other code (for example getters and setters) and most constructors.privateUse private for virtually all instance variables, and for methods that you don't wantoutside code to call (in other words, methods used by the public methods ofyour class).But although you might not use the other two (protected and default), you still need toknow what they do because you'll see them in other code.you are here ~ 667


when arrays aren't enough#4 Access Levels and Access Modifiers, cont.default and protecteddefaultBoth protected and default access levels are tied to packages. Default access is simple-itmeans that only code within the samepackage can access code with default access. So adefault class, for example (which means a class that isn't explicitly declared as puhlil:) canbe accessed by only classes within the same package as the default class.But what does it really mean to MUSS a class? Code that does not have access to a class isnot allowed to even think about the class. And by think, we mean use the class in code.For example, ifyou don't have access to a class, because ofaccess restriction, you aren'tallowed to instantiate the class or even declare it as a type for a variable, argument, orreturn value. You simply can't type it into your code at all! !fyou do, the compiler willcomplain.Think about the implications-a default class with public methods means the publicmethods aren't really public at all. You can't access a method ifyou can't see the class.Why would anyone want to restrict access to code within the same package? Typically,packages are designed as a group of classes that work together as a related set. So it mightmake sense that classes within the same package need to access one another's code, whileas a package, only a small number ofclasses and methods are exposed to the outsideworld (i.e. code outside that package).OK, that's default. It's simple-ifsomething has default access (which, remember, meansno explicit access rnodifierl), only code within the same package as the default thing(class, variable, method, inner class) can access that thing.Then what's proucudfor?protectedProtected access is almost identical to default access, with one exception: it allows subclassesto inherit the protected thing, even iJthose subclasses are()UtsUU the pad1.age of the super-­class they extend: That's it. That's all protected buys you-the ability to let your subclassesbe outside your superclass package, yet still inherit pieces of the class, including methodsand constructors.Many developers find very little reason to use protected, but it is used in some designs,and some day you might find it to be exactly what you need. One ofthe interesting thingsabout protected is that-unlike the other access levels-protected access applies only toinheritance. Ifa subclass-outside-the-package has a nference to an instance of the superc1ass(the superclass that has, say, a protected method), the subclass can 't access the protectedmethod using that superclass referencel The only way the subclass can access thatmethod is by inheritingit. In other words, the subclass-outside-the-package doesn't haveaccess to the protected method. it just has the method, through inheritance.668 appendix B


String and StringBufferappendix B Top Ten Reference#3 String and StringBufferlStringBuilder MethodsTwo of the most commonly used classes in th eJava API are String and StringBuffer (remember from#9 a few pages back, Strings are immutable, so a StringBuffer/StringBuilder can be a lot mor efficientif you're manipulating a String). As ofJ ava 5.0 you should use the StringBuilderclass instead ofStringBuffer, unless your String manipulations need to be thread-safe, which is not common. Here's abriefoverview of the key methods in these classes:Both String and StringBuffer/StringBuilder classes have:char charAt(int index);int Iengtht):String substring(int start, int end );String to.String () :/ / what char is at a certain position/ / how long is th is/ / get a part of this/ / what's the String value of th isTo concatenate Strings:String concat (string);String append (String);/ / for the String class/ / for StringBuffer & StringBuilderThe String class has:String replace(char old, char new);String substring(int begin, int end);char [] toCharArrayO ;String toLowerCase() ;String toUpperCaseO;String trim() ;String valueOf(char [])String valueOf(int i)/ / replace all occurences ofa char/ / get a portion ofa String/ / convert to an array of chars/ / convert all characters to lower case/ / convert all characters to upper case/ / remove whitespace from the ends/ / make a String out ofa char array/ / make a String out ofa primitive/ / other primitives are supported as wellThe StringBuffer & StringBuilder classes have:StringBxxxx delete(int start, int end);StringBxxxx insert(int offset, any primitive or a char [] );StringBxxxx replace(int start, int end, String s);Stringlsxxxx reverser):void setCharAt(int index, char ch);/ / delete a portion/ / insert something/ / replace this part with this String/ / reverse the SB from front to back/ / replace a given characterNote: StringBxxxx refers to either StringBufferor StringBuilder, as appropriate.you are here. 669


when arrays aren't enough#2 Multidimensional ArraysIn most languages, ifyou create, say, a 4 x 2 two-dimensional array, you would visualize arectangle, 4 elements by 2 elements, with a total of8 elements. But inJava, such an arraywould actually be 5 arrays linked together! Injava, a two dimensional array is simply an arra)'of arrays. (A three dimensional array is an array ofarrays of arrays, but we'll leave that foryou to play with.) Here's how it worksi.nt ]] (] a2d = new int [4] (2];The JVM creates an array with 4 elements. Each. ofthese four elements is actually a referencevariable referring to a (newly created), int array with 2 elements.int[J(]int array object (int[][DWorking with multidimensional arrays- To access the second element in the third array: int x = a2d [2) [1) i I I remember, 0 based!- To make a one-dimensional reference to one ofthe sub-arrays: int [J copy = a2d [1 J;-Short-cut initialization ofa2x3array: intlJ I) x = ( l 2,3,4 }, I 7,8,9 } };- To make a 2d arraywith irregular dimensions:int(J [J y = new int (2) [); II makes only the first array, with a length of 2y[Ol new int (3J; II makes the first sub-array 3 elements in lengthy(l] = new int 15J; II makes the second sub-array 5 elements in length670 appendix B


enumerationsappendix B Top Ten ReferenceAnd the number one topic that didn't quite make it in...#1 Enumerations (also called Enumerated Types or Enums)We've talked about constants that are defined in the API, for instance,JFrame.EXIT_ON_CLOSE. You can also create your own constants bymarking a variable static final. But sometimes you'll want to create a setofconstant values to represent the onlyvalid values for a variable. This set ofvalid values is commonly referred to as an enumeration. BeforeJava 5.0 youcould only do a half-bakedjob of creating an enumeration in Java. As ofJava5.0 you can create full fledged enumerations that will be the envy ofall yourpre:Java 5.0-using friends.Who's in the band?Let's say that you 're creating a website for your favorite band, and you want tomake sure that all of the comments are directed to a particular band member.The old way to fake an "enum":public static final int JERRY = 1;public static final int BOBBY = 2 ;public static final int PHIL = 3;I I later in the code We're h . Lh L b Lh L "~ °flll~ ;; a;; y;; e ;;'l'WIe we ~ot hereif (selectedBandMember == JERRY) { " s det tedBalldMel'Wlber" has a valid val"t.!II do JERRY related stuffThe good news about this technique is that it DOES make the code easier toread. The other good news is that you can't ever change the value of the fakeenums you've created; JERRY will always be 1. The bad news is that there'sno easy or good way to make sure that the value of selectedBandMemberwill always be 1, 2, or 3. Ifsome hard to find piece of code setsselectedBandMember equal to 812, it's pretty likely your code will break...you are here ~ 671


when arrays aren't enough#1 Enumerations, cont.The same situation using a genuineJava 5.0 enum. While this is a very basicenumeration, most enumerations usually arethis simple.A new, official "enum":~public enum Members { JERRY, BOBBY, PHIL };publicYour enum extends java.lang.EnumWhen you create an enum, you're creating a new class, and you're implicitly extendingjava . lang. Enum. You can declare an enum as its own standalone class, in its ownsource file, or as a member ofanother class.Using "if" and "switch" with EnumsUsing the enum wejust created, we can perform branches in our code using eitherthe if or switch statement. Also notice that we can compare enum instances usingeither == or the . equals () method. Usually == is considered better style.Members n = Members.BOBBY; ~Members ifName = Members.PHIL;switch (ifName) {case JERRY: System.out.print("make it sing ");case PHIL: System. out.print("go deep ") ;case BOBBY: System.out.println("Cassidy! ");______ Assi~r.ir.~ ar. er.1mI yal~ to a variable,if (n .equals(Members.JERRY)) System.out.println("Jerrrry!"); I. r, el0'(" """ ,if (n == Members.BOBBY) System.out.println("Rat Dog"); "--- ~o-\:)l J t"'e$e '"""$ ,"",,-\:,ed,"Rat D ~672 appendix 8


enumerationsappendix B Top Ten Reference#1 Enumerations, completedA really tricked-out version of a similar enumYou can add a bunch of things to your enum like a constructor, methods.variables, and something called a constant-specific class body. They'renot common, but you might run into them:L sstO il'\ -\:ppublic class HfjEnum ( ay~"",el'\1:. ~a L.\________ nils is a~\Il.~ oeda....td ~ o'Wl·enum Names ( ~__ L.' • _ ~~_ . ~e ~Q'I\S th $O-t.llleoJERRi' ("lead guitar) { public String sings () { ~ Tkese a....e e ok' dau bodies".return "plaintively";} ;/ "~Ylt.-s?etl It o . -th} J Think ~ t.he'" as O"t:rt"IO.ln~ eoLLod (iYl -thIS t,4StBOBBY ("rhythm guitar") ( public String s i nqs () I \)asit eYl.........n.n r oO .return "hoarsely"; ) the "S'IYI~O)l ""et.hcxl), iot S,,\~ IS), t.llleo 0" a lIayid'ole ...ith aYl en--PHIL ("bass") ; I r J~RRY ~ BOBBY·lIa v.t o-tprivate String instrument;Names(String instrument) (this. instrument = instrument;)public String getlnstrument{)return this. instrument;)public String sings () (return "occasionally";~~--This is -the tr>lAM'S toYlShvttm-. It. ruYlSOWIU +t*' e6th detla....ed eYllAM I/al~t.his ~ it. ...."'W\.\ t.hree tiMes)o(iYlpublic static void main(String [] args) (0 ___________for (Names n : Names.values(») ( ~System.aut.print


when arrays aren't enoughCaptain Byte gave Ensign Smith the following programming instructions to process the criticalnavigational codes:A Long Trip HomeCaptain Byte ofthe Flatland starship "Traverser" had received an urgent, Top Secret transmissionfrom headquarters. The message contained 30 heavily encrypted navigational codes that theTraverser would need to successfully plot a course home through enemy sectors. The enemyHackarians, from a neighboring galaxy, had devised a devilish code-scrambling ray that was capableofcreating bogus objects on the heap of the Traverser's only navigational computer. Inaddition, the alien ray could alter valid reference variables so that they referred to thesebogus objects . The only defense the Traverser crew had against this evil Hackarian ray wasto run an inline virus checker which could be imbedded into the Traverser's state ofthe artJava 1.4 code."Put the first five codes in an array of type ParsecKey. Put the last 25 codes in a five by five, twodimensional array oftype QuadmntKey. Pass these two arrays into the plolCourseO method ofthepublic final class Shipblavigation. Once the course object is returned run the inline virus checkeragainst all the programs reference variables and then run the NavSim program and bring me theresults."A few minutes later Ensign Smith returned with the NavSim output. "NavSim output ready forreview, sir", declared Ensign Smith. "Fine", replied the Captain. "Please review your work". "Yessir!", responded the Ensign, "First I declared and constructed an array of type ParsecKey with thefollowing code ; ParsecKey 0 p = new ParsecKey[5]; , next 1 declared and constructed an arrayoftype QuadrantKey with the following code: QuadrantKey 0 0 q = new QuadrantKey [5] [5]; .Next, I loaded the first 5 codes into the ParsecKey array using a 'for' loop, and then I loaded the last25 codes into the Quadrantkey,array using nested 'for'{oops, Next, I ran the virus checker againstall 32 reference variables, I for the ParsecKey array, and 5 for its elements, I for the QuadrantKeyarray. and 25 for its elements. Once the virus check returned with no viruses detected, I ran theNavSim program and re-ran the virus checker, just to be safe...Sir!"Captain Byte gave the Ensign a cool , long stare and said calmly, "Ensign, you are confined toquarters for endangering the safety oftbis ship, I don't want to see your face on this bridge againuntil you have properly learned your Java! Lieutenant Boolean, take over for the Ensign and do thisjob correctly!"674 appendix BWhy did the captain confine the Ensign to his quarters?


A Long Trip HomeCaptain Byte knew that in Java, multidimensional arrays are actuallyarrays of arrays. The five by five QuadrantKey array 'g', wouldactually need a total of31 reference variables to be able to accessall ofits components:I - reference variable for 'q'5 - reference variables for q [0) - q [4J25 - reference variables for q [0] [0] - q [4] [4]The ensign had forgotten the reference variables for the five onedimensional arrays embedded in the 'q' array. Any of those fivereference variables could have been corrupted by the Hackarianray, and the ensign's test would never reveal the problem.you are here ~ 675


This isn't goodbyeBring your brain over towickedlysmart.com

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!