| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A Simple Program: Hello World | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
It is a long standing tradition (well, as long standing as any tradition can be
in a field that's only forty years old) that the first example
program that is presented in any language is the hello world
program. This is a simple program whose only task is to print the words
"hello world" on your screen. Hello world makes a nice example because, since it does so little, it shows you exactly what the minimal structure of a program is in a given language. That is, the stuff you need to put into every program to make it acceptable to the compiler. (Recall that the compiler is the program that converts the text of a program in a high-level language to an equivalent assembly language program the computer can actually run.) Every programming language has a certain amount of structural overhead that it makes you put into every program, just so the compiler can tell it is a program. Starting with a simple example also insures that you know the series of steps needed to run the compiler to turn the text form of the program into an executable version the computer can run. In Java, the hello world program is written like this:
To run this program type the text of the program into emacs, creating a file named
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Understanding Hello World | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comments Identify and Clarify |
The first few lines of the hello world program (the ones beginning with //)
are not really part of the program at all, at least from the computer's perspective.
These lines are comments, which are completely ignored by the compiler.
They are there only to help the human reader of the program.
Every program you write should begin with a comment giving at least this much information,
to make it easy for the reader to identify the program and its purpose. Comments can also be inserted as annotations anywhere inside a program. They are often used to clarify parts of the code whose behavior or purpose might not otherwise be immediately clear, and are an important part of good programming style. Of course it is possible to over-comment a program. The example programs in these notes can be used to get a sense of the proper level of commenting. Your graders will note on your programs where they feel you are over- or under-commenting.
Java supports two different styles of comments, marked with different symbols.
The comment marker
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
It is important to note that comments made using the second form
cannot be nested. That is, you can't put one comment inside another.
This is because once the compiler sees the characters /*
it simply ignores all further text until it encounters the characters
*/. If one comment is nested inside another the delimeter
intended to close the inner comment will actually close the outer comment.
The compiler will then attempt to interpret anything left in the
outer comment as program source. For example, consider the following attempt to
nest a pair of comments:
The compiler sees it like this, where we have highlighted what the compiler thinks are the opening and closing delimeters: Thus the part of the outer comment after the inside comment is no longer actually in a comment.
Why should you care? Well when you are trying to debug a program
you often just temporarily comment out a part that's not working by wrapping it in a pair of comment delimiters.
You have to be careful that the part that you comment out does not
contain a comment (constructed with
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Of course, some authors say that adding a multi-line comment to a program by using the first kind of comment (putting the // comment delimiter a the beginning of each line) is the way that's bad.
They feel that a problem arises when you try to add text in the middle of one of the lines
and the rest of the line wraps around onto the next line. Now that new line doesn't begin
with the comment characters and causes problems. So, it looks like you can't really win.
It's up to you to decide which method you want to use to type multi-line comments.
From our viewpoint both are pretty much ok.
Java actually supports a third, special kind of comment, using the delimeters
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| The Heart Of The Program |
The heart of the Hello World program is the line:
This line is a single Java statement.
It tells Java to print the string
Why is the command name
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Java Is Object Oriented |
Java is what is known as an object oriented language.
In traditional languages the programmer writes functions
or procedures which manipulate data. The data itself
is considered to be passive. For example, a function might take a list of data
as something to work on and tell you whether a particular value is in the list. In object oriented languages this view is turned on its head. Data are active objects that know how to perform tasks. I.e., a list might be able to respond to a query about whether it contains a particular value. In this setting, programming consists of defining the different kinds of objects and their behaviors. In place of functions, one defines methods which are the instructions for an object on how to carry out some task.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sending a Message |
System.out is an object that
corresponds to the screen. One of the things it knows how to
do is to display data values on the screen. To ask this object
to display something on the screen for you, you send it the
message println (which is short for "print
line") along with the value you want it to display.
System.out responds by executing whatever code it has in the
method for performing that task. The value you send to be printed
is called the argument or parameter of the
message.
Some methods do not require parameters, they act in a way
that is independent of the current context. In such cases,
the method is called by writing the method name with an
empty pair of parentheses after it. For example,
Some methods can be called either with or without an argument. For example, if you call: like that, with no argument, it will just advance the cursor on the screen to the beginning of the next line (like hitting carriage return on the typewriter).
Some authors (including me)
sometimes blur the distinction between the point where the message
is sent and the point where the message is received by an object which selects a method
responding to it. Such authors will refer to
invoking the
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Packages |
Note that System is actually a
special bundle (called a package or, in older parlance,
a library) of objects that is available at any time within
Java. System.out is just one of several objects
contained in that package.
In fact, this package is actually a sub-package of a larger one. Its
full name is java.lang.System. However, we don't
need to use the full name, because all the packages in
java.lang are automatically made available to
every Java program.
We will talk more about packages in the next lecture.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| All Java Programs Define Objects |
While C++ is, like Java, an object-oriented language, for historical
reasons it also allows the programmer to program in the older
function-oriented style. In Java, all programming is object-oriented.
Every program defines some kind (or class) of object
and the tasks that objects of that class know how to perform.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
In the example above, our program defines
a class of HelloWorld objects. Of course, they
are very simple objects. All they know how to do is print
"Hello World" on the screen, which they do when the method
main is invoked.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| But We Will Ignore That For Now |
I know this is kind of confusing! Therefore, for most
of this course we will pretty much ignore the object-oriented
nature of Java, until we get some programming basics under our belts.
Words like public, static, void, and such are all important
keywords that tell the java compiler about how parts
of the program behave and fit together. But for now you don't need to
know what each one means.
For now, just consider the rest of the Hello World program outside the
heart of main like
some magical incantation that you have to include in every program.
We will explain the pieces of that incantation in phases as it becomes
necessary for you to move along.So, for example, if the name of your program is Foo (Foo?!?) your program should look like the following, without your worrying about what all the little bits mean:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
The Method main is a Special Method |
Note that we never explicitly invoke main
ourselves. It is a specially named method that must be present in
every application program (as opposed to an applet). It is invoked by the system when the
class is called from the command line, as when we typed
java HelloWorld.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Naming Programs And Files | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
The last program was named Foo because the
program didn't do anything, so it would be hard to pick a good
name for it. In general, though, you should make an effort
to pick names for your programs that are descriptive, like
HelloWorld, without being too long, like
FileBasedTelephoneAndAddressBook.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Writing Multi-Word Names |
You have probably noticed by now that when we want to make
a name from several words we do it by capitalizing the
words and smashing them together. The reason for this is that
Java, like most programming languages, does not allow you
to use spaces as part of an identifier (a fancy word for a name).
The characters allowed
in a valid Java identifier are the upper-case and lower-case
alphabetic characters,
the digits 0 through 9 (though not as the first letter of an identifier),
and the characters $ and _. The
letters and digits are referred to together as the
alphanumeric characters.
Different styles exist for writing multi-word identifiers. Many people use
the underscore character in place of a space, writing, for example,
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Once you have picked the name for your program (or class), the file containing
the program should ideally have exactly the same name, but with .java
appended to the end. The capitalization in the file name should be
exactly the same as in the program/class name.
So, for example, the HelloWorld program above should be
stored in a file named HelloWorld.java.
When the program is compiled
the compiler will create an object code file named with the name of the class and
with
Notice, by the way, whenever we include numbers in program and file names in this course,
for numbers less than 10 we use a leading 0. This makes all numbers two digits and insures
that program names appear in the right order when they are sorted alphabetically
(as they normally are in a Unix directory listing).
If we didn't do this then the program file
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Reserved Words |
Java, like most languages, bars some words from being used as identifiers
because they are already used for other purposes in the language. If they were
also allowed to be used as identifiers, it would make it difficult to determine if a program
were syntactically correct. The full list of Java reserved words
is:
If you do use one of these words as an identifier, the compiler will generate an error. Unfortunately, current Java compilers are not very bright, and the error will likely not be something as obvious as "{code("Error: Reserved word used as identifier.")}. It is more likely that the compiler will just become very confused and complain about something in the general area of the actual error.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Println vs. Print | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
In the program HelloWorld
we used the method System.out.println to send
some text to the screen. The behavior of this method is
that it displays whatever value you give it, and then moves down to
the beginning of the next line on the screen. Any subsequent
printing will occur on that next line. Sometimes, however,
it is desirable not to move down to the next line, as later you
might want to print something more on that same line. For this purpose
there is another command, System.out.print.
The following program shows the difference between these two commands:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Two things you should note about this program. First,
there is a space inside the quotes at the beginning of the
second item that is printed. If that space were not there,
then the output would look like:
with the word This on the first line right after the period
from the preceding item. With the space the output comes out as:
The computer doesn't know that
there should be a space after a period. It just prints exactly
what you tell it to. Second, if we had used
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
String Literals | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
In the preceeding programs, the texts in quotes that were sent to
System.out to be printed are examples of
string literals. A string is a
value consisting of a group of characters. A literal
is any value that you put into the source code of a program explicitly. String
literals are always typed inside a pair of double quotes to avoid confusing them
with other Java expressions. For example, suppose you wanted the string: to appear in the output. You can't write: because then Java would think you meant to do the calculation and display its result: In order to display exactly those characters, without the sum being computed, you would put the expression in quotes, as in:
A string literal can contain zero, one, or more characters.
The string with no characters in it, written
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Escape Characters | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Here's a puzzle: How would you get System.out to send the string
"Hello World!", including the quotes, to the screen?
You can't type:
because the characters between the parentheses are now four
separate items: two instances of the empty string with two identifiers,
We need a way to tell the compiler that the second and third quotes
are not intended to be the kinds of quotes that open and close string literals,
but rather are just literal characters in the string themselves. You do
this by putting a backslash character,
When this is executed, Java will not display the backslashes. They aren't there as characters in the string. They are just there to indicate that the characters following them (the quotes) are not to be interpreted in their usual way.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Formatting Codes |
Besides the quote there are a number of characters that have special meaning
when they are preceeded by the backslash inside a string literal. For example,
\n stands for the newline character, and when it is
sent to the screen (or other output device) it causes the
cursor to move down to the beginning of the next line before continuing with output.
This allows you to produce a multi-line output with a single print command, as in:
which would print:
In general, though, it is considered better style to use separate
invocations of The presence of the newline character in Java is mostly a throwback to C which did not have a command equivalent to println. Recall that you can also
use println to print just a blank line, by sending the message
with no arguments, as in:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Printing a Slash |
Here is another puzzle: how would you print a backward slash in the output? For example,
suppose we wanted the string:
in our output. How do you print the backslash? Easy, just put a backslash before the backslash, as in: The first backslash says that the next backslash is not an instruction to treat the n
specially, but rather is just the ordinary character \.The full set of special characters (sometimes called escape characters) used in Java is:
Note that the last escape code isn't needed for use in string literals. In that context you can just type the single quote character like any other character. But, as we shall see later, in character literals the literal is surrounded by single quotes. It is in that context that we need this escape code.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ASCII Codes |
As we discussed in the first lecture,
all information in the computer is stored as numbers. It is up to
the program to interpret what those numbers stand for in a given context.
In the early days of computing every computer manufacturer had their
own scheme for representing text. One manufacturer might have used a
scheme where the characters of the alphabet were numbered according to
the ordering "AaBbCc...Zz" while another might have used the ordering
"ABC...Zabc...z" (and lets not even discuss where they put the digits and the
punctuation marks). This made it almost impossible to transfer information
from one computer to another without a lot of translation in between. In the mid 1970's everyone agreed on a common encoding system called ASCII, the "American Standard Code for Information Interchange", to be used when transfering information between computers. ASCII numbers the characters from 0 to 127. This gave a standard encoding (into a 7-bit value) for all the usual characters, as well as for 32 non-printing characters (or control codes), like newline and tab, that were used to control the behavior of output devices. While ASCII was intended initially for communications between computers, by the early 1980's almost all systems were using it for their internal representation as well. Here is a chart with all the ASCII code and the corresponding character. The non-printing characters (the first 32) are represented by their official three-letter name. This chart is taken from the online Unix documentation. You can get a copy at any time by typing at the Unix prompt.
Java lets you designate any character by its ASCII
value written as a three digit octal
value preceeded by the backslash. Here is the same ASCII chart, but with the numbers
given in octal (this is also part of the output from the command
Thus, the exclamation point, whose decimal ASCII
code is 33, which is 41 in octal, can also be written
Of course, this way of designating characters is most useful for characters
with no printed representation. For example, decimal ASCII 7 (which is also octal 7),
is a non-printing character that will make most terminals (and terminal
emulators) ring a bell once. (Try adding ASCII is actually now being suplanted by Unicode which defines a much larger standard character set (with over 65,000 characters specified!). If you want to know a little bit about it, read this.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Numeric Literals | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Numeric literals are just numbers that are typed into the source code
of a program. Numeric Literals can be either whole numbers (called
integers), or decimal
values (called floating point numbers).
Very large or small floating point numbers can be written using a variation of scientific
notation by appending the letter "e" (or "E") followed by
a positive or negative exponent which represents a power of ten by which to multiply
the main part of the number. For example, the value 123456.987, which in scientific notation is written 1.23456987x105, could be written
as
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
One important thing to remember: when typing either
kind of literal, do not use commas to group digits of the number. The
compiler will not allow it.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Other Types of Literals | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
The output commands will accept any of the kinds of literals discussed so far as their
argument. There are several other types of literals, corresponding to the other
kinds of data that Java programs can manipulate. These will be discussed in the
next lecture.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Simple Arithmetic | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Java includes most of the standard arithmetic operators you are used to, and
expressions built from them can be used anywhere a literal can
be used, including, as you saw earlier, as the argument to the output commands. The following program uses this idea to display the areas of a square and a circle each 3 units across:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Basic Arithmetic Operators |
Notice that the symbol used for multiplication is the asterisk and not an x.
The other basic arithmetic operators are: + for addition, - for
subtraction, / for division.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| The Modulus Operator |
In addition, Java, like most programming languages defines the operator
% for modulus (or remainder).
The modulus operator tells you what is left after an even division. For example,
since 3 goes into 11 three times with 2 left over, 11 % 3 is 2. Unlike most programming
languages, Java allows you to use modulus with floating point numbers as well.
So, for example, 11.4 % 3.2 evaluates to 1.8, since 3.2 goes into 11.4 3 times with 1.8 left over.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Even though you probably think you won't have much use for the modulus operator,
you actually use it quite a bit without thinking about it, and it turns out, therefore, to be very important for programming purposes. For example, how do you tell if a number is even or odd?
It's even if there is no remainder when it is divided by 2. That is,
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Binary vs. Unary Operators |
All of the operators discussed above are binary infix operators.
That is, they work on a pair of arguments and are written between the two arguments.
The minus sign also works as a unary prefix operator in which case
it is written in front of its single argument. (I.e. -3 is the unary minus operator
applied to the number 3, and the expression has the value -3).
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Operator Precedence |
When more than one operator is used in an arithmetic expression the order in which
the operators are applied is determined by their precedence. If the
expression does not include parentheses, then the order in which the operators
are evaluated is the same as the one you learned in algebra:
If there is more than one operator from any one of these groups, the operators in that group are evaluated left to right. For example, in the expression: the division is done first, then the multiplication (because that is their left-to-right order), then the addition and finally the subtraction. That is, it is evaluated as though it were written:
When operator precedence does not provide the order you want, you use parentheses to force a particular ordering. If an operator tries to evaluate its operands and finds that one of them is a parenthesised expression, it drops what it is doing and evaluates the expression in parentheses first. So, for example, we could force the division in the last expression to be evaluated last by writing the expression as:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Types Affect Operator Behavior |
While you were reading the last paragraph
you probably assumed that the first example expression, 3 + 4 / 3 - 2 * 2,
evaluated to 0.333333... (to whatever precision the computer stores floating
point numbers). It turns out, though, that in Java (and C++) the expression is evaluated to
0! What's wrong? Is Java just stupid?
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
It's not that Java is stupid, it's just a little lazy. Whenever you
apply an operator to two integer arguments, Java assumes you are only interested
in an integer result. Obviously, for all the operators other than division this doesn't make
any difference. (Mathematicians would say that this is because the integers are
closed under those operations: combining two integers by multiplication,
addition, subtraction, or remainder, will always yield an integer result.)
But for division it can make a big difference, and you must be careful.
So, when the system did the division of 4 by 3, the answer it got was 1, because 3 goes into 4 once. The remaining
computation then became 3 + 1 - 2 * 2, which evaluates to 4 - 4
which, in turn, evaluates to 0.
If either of the arguments to a binary operator is a floating point number, then
the other argument is first lifted (or cast) to be a floating point number,
and the computation is then done using floating point arithmetic. So, if we write
the expression as
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Remember, the determination of whether to use integer or floating point arithmetic
(and whether to cast one of the arguments) is made on an operator-by-operator
basis. If we write the expression as 3.0 + 4 / 3 - 2 * 2 the division
will still yield a 1, only then will that value be cast to a floating point number
so that it can be added to the 3.0, yielding 4.0. The product 2 * 2 will
be computed using integers, and the result, 4, will then be converted to the
float value 4.0 so that it can be subtracted from the other 4.0,
and the final result will be 0.0.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String Addition |
In addition to being used for numerical computation,
the addition operator is also defined for strings in Java. The result of
adding one string to another is just what you'd expect: a string consisting
of the text in the first string followed by the text in the second string. So,
for example,
evaluates to:
Java will also allow you to add a number to a string. In that case, the number is replaced in the addition by its string representation. For example, the result of evaluating: is computed by first converting the value 6 to the string "6"
and then evaluating:
to get:
Of course, this is most useful when one of the arguments is actually the result of a larger computation. For instance, we could get the same result as above from typing:
Note that the parentheses are needed in that last example. Without them, the natural order of operations would have led the computation to behave as thought it were written: which would have computed the result:
This is a
useful feature that can save alot of calls to
Notice that we have again used parentheses around the numeric part of the output expression. They are not strictly necessary in this case, since the multiplication has precedence over the addition here. However, they help to make it clear what is going on.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Overloading | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
By the way, when an operator is defined to work for several different combinations
of type, like + is, we say that the operator is overloaded.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A Word about Whitespace | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
In the last program, the call to System.out was formatted across two
lines. This was done to keep the lines short enough to fit in the frame
within the text, and to highlight the two parts of the argument to the
command. In general, Java does not care about the presence of
whitespace characters
(spaces, tabs, newlines, etc.) in your program. A single space is
the same as arbitrary whitespace.
The only exception to this rule is inside string literals.
As we mentioned earlier, a string literal must be contained on a single line, and inside
the string literal
spaces are significant.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
The effect of this is that a single statement may be stretched
over several lines, or (though this is discouraged) several statements
may appear on a single line. That is why the semicolons are used as
statement terminators. It is the semicolons, rather than the whitespace,
which determine the structure of the program.
Therefore, whitespace can and should be used to improve the readability
of your programs. Blank lines should be used to separate logical blocks of
the program. Indenting should be used to indicate the nesting structure
of the program. As with other matters, you may take the examples on these
pages as a guide to good style. While you don't need to keep the lines of your program as short as those used here (where we are constrained by embedding the code in this narrow text), you should always keep your lines shorter than 80 characters wide. That is the standard width of a terminal screen, and the width of a typewritten page in 12 point monospaced characters.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Last modified August 29 for Fall 99 cs5 by mike@cs.hmc.edu
This page copyright ©1998 by Joshua S. Hodas. It was built with Frontier on a Macintosh . Last rebuilt on Tue, Oct 20, 1998 at 9:32:05 PM. | |
http://www.cs.hmc.edu/~hodas/courses/cs5/week_02/lecture/lecture.html | |