The words you are searching are inside this book. To get more targeted content, please make full-text search by clicking here.
Discover the best professional documents and content resources in AnyFlip Document Base.
Search
Published by , 2018-04-08 11:57:54

head-first-java-2nd-edition

head-first-java-2nd-edition

htitializhtg a static variable numbers and statics

Static variables are initialized when a class is loaded: A class is All static variables
loaded because thejVM decides it's time to load it. Typically, in a class are
the jVM loads a class because sornebody's trying to make a Initialized before
new instance of the class, for the first time, or use a static any object of
method or variable of the class. As a programmer. you also that class can be
have the option of telling thejVM to load a class, but you're created.
not likely to need to do that. In nearly all cases, you're better
off letting the jVM 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 that
class can be created.

Static variables in a class are initialized before any static method
of the class runs.

olass Player {

static int playerCount ;:; 0;

private String name;
public Player(String n)

n&IIl8 = n;

playerCount++ ;

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\<St. like a Sta-t'I(.
...d.hod-wit.h the tlass l'Id",e.

Static variables are initialized when the class is loaded. If you
don't explicitly initialize a static variable (by assigning it a
value at the time you declare it), it gets a default value, so int
variables are initialized to zero, which means we didn't need
to explicitly say "playerflount = 0", Declaring. but not initial-
izing, a static variable means the static variable will get the de-
fault value for that variable type, in exactly the same way that
instance variables are given default values when declared.

you are here ~ 281

static final constants

-static fh1al variables are cot1stat1ts

A variable marked finalmeans that-s-once initialized-it can
never change. In other words, the value of the static final variable
will stay the same as long as the class is loaded: Look up Math.PI
in 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 an
instance of class Math (which, remember, you're not allowed to
create).

The variable is marked final because PI doesn't change (as far as
Java is concerned).

There is no other way to designate a variable as a constant, but

