Thinking in Java - 4th Edition
1079 pág.

Thinking in Java - 4th Edition

Disciplina:Programação Orientada a Objetos1.262 materiais32.145 seguidores
Pré-visualização50 páginas
in Java Bruce Eckel

point number as a selector, it won’t work in a switch statement. For non-integral types, you
must use a series of if statements. At the end of the next chapter, you’ll see that Java SE5’s
new enum feature helps ease this restriction, as enums are designed to work nicely with
switch.

Here’s an example that creates letters randomly and determines whether they’re vowels or
consonants:

//: control/VowelsAndConsonants.java
// Demonstrates the switch statement.
import java.util.*;
import static net.mindview.util.Print.*;
public class VowelsAndConsonants {
 public static void main(String[] args) {
 Random rand = new Random(47);
 for(int i = 0; i < 100; i++) {
 int c = rand.nextInt(26) + ‘a’;
 printnb((char)c + ", " + c + ": ");
 switch(c) {
 case ‘a’:
 case ‘e’:
 case ‘i’:
 case ‘o’:
 case ‘u’: print("vowel");
 break;
 case ‘y’:
 case ‘w’: print("Sometimes a vowel");
 break;
 default: print("consonant");
 }
 }
 }
} /* Output:
y, 121: Sometimes a vowel
n, 110: consonant
z, 122: consonant
b, 98: consonant
r, 114: consonant
n, 110: consonant
y, 121: Sometimes a vowel
g, 103: consonant
c, 99: consonant
f, 102: consonant
o, 111: vowel
w, 119: Sometimes a vowel
z, 122: consonant
...
*///:~

Since Random.nextInt(26) generates a value between 0 and 26, you need only add an
offset of ‘a’ to produce the lowercase letters. The single-quoted characters in the case
statements also produce integral values that are used for comparison.

Notice how the cases can be “stacked” on top of each other to provide multiple matches for a
particular piece of code. You should also be aware that it’s essential to put the break
statement at the end of a particular case; otherwise, control will simply drop through and
continue processing on the next case.

Controlling Execution 105 

106 Thinking in Java Bruce Eckel

In the statement:

int c = rand.nextInt(26) + ‘a’;

Random.nextInt( ) produces a random int value from 0 to 25, which is added to the value
of ‘a’. This means that ‘a’ is automatically converted to an int to perform the addition.

In order to print c as a character, it must be cast to char; otherwise, you’ll produce integral
output.

Exercise 8: (2) Create a switch statement that prints a message for each case, and put
the switch inside a for loop that tries each case. Put a break after each case and test it,
then remove the breaks and see what happens.

Exercise 9: (4) A Fibonacci sequence is the sequence of numbers 1, 1, 2, 3, 5, 8, 13, 21,
34, and so on, where each number (from the third on) is the sum of the previous two. Create
a method that takes an integer as an argument and displays that many Fibonacci numbers
starting from the beginning, e.g., If you run java Fibonacci 5 (where Fibonacci is the
name of the class) the output will be: 1, 1, 2, 3, 5.

Exercise 10: (5) A vampire number has an even number of digits and is formed by
multiplying a pair of numbers containing half the number of digits of the result. The digits
are taken from the original number in any order. Pairs of trailing zeroes are not allowed.
Examples include:
1260 = 21 * 60
1827 = 21 * 87
2187 = 27 * 81
Write a program that finds all the 4-digit vampire numbers. (Suggested by Dan Forhan.)

Summary
This chapter concludes the study of fundamental features that appear in most programming
languages: calculation, operator precedence, type casting, and selection and iteration. Now
you’re ready to begin taking steps that move you closer to the world of object-oriented
programming. The next chapter will cover the important issues of initialization and cleanup
of objects, followed in the subsequent chapter by the essential concept of implementation
hiding.

Solutions to selected exercises can be found in the electronic document The Thinking in Java Annotated Solution Guide,
available for sale from www.MindView.net.

 

Initialization
& Cleanup

As the computer revolution progresses, “unsafe” programming has
become one of the major culprits that makes programming expensive.

Two of these safety issues are initialization and cleanup. Many C bugs occur when the
programmer forgets to initialize a variable. This is especially true with libraries when users
don’t know how to initialize a library component, or even that they must. Cleanup is a special
problem because it’s easy to forget about an element when you’re done with it, since it no
longer concerns you. Thus, the resources used by that element are retained and you can
easily end up running out of resources (most notably, memory).

C++ introduced the concept of a constructor, a special method automatically called when an
object is created. Java also adopted the constructor, and in addition has a garbage collector
that automatically releases memory resources when they’re no longer being used. This
chapter examines the issues of initialization and cleanup, and their support in Java.

Guaranteed initialization
with the constructor

You can imagine creating a method called initialize( ) for every class you write. The name is
a hint that it should be called before using the object. Unfortunately, this means the user
must remember to call that method. In Java, the class designer can guarantee initialization of
every object by providing a constructor. If a class has a constructor, Java automatically calls
that constructor when an object is created, before users can even get their hands on it. So
initialization is guaranteed.

The next challenge is what to name this method. There are two issues. The first is that any
name you use could clash with a name you might like to use as a member in the class. The
second is that because the compiler is responsible for calling the constructor, it must always
know which method to call. The C++ solution seems the easiest and most logical, so it’s also
used in Java: The name of the constructor is the same as the name of the class. It makes
sense that such a method will be called automatically during initialization.

Here’s a simple class with a constructor:

//: initialization/SimpleConstructor.java
// Demonstration of a simple constructor.
class Rock {
 Rock() { // This is the constructor
 System.out.print("Rock ");
 }
}
public class SimpleConstructor {
 public static void main(String[] args) {
 for(int i = 0; i < 10; i++)
 new Rock();

 

 }
} /* Output:
Rock Rock Rock Rock Rock Rock Rock Rock Rock Rock
*///:~

Now, when an object is created:

new Rock();

storage is allocated and the constructor is called. It is guaranteed that the object will be
properly initialized before you can get your hands on it.

Note that the coding style of making the first letter of all methods lowercase does not apply to
constructors, since the name of the constructor must match the name of the class exactly.

A constructor that takes no arguments is called the default constructor. The Java documents
typically use the term no-arg constructor, but “default constructor” has been in use for many
years before Java appeared, so I will tend to use that. But like any method, the constructor
can also have arguments to allow you to specify how an object is created. The preceding
example can easily be changed so the constructor takes an argument:

//: initialization/SimpleConstructor2.java
// Constructors can have arguments.
class Rock2 {
 Rock2(int i) {
 System.out.print("Rock " + i + " ");
 }
}
public class SimpleConstructor2 {
 public static void main(String[] args) {
 for(int i = 0; i < 8; i++)
 new Rock2(i);
 }
} /* Output:
Rock 0 Rock 1 Rock 2 Rock 3 Rock 4 Rock 5 Rock 6 Rock 7
*///:~

Constructor arguments provide you with a way to provide parameters for the initialization of
an object. For example, if the class