Chapter 3

What Java Does (and When)

In This Chapter

check1 Making decisions with Java statements

check1 Repeating actions with Java statements

check1 Adding exception handling

Human thought centers on nouns and verbs. Nouns are the “stuff,” and verbs are the stuff’s actions. Nouns are the pieces, and verbs are the glue. Nouns are, and verbs do. When you use nouns, you say, “book,” “room,” or “stuff.” When you use verbs, you say “Do this,” “Do that,” “Hoist that barge,” or “Lift that bale.”

Java also has nouns and verbs. Java’s nouns include String, ArrayList, and JFrame, along with Android-specific things such as Activity, Application, and Bundle. Java’s verbs involve assigning values, choosing among alternatives, repeating actions, and other courses of action.

This chapter covers some of Java’s verbs. In Chapter 4 of this minibook, you bring in the nouns.

Making Decisions (Java if Statements)

When you’re writing computer programs, you’re constantly hitting forks in roads. Did the user correctly type his or her password? If yes, let the user work; if no, kick the bum out. So the Java programming language needs a way of making a program branch in one of two directions. Fortunately, the language has a way: It’s called an if statement. The use of an if statement is illustrated in Listing 3-1.

Listing 3-1: A Method with an if Statement

public void onClick(View v) {

    if (((CheckBox) v).isChecked()) {

       textview.setTextColor(Color.GREEN);

       textview.setText("Thank you!");

    } else {

       textview.setTextColor(Color.RED);

       textview.setText("No harm done.");

    }

}

 

Android calls the onClick method in Listing 3-1 when the user clicks a particular check box. (Android uses the parameter v to pass this check box to the onClick method. That’s how the onClick method finds out which object the user clicked.) If clicking puts a check mark in the check box, the text view displays Thank you! in green letters. Otherwise, the text view displays No harm done. in red letters. (See the colorless Figure 3-1.)

image

Figure 3-1: Checking and unchecking in Listing 3-1.

An if statement has the following form:

if (condition) {

    statements to be executed when the condition is true

} else {

    statements to be executed when the condition is false

}

 

In Listing 3-1, the condition being tested is

((CheckBox) v).isChecked()

 

In this condition, variable v is the onClick method’s parameter — the thing that Android passes to the onClick method. Listing 3-1 is far from being a complete Android app. But presumably, v is a check box. (See the sidebar, “Central casting.”)

Android’s isChecked method returns either true or falsetrue when the v check box is checked; false when the v check box isn’t checked.

The condition in an if statement must be enclosed within parentheses. The condition must be a boolean expression — an expression whose value is either true or false. (See Chapter 2 of this minibook for information about Java’s primitive types, including the boolean type.) So, for example, the following condition is okay:

