Figure 5-1: What part of the word “don’t” do you not understand?
Chapter 5
Composing a Program
In This Chapter
Reading input from the keyboard
Editing a program
Shooting at trouble
Just yesterday, I was chatting with my servant, RoboJeeves. (RoboJeeves is an upscale model in the RJ-3000 line of personal robotic life-forms.) Here’s how the discussion went:
Me: RoboJeeves, tell me the velocity of an object after it’s been falling for 3 seconds in a vacuum.
RoboJeeves: All right, I will. “The velocity of an object after it’s been falling for 3 seconds in a vacuum.” There, I told it to you.
Me: RoboJeeves, don’t give me that smart-alecky answer. I want a number. I want the actual velocity.
RoboJeeves: Okay! “A number; the actual velocity.”
Me: RJ, these cheap jokes are beneath your dignity. Can you or can’t you tell me the answer to my question?
RoboJeeves: Yes.
Me: “Yes,” what?
RoboJeeves: Yes, I either can or can’t tell you the answer to your question.
Me: Well, which is it? Can you?
RoboJeeves: Yes, I can.
Me: Then do it. Tell me the answer.
RoboJeeves: The velocity is 153,984,792 miles per hour.
Me: (After pausing to think . . .) RJ, I know you never make a mistake, but that number, 153,984,792, is much too high.
RoboJeeves: Too high? That’s impossible. Things fall very quickly on the giant planet Mangorrrrkthongo. Now, if you wanted to know about objects falling on Earth, you should have said so in the first place.
Sometimes that robot rubs me the wrong way. The truth is, RoboJeeves does whatever I tell him to do — nothing more and nothing less. If I say “Feed the cat,” then RJ says, “Feed it to whom? Which of your guests will be having cat for dinner?”
Computers Are Stupid
Handy as they are, all computers do the same darn thing. They do exactly what you tell them to do, and that’s sometimes very unfortunate. For example, in 1962, a Mariner spacecraft to Venus was destroyed just 4 minutes after its launch. Why? It was destroyed because of a missing keystroke in a FORTRAN program. Around the same time, NASA scientists caught an error that could have trashed the Mercury space flights. (Yup! These were flights with people on board!) The error was a line with a period instead of a comma. (A computer programmer wrote DO 10 I=1.10
instead of DO 10 I=1,10
.)
With all due respect to my buddy RoboJeeves, he and his computer cousins are all incredibly stupid. Sometimes they look as if they’re second-guessing us humans, but actually they’re just doing what other humans told them to do. They can toss virtual coins and use elaborate schemes to mimic creative behavior, but they never really think on their own. If you say, “Jump,” then they do what they’re programmed to do in response to the letters J-u-m-p.
So when you write a computer program, you have to imagine that a genie has granted you three wishes. Don’t ask for eternal love because, if you do, then the genie will give you a slobbering, adoring mate — someone that you don’t like at all. And don’t ask for a million dollars unless you want the genie to turn you into a bank robber.
Everything you write in a computer program has to be very precise. Take a look at an example. . . .
A Program to Echo Keyboard Input
Listing 5-1 contains a small Java program. The program lets you type one line of characters on the keyboard. As soon as you press Enter, the program displays a second line that copies whatever you typed.
Listing 5-1: A Java Program
import java.util.Scanner;
class EchoLine {
public static void main(String args[]) {
Scanner myScanner = new Scanner(System.in);
System.out.println(myScanner.nextLine());
}
}
Figure 5-1 shows a run of the EchoLine
code (the code in Listing 5-1). The text in the figure is a mixture of my own typing and the computer’s responses.
Figure 5-1: What part of the word “don’t” do you not understand?
In Figure 5-1, I type the first line (the first Please don’t repeat this to anyone
line) and the computer displays the second line. Here’s what happens when you run the code in Listing 5-1:
1. At first, the computer does nothing.
The computer is waiting for you to type something.
2. You click your mouse inside Eclipse’s Console view.
As a result you see a cursor on the left edge of Eclipse’s Console view, as shown in Figure 5-2.
Figure 5-2: The computer waits for you to type something.
3. You type one line of text — any text at all (see Figure 5-3).
Figure 5-3: You type a sentence.
4. You press Enter, and the computer displays another copy of the line that you typed, as shown in Figure 5-4.
Figure 5-4: The computer echoes your input.
After displaying a copy of your input, the program’s run comes to an end.
Typing and running a program
This book’s website (http://allmycode.com/BeginProg3
) has a link for downloading all the book’s Java programs. After you download the programs, you can follow instructions in Chapter 2 to add the programs to your Eclipse workspace. Then, to test the code in Listing 5-1, you can run the readymade 05-01 project.
But instead of running the readymade code, I encourage you to start from scratch — to type Listing 5-1 yourself and then to test your newly created code. Just follow these steps:
1. Launch Eclipse.
2. From Eclipse’s menu bar, choose File⇒New⇒Java Project.
Eclipse’s New Java Project dialog box appears.
3. In the dialog box’s Project Name field, type MyNewProject.
4. Click Finish.
Clicking Finish brings you back to the Eclipse workbench, with MyNewProject
in the Package Explorer. The next step is to create a new Java source code file.
5. In the Package Explorer, select MyNewProject
and then, in Eclipse’s main menu, choose File⇒New⇒Class.
Eclipse’s New Java Class dialog box appears.
6. In the New Java Class dialog box’s Name field, type the name of your new class.
In this example, use the name EchoLine. Spell EchoLine exactly the way I spell it in Listing 5-1, with a capital E, a capital L, and no blank space.
In Java, consistent spelling and capitalization are very important. If you’re not consistent within a particular program, then the program will probably have some nasty, annoying compile-time errors.
Optionally, you can put a check mark in the box labeled
public static void main(String[] args}
. If you leave the box unchecked, you’ll have a bit more typing to do when you get to Step 8. Either way (checked or unchecked) it’s no big deal.
7. Click Finish.
Clicking Finish brings you back to the Eclipse workbench. An editor in this workbench has a tab named EchoLine.java.
8. Type the program of Listing 5-1 in the EchoLine.java editor.
Copy the code exactly as you see it in Listing 5-1.
• Spell each word exactly the way I spell it in Listing 5-1.
• Capitalize each word exactly the way I do in Listing 5-1.
• Include all the punctuation symbols — the dots, the semicolons, everything.
• Double-check the spelling of the word println
. Make sure that each character in the word println
is a lowercase letter. (In particular, the l
in ln
is a letter, not a digit.)
If you typed everything correctly, you don’t see any error markers in the editor.
If you see error markers, then go back and compare everything you typed with the stuff in Listing 5-1. Compare every letter, every word, every squiggle, every smudge.
9. Make any changes or corrections to the code in the editor.
When at last you see no error markers, you’re ready to run the program.
10. Select the EchoLine class either by clicking inside the editor or by clicking the MyNewProject branch in the Package Explorer.
11. In Eclipse’s main menu, choose Run⇒Run As⇒Java Application.
Your new Java program runs, but nothing much happens.
12. Click your mouse inside Eclipse’s Console view.
As a result, a cursor sits on the left edge of Eclipse’s Console view. (Refer to Figure 5-2.) The computer is waiting for you to type something.
If you forget to click your mouse inside the Console view, Eclipse may not send your keystrokes to the running Java program. Instead, Eclipse may send your keystrokes to the editor or (strangely enough) to the Package Explorer.
13. Type a line of text and then press Enter.
In response, the computer displays a second copy of your line of text. Then the program’s run comes to an end. (Refer to Figure 5-4.)
If this list of steps seems a bit sketchy, you can find much more detail in Chapter 3. (Look first at the section in Chapter 3 about compiling and running a program.) For the most part, the steps here in Chapter 5 are a quick summary of the material in Chapter 3. The big difference is that in Chapter 3, I don’t encourage you to type the program yourself.
So what’s the big deal when you type the program yourself? Well, lots of interesting things can happen when you apply fingers to keyboard. That’s why the second half of this chapter is devoted to troubleshooting.
How the EchoLine program works
When you were a tiny newborn, resting comfortably in your mother’s arms, she told you how to send characters to the computer screen:
System.out.println(
whatever text you want displayed
);
What she didn’t tell you was how to fetch characters from the computer keyboard. There are lots of ways to do it, but the one I recommend in this chapter is
myScanner.nextLine()
Now, here’s the fun part. Calling the nextLine
method doesn’t just scoop characters from the keyboard. When the computer runs your program, the computer substitutes whatever you type on the keyboard in place of the text myScanner.nextLine()
.
To understand this, look at the statement in Listing 5-1:
System.out.println(myScanner.nextLine());
When you run the program, the computer sees your call to nextLine
and stops dead in its tracks. (Refer to Figure 5-2.) The computer waits for you to type a line of text. So (refer to Figure 5-3) you type this line:
Hey, there’s an echo in here.
The computer substitutes this entire Hey
line for the myScanner.nextLine()
call in your program. The process is illustrated in Figure 5-5.
The call to myScanner.nextLine()
is nestled inside the System.out.println
call. So when all is said and done, the computer behaves as if the statement in Listing 5-1 looks like this:
System.out.println(“Hey, there’s an echo in here.”);
The computer displays another copy of the text Hey, there’s an echo in here.
on the screen. That’s why you see two copies of the Hey
line in Figure 5-4.
Figure 5-5: The computer substitutes text in place of the nextLine
call.
Getting numbers, words, and other things
In Listing 5-1, the words myScanner.nextLine()
get an entire line of text from the computer keyboard. So if you type
Testing 1 2 3
the program in Listing 5-1 echoes back your entire Testing 1 2 3
line of text.
Sometimes you don’t want a program to get an entire line of text. Instead, you want the program to get a piece of a line. For example, when you type 1 2 3
, you may want the computer to get the number 1
. (Maybe the number 1
stands for one customer or something like that.) In such situations, you don’t put myScanner.nextLine()
in your program. Instead, you use myScanner.
nextInt
()
.
Table 5-1 shows you a few variations on the myScanner.next
business. Unfortunately, the table’s entries aren’t very predictable. To read a line of input, you call nextLine
. But to read a word of input, you don’t call nextWord
. (The Java API has no nextWord
method.) Instead, to read a word, you call next
.
Table 5-1 Some Scanner Methods
To Read This . . . |
. . . Make This Method Call |
A number with no decimal point in it |
|
A number with a decimal point in it |
|
A word (ending in a blank space, for example) |
|
A line (or what remains of a line after you’ve already read some data from the line) |
|
A single character (such as a letter, a digit, or a punctuation character) |
|
Also, the table’s story has a surprise ending. To read a single character, you don’t call next
Something
. Instead, you can call the bizarre findWithin Horizon(“.”,0).charAt(0)
combination of methods. (You’ll have to excuse the folks who created the Scanner
class. They created Scanner
from a specialized point of view.)
To see some of the table’s methods in action, check other program listings in this book. Chapters 6, 7, and 8 have some particularly nice examples.
Type two lines of code and don’t look back
Buried innocently inside Listing 5-1 are two extra lines of code. These lines help the computer read input from the keyboard. The two lines are
import java.util.Scanner;
Scanner myScanner = new Scanner(System.in);
Concerning these two lines, I have bad news and good news.
The bad news is, the reasoning behind these lines is difficult to understand. That’s especially true here in Chapter 5, where I introduce Java’s most fundamental concepts.
The good news is, you don’t have to understand the reasoning behind these two lines. You can copy and paste these lines into any program that gets input from the keyboard. You don’t have to change the lines in any way. These lines work without any modifications in all kinds of Java programs.
Just be sure to put these lines in the right places:
Make the
import java.util.Scanner
line be the first line in your program.
Put the
Scanner myScanner = new Scanner(System.in)
line inside your main
method immediately after the public static void main(String args[]) {
line.
At some point in the future, you may have to be more careful about the positioning of these two lines. But for now, the rules I give will serve you well.
Expecting the Unexpected
Not long ago, I met an instructor with an interesting policy. He said, “Sometimes when I’m lecturing, I compose a program from scratch on the computer. I do it right in front of my students. If the program compiles and runs correctly on the first try, I expect the students to give me a big round of applause.”
At first, you may think this guy has an enormous ego, but you have to put things in perspective. It’s unusual for a program to compile and run correctly the first time. There’s almost always a typo or another error of some kind.
So this section deals with the normal, expected errors that you see when you compile and run a program for the first time. Everyone makes these mistakes, even the most seasoned travelers. The key is keeping a cool head. Here’s my general advice:
Don’t expect a program that you type to compile the first time.
Be prepared to return to your editor and fix some mistakes.
Don’t expect a program that compiles flawlessly to run correctly.
Even with no error markers in Eclipse’s editor, your program might still contain flaws. After Eclipse compiles your program, you still have to run the program successfully. That is, your program should finish its run and display the correct output.
You compile and then you run. Getting a program to compile without errors is the easier of the two tasks.
Read what’s in the Eclipse editor, not what you assume is in the Eclipse editor.
Don’t assume that you’ve typed words correctly, that you’ve capitalized words correctly, or that you’ve matched curly braces or parentheses correctly. Compare the code you typed with any sample code that you have. Make sure that every detail is in order.
Be patient.
Every good programming effort takes a long time to get right. If you don’t understand something right away, then be persistent. Stick with it (or put it away for a while and come back to it). There’s nothing you can’t understand if you put in enough time.
Don’t become frustrated.
Don’t throw your pie crust. Frustration (not lack of knowledge) is your enemy. If you’re frustrated, you can’t accomplish anything.
Don’t think you’re the only person who’s slow to understand.
I’m slow, and I’m proud of it. (Kelly, Chapter 6 will be a week late.)
Don’t be timid.
If your code isn’t working and you can’t figure out why it’s not working, then ask someone. Post a message on groups.google.com
or send me an e-mail message. (Send it to BeginProg3@allmycode.com
.) And don’t be afraid of anyone’s snide or sarcastic answer. (For a list of gestures you can make in response to peoples’ snotty answers, see Appendix Z.)
Diagnosing a problem
The “Typing and running a program” section, earlier in this chapter, tells you how to run the EchoLine
program. If all goes well, your screen ends up looking like the one shown in Figure 5-1. But things don’t always go well. Sometimes your finger slips, inserting a typo into your program. Sometimes you ignore one of the details in Listing 5-1, and you get a nasty error message.
Of course, some things in Listing 5-1 are okay to change. Not every word in Listing 5-1 is cast in stone. So here’s a nasty wrinkle — I can’t tell you that you must always retype Listing 5-1 exactly as it appears. Some changes are okay; others are not. Keep reading for some “f’rinstances.”
Case sensitivity
Java is case-sensitive. Among other things, case-sensitive means that, in a Java program, the letter P
isn’t the same as the letter p
. If you send me some fan mail and start with “Dear barry” instead of “Dear Barry,” then I still know what you mean. But Java doesn’t work that way.
So change just one character in a Java program and instead of an uneventful compilation, you get a big headache! Change p
to P
like so:
//The following line is
incorrect
:
System.out.
Println
(myScanner.nextLine());
When you type the program in Eclipse’s editor, you get the ugliness shown in Figure 5-6.
Figure 5-6: The Java compiler understands println
, but not Println
.
When you see error markers and quick fixes like the ones in Figure 5-6, your best bet is to stay calm and read the messages carefully. Sometimes, the messages contain useful hints. (Of course, sometimes they don’t.) The message in Figure 5-6 is The method Println(String) is undefined for the type PrintStream
. In plain English, this means “The Java compiler can’t interpret the word Println
.” (The message stops short of saying, “Don’t type the word Println
, you dummy!” In any case, if the computer says you’re one of us Dummies, you should take it as a compliment.) Now, there are plenty of reasons why the compiler may not be able to understand a word like Println
. But, for a beginning programmer, you should check two important things right away:
Have you spelled the word correctly?
Did you accidentally type printlin
(with a digit 1
) instead of println
?
Have you capitalized all letters correctly?
Did you incorrectly type Println
or PrintLn
instead of println
?
Either of these errors can send the Java compiler into a tailspin. So compare your typing with the approved typing word for word (and letter for letter). When you find a discrepancy, go back to the editor and fix the problem. Then try compiling the program again.
Omitting punctuation
In English and in, Java using the; proper! punctuation is important)
Take, for example, the semicolons in Listing 5-1. What happens if you forget to type a semicolon?
//The following code is
incorrect
:
System.out.println(myScanner.nextLine())
}
If you leave off the semicolon, you get the message shown in Figure 5-7.
Figure 5-7: A helpful error message.
A message like the one in Figure 5-8 makes your life much simpler. I don’t have to explain the message, and you don’t have to puzzle over the message’s meaning. Just take the message insert “;” to complete Statement
on its face value. Insert the semicolon between the end of the System.out.println(myScanner.nextLine())
statement and whatever code comes after the statement. (For code that’s easiest to read and understand, tack on the semicolon at the end of the System.out.println(myScanner.nextLine())
statement.)
Using too much punctuation
In junior high school, my English teacher said I should use a comma whenever I would normally pause for a breath. This advice doesn’t work well during allergy season, when my sentences have more commas in them than words. Even as a paid author, I have trouble deciding where the commas should go, so I often add extra commas for good measure. This makes more work for my copy editor, Kelly, who has a trash can full of commas by the desk in her office.
It’s the same way in a Java program. You can get carried away with punctuation. Consider, for example, the main
method header in Listing 5-1. This line is a dangerous curve for novice programmers.
For information on the terms method header and method body, see Chapter 4.
Normally, you shouldn’t be ending a method header with a semicolon. But people add semicolons anyway. (Maybe, in some subtle way, a method header looks like it should end with a semicolon.)
//The following line is
incorrect
:
public static void main(String args[])
;
{
If you add this extraneous semicolon to the code in Listing 5-1, you get the message shown in Figure 5-8.
Figure 5-8: An unwanted semicolon messes things up.
The error message and quick fixes in Figure 5-8 are a bit misleading. The message starts with This method requires a body
. But the method has a body. Doesn’t it?
When the computer tries to compile public static void main(String args[]);
(ending with a semicolon), the computer gets confused. I illustrate the confusion in Figure 5-9. Your eye sees an extra semicolon, but the computer’s eye interprets this as a method without a body. So that’s the error message — the computer says This method requires a body instead of a semicolon
.
Figure 5-9: What’s on this computer’s mind?
If you select the Add Body quick fix, Eclipse creates the following (really horrible) code:
import java.util.Scanner;
class EchoLine {
public static void main(String args[]) {
}
{
Scanner myScanner = new Scanner(System.in);
System.out.println(myScanner.nextLine());
}
}
This “fixed” code has no compile-time errors. But when you run this code, nothing happens. The program starts running and then stops running with nothing in Eclipse’s Console view.
We all know that a computer is a very patient, very sympathetic machine. That’s why the computer looks at your code and decides to give you one more chance. The computer remembers that Java has an advanced feature in which you write a method header without writing a method body. When you do this, you get what’s called an abstract method — something that I don’t use at all in this book. Anyway, in Figure 5-9, the computer sees a header with no body. So the computer says to itself, “I know! Maybe the programmer is trying to write an abstract method. The trouble is, an abstract method’s header has to have the word abstract
in it. I should remind the programmer about that.” So the computer offers the add ‘abstract’ modifier
quick fix in Figure 5-9.
One way or another, you can’t interpret the error message and the quick fixes in Figure 5-9 without reading between the lines. So here are some tips to help you decipher murky messages:
Avoid the knee-jerk response.
Some people see the add ‘abstract’ modifier
quick fix in Figure 5-9 and wonder where they can add a modifier. Unfortunately, this isn’t the right approach. If you don’t know what an ‘abstract’ modifier
is, then chances are you didn’t mean to use an abstract modifier in the first place.
Stare at the bad line of code for a long, long time.
If you look carefully at the public static . . .
line in Figure 5-9, then eventually you’ll notice that it’s different from the corresponding line in Listing 5-1. The line in Listing 5-1 has no semicolon, but the line in Figure 5-9 has a semicolon.
Of course, you won’t always be starting with some prewritten code like the stuff in Listing 5-1. That’s where practice makes perfect. The more code you write, the more sensitive your eyes will become to things like extraneous semicolons and other programming goofs.
Too many curly braces
You’re looking for the nearest gas station, so you ask one of the locals. “Go to the first traffic light and make a left,” says the local. You go straight for a few streets and see a blinking yellow signal. You turn left at the signal and travel for a mile or so. What? No gas station? Maybe you mistook the blinking signal for a real traffic light.
You come to a fork in the road. “The directions said nothing about a fork. Which way should I go?” You veer right, but a minute later, you’re forced onto a highway. You see a sign that says, “Next Exit 24 Miles.” Now you’re really lost, and the gas gauge points to “S.” (The “S” stands for “Stranded.”)
So here’s what happened: You made an honest mistake. You shouldn’t have turned left at the yellow blinking light. That mistake alone wasn’t so terrible. But that first mistake lead to more confusion, and eventually, your choices made no sense at all. If you hadn’t turned at the blinking light, you’d never have encountered that stinking fork in the road. Then, getting on the highway was sheer catastrophe.
Is there a point to this story? Of course there is. A computer can get itself into the same sort of mess. The computer notices an error in your program. Then, metaphorically speaking, the computer takes a fork in the road — a fork based on the original error — a fork for which none of the alternatives leads to good results.
Here’s an example. You’re retyping the code in Listing 5-1, and you mistakenly type an extra curly brace:
//The following code is
incorrect
:
import java.util.Scanner;
class EchoLine {
public static void main(String args[]) {
Scanner myScanner = new Scanner(System.in);
}
System.out.println(myScanner.nextLine());
}
}
In Eclipse’s editor, you hover over the leftmost marker. You see the messages shown in Figure 5-10.
Figure 5-10: Three error messages.
Eclipse is confused because the call to System.out.println
is completely out of place. Eclipse displays three messages — something about println
, something about the parenthesis, and something very cryptic concerning misplaced constructs. None of these messages addresses the cause of the problem. Eclipse is trying to make the best of a bad situation, but at this point, you shouldn’t believe a word that Eclipse says.
Computers aren’t smart animals, and if someone programs the Eclipse to say misplaced construct(s)
, then that’s exactly what the Eclipse says. (Some people say that computers make them feel stupid. For me, it’s the opposite. A computer reminds me how dumb a machine can be and how smart a person can be. I like that.)
So when you see a bunch of error messages, read each error message carefully. Ask yourself what you can learn from each message. But don’t take each message as the authoritative truth. When you’ve exhausted your efforts with Eclipse’s messages, return to your efforts to stare carefully at the code.
Misspelling words (and other missteps)
You’ve found an old family recipe for deviled eggs (one of my favorites). You follow every step as carefully as you can, but you leave out the salt because of your grandmother’s high blood pressure. You hand your grandmother an egg (a finished masterpiece). “Not enough pepper,” she says, and she walks away.
The next course is beef bourguignon. You take an unsalted slice to dear old Granny. “Not sweet enough,” she groans, and she leaves the room. “But that’s impossible,” you think. “There’s no sugar in beef bourguignon. I left out the salt.” Even so, you go back to the kitchen and prepare mashed potatoes. You use unsalted butter, of course. “She’ll love it this time,” you think.
“Sour potatoes! Yuck!” Granny says, as she goes to the sink to spit it all out. Because you have a strong ego, you’re not insulted by your grandmother’s behavior. But you’re somewhat confused. Why is she saying such different things about three unsalted recipes? Maybe there are some subtle differences that you don’t know about.
Well, the same kind of thing happens when you’re writing computer programs. You can make the same kind of mistake twice (or at least, make what you think is the same kind of mistake twice) and get different error messages each time.
For example, if you change the spelling or capitalization of println
in Listing 5-1, Eclipse tells you the method is undefined for the type PrintStream
. But if you change System
to system
, Eclipse says that system cannot be resolved
. And with System
misspelled, Eclipse doesn’t notice whether println
is spelled correctly or not.
In Listing 5-1, if you change the spelling of args
, then nothing goes wrong. The program compiles and runs correctly. But if you change the spelling of main
, you face some unusual difficulties. (If you don’t believe me, read the “Runtime error messages” section.)
Still in Listing 5-1, change the number equal signs in the Scanner myScanner = new Scanner(System.in)
line. With one equal sign, everybody’s happy. If you accidentally type two equal signs (Scanner myScanner == new Scanner(System.in)
), Eclipse steers you back on course, telling you Syntax error on token “==”, = expected
(see Figure 5-11). But if you go crazy and type four equal signs or if you type no equal signs at all, Eclipse misinterprets everything and suggests that you insert “;” to complete BlockStatements
. Unfortunately, inserting a semicolon is no help at all (see Figure 5-12).
Figure 5-11: Remove the second of two equal signs.
Figure 5-12: You’re missing an equal sign, but Eclipse fails to notice.
So remember: Java responds to errors in many different ways. Two changes in your code might look alike, but similar changes don’t always lead to similar results. Each problem in your code requires its own individualized attention.
Runtime error messages
Up to this point in the chapter, I describe errors that crop up when you compile a program. Another category of errors hides until you run the program. A case in point is the improper spelling or capitalization of the word main
.
Assume that, in a moment of wild abandon, you incorrectly spell main
with a capital M
:
//The following line is
incorrect
:
public static void
Main
(String args[]) {
When you type the code, everything is hunky-dory. You don’t see any error markers.
But then you try to run your program. At this point, the bits hit the fan. The catastrophe is illustrated in Figure 5-13.
Figure 5-13: Whadaya mean “Main method not found in class EchoLine?”
Sure, your program has something named Main
, but does it have anything named main
? (Yes, I’ve heard of a famous poet named e. e. cummings, but who the heck is E. E. Cummings?) The computer doesn’t presume that your word Main
means the same thing as the expected word main
. You need to change Main
back to main
. Then everything will be okay.
But in the meantime (or in the maintime), how does this improper capitalization make it past the compiler? Why don’t you get any error messages when you compile the program? And if a capital M
doesn’t upset the compiler, why does this capital M
mess everything up at runtime?
The answer goes back to the different kinds of words in the Java programming language. As it says in Chapter 4, Java has identifiers and keywords.
The keywords in Java are cast in stone. If you change class
to Class
, or change public
to Public
, then you get something new — something that the computer probably can’t understand. That’s why the compiler chokes on improper keyword capitalizations. It’s the compiler’s job to make sure that all the keywords are used properly.
On the other hand, the identifiers can bounce all over the place. Sure, there’s an identifier named main
, but you can make up a new identifier named Main
. (You shouldn’t do it, though. It’s too confusing to people who know Java’s usual meaning for the word main
.) When the compiler sees a mistyped line, like public static void Main
, the compiler just assumes that you’re making up a brand-new name. So the compiler lets the line pass. You get no complaints from your old friend, the compiler.
But then, when you try to run the code, the computer goes ballistic. The Java virtual machine (JVM) runs your code. (For details, see Chapter 1.) The JVM needs to find a place to start executing statements in your code, so the JVM looks for a starting point named main
, with a small m
. If the JVM doesn’t see anything named main
, then the JVM gets upset. “Main method not found in class EchoLine,” says the JVM. So at runtime, the JVM, and not the compiler, gives you an error message.
What problem? I don’t see a problem
I end this chapter on an upbeat note by showing you some of the things you can change in Listing 5-1 without rocking the boat.
The identifiers that you create
If you create an identifier, then that name is up for grabs. For example, in Listing 5-1, you can change EchoLine
to RepeatAfterMe
.
class
RepeatAfterMe
{
public static void main ...
etc
.
This presents no problem at all, as long as you’re willing to be consistent. Just follow most of the steps in this chapter’s earlier “Typing and running a program” section.
In Step 6, instead of typing EchoLine, type RepeatAfterMe in the New Java Class dialog box’s Name field.
In Step 8, when you copy the code from Listing 5-1, don’t type
class EchoLine {
near the top of the listing. Instead, type the words
class RepeatAfterMe {
Spaces and indentation
Java isn’t fussy about the use of spaces and indentation. All you need to do is keep your program well-organized and readable. Here’s an alternative to spacing and indentation of the code in Listing 5-1:
import java.util.Scanner;
class EchoLine
{
public static void main( String args[] )
{
Scanner myScanner =
new Scanner( System.in );
System.out.println
( myScanner.nextLine() );
}
}
How you choose to do things
A program is like a fingerprint. No two programs look very much alike. Say I discuss a programming problem with a colleague. Then we go our separate ways and write our own programs to solve the same problem. Sure, we’re duplicating the effort. But will we create the exact same code? Absolutely not. Everyone has his or her own style, and everyone’s style is unique.
I asked fellow Java programmer David Herst to write his own EchoLine
program without showing him my code from Listing 5-1. Here’s what he wrote:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class EchoLine {
public static void main(String[] args)
throws IOException {
InputStreamReader isr =
new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String input = br.readLine();
System.out.println(input);
}
}
Don’t worry about BufferedReader
, InputStreamReader
, or things like that. Just notice that, like snowflakes, no two programs are written exactly alike, even if they accomplish the same task. That’s nice. It means your code, however different, can be as good as the next person’s. That’s very encouraging.