there 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: If you don't give a value to a finol vorlable
in one of those two places:
public clulS ]1'00 (
publ~c static final lot FCC_X = 25; public class Bar (
public static final double BAR_SIGN;
b~t~"j't~~}.esIh/aOtrJlJia,.}ebdl~"". ~ ~lo)r.vlblbtOPl '\ 110 illi'b _}il4 t;olll

di-e -~~i.lbt. The complier will catch It:
e all "pp&
lAPldc....-.,._~. J ..s.o.,i~Ulaell
$Cpal"'ab .l,f.d$C,
OR ~ Ule 'worcit

• In 0 static Inltfollzer:

public class Bar {
public IlltatiC final double BAR SIGN;

fitlal iSKt just for static numbers and statics
variables...
A linaL variable means you
You can use the keyword final to modify non- can't change its value.
static variables too, including instance variables.
local variables, and even method parameters. In A tinal method means you
each case, it means the same thing: the value can't
be changed. BUl you can also use final to stop can't override the method.
someone from overriding a method or making a
subclass. A tinal class means JOU

non-static final variables can't extend the class (i.e.
you can't make a subclass).
clan Foo! ( 'f0!> t.'!,,'f, thd,,~e S'IU
final Int size '" 3; f-- YI()W

final int whuffi.e;

Foof () ( = 42; ~ \'\ow 'fo ... t<lI'I't Lha,,~e I.H'
whuffie
Wh re

)

void doStuff{final iet x)

I I you can' t change )Ii

void doMore () (

final iet z '" 7;

II you can't change z

final method

class Poo£ (
final void calcWhuffi.e ()

II ~rtant things
II that must never be overridden

final class

final class MyMostPer£ectClass

II cannot be llIxtended

you are here ~ 283

static and final • Astatic method should be called using the class
name rather than an object reference variable:
Q...: Astatic method can't access II Maoth . random () vs. myFoo . go ( )

non-static variable. But can a non-statlc • Astatic method can be invoked without any Instances
method access II static variable? ofthe method's class on the heap.

A: Of course.Anon-static method ina • Astatic method isgood for autility method that does
not (and will never) depend on a particular Instance
class can always call a static method In the variable value.
class or access a static variable of the class.
• Astatic method is not associated with aparticular
Q...: Why would I want to make a class instanee----only the c1ass---so Itcannol access any
Instance vanable values offts class. Itwouldn't know
final1 Doesn't that defeat the whole which Instance's values to use.
purpose of 007
• Astatic method cannot access anon-static method,
A: Yes and no.A typical reason for since non-static methods are usually associated with
instance variable state.
making a class final Isfor security.You
can't, for example, make a subclass of the • Ifyou have a class with only static methods, and you
String class.Imagine the havoc If someone do not want the class tobe instantiated, you can mark
extended the String class and substituted the constructor private.
their own String subclass objects,
polymorphically, where String objects • Astatic variable isa variable shared byall members
are expected. Ifyou need to count on a ofa given class. There isonly one copy ofa static
particular Implementation of the methods variable ina class, rather than one copy per each
Ina class,make the class final. individual instance for instance variables.

Q...: Isn't It redundant to have to mark • Astatic method can access a static variable.

the methods final Ifthe class Is final? • To make a constant in Java, mark a variable as both
static and final.
A: If the class Isfinal,you don't need to
• Afinal static variable must be assigned a value either
rnarkthe methods final. Thinkabout It-If atthe time it isdeclared, orin a static initializer.
a class Isfinal It can never be subclassed, static {
so none ofthe methods can ever be
overridden. DOG_CODE:: 420;
On the other hand, If you do want to allow }
others to extend your class,and you want
them to be able to override some, but not • The naming convention for constants (final static
all,of the methods, then don't mark the variables) Is to make the name aU uppercase.
class final but go In and selectively mark
specific methods as final.A final method • A final variable value cannot be changed once Ithas
means that a subclass can't override that been assigned.
particular method.
• Assigning a value to a final Instance variable must be
284 chapter 10
either at the time It Is declared, orinthe constructor.

• Afinal method cannot be overridden.

• Afinal class cannot be extended (subclassed).

numbers and statics

~ yoor pencil

What's Legal? ...KEEP

Given everything you've just RIGHT
learned about static and final,
which of these would compile?

• public clll.Sl! 11'00 • public class F004 12;
static: int Xi BUtic final int x
public: void go() ( public: void go() (
Systam.out.println{x) ; Systam.out.println(x) ;

• public c:lass Foo2 { • public: c1ass Foo5 (
int Xi statio tiDal int X '" 12;
public static void go () (
Syatem.out.println(x); public void go (final int x)
System.out.println(x);

• public class Foo3 • public class Foo6
final int X i int x '" 12;

public: void go() ( public static void go(final int x) (
Syatem.out.println(x); SyatBm ,out.println{xl;

you are here) 285

Math methods

Math lItethods Math.random{)

Now that we know how static Returns a double between 0.0 through (but
methods work, let's look
at some static methods in not including) 1.0.
class Math. This isn't all of
them,just the highlights. =double rl Math. random 0 ;
Check your API for the rest
including sqrtf), tant), ceilf), int r2 = (int) (Math.random() * 5);
floor'(), and asint).

Math.absO 240.45

Returns a double that is the absolute value of
the argument. The method is overloaded, so
if you pass it an int it returns an into Pass it a
double it returns a double.

=int x Math .abs(-240); II returns 240
double d = Math.abs(240.45); II returns

Math.roundO

Returns an int or a long (depending on

whether the argument is a float or a double)

rounded to the nearest integer value.

int x = Math.round( -24.8f); II returns -25
int y = Math.round(24.45f); II returns 24

t Re"'e",bel"', .floa'bn~ point lit el"'als al"'e ass"''''ed

to be do",bles "'nless yo", add t he '.f',
Math.minO

Returns a value that is the minimum of the

two arguments. The method is overloaded to

take ints , longs, floats, or doubles.

int x = Math.min(24,240); II returns 24
=double y Math.min(90876.5, 90876 .49); II returns 90876.49

Math.maxO

Returns a value that is the maximum of the
two arguments. The method is overloaded to
take ints, longs, floats, or doubles.

=int x Math.max(24,240); II returns 240
=double y Math.max(90876 .5, 90876.49); II returns 90876.5

286 chapter 10

Wrappit1g a pritttifive numbers and statics

Sometimes you want to treat a primitive like ~ object
an object For example, in all versions ofJava
prior to 5.0, you cannot put a primitive directly primitive
into a collection like ArrayList or HashMap:
When you need to treat
int x :: 32;
a primitive like an object,
=ArrayList list new ArrayList(); wrap it. Ii you're using any
version of Java before 5.0,
list. add (xl i ~ you'll Jo this when you

I"" s,:''v '" ()Ttt~.hh\h'iaas"tte..L'a0tt=-1aa.0~kI."kI''ete"TswohaObt"j'"reke.,d,,:s'Lt...JI"1>"t(O.t:bfS~".Saul.Ye.J~Tdli(Jr.'.ft!.-sL.~,\ t\.f&IO0S1'Lti\.1~'1~Jo'h'ad.'av'saI'1'1t\.a'iSv~d.eaOd's·J)m!-I-"'iC_sLVt~.'ods need to store a primitive

There's a wrapper class for every primitive type, value inside a collection like
and since the wrapper classes are in the java.
lang package, you don't need to import them . ArrayList or lIashMap.
You can recognize wrapper classes because
each one is named after the primitive type it ..,.."
wraps, but with the first letter capitalized to
follow the class naming convention. ~'feginetr o~f1I

Oh yeah, for reasons absolutely nobody on the
planet is certain of, the API designers decided
not to map the names exactly from primitive
type to class type. You'll see what we mean:

Boolean

Chara~ter ~

Byte Watth 0I<t.! The N",es al"'~"J.t..
Short / ",ayyed e'll4d.l'f to the ~1"'i~l\Jt

Integer t~s. The tlolS na...es are .. 'f
Long sfelltd o>J.t..

Float

Double

Note: the plchJre III \he top Is a chocolate In e roll wrapper. Get
It? WraPP6r? Some people think It looks like a baked potato. bill
\hilt Wlll1ls100.

you are here. 287

static methods

This is stupid, You mean I can't
just makean ArrayList of ints??i I
have to wrap every single frickin' one in a new
Integer object, then unwrap it when I try
to access that value in the ArrayList?

That's a waste of t ime and an error
waiting 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 primitives
and object references were object references. and they were NEVER
treated interchangeably. It was always up to you, the programmer, to do
the wrapping and unwrapping, There was no way to pass a primitive to a
method expecting an object reference, and no way to assign the result of a
method returning an object reference directly to a primitive variable----even
when the returned reference is to an Integer and the primitive variable is
an 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 hold
the primitive the Integer wraps). All the work was up to you.

An ArrayList of primitive ints

Without autoboxing (Java versions before 5.0) t '? 0 ~~ ~tauD\lJ.bI ~'l'elOc"t{.,.h')
~(Rat"ll,t"l\,'rbYear~,Lb.ie~boY.t..n:r~' \i~b
pub Li c void doNumsOldWay () { M1faeGlui~~al'lt\Ao.trrTa~1/Lp':2r-t.'-

you=ArrayList a yLi

tlistOfNum i ~
listOfNumbe rs new A r r st(); t.hl l
bers, add (new In ger (3»
so '/0c'0.'a~nI<~I\Ia~ d\idP. t\o.e y . 1., ('l' L lise-,
'IUllt
t e wYao r"I" ?ll\\uP~~"" ~1.""St.
'n' dl'l
I "r\:.

In teger one = (Inteqer) lis tofNumbers . ge t (0) ; ~""'lS O'o't as t'fVl
Ot.bh~'tdO:.b,jbtGutt. t~oO'o>alG\ aI""lU..~destr. .
int intone = ODe. intValue () ;
y~ tFihd/ly
t "
out 0+ the
Itdn"u~. hI! pl"''''ltivt:'

2BB chapter 10

numbers and statics

Autoboxing: blurring the line
between pritMitive and object

The autoboxing feature added to Java 5.0 does
the conversion from primitive to wrapper object
automaticalyl !

Let's see what happens when we want to make an
ArrayList to hold ints.

An ArrayList of primitive ints

With autoboxing (.Java versions 5.0 or greater)

public void doNumsNewWay() { Make al'l fl1\. rra~ L: t ok t'j\'e Il'lteCjer.
ArrayList<Integer> listOfNumbe rs
IS
-l
new Arra yList<Integer>();

li stOfNumbe rs.add(3); JlASt add it ! AH:holA~h there is NOT a ",eihod il'l ArrayList

=int num listOfNumbers.get(O); .f01" add(iI'lV, the lon-piler does all the wrafpil'l5

":h':I:~~~~~e:;uto",atilallyul'lwraps (IAl'lbo~es) (bo)/,;n5) .for 'lOlA. 11'1 other words, there I"eall'l IS
idnitrVeallli!A~()to a f:.lrei""It~lvoey'o~~/ItlahOll'lAtashsai5v1'i1n5thteo int va/loe
lall the a\'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 takes

ints. cyOIA lan add both ints al'ld l\'Ite~ers to al'l

A'f'l"a'lList<lnte~er>.)

....ethod 0\'1 the Inte5er objelt.

Q.: Why not declare an ArrayList<int> if you want to

hold ints7

A.: Because...you can't. Remember,the rule for generic

types is that you can specify only class or interface types, not
primitives. So ArrayList<int> will not compile. But as you can

see from the code above, it doesn't really matter, since the
compiler lets you put ints into the ArrayList<lnteger>.ln fact,

there's really no way to preventyou from putting primitives

into an ArrayList where the type of the list is the type of that
primitive's wrapper, if you're using a Java S.D-compliant com-
piler, since autoboxing will happen automatically. So,you can
put boolean primitives in an ArrayList<Boolean> and chars
into an ArrayList<Character>.

you are here ~ 289

staUc methods

Aufoboxit1Q works al",ost everywhere

Autoboxing lets you do more than just the obvious wrapping and
unwrapping to use primitives in a collection... it also lets you use
either a primitive or its wrapper type virtually anywhere one or the
other is expected. Think about thatl

Fun with autoboxing

Method arguments .~ \1

If a method takes a wrapper type, you "''>1''ger Ol:i~ / int
can pass a reference to a wrapper or
a primitive of the matching type. And void takeNumber(Integer i) { }
of course the reverse is true-if o
method takes (] primitive, you can int giveNumber ()
pass in either a compatible primitive
or a reference to a wrapper of that return X;
primitive type.

Return values

If a method declares a primitive
return type, you can return either a
compatible primitive or a reference
to the wrapper of that primitive type.
And if a method declares a wrapper
return type, you can return either a
reference to the wrapper type or a
primitive of the matching type.

Boolean expressions true

Any place a boolean value is expected, ~/ean o~f \1
you can use either an expression that
evaluates to a boolean (4 ) 2), or a boolean
primitive boolean, or a reference to a
Boolean wrapper. ~f

if (bool) {

System.out.println("trueH ) ;

290 chapter 10

numbers and statics

Operations on numbers i++i

This is probably the strangest one-yes, you
can now use a wrapper type as an operand
in operations where the primitive type is
expected. That means you can apply , say,
the increment operator against a reference
to an Integer object!

But don't worry-this is just a compiler trick.
The language wasn't modified to make the
operators work on objects; the compiler
simply converts the object to its primitive
type before the operation. It sure looks
weird, 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;

Assignments

You can assign either a wrapper or primitive
to a variable declared as a matching wrapper
or primitive. for example, a primitive int
variable can be assigned to an Integer
reference variable, and vice-versa-o
reference to an Integer object can be
assigned to a variable declared as an jnt
primitive.

~ your pencil public class TastBox

Will this code compile? Will Itrun? IfII runs, Integer i;
what will ~do7 int j;
Take your time and think about this one; it
brings up an implication ofautoboxing that public static void main (String[] ll%gs) (
we didn't talk about. T.stBox t ; new T.stBox() i
t.qo() ;
You'll have to go to your compiler to find
}
the answers. (Yes. we're forclng you to
experiment, for your own good ofcourse.) public void go 0

j-ii
Systam.out.println(j);
Systam.out .println(i);

you are here) 291

wrapper methods

Jut waltl There1s ",ore! Wrappers
have static utility tMethods too!

Besides acting like a normal class. the wrappers have a
bunch of reaJly useful static methods. We','e used one in
this book before--lnteger.parselntO.
The parse methods take a String and give you back a
primitive value .

Converting a String to a
primitive 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 Wrappers Every method or
Exception in thread "main N constructor that parses
java .lang.NumberFormatException: two a String can throw a
at java.lang.lnteger.parselnt(Integer .java:409) NumberFormatExceptlon.
at java .lang .lnteger.parselnt(Integer .java:458) It's a runtime exception,
at Wrappers.main(Wrappers.java:9) so you don't have to
handle or declare It.
292 chapter 10 But you might want to.

(We'U talk about Exceptions in the
next chapter.)

numbers and statics

Attd .,ow i" reverse... fuYttittg a
prhMitive ttutMber ittto a Strittg

There are several ways to tum a number into a String.

The easiest is to simply concatenate the number to an Lh '+' o~cra~ is o...~y\oa~,d

existing String. R,,,,t"'\'cr \. lAo",a,d.lt..\d.iWol~yc.rloatooto.d- as a
i" Java (tht. 1:.0 a
double d '" 42.5; t;-~ t.

_I'f
Stt·~.."oJ. cL.o-CWO lu\:.et.sNiS"hLiO,,~i-rr'.t1.dv.'
String doubleString = .... " + 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..bk

you are here ~ 293

number formatting

Nutttber fortttatti.,g

InJava, formatting numbers and dates doesn't have to be coupled with I/O. Think
about it. One of the most typical ways to display numbers to a user is through a
GUI. You put Strings into a scrolling text area, or maybe a table. If formatting was
built only into print statements, you'd never be able to format a number into a nice
String to display in a GUI. Before Java 5.0, most formatting was handled through
classes in the java. text package that we won't even look at in this version of the
book, now that things have changed.

In Java 5.0, theJava team added more powerful and flexible formatting through a
Formatter class injava.util. But you don't need to create and call methods on the
Formatter class yourself, because Java 5.0 added convenience methods to some of
the I/O classes (including printf'(j ) and the String class. So it's a simple matter of
calling a static String.formatO method and passing it the thing you want formatted
along with formatting instructions.

Of course, you do have to know how to supply the formatting instructions, and
that takes a little effort unless you're familiar with the frrintf() function in C/CH.
Fortunately, even if you don't know printf() you can simply follow recipes for the
most basic things (that we're showing in this chapter) . But you will want to learn
how to format if you want to mix and match to get anything you want.

We'll start here with a basic example, then look at how it works. (Note: we'll revisit
formatting again in the I/O chapter.)

Formatting a number to use commas

public class TestFormats (

public static void ma in (String[ ) args) {

String s = String. format ("lis, d",

System.out.println(s) ; ~

1,000,000,000

294 chapter 10

FortMaffit1g decot1sfrucfed... numbers and statics
yo u are here. 295
At the most basic level, formatting consists of two main parts
(th ere is more, but we'll start with this to keep it cleaner):

__ Formatting Instructions

You use special format specifiers that describe how
the argument should be formatted.

e The argument to be formatted.

Although there can be more than one argument, we'll
start with just one. The argument type can't be just
anything... it has tobe something that can be formatted
using the format specifiers inthe formatting instructions.
For example, if your formatting instructions specify a
floating point number, you can't pass ina Dog oreven a
String that looks like afloating point number.

•Do this... •to this.
format ("%, d", 1000000000);

~ ~

i\

Use these instructions... on this argument.

What do these Instructions actually say?

"Take the second argument to this method, and

format 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 percent
sign (%) in a format String (which is always the first argument
to a formatf ) method), think of it as representing a variable,
and the variable is the other argument to the method. The rest
of the characters after the percent sign describe the formatting
instructions for the argument.

the formatO method

The 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 it
can actually include characters that you just want printed as-is, without extra

formatting. When you see the % sign, though, think of the percent sign as a

variable that represents the other argument to the method.

I have 476578.10 bugs to fix.

The "%" sign tells the formatter to insert the other method argument (the
second argument to formatf), the number) here, At"lD format it using the
u .2r characters after the percent sign. Then the rest of Ute format Suing,
"bugs to fix" , is added to the final output .
Adding a comma

format("! have %,.2£ bugs to fix. u , 476578.09876);

I have 476,578.10 bugs to f~.

296 chapter 10

numbers and statics

But how does it even KNOW

where the instructions end and the

rest of the characters begin? How come

it doesn't print out the "f" in "%.2f'? Or

the "2"( How does it know that the .2f
was part of the instructions and NOT

part of the StriT\9?

The format Stri"Q uses its

ow., little lattguage sytttax

You obviously can't put just an),thingafter the "%~
sign. The syntax for what goes after the percent
sign follows very specific rules, and describes
how to format me argument that gets inserted at
that point in the result (formatted) String.

You've already seen two examples:

%, d means "insert commas and format the

number as a decimal integer,"

and

%.2£ means "format the number as a floating

point with a precision of two decimal places."

and

%,.2£ means "insert commas and format the

number as a floating point with a precision of
two decimal places."

The real question is really, "How do I know what
to put after the percent sign to get it to do what
I want?" And that includes knowing the symbols
(like "d" for decimal and "f" for floating point)
as well as the order in which the instructions
must be placed following the percent sign. For
example, if you put the comma after the "d" like
this: k%d,~ instead of "'%,d" it won 't workl

Or 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 specifier

The fortMat specifier

Everything 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, the
formatter assumes the next set of characters are meant to be pan of the output
String, until or unless it hits another percent (%) sign. Hmmmm ... is that even
possible? Can you have more than one formatted argument variable? Put that
thought 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 the
percent (%) sign and describe how the argument should be formatted.
A format specifier can have up to five different parts (not
Including the MOJo"). Everything In brackets [] below Is optional, so
only the percent (0J0) and the type are required. But the order Is
also mandatory, so any parts you DO use must go In this order.

%[argument number] [flags] [width) [.precision)type

%[argument number] [flags] [width) [.precision) type

------~Jl
format("%,6.1f N , 42.000);

298 chapter 10

numbers and statics

The ot1ly required specifier is for TVPE

Although type is the only required specifier, remember that if you do put
in anything else, type must always come last! There are more than a dozen
different type modifiers (not including dates and times; they have their own
set), but most of the time you 'll p robably use %d (decimal) or %f (floating
point) . And typically you 'll combine %fwith a precision indicator to set the
number of decimal places you want in your output.

The TYPE is mandatory, everything else is optional. You must include a
type in your tormat
%d decimal A4-2.25 wcxo/d ot I It instructions, and it you
work, specity things besides
~format ("%d", 42) ; wo",ld be th tI type, the type must
.d',rettly assi3et1saallideoa",sbltrt'tI3 to always COme last.
Itlt variable. e atl Most ot the time,
you'll probably tormat
The argument must be compatible with an int, so that means numbers using either
only byte, short, int, and char (or their wrapper types) .
"d" rror Jec'rmal or "lt'»
%f floating point »e\"e waef\"teOfttisl'b,iol\''\le~'l'~Ihd,et~t"okvi-t
with tor lloating point.
format ("%.3£", 42. 000000) ;

42 .000 "..,171 so we el'lded ",y WIth
th\"ee u\"oes·

The argument must be of a floating point type, so that
means only a float or double (primitive or wrapper) as well
as somethin g called BigDecimal (which we don't look at in
thi s book) .

%x hexadecimal

format ("%x", 42);

The argument must be a byte , short, int, long (including
both primitive and wrapper type s), and BigInteger.

%c character

format ("%c", 42);

The argument must be a byte, short, char, or int (including
both primitive and wrapper types).

you are here . 299

format arguments

What happens if I 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 two
arguments after the format String (first argument), so that means your call to formatt)
will have three arguments instead of two. And inside that first argument (the format
String), you'll have two different format specifiers (two things that start with "%"). The
first format specifier will insert the second argument to the method, and the second
format specifier will insert the third argument to the method. In other words, the
variable insertions in the format String use the order in which the other arguments are
passed into the formatf) method.

i nt one = 20 45 6654 ;
doubl e two = 100567890.248907 ;

St r i ng s = String. f o r mat ("The r a nk i s %,d out of %,.2£", one, twO);

~

The rank is 20,456,654 out of 100 ,567,890 .25

We added tOl'l\l'I\OS to both vat'iables,
and t'estt'itted the .fIO<ltin~ point
n~l'I\bet' (the setond variable) to two
detil'l\al plates.

As you'll see when we get to date formatting, you might actually want to apply different
formatting specifiers to the same argument. That's probably hard to imagine until you
see how dateformatting (as opposed to the numberformatingwe've been doing) works.
Just know that in a minute, you'll see how to be more specific about which format
specifiers are applied to which arguments.

Q: Um,there's something REALLY strange going on here. Just how many arguments can I

pass? I mean, how many overloaded format() methods are INthe String class? So,what happens
if Iwant to pass, say, ten different arguments to be formatted for a single output String?

A: Good catch. Yes, there is something strange (or at least new and different) going on, and

no there are not a bunch of overloaded formatO methods to take a different number of possible
arguments. In order to support this new formatting (printf-like) API in Java,the language needed
another new feature-variable argument lists (called varargs for short) .We'll talk about varargs
only in the appendix because outside of formatting, you probably won't use them much in a well-
designed system.

300 chapter 10

numbers and statics

So tMuch for t1utMbers, what about dates?

Imagine you want a String that looks like this: "Su n d ay, Nov 28 2004"

Nothing special there, you say? Well, imagine that all you have to start with is a variable
of type Date-AJava class that can represent a timestamp, and now you want to take that
object (as opposed to a number) and send it through the formatter.

The main difference between number and date formatting is that date formats use a
two-character type that starts with "t" (as opposed to the single character "f" or "d ", for
example). The examples below should give you a good idea of how it works:

The complete date and time %tc

String. format ("%tc", new Date());

Sun Nov 28 14 :52:41 MST 2004

Just the time %tr

String. format ("%tr", new Date () ) ;

03:01 :47 PM

Day of the week, month and day %tA %tB %td

There isn't a single format specifier that will do exactly what we
want, so we have to combine three of them for day of the week
(%tA), month (%tB), and day ofthe month (%td).

Sunday, November 28

Same as above, but without duplicating the arguments %tA %tB %td

Date today = new Date () ; The a\'l~le-bl"atkd: "<" is jlASt a\'lothel"
String. format (" %tA, %< t B %< t d " , today); ~Ia~ ill iht
speti+iel" that tells tahl"e~~"'el'lt
+ol"",aH el" to "lASe the ..fl"eviOlAS
a~ail'l." So it saves '1~ hOM l"efeatil'l~ the
al"~lA",e\'lts, al'ld i\'lSuad 'i0~ +Ol"",at the
SaMe al"~~el'lt thl"ee diHel"el'lt ways.

you are here. 301

manipulating dates

Let's see... how many work
days will there be if the
project starts on Feb 27th and
ends on August 5th?

Workhtg with Pates

You need to do more with dates than just get
UN:ldy s date. You need your programs to adjust
dates, find elapsed times, prioritize schedules,
heck, make schedules. You need industrial
strength date manipulation capabilities .
You could make your own date routines of
course... (and don't forget about leap years l)
And, ouch, those occasional, pesky leap-
seconds. Wow, this could get complicated. The
good news is that the Java API is rich with
classes that can help you manipulate dates.
Sometimes it feels a little too rich ...

302 chapter 10

numbers and statics

Movit1Q backward at1d forward it1 tittte

Let's say your company's work schedule is Monday through Friday. v.ror a·time-stamp o:rt tnto"w,
You've been assigned the task of figuring out the last work day in use Date. But lor everything
each calendar month this year... else, use Calendar.

It seems that java.util.Date Is actually••• out of date

Earlier we used java.util.Date to find today's date, so it seems
logical that this class would be a good place to start looking for
some handy date manipulation capabilities, but when you check
out the API you'll find that most of Date's methods have been
deprecated!

The Date class is still great for getting a "time stamp"-an object
that represents the current date and time, so use it when you want
to say, "give me NOW".

The good news is that the API recommends java.util.Calendar
instead, so let's take a look:

Use Java.util.Calendar for your date manipulation

The designers of the 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 Calendar

class that you'll see on the next page), and the JVM hands you back

an instance of a concrete subclass of Calendar. (Calendar is actually
an abstract class, so you're always working with a concrete subclass.)

More interesting, though, is that the kind of calendar you get
back will be appropriate for your locale. Much of the world uses the
Gregorian calendar, but if you're in an area that doesn't use a
Gregorian calendar you can getJava libraries to handle other
calendars such as Buddhist, or Islamic orJapanese.

The standard Java API ships withjava.util.GregorianCalendar, so
that's what we'll be using here. For the most part, though, you
don't even have to think about the kind of Calendar subclass you're
using, and instead focus only on the methods of the Calendar class.

you are here . 303

getting a Calendar

&ettit1g at' object that extends Calendar

How in the world do you get an "instance" of an abstract class?
Well you don't of course, this won't work:

v - - -This WON'T work: nt tompile¥ .....0I'I't allow this I

Calendar cal = new Calendar () ; .

Instead, use the static "getlnstanceO" method:

=Calendar cal Calendar .getlnstance() ;

Wait a minute.
If you can't make an
instance of the Calendar
class, what exactly are you
assigning to that Calendar

reference?

You can't get an instance of Calendar,
but you can can get an instance of a
concrete Calendar subclass.

Obviously you can't get an instance of Calendar, because
Calendar is abstract, But you're still free to call static methods
on Calendar, since SUllie methods are called on the class;
rather than on a particular instance. So you call the static
getInstanceO on Calendar and it gives you back... an instance
of a 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 class
Calendar.

In most of the 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 statics

Workittg with Calettdar objects

There are several key concepts you 'U need to understand in
order to work with Calendar objects:

• Fields hold state- A Calendar object bas many fields that are used to
represent aspects of its ultimate state, its date and time. For instance, you
can get and set a Calendar's yearor month.

• Dates and Times can be incremented - The Calendar class has methods that
allow you to add and subtract values from various fields, for example "add
one to the month". or "subtract three years" .

• Dates and TImes can be represented in milhseconds- The Calendar class
lets you convert your dates in to and out ofa millisecond representation .
(Specifically, the number of milliseconds that have occured since January
l st, 1970.) Th is allows you to perform precise calculations such as "elapsed
time between twO times" or "add 63 hours and 23 minutes and 12 seconds
to this time",

An example of working with a Calendar object: 1 ~o&r at \",~D.
. t.o
Calenda r c = Ca lendar . get I ns tance () i ~ Ja'" J o-ba$td.1
b"'\L
,--_._~ n.JdUl.t.~nt. ,..(l¥\\)1 i.s z.l'"

c.set(2004,O, 7,15,40); ~ . L .LL' t.o a hie> 01'
ConV~ "{.I\\s
long dayl = c. getTimelnMillis (); ~ J

otoJ 3W\OIo'l'It. ",i\Iis«.ow-dS.

dayl +~ 1000 * 60 * 60;

c .setTimelnMillis(dayl); (

System.out.println("new hour " + c.qet(c.HOUR_OF_DAY») ;

c.add(c .DATE, 35) ; ~-------Add 3'5 da'f1 to the dau, whith

System.out.println("add 35 days" + c.getTime()); shOl.lld ""ove lAS jPlto FebYu.ilry.

c.roll(c.DATE, 35); <:~---~--

System.out.println("roll 35 days" + c.getTime(»)i

c.set(c.DATE, 1);

System.out.println("set to 1 " + c.qetTime(»);

This outp",t, ton~i_s how ...illis.

add, yoll, dPld set w~k

you are here ~ 305

Calendar API

Highlights of the Calettdar API

WeJUSt worked through using a few of the fields and
methods in the Calendar class. This is a big API so
we're showing only a few of the most common fields
and methods that you'll use. Once you get a few of
these it should be pretty easy to bend the rest of the
this API to your will.

Key Calendar Methods

add(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() Key Calendar Fields -,
Returns this Calendar's time In millis,as a long.
-
roll(int field, boolean up) DATE I DAY_OF_MONTH
Adds or subtracts time without changing larger fields.
Get / set the day of month

set(int field.lnt value} HOUR/HOUR_OF DAY
Sets the value of a given Calendar field.
Get! Set the 12 h-
set(year. month. day, hour. minute) (allints)
MILLISECOND Our Or 24 hour value .

A common variety of set to set a complete time. Get / Setthe milliseconds,

setTlmelnMfllis(long millis) MINUTE

Sets a Calendar's time based on a long rnllli-tirne. Get / set the mInute.

II more ... MONTH

Get / set the month.

- - -...._ ..._ - _. ._ - - . . , YEAR

Get / Set the year.

ZONE_OFFSET

Get / set raw offset of GMT I
1/ more...
n mUUs.

06 chapter 10

Evett ttlore Statics!... static jttlJ!orts numbers and statics

New to Java 5.0 ... a real mixed blessing. Some people love Use CareluUy:
this idea, some people hate it, Static imports exist only to save
you some typing. [f you hate to type, you rnightjust like this static imports can
feature. The downside to static imports is that - if you're not
careful- using them can make your code a lot harder to read. make your code
The basic idea is that whenever you're using a static class, a
static variable, or an enum (more on those later) , you can contusing to read
import them, and save yourself some typing.

Some old-fashioned code:
import java.lang.Math;
class NoStatic {

publiC static void main (String () argsl (

Math.tan(60});

Same code, with static Imports: - Caw.aII & Gokhas
;import static java.lanq.System.Outi
;import static java.lanq.Math.*i • If you're only going to use a static member
class WithStatic (
a fewtimes, we think you should avoid
public static void main (String [] args)
static Imports, to help keep the code more

readable.

• Ifyou're going to use a static member a lot,

(like doing lots ofMath calculanons), then
it's probably OK to use the static Import.

• Notice that you can use wildcards (."), in

your static Import declaration.

• Abig issue with static imports is that it's
not too hard tocreate naming conflicts. For
example, if you have two different classes
with an "addO' method, how will you and
the compiler know which one to use?

you are here. 307

static vs. instance Tonight's Talk: An instance variable
takes cheap sIlots at a static variable
Fireside Chats

@

In.stanoe Variable S1atic Variable

I don't even know why we're doing this.
Everyone knows static variables are just used
for constants. And how many of those are
there? I think the whole API must have, what,
four? And it's not like anybody ever uses
them.

Full of it. Yeah, you can say that again. OK, You really should check your facts . When
so there are a few in the Swing library, but was the last time you looked at the API? It's
everybody knows Swing is just a special case. frickiri ' loaded with statics! It even has entire
classes dedicated to holding constant values.
There's a class called SwingConstarus, for
example, that's just fuU of them .

It might be a special case, but it's a really
important onel And what about the Color
class? What a pain if you had to remember the
RGB values to make the standard colors? But
the color class already has constants defined
for blue, purple, white, red, etc. Very handy.

Ok, but besides a few GUI things, give me an How's System.out for starters? The out in
example ofjust one static variable that anyone System.out is a static variable of the System
would actually use. In the real world. class. You personally don't make a new
instance of the System, you just ask the System
Well, that's another special case . And nobody class for its out variable.
uses that except for debugging anyway.
Oh.Iike debugging isn't important?

And here's something that probably never
crossed your narrow mind-let's face it, static
variables are more efficient. One per class
instead of one per instance. The memory
savings might be huge!

308 chapter 10

numbers and statics

Instance Variable Static Variable
Urn, aren't you forgetting something? What?

Static variables are about as un-OO as it gets!! What do you mean un-OO?
Gee why notjust go take a giant backwards
step and do some procedural programming I am NOT a global variable. There's no such
while we're at it. thing. I live in a class! That's pretty 00 you
know, a CLASS. I'm not just sitting out there
You're like a global variable, and any in space somewhere; I'm a natural part of the
programmer worth his PDA knows that's state of an object; the only difference is that
usually a Bad Thing. I'm shared by all instances of a class. Very
efficient.
Yeah you live in a class, but they don't call
it Clas.rOriented programming. That's just Alrightjust stop right there. THAT is
stupid. You're a relic. Something to help the definitely not true. Some static variables are
old-timers make the leap to java. absolutely crucial to a system . And even the
ones that aren 't crucial sure are handy.

Well, OK, every once in a while sure, it makes Wh y do you say that? And what's wrong with
static methods?
sense to use a static, but let me tell you , abuse
of static variables (and methods) isthe~iDark
of an immature 00 programmer. A designer

should be thinking about objectstate, not class

state.

Static methods are the worst things of all, Sure, I know that objects should be the focus
because it usually means the programmer is of an 00 design, butjust because there are
thinking procedurally instead of about objects some clueless programmers out there... don 't
doing things based on their unique object throw the baby out with the bytecode. There's
state. a time and place for statics, and when you
need one, nothing else beats it.
Riiiiiight. Whatever you need to tell yourself. ..
you are he re . 309

be the compiler

BE the comriIer

class StaticSuper{ The Java file on this page represents a

complete progrlU'l. Your joh is to rIa)'

cOIlIpiler and deterrnne whether this

file will cOIllpile. If it won't cOIlIpile.

how would )'OU 1'lX it. and
if it does compile. whllt
would he ~ output?

static {
System.out.println("super static block");

}

StaticSuper{ If it complies, which of these Is
System.out.println( the output?
"super constructor");
Possible Output
} Rle Edit Wlndow Hel ell
} %java StaticTests
static block 4
public class StaticTests extends StaticSuper { in main
static int randj super static block
super constructor
static { constructor

rand = (int) (Math.random() * 6)j

system.out.println("static block n + rand);

}

StaticTests () { Possible Output
System.out.println("constructor");
File Edit Wlndow Het Electrle:l
}
%java StaticTests
public static vcid main{String [] args) { super static block
System.cut.println("in main"); static block 3
StaticTests st = new StaticTests()j in main
super constructor
} constructor
}

310 chapter 10

numbers and statics

This chapter explored the wonderful, static, world
of Java. Your Job is to decide whether each of the
following statements Is true or false.

1. To use the Math class, the first step is to make an instance of it.
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 of a 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. If a class is marked final, all of its methods must be marked final.
10. A final method can only be overridden if its 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.format

package.

you are here ~ 311

code magnets Lunar Code Magnets
312 chapter 10
This one might actually be usefullin addition to what you've learned in the last few

pages about manipulating dates, you'll need a little more information...First full

moons 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 program
that produces the output listed below (plus more full moon dates). (You might not
need all of the magnets, and add all the curly braces you need.) Oh, by the way, your
output will be different if you don't live in the mountain time zone.

I long dayl = c.getTimelnMillis() ; I

Ic . s e t (2004 , l , 7 , 15 , 40 ) ; I

rimPort static java. lang. system. out;

static int DAY IM :: 60 Or 60 .. 24; -
1\
•.~I (c. format J l
~ ("full moon on llitc", c»;

LCalendar new Calendar();
C-

r " l as s FullMoons (

I public static void main (Strinq [] arqs) { I

I Idayl += (DAY_1M .. 29.52);

Ifor (int x :: 0 ; X < 60; x++)
{ a~

Lstati.e int DAY IM =: 1000
Or 60 Or 60 .. 24;- ,
l
I println -1lJ .~port
.
("full moon on %t", c) ) ;
Java.i.o.*;

\~

limport java .util.*; }

I ~static import java.lanq.System.out;

I e.set{2004,O,7,15,40); r out.println

c .setT1meInHi (string . format
lliS(daYl);

Calendar c = Calendar.get1nst&nce();

numbers and statics

True or False

1. To use the Math class, the first step is to False

make an instance of it.

2. You can mark a constructor with the key- False

word 'static'.

3. Static methods don't have access to an True

object's instance variables.

4. It is good practice to call a static method False

using a reference variable.

5. Static variables could be used to count the True

instances of a class.

6. Constructors are called before static vari- False

staticSuper( ) { ables are initialized.
System.out.println(
usuper constructorH ) ; 7. MAX_SIZE would be a good name for a True

} static final variable.

StaticSuper is a constructor, and must 8. A static initializer block runs before a class's True:
nave ( ) in its signature. Notice thor as
the output below demonstrates, the static constructor runs.
blocks for both classes run before either
of the constructors run. 9. If a class is marked final. all of its methods False

Possible Output must be marked final.

File Ed~ WIndOW Hel elln ]O. A final method can only be overridden if False

%java StaticTests its class is extended.
super static block
static block 3 11. There is no wrapper class for boolean False
in main
super constructor primitives.
constructor
12. A wrapper is used when you want to treat a True

primitive like an object

13. The parseXxx methods always return a False

String.

14. Formatting classes (which are decoupled False

from I/O), are in the java.format package.

you are here . 313

code magnets solution

import java.util.·; Notes on the Lunar Code Magnet:
import static java.lanq.Syatem.out;
olass FullMoons ( You might discover that a few of the
dates produced by this prognun are
statio int DAY rM : 1000 • 60 • 60 • 24; off by a day. This astronomical stuff
publi~ static void main (String [) args) is a little tricky, and if we made it
perfect, it would be too complex to
=Ca18nda~ c Calendar.getlnstance(); make an exercise here.

c.aet(2004,O,7,15,40); Hint: one problem you might try to
long day! = c.qetTimelnM1l1i9(); solve is based on differences in time
zones. 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 handling

Risky Behavior

Stuff happens. The file isn't there. The server Is down. No matter how

good 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 the
exceptional situation? So far in this book. we haven't really taken any risks. We've certainly had
things go wrong at runtime, but the problems were mostly flaws In our own code. Bugs. And
those we should fix at development time. No, the problem·handllng code we're talking about
here is for code that you can't guaranatee will work at runtime. Code that expects the file to be
in the right directory, the server to be running, or the Thread to stay asleep. And we have to do
this now.Because in thischapter, we're going to build something that uses the risky JavaSound
API. We're going to build a MIDI Music Player.

this is a new chapter 315

building the MIOI Music Player

Let"s tMake a Music Machitte

Over the next three chapters, we'll build a few different sound
applications. including a BeatBox Drum Machine. In fact,
before the book is done, we'll have a multi-player version so
you can send your drum loops to another player, kind of like
a chat room . You're going to write the whole thing, although
you can choose to use Ready-bake code for the CUI parts.
OK. so not every IT department is looking for a new BeatBox
server, but we're doing this to learn more about Java. Building
a BeatBox isjust a way to have fun while we're learning java.

the fh11shed JeatJox looks sotMethl"g like this:

Crash Cymbal )
Hand Clap
High Tom dance beat
Hi Bongo
Maracas Andy: groove 112
Whistle Chris: groove2 revised
Low Conga Nigel: dance beat
Cowbell
Vibraslap

Low-mid Tom 0 G

High Agogo

Open HI CongaO LJ ILJ .= 1..::, ~I LJ

Put checkmarks in the boxes for each of the 16 'beats', For example, on beat
1 (of 16) the Bass drum and the Maracas will play. on beat 2 nothing, and
on 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, you
can "capture" one of your own patterns by sending it to the BeatBox server
(which means any other players can listen to it). You can also load any of the
incoming patterns by clicking on the message that goes with it.

316 c hapter 11

WeIll start with the basics exception handling

Obviously we've got a few things to learn before the whole MIDI dtllit.e b\Ows how to
program is finish ed , including how to build a Swing GUl, how
to connect to another machine via networking, and a little I/O \"caa' a MIDI .filt al'lQ flay batl<.
so we can sendsomething to the other machine.
the S04.lI\d. nt dtvite ...i~ht.
Oh yeah , and theJavaSound API. That's where we'll start in this MIDI ~ih: be a syr.thtsiuY ~oaYa or
chapter. For now, you can forget the GUl, forget the networking
and the I/O, and focus only on getting some MIDI-generated s.or..e ot.h~ kitld of i~\II>\ent..
sound to come out of your computer. And don't worry if you (,.(s.....lIy, a MIDI it'Sb--ellt.
don't know a thing about MIDI, Or a thing about reading or tan playa LOT o.f diH~tnt
making music. Everything you need to learn is covered here.
You can almost smell the record deal. ~ (yi.1no, d..,.,..1, violil'l,
eitJ, alia all at the sa",e +'i",e.
fhe JavaSou)1d API So a MIDI tilt is,,'+' like shed
"'Iolit ~ot" jldi Ot\e "'1ol'ltiall iPl
javaSound is a collection of classes and interfaces added to the baPld -- it. taft hold the
java starting with version 1.3. These aren't special add-oris:
they're part of the standard J2SE class library.javaSound is split farh for ALL t.ht "'lolitiar\5
into two parts: MIDI and Sampled. We use only MIDI in this
book. MIDI stands for Musical Instrument Digital Interface, flayi,,~ a farbtlOlar SOl'>5'
and is a standard protocol for gerting different kinds of
electronic sound equipment to communicate. But for you are here. 317
our BeaiBox app, you can think of MIDI as a kind oj
sheet music that you feed into some device you can think
of like a high-tech 'player piano'. In other words, MIDI
data doesn't actually include any sound, but it does
include the instructions that a MIDI-reacling instrument
can play back . Or for another analogy, you can think of
a MIDI file like an HTML document, and the instrument
that renders the MIDI file (i.e. plays it) is like the Web
browser.

MIDI data says what to do (play middle C, and here 's how hard
to hit it, and here 's how long to hold it, etc.) but it doesn't say
anything at all about the actual sound you hear. MIDI doesn't
know how to make a Elute, piano, or Jimmy Hendrix guitar
sound, For the actual sound, we need an instrument (a MIDI
device) that can read and playa MIDI file. But the device is
usually more like an entire band or orchestra of instrurnen15. And
that instrument might be a physical device, like the electronic
keyboard synthesizers the rock musicians play. or it could
even be an instrument built entirely in software. living in your
computer.

For our BealBox, we use only the built-in , software-only
instrument that you get with Java. It's called a syntMsiu:r (some
folks refer to it as a softumresynth) because it creates sound.
Sound that you hear.

but It looked so simple

First we t1eed a Sequet1cer

Before we can get any sound to play, we need a Sequencer object. The
sequencer is the object that takes all the MIDI data and sends it to the right
instruments. It's the thing that plays the music. A sequencer can do a lot of
different things, but in this book, we're using it strictly as a playback device. Like
a CD-player on your stereo, but with a few added features. The Sequencer class
is in thejavax.sound.midi package (part of the standard java library as of version
1.3). So let's start by making sure we can make (or get) a Sequencer object.

aM:. t)-.~ i~ay...~ 6 .d\ ~_e.\(-~~ Ii ~'\~tY ob)tt.t It:1 -tht

import j avax. sound. midi . '* ; . ....,
~ \llIY We.l'Iee ~ ok tne MIDI de~it.dll,sb- .....er.t
-the -thi,,~ t.hat, ....el\•
public class MusioTestl { ...d;n fd . . It: r L, to
....e ye l.LS",~ , MIDI in-tO\""'auC7J\ '
public void play 0 ( 1 "
sc,\\OLnt.fS 6 b ,..d I
=Sequencer sequencer MidiSys tem. ga tSaquencer () ; II tn

, 'Bllt. ....e dO'l'>'t Nlte 6 Y6
a sonlj ' .....v-selves __ ....e have to asK t'ke

System.out .println("We got a s e q u e n c e r " ) " "~ "M,i..d..~Oyls'let."e'"'" to ~i~t. lAj, Ol'It·

;

II close play

public static void main(Strlng(] args)

=MusicTestl mt Daw MusicTestl(} ;

IDt. play () ;

II clOSE! main SOlMethingl wrong!
II close class

,This t.«Je won't t.tm.pile! The to",piler ~ys t.nt\""e's ah
IAhreporkd e~epi.iOh' thai "'lASt be t.al.l~ht. or detlared.

318 chapter 11

exception handling

What happet1s whet1 a tMethod you warttto call
(probably it' a class you didt1~t write) is risky?

" Let's say you want - - ._n,-.. ..111 _ _ II ,
to call a method In a
o~•._.,.uQ .l ~_ -I" ,
class that you didn't
write. your coc e class you

you didn't write

• That method does --,_ t_ 1 void moo () (
something risky, _ f1, if (serverDown)
something that might axplode()i
not work at runtime. class you
didn't write )

}

~ You need to know ~~.-=' . I
that the method
you're calling is crass you
risky.
didn't write
you

@ You then write code

that can handle the
failure if It does
happen. You need to be
prepared, just in case.

your co e

you

you ar e her e ~ 319

Methods iN Java ose except/om: to tell the ca/liM9 code,

·Sotttethlftg Bad HappeHed. I failed;'

mechan~m",Java's exception.handliog a dean, well·lighted way to handle "exceptional

shuations' that pop up at runtime;;t lets}'OuPOl all your error.handling code in one

easy-to-readplace. It's based On you knowingthat the method you're calhng;, risky

(i.e. that the method mighl gene,",e an exception), SO thar you can write code '0 deal
w;th that pos,,;bmty. l£}'Oo k_ you might get an exception when you calla ParUcuJar

tmheetehxocde,pytioounc. an be fmP- for-poss;bly even '''-from-the problem thaI caused

rSios,kyhmowetdhoo}d'O'sudkencolawraiftiaonm. ethod throws an eXception! You find a throw. clause;n the

The getSequencer () lIIethOd takes a risk. It Can fail at runtlllle.

So It lIIust 'declare' the risk you take When you call it.

•eee @ MldlSvslem (Java 2 PIa((orm SE vl.4.01
hck
t.~ It f

Sll>p Rdrt:Sh Hl>rrIC _ i_ A~Ic>RlI

getSe-quencer ....--~ r~ API dots it"

M ~,"alta-()

L~~~I pUb lic ~ t a t i c '~-C'-all(l n s" r 9·ts~th.arco.~~.9 ( M_l _ldll1o Av:ll 1 h l~ Ex £~ Rt l Qn Un thr-ow an tXQf'i
MidiU..a\lai'ab'eE~
A~od has fo dula
~ Oblains the default sequencer. the ~0fIS it ...iSh
thl"o....
.~..
/ Rtturns: cer

g ~~:\':tOlJrq the default sequcn .. I availabledue
ThrowHs!:d s<eNq'IucnCCTIS no
~ VOiceSlalys HJo.) y a 1 I .J b l" EnxscC p rl on _ .If the

• •

5' ExcepUons

,,1 I

320 chapte r 11

exception handling

The cOlMpiler t1eeds to kttow ---
that YOU kttow you're caUit1g

arisky lMethod.

If you wrap the risky code in something called a
try/catch, the compiler will relax.

A try/catch block tells the compiler that you
knota an exceptional thing could happen in the
method you're calling, and that you're prepared
to handle it. That compiler doesn 't care Iwwyou

handle it; it cares only that you say you're taking

care of it,

import j AVax . sound. midi . * ;

public class MusicT~stl {
public void play ()

try { ,J, tM yisk'f iYl~

!=Sequencer sequencer MidiSystElm . getsequenCGr () ; i : ; - 'l..AJ' h'ot't .
aIYI v 1
System.out.prlntln( "Suceessfully got a sequencer");

} catch (MidiUnavailableException ex) {

Systelll. out. println ("Bummer") ;

II close play

public static void main{Strinq[] args)
MusicTestl mt = new MusicTestl():
mt.play{) :

II close main
II closit class

you are here. 321

exceptions are objects

A" exceptio" is a" object...
of type Exceptio"_

Which is fortunate, because it would be much harder
to remember if exceptions were of type Broccoli .

Remember from your polymorphism chapters that
an object of type Exception can be an instance of any
subclassof Exception.

Because an Exception is an object, what you catchis an
object. In the following code. the catch argument
is declared as type Exception, and the parameter
reference variable is ex,

Throwable try {
getMeasage{)
printStackTraceO I I do risky thJ...nq ·,t I s J. ~L \',\:.t. 4tl.\a't"i\l:.'.l~
.LI."O ay~-tl'l
~JlleYta'hYle.n'el.~.TLty'ItI.l\'/OYaIll T ~a ",e'V'"
Part
Exception } catch(Exception ex) {
dass
t~~O l.\ass T\I't"owa'ble
61'10 il'lheY'It two \I.e'( II try to recover

...dho~ } ~ This ~od I

E~tp£ t O, l lvr qu I' Ii

II if'

.> <, Otl Is tJ.ro'Nrl, "

IOElceeptlon Intarrupl&dExceptlon What you write in a catch block depends on the
exception that was thrown. For example, if a server
is down you might use the catch block to try another
server. If the file isn't there, you might ask the user
for help finding it.

322 chapter 11

exception handling

If it's yourcode that catches the exceptio",

-the., whose code throws it? -.- ._':..::~ I class with Q
_ ... J tn I risky method
You'll spend much more of yourJava coding time handling _"" J.
exceptions than you'll spend cnatingand throwing them yourself.
For now, just know that when your code callsa risky method-a your code
method that declares an exception-it's the risky method that
throws the exception back to yfJU, the caller.

In reality, it might be you who wrote both classes. It really
doesn't matter who writes the code... what matters is knowing
which method throws the exception and which method catches it.

When somebody writes code that could throw an exception, they
must declare the exception.

• Risky, exception-throwing code: ~,~ "'~&Ao)d-\:M,haVt S'I1't \ tnt ~'foI0d'I'~\0'f-Cl'o,'1eytIO"
~ ott~Y''''Y
-\:,t\ a

t,hyo'OlS a

public void takeRi.sk () BadExcepUon ( One methqd WIll
entch ..VhClt £lncnher
if (abandonAllHope) (
- -tnetlloJ thr9'vv~. J\n
new BadException();
exce ptIon 'is aJVY'ly':i
i:;e) '\l~t:G~
objett w E~~ thl"O\Vn back [o the
/:h.-ow it.

elll)e\".

• Your code that calls the risky method: The 111eth<)d thnt

public void crossFingers() th\'ovv' ~ ha~ t<:> dechu-e

( ----=--

that 'It nl'ir,-ht thrq\\!

anObject.takeRisk()j the exception.

) (BadException ex) {

System. out.println ("Aaarqh! ") ; yIf~et.04l l.i '.1 r ih
.
a at LMsTex .printStackTrace () ; 1I \. .-tror" e
sicltk brU- ,over ~er..J\,..I, on,
. /
~ ~i II ~le ~'~ -the P""ini$tallcTrciteO ....tt.hod
a e-,ttepiior.s Illherit.

you are here ~ 323

checked and unchecked exceptions The compiler checks for everything
except RuntimeExceptions.
E.'Il.ttf"t1Ol\S thai aye NOT s~t1asu:s of
Runti",eEuepiic»l cll"e thet.ked .for by The compiler guarantees:

~c t.oto.pilcr. Th~'rc ~Iled "thetJccd If you throw an exception in your code you must declare it using
t"J'-UpiiOflSIi the throws keyword in your method declaration.

Exception If you call a method that throws an exception (in other words,
a method that declares It throws an exception), you must
acknowledge 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 Is the FIRST time Q.: I'll bite. WHY doesn't the complier care about those

we ve had to try/cate:h an EJcceptlon7 What about the runtime exceptions? Aren't they Just as likely to bring the
exceptions I've already gotten like NullPolnterEJcception whole show to a stop?
and the exceptJon for DlvldeByZero. I even got a
NumberFormatExceptlon from the Integer.parselntO A: Most RuntimeExceptlons come from a problem in
method. How come we didn't have to catch those?
your code logic, rather than a condition that fails at runtime
A.: The compiler cares about all subclassesof Exception,
in ways that you cannot predict or prevent. You cannot
unless they are a special type , RuntimeException. Any guarantee the file is there .You cannot guarantee the server
exception classthat extends RuntlmeExceptlon gets a
free pass.RuntimeExceptions can be thrown anywhere, is up. But you can make sure your code doesn't index off the
with or without throws declarations or try/catch blocks. end of an array (that's what the .length attribute is for) .
The complier doesn't bother checking whether a method
You WANT RuntimeExceptions to happen at development
declares that It throws a RuntimeExceptlon, or whether the and testing time.You don't want to code in a try/catch, for
example, and have the overhead that goes with it, to catch
caller acknowledges that they might get that exception at something that shouldn't happen In the first place.
runtime.
A try/catch is for handling exceptional situations, not flaws
324 chapter 11 in your code, Use your catch blocks to try to recover from
situations you can't guarantee wlll succeed.Or at the very
least, print out a message to the user and a stack trace, so
somebody can figure out what happened.

exception hand Iing

• Amethod can throw an exception when something fails at runtime. ~etaco"Mitive tiP
\ m somethIng new,
• An exception is always an object oftype Exception. (Which, asyou \f you're trying /t8os1etahln~O~ntcrey to learn
make that\he yOU putthis
remember from the polymorphism chapters means the object is from a
before goIng to sleep. 'can tearyourself
class thai has Exception somewhere upitsinheritance tree.)
book down .(assu~I~~~O~nyth\ng else more
• The compiler does NOT pay attention toexceptions that are of acbwhoXaalyl.eYfnrooguminr gbItrt)a~dInaonnntBthBedbSaatlCdmI<eTohtfoaatpCcroohcueeledsristoaswk'eh"at
you've read and lea~ to'shova something
type RuntlmeException. ARuntimeExceplion does not have to be a feW hoUrs. If you f ur Java. some of the
new in right onto~ 0 .yo
declared orwrapped in a try/catch (although you're free todo either or
both of those things) Java might not'sllek.

• All Exceptions the compiler cares about are called 'checked . doesn't rule oullearning
exceptions' which really means compiler-<:hecked exceptions. Only
RuntimeExceptions are excluded from compiler checking. All other Of course, thIS WorldnK~ICoknBOyXolungr latesl
exceptions must be acknowledqed in your code, according to the a physical sk1\1. routine
rules. Ballroom
probably won'l affect your
• Amethod throws an exception with the keyword throw, followed by
Java leamlng.
a new exception object:
For the best resulls' read Ihls
throw new NoCaffeineException(); book {orat least1001< al
the pictures) right before
• Methods that might throw a checked exception must announce it with
goin9to sleep.
a throws Exception declaration.

• If your code calls a checked-exception-throwing method, it must
reassure the complier that precautions have been taken.

• Ifyou're prepared 10 handle the exception, wrap the call In a tJy/catch,
and put your exception handling/recovery code in the catch block.

• Ifyou're not prepared tohandle Ihe exception, you can still make the
compiler happy byofficially 'ducking' the exception. We'll talk about
ducking a little lalerin this chapter.

~ your penCil

Things you want to do What might go wrong

Which of these do you think 'v'connect to a remote server
might throw an exceptfon that
the com pller would care about? _ access an arraybeyond its length
We're only looking for the _ display a window on the screen
things that you can't control In
your code. We did the first one. retrieve data from a database
_ see if a text file is where you think It is
(Because Itwas the easiest.)
create a new file
read a character from the command-line _

you are here . 325

exceptions and flow control

Flow eontrol it1 try/catch blocks

When you call a risky method, one of two things can hap-
pen. The risky method either succeeds, and the try block
completes, or the risky method throws an exception back to
your calling method.

If the try succeeds

(doRiskyThlngO does not try {

throw an exception)

(j Foo f x.doRiskyThing();

int b f . getNum () ;

catch (Exception ex) {
System.out.println("failedU ) ;

1(~ lsystem. out. println ("We made it!");

If the try fails

(because doRlskyThlngO
dOBS throw an exception)

try (
.------i~!flHIFoo f

'<::I'

iot b

} catch (Exception ex) (

~ System.out. println ("failed") ;

~stem.out.println("We made it!");
-I

326 chapte r 11

exception andling

Fh,ally: for the thlttQs you wattt
to do no fffatter what.

If you try to cook something, you start by turning on
the 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 put
code that must run regardless
of an exception.

try ( If the try block fails (an exceptIDn), flow
control immediately moves to the catch block.
turnOvenOn(); When the catch block completes, the finally
block runs. When the finally block completes,
x , ba Ice () ; the rest of the method conUnues on.

catch (BakingException ex) If the tr-y block succeeds (no exception),
ex.printStackTrace()i flow control skips over the catch block and
moves to the finally block. When lhe finally
) finally ( block compleles, the rest of the method
continues on.
turnOvenOf£();
If the try or catch block has a return
) statement, finally will still runl Flow
jumps lo the finally, then back to the relum.
Without finally, you have to put the
tumOvenOffO in both the try and the catch you are here ~ 327

because you have to turn offthe oven JU> matter
what . A finally block lets you put all your
important cleanup code in oneplace instead of

duplicating it like this:

try {

turnOvenOn () ;

x.bake o .

turnOvenOff () ;
} catch (BakingException ex) (

ex.printStackTrace();
turnOvenOf f () ;

flow control exercise

~yourpendl Look at the c:ode to the left. What do you think the
Flow ContPoI output of this program would bel What do you think
It would be If the third line of the program were

changed to: String test. "yes", 1

AssumeScaryExceptlon extends Exception.

public class TestExceptions { Output when test =' "no"
public static void main(String () args) {

String test = "no N; Output when test = "yes"
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");

}

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 JO pua . ,(lIeuy . UOlldCl»)«l 've)~ . ~SIJ lJelS . Nl uelS :.5i1,.{. ~al U"4M

ulew lO pUiI - Alleuy - .tit pua - A~S!J pUCI - A~SIJ lJl?1S - ,VllJelS :.ou . = l5Cll UCl1.!M

328 chapter 11

exception handling

Pid we lIte.,tio., that atltethod ca.,
throw tMore tha., o.,e exception?

A method can throw multiple exceptions if it dam well needs to. But
a method's declaration must declare all the checked exceptions it can
throw (although if two or more exceptions have a common superc1ass, the
method can declare just the superclass.)

CatchlnQ lHultlple exceptlo"s

The compiler will make sure that you've handled all the checked excep-
tions thrown by the method you're calling. Stack the catch. blocks under
the 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 exception

public class Foo {

publ ic void go ()

Laundry laundry new Laundry () ; it doLa~dr'f() ~..o\WS a

try { Pa"b~uepiiCW\1 i.e lands ill the
laundry.doLaundry();
1/ Pa"b.~~O'r\ utth blotk.
~
} catch (PantsException pex) {

II recovery code

) Catch(LingerieExcePti~) (
~ JLU.~ide~w'~'it"t~.,~.~.t0'y'T~'b'''O)..l't0\ll'y\.dOi~t.IS\haa"absloit".\t.t·he
I I recovery code

}

you are here ~ 329

polymorphic exceptions exception All eU~QtIS ho'le

Exceptiotts are polytMorphic f.~~ as a

Exceptions are objects, remember. There 's nothing all that SlI"cY tolass-
special about one, except that it is a thing that can bethrown.
So like all good objects, Exceptions can be referred to IOExceptlon CloltilngExeeptlon
polymorphically. A LingerieException object, for example,
could be assigned to a ClothingException reference. A
PantsException could be assigned to an Exception reference.
You get the idea. The benefit for exceptions is that a method
doesn't have to explicitly declare every possible exception it
might throw; it can declare a superclass of the exceptions.
Same thing with catch blocks-you don't have to write a catch
for each possible exception as long as the catch (or catches)
you have can handle any exception thrown.

@ You can DECLARE exceptions using

a supertype of the exceptions you
throw.

@ You can CATCH exceptions using a

supertype of the exception thrown.

try ( ~\, ""'I try (
. / 1C.<1\"atn·l4-1-UT.../......•.~
laundry. doLa und ry () ; Ie \Jot\a.u <...·rlaundry.doLaundry();
t. i-:-
I f~ .~ \;I ' :.l
' .' 0 ! I/~
catch(ClothingException cex) { catch (ShirtException sex)
II recovery code
II recovery code

330 chapter 11


Click to View FlipBook Version