if (numberOfTries < 17) {

 

But the strange kind of condition that you can use in languages, such as C++, is not okay:

if (17) { //This is incorrect.

 

You can omit curly braces when only one statement comes between the condition and the word else. You can also omit braces when only one statement comes after the word else. For example, the following code is okay:

if (((CheckBox) v).isChecked())

    textview.setText("Thank you!");

else {

    textview.setTextColor(Color.RED);

    textview.setText("No harm done.");

}

 

An if statement can also enjoy a full and happy life without an else part. So the following code forms a complete if statement:

if (((CheckBox) v).isChecked()) {

    textview.setTextColor(Color.GREEN);

    textview.setText("Thank you!");

}

Testing for equality

Java has several ways to test for equality (“Is this value the same as that value?”). None of these ways is the first thing you’d think of doing. In particular, to find out whether the parameter v is the thing you call checkbox1, you don’t write if (v = checkbox1). Instead, you use a double equal sign (==). You write if (v == checkbox1). In Java, the single equal sign (=) is reserved for assignment. So n = 5 means “Let n stand for the value 5,” and v = checkbox1 means “Let v stand for the checkbox1 object.”

Comparing two strings is yet another story. When you compare two strings with one another, you don’t want to use the double equal sign. Using the double equal sign would ask, “Is this string stored in exactly the same place in memory as that other string?” That’s usually not what you want to ask. Instead, you usually want to ask, “Does this string have the same characters in it as that other string?” To ask the second question (the more appropriate question), Java’s String type has a method named equals:

if (response.equals("yes")) {

 

The equals method compares two strings to see whether they have the same characters in them. In this paragraph’s tiny example, the variable response refers to a string, and the text "yes" refers to a string. The condition response.equals("yes") is true if response refers to a string whose letters are ‘y’, then ‘e’, and then ‘s’.

crossreference Like most programming languages, Java has the usual complement of comparison operators (such as < for “less than”) and logical operators (such as && for “and”). For a list of such operators, visit http://download.oracle.com/javase/tutorial/java/nutsandbolts/opsummary.html.

Choosing among many alternatives (Java switch statements)

I’m the first to admit that I hate making decisions. If things go wrong, I would rather have the problem be someone else’s fault. Writing the previous sections (on making decisions with Java’s if statement) knocked the stuffing right out of me. That’s why my mind boggles as I begin this section on choosing among many alternatives.

Consider the code in Listing 3-2.

Listing 3-2: A Java switch Statement

public void onClick(View v) {

    String message;

    Editable edit = textfield.getText();

    if (edit.length() != 0) {

        int number =

            Integer.valueOf(edit.toString());

        switch (number) {

        case 0:

            message = "none";

            break;

        case 1:

            message = "one";

            break;

        case 2:

            message = "two";

            break;

        case 3:

            message = "three";

            break;

        default:

            message = "many";

        }

        label.setText(message);

    }

}

 

The code in Listing 3-2 is part of an app, and the app’s screen is pictured in Figure 3-2.

image

Figure 3-2: A TextView object reports on an EditText object’s content.

The user clicks something or other (something not specified in Listing 3-2 or in Figure 3-2). As a result of the user’s click, Android does the stuff in Listing 3-2. Some of that stuff involves a Java switch statement. The switch statement examines the characters in a text field. (In Figure 3-2, the text field contains 011.) To make sure that the text field characters are all digits, I included the following element in the app’s layout document:

<EditText android:layout_height="wrap_content"

      android:id="@+id/editText1"

      android:layout_width="match_parent"

      android:inputType="number"></EditText>

 

In the first line of the switch statement, number is a whole number. If number is 0, the code makes message be "none". If number is 1, the code makes message be "one". If number is not 0, 1, 2, or 3, the default part of the switch statement takes over, and the code makes message be "many".

Each break statement in Listing 3-2 says, “Jump past any remaining cases.” You can omit a break statement, but do so at your own peril! For example, if you write

case 2:

    message = "two";

case 3:

    message = "three";

default:

    message = "many";

}

 

and number is 2, Java executes three cases, one after another — namely, message = "two" followed by message = "three" followed immediately by message = "many". The lack of break statements tells Java to fall-through from one case to the next. The end result is that the message is "many", and that’s probably not what you want.

A switch statement has the following form:

switch (expression) {

case constant1:

    statements to be executed when the

    expression has value constant1

case constant2:

    statements to be executed when the

    expression has value constant2

case …

default:

    statements to be executed when the

    expression has a value different from

    any of the constants

}

 

You can’t put any old expression in a switch statement. The expression that’s tested at the start of a switch statement must have

  • One of the primitive types char, byte, short, or int, or
  • One of the reference types Character, Byte, Short, or Integer, or
  • An enum type

An enum type is a type whose values are limited to the few that you declare. For example, the code

enum TrafficSignal {GREEN, YELLOW, RED};

 

defines a type whose only values are GREEN, YELLOW, and RED. Elsewhere in your code, you can write

TrafficSignal signal;

signal = TrafficSignal.GREEN;

 

to make use of the TrafficSignal type.

tip Starting with Java 7, you can put a String type expression at the start of a switch statement, as follows:

String myString = "one";

// …

// Set the value of myString here

// …

switch (myString) {

case "one":

    textView.setText("1");

    break;

case "two":

    textView.setText("2");

    break;

default:

    break;

}

Repeating Instructions Over and Over Again

In 1966, the company that brings you Head & Shoulders shampoo made history. On the back of the bottle, the directions for using the shampoo read, “Lather, rinse, repeat.” Never before had a complete set of directions (for doing anything, let alone shampooing your hair) been summarized so succinctly. People in the direction-writing business hailed this as a monumental achievement. Directions like these stood in stark contrast to others of the time. (For instance, the first sentence on a can of bug spray read, “Turn this can so that it points away from your face.” Duh!)

Aside from their brevity, the thing that made the Head & Shoulders directions so cool was that, with three simple words, they managed to capture a notion that’s at the heart of all instruction-giving — the notion of repetition. That last word, repeat, took an otherwise bland instructional drone and turned it into a sophisticated recipe for action.

The fundamental idea is that when you’re following directions, you don’t just follow one instruction after another. Instead, you take turns in the road. You make decisions (“If HAIR IS DRY, then USE CONDITIONER”), and you go into loops (“LATHER-RINSE and then LATHER-RINSE again”). In application development, you use decision-making and looping all the time.

Java while statements

In an Android app, a content provider feeds a cursor to your code. You can think of the cursor as a pointer to a row in a table. In Listing 3-3, each table row has three entries — an _id, a name, and an amount. Supposedly, the _id uniquely identifies a row, the name is a person’s name, and the amount is a huge number of dollars owed to you by that person.

crossreference For the rundown on content providers, see Book III, Chapter 5.

Listing 3-3: A while Loop

cursor.moveToFirst();

while (!cursor.isAfterLast()) {

    String _id = cursor.getString(0);

    String name = cursor.getString(1);

    String amount = cursor.getString(2);

    textViewDisplay.append(_id + " " + name + " " + amount + " ");

    cursor.moveToNext();

}

 

A cursor’s moveToFirst method makes the cursor point to the first row of the table. Regardless of the row a cursor points to, the cursor’s moveToNext method makes the cursor point to the next row of the table. The cursor’s isAfterLast method returns true when, having tried to move to the next row, there’s no next row.

In Java, an exclamation point (!) means “not,” so while (!cursor.isAfterLast()) means “while it’s not true that the cursor has reached past the table’s last row …” So the loop in Listing 3-3 repeatedly does the following:

As long as the cursor has not reached past the last row,

    get the string in the row’s initial column and

        make _id refer to that string,

    get the string in the row’s middle column and

        make name refer to that string,

    get the string in the row’s last column and

        make amount refer to that string, and

append these strings to the textViewDisplay, and then

move the cursor to the next row in preparation

        for returning to the top of the while statement.

 

Imagine that a particular cursor’s table has 100 rows. Then a processor executes the statements inside Listing 3-3's while loop 100 times. Using the official developer lingo, the processor performs 100 loop iterations.

A while statement has the following form:

while (condition) {

    statements to be executed

}

 

You can omit the curly braces when the loop has only one statement to be executed.

technicalstuff In Listing 3-3, the characters form an escape sequence. When you put inside a string, you’re escaping from the normal course of things by displaying neither a backslash nor a letter n. Instead, in a Java string always means “Go to the next line.” So in Listing 3-3, puts a line break between one _id, name, amount group and the next.

Java for statements

Life is filled with examples of counting loops. And app development mirrors life — or is it the other way around? When you tell a device what to do, you’re often telling the device to display three lines, process ten accounts, dial a million phone numbers, or whatever.

Listing 3-3 displays all the rows in a table full of data. Sometimes, all the data is too much data. To get the idea of what the table has to offer, you might want to display only the first ten rows of data. The code in Listing 3-4 does the job.

Listing 3-4: A for Loop

cursor.moveToFirst();

for (int i = 0; i < 10; i++) {

    String _id = cursor.getString(0);

    String name = cursor.getString(1);

    String amount = cursor.getString(2);

    textViewDisplay.append(i + ": " + _id + " " + name + " " + amount + " ");

    cursor.moveToNext();

}

 

Listing 3-4 declares an int variable named i. The starting value of i is 0. As long as the condition i < 10 is true, the processor executes the instructions inside the for statement. In this example, the for statement’s instructions include getting an _id, getting a name, getting an amount, and appending all that stuff to the textViewDisplay. In addition to that stuff, the textViewDisplay gets the value of i (be it 0, 1, 2, or any number less than 10).

To keep the ball rolling, the last instruction in the for statement moves the cursor to the next line. But wait! What happens when the processor goes to the beginning of the loop again? Before starting the loop anew, the processor does i++, which is Java-speak for “Add 1 to i.” So after ten loop iterations, the value of i finally reaches 10 and the execution of the for loop’s instructions comes to an end.

A for statement has the following form:

for (initialization ; condition ; update) {

    statements to be executed

}

  • An initialization (such as int i = 0 in Listing 3-4) defines the action to be taken before the first loop iteration.
  • A condition (such as i < 10 in Listing 3-4) defines the thing to be checked before an iteration. If the condition is true, the processor executes the iteration. If the condition is false, the processor doesn’t execute the iteration and moves on to execute whatever code comes after the for statement.
  • An update (such as i++ in Listing 3-4) defines an action to be taken at the end of each loop iteration.

As always, you can omit the curly braces when the loop has only one statement to be executed.

Like the protagonist in an ancient Greek tragedy, the loop in Listing 3-4 has a fatal flaw. The loop comes crashing down if the cursor’s table has fewer than ten rows. To remedy this (and to save the protagonist), you can add a check for “rowlessness” inside the loop:

for (int i = 0; i < 10; i++) {

    if (cursor.isAfterLast()) {

        break;

    }

    String _id = cursor.getString(0);

    String name = cursor.getString(1);

    String amount = cursor.getString(2);

    textViewDisplay.append(i + ": " + _id + " " + name + " " + amount + " ");

    cursor.moveToNext();

}

 

The if statement says “If there are no more rows (because the cursor is already positioned after the last row) then execute the break statement.” And inside a loop (a while loop, a for loop, or some other kind of loop), a break statement says, “This looping is done” and “We’re outta here.” The processor moves on to execute whatever statement comes immediately after the loop’s code.

Java do statements

To find a particular row of a cursor’s table, you normally do a query. (For straight talk about queries, see Book IV.) You almost never perform a do-it-yourself search through a table’s data. But just this once, look at a loop that iterates through row after row — the loop is in Listing 3-5.

Listing 3-5: Leap Before You Look

cursor.moveToFirst();

String name;

do {

    String _id = cursor.getString(0);

    name = cursor.getString(1);

    String amount = cursor.getString(2);

    textViewDisplay.append(_id + " " + name + " " + amount + " ");

    cursor.moveToNext();

} while (!name.equals("Burd") && !cursor.isAfterLast());

 

With a do loop, the processor jumps right in, takes action, and then checks a condition to see whether the result of the action is what you want. If the result is what you want, execution of the loop is done. If not, the processor goes back to the top of the loop for another go-around.

In Listing 3-5, you’re looking for a row with the name Burd. (After all, the bum owes you lots of money.) When you enter the loop, the cursor points to the table’s first row. Before checking a row for the name Burd, you fetch that first row’s data and add the data to the textViewDisplay where the user can see what’s going on.

Before you march on to the next row (the next loop iteration), you check a condition to make sure that another row is worth visiting. (Check to make sure that you haven’t yet found that Burd guy, and that you haven’t moved past the last row of the table.)

technicalstuff To get the code in Listing 3-5 working, you have to move the declaration of name outside the do statement. A declaration that’s inside a pair of curly braces (such as the _id, name, and amount declarations in Listing 3-4) cannot be used outside curly braces. So, in Listing 3-5, if you don’t move the name declaration outside the loop, Java complains that !name.equals("Burd") is incorrect.

Arrays in Java

An array is a bunch of values of the same type. Each value in the array is associated with an index. For example, the following code puts 15.020999999999999 in an app’s textView1:

double[] measurements = new double[3];

measurements[0] = 5.7;

measurements[1] = 9.32;

measurements[2] = 0.001;

textView1.setText(Double.toString(measurements[0]

        + measurements[1] + measurements[2]));

 

technicalstuff Arithmetic with float values and double values suffers from the woes of numeric errors. The sum 5.7 + 9.32 + 0.001 is 15.021, not 15.020999999999999. But computers use the bits 0 and 1 (instead of the digits 0 through 9) to store numbers internally. The use of zeros and ones, along with the fact that computers can’t store infinitely long decimal expansions, leads inevitably to arithmetic errors. Sorry about that!

The following code puts Barry Burd and Jane Dough in an app’s textView1:

String[] names = new String[3];

names[0] = new String("Barry Burd");

names[1] = new String("John Public");

names[2] = new String("Jane Dough");

textView1.setText(names[0] + " and " + names[2]);

 

You can step from value to value in an array using a for loop. For example, the following code puts Barry Burd John Public Jane Dough in an app’s textView1:

String[] names = new String[3];

names[0] = new String("Barry Burd ");

names[1] = new String("John Public ");

names[2] = new String("Jane Dough ");

textView1.setText("");

for (int i = 0; i < 3; i++) {

   textView1.append(names[i]);

}

Java’s enhanced for statements

In the mid-1960s, a company advertised its product by announcing, “Our product used to be perfect. But now, our product is even better!”

In the mid-2000s, the newly created Java 5 specification had a brand-new kind of loop. This feature has been part of Java for several years, but it’s still called the enhanced for loop. The following code uses an enhanced for loop to put Barry Burd John Public Jane Dough in an app’s textView1:

String[] names = new String[3];

names[0] = new String("Barry Burd ");

names[1] = new String("John Public ");

names[2] = new String("Jane Dough ");

textView1.setText("");

for (String s : names) {

   textView1.append(s);

}

 

Here’s another example. Suppose you have a cursor, and the cursor points to a table’s row. (To keep this example simple, I assume that each column contains String data.) You don’t know the table’s column names, and you don’t know how many columns the table has. Java’s enhanced for statement provides an elegant way to deal with this kind of situation. Listing 3-6 shows you the story.

Listing 3-6: An Enhanced for Loop

cursor.moveToFirst();

while (!cursor.isAfterLast()) {

    String[] columnNames = cursor.getColumnNames();

    for (String colName : columnNames) {

        int index = cursor.getColumnIndex(colName);

        textViewDisplay.append(colName + ":" + cursor.getString(index) + ", ");

    }

    textViewDisplay.append(" ");

    cursor.moveToNext();

}

 

In Listing 3-6, a cursor’s getColumnNames method returns an array of String values. The code assigns this array to the columnNames variable. Then the enhanced for loop creates a variable (colName) that steps through the String values in the array. The line

for (String colName : columnNames)

 

says, “Repeat the instructions in the for statement once for each of the String values stored in the columnNames array. During each value in the array, let the variable colName stand for that value during one of the loop’s iterations.” So, for example, if the columnNames array contains the strings _id, name, and amount, the processor performs three iterations of the enhanced loop in Listing 3-6. During the first iteration, colName stands for "_id". During the second iteration, colName stands for "name". During the third iteration, colName stands for "amount".

With or without enhanced loops, a cursor’s getString method needs a column number. In Listing 3-5 (and in previous listings), I hand column numbers 0, 1, and 2 to the getString method. In Listing 3-6, I fetch these column numbers from the column names, using the cursor’s getColumnIndex method.

An enhanced for statement has the following form:

for (TypeName variable : arrayOrCollection) {

    statements to be executed

}

 

The TypeName is the type of each element in the arrayOrCollection. The loop performs an iteration for each element of the arrayOrCollection. During each iteration, the variable refers to one of the elements in the arrayOrCollection.

Jumping Away from Trouble

The Java programming language has a mechanism called exception handling. With exception handling, a program can detect that things are about to go wrong and respond by creating a brand-new object. In the official terminology, the program is said to be throwing an exception. That new object, an instance of the Exception class, is passed like a hot potato from one piece of code to another until some piece of code decides to catch the exception. When the exception is caught, the program executes some recovery code, buries the exception, and moves on to the next normal statement as if nothing had ever happened.

The whole thing is done with the aid of several Java keywords. These keywords are as follows:

  • throw: Creates a new exception object.
  • throws: Passes the buck from a method up to whatever code called the method.
  • try: Encloses code that has the potential to create a new exception object. In the usual scenario, the code inside a try clause contains calls to methods whose code can create one or more exceptions.
  • catch: Deals with the exception, buries it, and then moves on.

For example, Java’s Integer.parseInt method turns a String value into an int value. The value of "279" + 1 is "2791", but the value of Integer.parseInt("279") + 1 is 280. A call to Integer.parseInt throws a NumberFormat Exception if the call’s parameter isn’t a whole number. So if your code calls Integer.parseInt("3.5"), your code has to deal with a NumberFormat Exception. (The String value "3.5" doesn’t stand for a whole number.)

Here’s a simple method to add one to a number that’s represented as a String value:

int increment(String str) {

   return Integer.parseInt(str) + 1;

}

 

If you call increment("985"), you get 986. That’s good.

But if you call increment("2.71828"), your code crashes, and your app stops running. Java leaves clues about the crash in the Logcat tab. The clues (which form a Java stack trace) look something like this:

Exception in thread "main" java.lang.NumberFormatException:

For input string: "2.71828"

    at java.lang.NumberFormatException.forInputString

    at java.lang.Integer.parseInt

 

If you add some exception handling code to the increment method, your code keeps running with or without the increment("2.71828") call.

int increment(String str) {

    try {

        return Integer.parseInt(str) + 1;

    } catch (NumberFormatException e) {

        return 0;

    }

}

 

With the try and catch in the revised method, Java attempts to evaluate Integer.parseInt(str). If evaluation is successful, the method returns Integer.parseInt(str) + 1. But if str has a weird value, the call to Integer.parseInt throws a NumberFormatException. Fortunately, the revised increment method catches the NumberFormatException, returns the value 0, and continues running without bothering the user.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.197.250