JAVA
Translate this page
using FreeTranslation.com
LAST UPDATED:
Thursday, 08 November 2007 18:30:52 -0600
Not everything in the Java universe is technical. Much of the
community that's sprung up around the language has to do with the
merits of open-source software, platform interoperability, free
encryption, and other causes. You can lend your voice to those of the
programmers at the Java Lobby by signing up at this Web site:
http://www.javalobby.org

MORE ABOUT THE UNARY OPERATORS
There is an omission that was made back when I was talking about unary
operators like ++ and --. At the time, I noted that this:
x++;
is functionally the same as this:
++x;
Strictly speaking, that's accurate. If you have a variable on a
line
by itself with an increment or decrement operator, it does not matter
whether the operator goes before the variable or after it. However,
the position of the operator makes a difference in a more complex
statement. For example, this:
x = 5;
y = ++x + 5;
results in y holding the value 11 and x holding 6. The ++ operates
on
x before the 5 is added. On the other hand, this:
x = 5;
y = x++ + 5;
results in y holding the value 10 and x holding 6. The addition
takes
place before the increment operator does its work. However, the
addition of 1 to x still takes place before execution moves ahead to
the next statement. Thanks, everyone!
----------------------------------------------
DECLARING MULTIPLE VARIABLES ON ONE LINE
You know how to declare variables by announcing their data type and
name in a line of code, like this:
float ssMinnow;
You may not know that you can declare multiple variables of a given
type on a single line. The key is the lowly comma. Here's the syntax:
float titanic, minnow, lusitania, andreaDoria, andreaGail;
That line of code results in five different variables of type
float.
The data type starts the line and the semicolon concludes it. Commas
separate the names of the variables that are being declared.
And let it not be said that Tipworld writers lack a sense of irony.
----------------------------------------------
INITIALIZING LOTS OF VARIABLES AT ONCE
Last time, we saw the syntax for declaring multiple variables at once,
using commas. As it happens, we can simultaneously declare and
initialize a whole slew of variables in much the same way. You know
how to combine variable declaration with variable initialization, like
this:
int wheelsOnBigRig = 18;
To do multiple variables at the same time, the syntax looks like
this:
int wheelsOnBigRig = 18, wheelsOnSchoolBus = 6, wheelsOnCar = 4,
wheelsOnBike = 2;
It's the same function the commas serve in a straight
multiple-variable declaration, except with the assignment operators
(=) and values thrown in. The spaces on either side of the =
characters are optional.
----------------------------------------------
USING MULTILINE VARIABLE DECLARATIONS TO CLARIFY CODE
Looking at printouts of Java code sometimes is necessary when hunting
bugs, but it can make your eyes cross in a hurry. One way to make the
job easier is with multiple-line declaration and assignment statements
for variables. All you need to do is insert a carriage return (a press
of the Enter key) after each comma. So, this:
int wheelsOnBigRig = 18, wheelsOnSchoolBus = 6, wheelsOnDavesHouse
=
8, wheelsOnCar = 4, wheelsOnBike = 2;
is the functional equivalent of this:
int wheelsOnBigRig = 18,
wheelsOnSchoolBus = 6,
wheelsOnDavesHouse = 8,
wheelsOnCar = 4,
wheelsOnBike = 2;
The latter is easier to follow in written form, since there is no
potential for an awkward line break and no need to scroll off to the
right in your editor.
----------------------------------------------
NOT-A-NUMBER (NaN)
How does Java react when it's presented with a mathematical operation
that yields an indeterminate result, such as division of zero by zero?
It depends on what sort of data type you're working with. If you're
using a floating-point type--float or double--it reacts a lot like it
does when it encounters an operation that yields positive or negative
infinity (Infinity or -Infinity). There's a special value that can be
assigned to variables when they're assigned an indeterminate result of
an operation. The value is NaN, which stands for "Not a Number." Zero
divided by zero yields NaN in any operation involving floating-point
data types (float and double).
What happens when you divide zero by zero with integer types?
That's
on the plate for next time.
----------------------------------------------
IS THERE A NaN FOR INTEGER TYPES?
You know that when you perform an operation that gives an
indeterminate result--such as dividing zero by zero--with variables of
type float or double, you get NaN as a result. What happens when you
do the same sort of operation with an integer data type such as short,
byte, int, or long? Again, something special happens, but the result
isn't NaN. NaN doesn't exist in the integer context. Rather, an
indeterminate operation with integer types results in an exception
arising. Exceptions and the mechanisms for dealing with them are
fairly elaborate, but let's get familiar with the terminology here.
Exceptions are sort of like errors, with the exception (sorry) that
exceptions are not always bad. Exceptions just indicate that something
out of the ordinary has happened. Performing an integer math operation
with an indeterminate result is unusual. If a program is executing and
such an event happens, the Java Virtual Machine registers an exception
("an exception is thrown" is the usual terminology). This doesn't mean
the program stops; it means that whatever mechanism is in place to
handle unusual circumstances comes into play.
----------------------------------------------
THE DOWNSIDE OF MULTIPLE VARIABLE DECLARATIONS
Mark wrote in with his opinion on the merits of declaring several
variables on one line. In case you've forgotten, here's what he's
referring to:
float titanic, minnow, lusitania, andreaDoria, andreaGail;
That's legal, but Mark says, "It is bad style. When you allow only
one
variable declaration per line, it is easier to get developers to
properly comment their declarations."
Good point! Mark prefers something like this:
float titanic, // Seen the movie?
minnow, // Seen the TV show?
maine; // Have you forgotten?
Those // sequences denote comments. Comments on each line allow the
programmer to say what each variable will be used for. We'll cover
comments further, starting next time.
----------------------------------------------
REMAINDER-OF-LINE COMMENTS
The Java language provides a mechanism for shielding a portion of a
code line from being looked at by the Java compiler. Called a
remainder-of-line comment delimiter, two forward slashes (//) serves
this purpose. Here's how it works in practice. This:
int oranges;
is a normal line of code that would fit just fine into a compilable
program. To explain what oranges will hold, though, we can use the //
marker, like this:
int oranges; // Variable oranges will hold the number of oranges in
the basket.
That line will compile exactly as well as the commentless one. It's
better, though, because a human being reading the code would have a
clue about the purpose of the variable.
----------------------------------------------
MULTILINE COMMENTS
The remainder-of-line comment delimiter (//) protects comments only
between the delimiter and the end of the line. Sometimes, you'll want
comments to span multiple lines. Java provides a mechanism for this
purpose:
Multiline comments open with
/*
and close with
*/
Anything between the two delimiters, even if they're on widely
separated lines, is ignored by the Java compiler. Often, you'll see
people use these comments for copyright statements, like this:
/*************************
Easy-Scooper Lite
by Ace Programmer (acepro@purple-sage.com)
Copyright (c)1999 Ace Productions
*************************/
Notice how the extra asterisks don't matter. All the compiler cares
about is the opening /* and the closing */.
----------------------------------------------
JAVADOC COMMENTS
Java's more than a programming language--it's a whole system for
creating good software. One characteristic of good software is that it
is well documented. There are papers or electronic documents that
explain how the software works and how it is used. Documentation is
especially important when you're writing software that will be used as
a component in the creation of other software.
The Java Development Kit ships with lots of stuff in addition to
the
Java compiler and the Java Virtual Machine. One of the extras is a
program called Javadoc that's used to generate documentation about
Java programs. When you run Javadoc on your source code, it extracts
some information automatically. You can specifically designate
comments for inclusion in the Javadoc documentation as well. Just use
a special set of comment delimiters:
/**
Javadoc will pay attention to the comments in here and will include
them in documentation.
*/
The compiler ignores Javadoc comments, just like all other
comments.
We'll explore Javadoc more in the future.
----------------------------------------------
COMMENTS AS TROUBLESHOOTING AIDS
One of the handiest uses of comments is as an aid in tracking down
problems in your code. If you wrote some code and kept getting a
compiler error, you could attempt to isolate the offending line (or
lines) of code by hiding it (or them) with a comment. Say you had
this:
int bears = 3;
System.out.println(bears)
and you tried to compile it. You'd get an error message (the second
line has no ending semicolon). If you couldn't spot the problem right
away, you could put // in front of the second line and recompile with
no errors, proving that the error was in the second line and allowing
you to check the rest of the program for problems before coming back
to fix the broken line.
----------------------------------------------
INTRODUCING THE BOOLEAN DATA TYPE
Java has a data type you can use to define variables that will contain
boolean (true/false) values. Variables of the boolean type occupy a
one-byte space in memory--they're the most compact variables around.
Declare a variable of type boolean just like any other variable:
boolean flag;
----------------------------------------------
ASSIGNING VALUES TO BOOLEAN VARIABLES
Boolean variables can take two values: true and false. Assign the
values to the variable with the equal sign, like this:
boolean flag;
flag = true;
flag = false;
Note that the values don't get quotes around them. They're not
strings--they're special values designated by true and false.
----------------------------------------------
THE BASIC COMPARISON OPERATORS
Java provides several operators for comparing values and generating
boolean results that describe the relationship. Here are three of the
most useful:
- Equal to (==)--Returns true if the left operand is equal to the
right operator.
- Greater than (>)--Returns true if the left operand is greater than
the right operator.
- Less than (<)--Returns true if the left operand is less than the
right operator.
Here are some examples:
(7 == (9-2)) // Evaluates to true
(9 (4 * 11)) // Evaluates to true
----------------------------------------------
OTHER COMPARISON OPERATORS
In addition to the basic comparison operators, there are some others.
Two of these combine basic comparison operators; the other combines
the equality comparison with the "not" logical operator. Here are the
remaining three:
- Not equal to (!=)--Returns true if the left operand is not equal
to the right operator.
- Greater than or equal to (>=)--Returns true if the left operand is
equal to or greater than the right operator.
- Less than or equal to (
----------------------------------------------
ASSIGNING THE RESULTS OF COMPARISON STATEMENTS
As it turns out, because statements involving comparison operators
evaluate to true or false, you can assign them to variables of the
boolean data type. Here's how it's done:
boolean flag, flag2;
flag = (7 < 9);
flag2 = (9 == 4);
After that, flag holds the value true and flag2 holds false. You
can
do the same thing with variables:
int a = 5, b = 4;
boolean flag;
flag = (b <= a);
That sequence results in flag holding true.
----------------------------------------------
IF STATEMENTS
One of the most common uses of comparison statements is in conditional
statements. The if statement is the most basic conditional. It's used
to make code executable only under certain circumstances. Here's the
basic syntax of the if statement:
if (condition)
{
// Statements to execute if condition is true.
}
In that illustration, the statements within the curly brackets
(which
is what the { and } characters are called) run only in situations in
which condition is true.
----------------------------------------------
MORE ABOUT THE IF STATEMENT
Let's take a look at a concrete example of an if statement.
if (testValue != 13)
{
System.out.println("This is a superstitious program!");
}
In this case, the println() statement executes only when testValue
(which is a variable declared elsewhere in the program) is not equal
to 13.
----------------------------------------------
LOGICAL OPERATORS
Sometimes you need to evaluate boolean values--including those
generated by comparison statements--in groups. You may want code to
execute only if something AND something else are true. Use special
logical operators to create logical statements that incorporate
multiple boolean values. Here are the three main logical operators:
- AND (&)--Returns true only if the expression to its left and the
expression to its right are both true.
- OR (|)--Returns true if either the expression to its left or the
expression to its right is true, or if both are true.
- NOT (!)--Negates a boolean value. When placed in front of an
expression that by itself evaluates to true, the overall expression
becomes false and vice-versa.
Here's how they're used. This statement:
((5 < 6) & (9 > 7))
evaluates to true because both (5 7) are true. On the other hand,
this:
((5 < 6) & (9 > 15))
is false because the second comparsion is false.
----------------------------------------------
USING CONDITIONAL OR AND CONDITIONAL AND
In a standard statement using the logical and operator (&), both
values being compared must be true for the whole statement (the one
with the & in it) to be true. If you look at the left-hand value and
it's false, there's no need to look at the right-hand element because
its value doesn't matter--the statement's going to be false.
Similarly, if you have an or statement (|) and the left-hand element
is true, it doesn't matter what the right-hand statement evaluates
to--the statement will be true. You could save some time over the long
run if you used this approach. Java has special operators for the
purpose. Here they are:
AND (&&)
OR (||)
These are called conditional logical operators. They examine the
right-hand element in an expression only if their examination of the
left-hand element is inconclusive.
----------------------------------------------
IF...ELSE STATEMENTS
If statements are neat, but they're often not enough. You need a way
to say, "If this is true, do this, but if it's false, do something
else." The mechanism for doing this is called an if...else statement.
These statements are the same in Java as in many languages. Here's the
syntax:
if (condition)
{
// Statements to execute if condition is true.
}
else
{
// Statements to execute if condition is false.
}
----------------------------------------------
THE SWITCH STATEMENT
You can check for a variety of circumstances by putting a bunch of if
statements in sequence or nesting a lot of if...else statements within
one another, but there's a special control structure that will save
you the trouble. The switch statement looks at an expression and
initiates different behaviors depending on the expression's value.
Here's the generalized syntax:
switch (expression)
{
case value1 : // Code to execute if expression is equal to value1.
case value2 : // Code to execute if expression is equal to value2.
case value3 : // Code to execute if expression is equal to value3.
// ...
case valuen : // Code to execute if expression is equal to valuen.
default: // Code to execute if expression is equal to none of the
above values.
}
See? The Java Virtual Machine compares expression (usually a
variable)
to all of the values in the case statements. If it finds a match, the
JVM runs the code in that case statement. If its value matches none of
them, it runs the code in the default case statement.
----------------------------------------------
THE EMPTY STATEMENT: "DO NOTHING"
Sometimes you want a program to do nothing under certain
circumstances. The way to tell the Java Virtual Machine to do nothing
is to put a semicolon on a line by itself. Here's how it works:
if (!(flag))
{
; // Do nothing!
}
else
{
System.out.println("Warning! The variable flag is true!);
}
You could avoid this situation by changing the conditional to
(flag)
by itself, putting the println() statement after the if line, and
getting rid of the else part entirely. Still, it's nice to know how to
do nothing when you need to.
----------------------------------------------
INTRODUCING THE CHAR DATA TYPE
Java provides a data type that represents single characters. Called
char, the data type enables variables to hold any solitary letter,
number, punctuation mark, or special escape sequence (such as the one
that represents a carriage return). Because Java works with a
character-encoding system called Unicode that incorporates all written
characters of all human languages (plus Hobbit, Klingon, and a bunch
of other stuff), you can use char to hold pretty much any character
you want. Variables of type char occupy two bytes in memory.
Declare variables of type char like variables of any other type:
char whatACharacter;
Then, assign as usual:
whatACharacter = "A":
whatACharacter = "8";
Note that "8" is a character, different from the value 8 on which
arithmetic can be performed.
CORRECTION: The code in the October 28 Java Tip was flawed. The
corrected code looks like this:
if (flag)
{
; // Do nothing!
}
else
{
System.out.println("Warning! The variable flag is false!");
}
----------------------------------------------
SPECIAL CHARACTER ESCAPE SEQUENCES
Variables of the char data type can take values that aren't readily
depicted as literal characters. You can put a backspace in a char
variable, or a tab. The trick is what's called an escape sequence,
which is any of several combinations of a backslash and a letter. Here
are five of them:
\b Backspace
\f Form feed
\n New line
\r Carriage return
\t Tab
Assignment is the same as with "normal" characters. Use the quotes
and
everything:
tabCharacter = "\t":
CORRECTION
The November 1 tip contained an error. When assigning literal values
to a variable of type char, you must use single quotes, not double
quotes, like this:
whatACharacter = 'A':
whatACharacter = '8';
----------------------------------------------
ASSIGNING A UNICODE CHARACTER TO A CHAR VARIABLE
You know a bit about Unicode already, but how do you assign a
particular Unicode character to a variable of type char? The sequence
\u, placed before the four-digit hexadecimal Unicode value, is the
trick here.
char unicodeCharacter;
unicodeCharacter = "\u10A0";
In case you're wondering, Unicode character 10A0 is a character
used
in traditional Georgian script. You can see full lists of all Unicode
characters and their corresponding hex values at
http://www.unicode.org
----------------------------------------------
UNDERSTANDING FOR LOOPS
Making decisions is swell, but we also need a way to repeat things
many times. You can repeat something a fixed number of times with a
control structure called a for loop. The basic syntax of a for loop
looks like the following. Pay attention, because for loops look like
this in lots of computer languages:
for (initialValue; test; incrementor)
{
// Statements to be repeated.
}
Here's what the values mean:
- initialValue: The value of the index variable when execution of
the loop starts.
- test: A Boolean expression which, when found to be false, causes
iteration of the code in the loop to halt.
- incrementor: An arithmetic expression that changes the value of the
index variable at the start of each iteration of the loop.
----------------------------------------------
UNDERSTANDING WHILE LOOPS
We can use for loops if we know how many times we want something
repeated, but what if we want to repeat a set of statements until a
condition becomes true--say, until the solution to a problem has been
found? In that case, we can use a while loop. Here's the syntax:
while (condition)
{
// Statements to be repeated, including a statement (or several)
that
alters the condition above.
}
There's not a lot to while loops, except that a statement that
evaluates to a boolean value (called condition above) is tested, and,
if it is true, the code in the loop executes. Then the condition is
tested again, and, depending on its value, the code is or is not
executed once more. The important thing to remember is that the code
in the loop absolutely must change the value of condition at some
point. Otherwise, execution never breaks out of the loop.
----------------------------------------------
INTRODUCING ARRAYS
An array is a data structure that allows you to store multiple values
under a single variable name. You could, for example, store the names
of all the passengers on a bus in an array. You could also use an
array to store some portion of the Fibonacci number sequence. There
are many uses for arrays, and you may have encountered some of them in
simpler languages like JavaScript. Java, however, imposes more rules
on the declaration and population of arrays than do other languages.
In large part, this has to do with Java's stricter rules about data
typing.
You can declare an array variable without assigning anything to it,
just as you can declare a variable of any basic type (double, char,
and so on) without giving it a value. The most common way to declare
an array variable without assigning it a value is like this:
char[] varname;
That statement establishes a variable called varname that will, at
some point, hold an array of char values.
----------------------------------------------
CREATING AN ARRAY
Once you've created an array variable, you'll want to create an array
for it to contain. An array is an example of what's called an object.
An object is an instance of a particular kind of thing. (For those of
you keeping track, a kind of thing--as opposed to an instance of that
thing--is called a class.) Objects are, however, different from
instances of basic data type, such as float and int values.
What's more, an array object has several elements, each of which
can
contain a value.
To create an array object, we need to use the new keyword. We also
need to specify what kind of data the elements of the array will hold,
and how many elements there will be. Here's the syntax for declaring
an array variable:
char[] varname;
varname = new char[5];
The first line establishes a variable for holding an array of char
values. The second line creates an array of five char values.
(Actually, it only allocates memory for it, but that's close enough
for now.)
Both "object" and "class" are very heavily used words with more
meanings than I've provided here! Stick around and we'll learn more
about other phenomena to which the words apply.
----------------------------------------------
DEFAULT VALUES IN AN ARRAY
When you declare an array variable and specify a new array that's
assigned to it, like
char[] varname;
varname = new char[5];
the array isn't empty. Believe it or not, it actually contains
default
values. The default values depend on the kind of data the array has
been declared to hold. In the example above, the varname array holds
five instances of '\u0000', which is the Unicode character
specification for a null character.
In an array, all numerical types (short, byte, int, float, double,
and
long) have initial values of 0. Array elements of type boolean are
initialized as false.
You can also declare an array to contain objects in its
elements--more
on that later. For now, know that such array elements have a special
value called null.
----------------------------------------------
POPULATING AN ARRAY
Just for fun, let's say you've already declared an array:
char[] vowel;
vowel = new char[5];
Now you want to assign values to its elements. There are a couple
of
things to remember.
The first thing to keep in mind is the basic syntax, which looks
like
this:
arrayName[n] = value;
In this case, arrayName is the name of the array, n is the index
number of the element to which you want to assign a value, and value
is the value that's being assigned to that element. Remember, too,
that value must be of the same type that the array was declared to
hold. You can't mix and match data types in a Java array.
One more thing to remember is that array index numbers start at 0.
Accordingly, arrayName[0] is the first element in the array,
arrayName[1] is the second, and so on. In an array of 30 elements, the
last element is arrayName[29]. Continuing with the vowels example, we
could assign values like this:
vowels[0] = 'a';
vowels[1] = 'e';
vowels[2] = 'i';
vowels[3] = 'o';
vowels[4] = 'u';
Now, you're probably thinking there's gotta be a faster way to do
this. Indeed, there is! Next time...
----------------------------------------------
ASSIGNING A SERIES OF VALUES TO AN ARRAY VARIABLE
We've seen that it's possible to very deliberately declare an array
variable, create an array of default values assigned to that variable,
and then populate the elements of the array with "real" values one by
one.
Now, let's take a look at the shorter way of doing the same thing.
For
example, instead of
char[] vowels;
vowels = new char[5];
vowels[0] = 'a';
vowels[1] = 'e';
vowels[2] = 'i';
vowels[3] = 'o';
vowels[4] = 'u';
we can do the following:
char[] vowels = {'a', 'e', 'i', 'o', 'u'};
The net effect is precisely the same--an array of five char
elements,
represented by the variable vowels. There's no explicit statement of
the number five--the way there would be in a "new char[5]"
phrase--but, after all, Java can count without our help.
----------------------------------------------
GETTING THE LENGTH OF AN ARRAY
It's handy to know the length of (also known as the number of elements
in) an array. You'll need to know the length of an array, for example,
to systematically examine its elements. After all, the first element's
index number is always 0, while the last element's index number is
always defined by the expression
length - 1
where length is the number of elements in the array. As it happens,
there's an easy way to get the number of elements in any given array.
It's easy because arrays are objects. Objects can have (among other
things) properties that describe them. An array object has a property
called length, which is an integer that represents the number of
elements in the array. You refer to the length property like this:
arrayName.length
Here, arrayName is the name of the variable that holds the array
whose
length you want. Here's an example:
int numberOfVowels;
char[] vowels = {'a', 'e', 'i', 'o', 'u'};
numberOfVowels = vowels.length;
This code results in numberOfVowels holding 5. From that, it's easy
to
calculate that the last element in the vowels array is vowels[4], or
vowels[(numberOfVowels - 1)].
----------------------------------------------
USING EXTERNAL RULES TO DEFINE DATA STRUCTURES
By now, declaring an array should be no problem for you. The fastest
way to do it is with a statement similar to this one:
int[] mondays = {6, 13, 20, 27};
This statement yields a single variable that contains an ordered
list
of the dates in December 1999 that fall on a Monday. Accordingly, you
can refer to the second Monday's date as mondays[1].
But what if you want to use the same variable to refer to specific
times on those Mondays? You could do something awkward, like remember
that the first element in the array and every third element thereafter
was a date, while intermediate elements held times, like this:
int[] datesAndTimes = {6, 9, 15, 13, 13, 21};
Under this awkward system, the array would represent the times 0900
and 1500 on December 6 and the times 1300 and 2100 on December 13.
This would work, but the possibility for error is large.
As it happens, Java provides a handy way to structure this kind of
data--which we call two-dimensional arrays. Now that you know the hard
way to do it, you'll have to tune in tomorrow to learn the easy way.
----------------------------------------------
INTRODUCING TWO-DIMENSIONAL ARRAYS
While it's possible to impose external rules upon a one-dimensional
array (for example, remembering that the odd-numbered elements contain
one kind of data and the even-numbered elements contain something
else), this approach is needlessly complex and invites error. Since
there is no inherent structure to the data, you have to remember the
artificial (even/odd) rules, and errors will result if you don't.
Happily, Java provides a better method of handling multidimensional
arrays. These "arrays of arrays" are exactly what the name
implies--arrays in which each element is another array. To declare a
variable to hold such an array, use this syntax:
int datesAndTimes[][];
Then, to put a two-dimensional array in that variable, use
something
like this:
datesAndTimes = new int[3][2];
This creates an array of three elements, each of which contains
another array of two elements.
----------------------------------------------
MULTIPLE DATA TYPES? NO...
In thinking about multidimensional arrays (which is to say,
two-dimensional arrays for the moment), it's tempting to ask if
there's a way to get them to hold data of multiple types. The answer,
as far as the basic data types are concerned, is no.
You see, when you make the declaration
int datesAndTimes[][] = new int[3][2];
you get an array of three elements, each of which contains another
array object of two elements. The elements of the three-element array
are occupied by the references to the subsidiary two-element arrays.
There's no room for anything else there.
----------------------------------------------
REFERRING TO THE CONTENTS OF A TWO-DIMENSIONAL ARRAY
Okay, so you've created a two-dimensional array with a statement like
this:
int datesAndTimes[][] = new int[3][2];
Now, you want to populate that array with integers representing
dates
and times. Element 0 in each subsidiary (two-element) array will be
the date of a Monday in December, while element 1 in those arrays will
be an hour. Here's how to do the assignments:
datesAndTimes[0][0] = 6; datesAndTimes[0][1] = 13;
datesAndTimes[1][0] = 13; datesAndTimes[1][1] = 9;
datesAndTimes[2][0] = 20; datesAndTimes[2][1] = 22;
This data structure refers to 1300 on December 6; 0900 on December
13;
and 2200 on December 20. Note that we're still imposing artificial
rules on the arrays. We still must remember that every 0th element in
every subsidiary array is a date, while every 1st element is a time.
Still, there's now some inherent structure to the data.
----------------------------------------------
HOW TO THINK OF TWO-DIMENSIONAL ARRAYS
Consider this two-dimensional array we've been working with for the
past few days:
int datesAndTimes[][] = new int[3][2];
You can think of a two-dimensional array as a table or grid. In the
example above, the imaginary grid would be three spaces across by two
spaces down. You can refer to any element in the table by its "across"
coordinate (remembering to start counting at 0) followed by its "down"
coordinate. The element in the lower-right corner of the table could
be referred to as datesAndTimes[2][1].
----------------------------------------------
ARRAYS OF MORE THAN TWO DIMENSIONS
If you really want to, you can declare multidimensional arrays of more
than two dimensions--arrays of arrays of arrays (in the case of a
three-dimensional array), if you like. The syntax is familiar--just
more of the same, really. For example, you might start by declaring
the array like this:
int dataCube[][][] = new int[3][3][3];
Then, to reference an element, use something like this:
int dataCube[0][0][3] = 56;
There's no rule that says a multidimensional array must be cubic.
You
can just as well do this:
int dataCube[][][] = new int[5][4][4];
which results in the creation of an array of five two-dimensional
arrays, each four-by-four elements.
----------------------------------------------
THINKING OF STRINGS AS ARRAYS
An array is a collection of data, organized into an ordered series of
elements and referred to by a common name. You could, for example,
declare an array of elements of type char.
If you think about it, a string--a sequence of characters that
means
something, either in a human language or to a machine--is really an
array of characters. Java acknowledges this fact and allows you to
work with strings as arrays of characters.
A string stored in a variable is a special data type--a kind of
object
called a String object. The String object behaves much like an Array
object. You declare a variable for holding a String much like you'd
declare a variable for holding an Array. The syntax looks like this:
String quote = new String;
As you can see, the keyword new comes into play here, just as it
does
when you declare an Array object.
----------------------------------------------
ASSIGNING A VALUE TO A STRING VARIABLE
Once you've declared a variable and noted that it will contain a
String object, as in
String quote = new String;
you're free to define that String object more specifically. A
String
object incorporates a sequence of characters. When you define a String
object by explicitly stating the sequence of characters--by using a
"string literal," to put it another way--you enclose the sequence in
quotation marks (""). Here's how it looks:
quote = "We have nothing to fear but fear itself.";
To accomplish the same effect with a single line of code, we could
have used this statement:
String quote = "We have nothing to fear but fear itself.";
Next time, we'll start to examine some of the ways a String object
behaves like an Array objects containing data of type char.
----------------------------------------------
GETTING THE LENGTH OF A STRING
Recall that if you declare an Array object like this:
char[] letters = {'a', 'b', 'c'};
you can find the number of elements in the array by using the
length
property that all arrays have. In other words, this:
letters.length
is equal to the value 3. Strings, being similar to arrays of
characters, also have length properties. If you use the declaration
String quote = "We have nothing to fear but fear itself.";
and then make reference to quote.length, you'll find that
quote.length
has the numerical value 40. There are 40 characters in the string
referred to by the variable called quote. Note that the quotation
marks are not part of the string; they're just delimiters.
----------------------------------------------
REFERRING TO CHARACTERS IN A STRING
You know that you can declare a string like this:
String quote = "We have nothing to fear but fear itself.";
and that you can get the number of characters in the string by
referring to its length property. That sounds like an Array object,
eh? Well, then, it stands to reason that you can refer to characters
in the string just as you would refer to elements in an array.
But you can't, not exactly. Although the characters in a string
have
index values and the first character in a string has index 0 (not 1),
you can't use the square-bracket syntax to access characters in a
string. Instead, you must use a method of the String object called
charAt(). The best way to illustrate the behavior of charAt() is to
give some examples. Working with the string contained by variable
quote, as defined above, these statements are true:
char character;
character = quote.charAt(0);
// Variable character holds 'W'. character = quote.charAt(5);
// Variable character holds 'v'. character = quote.charAt(39);
// Variable character holds '.'.
----------------------------------------------
CONVERTING THE CASE OF A STRING'S CHARACTERS
Say you've declared a String object with this declaration:
String quote = "We have nothing to fear but fear itself.";
Later in your program, you decide that you want President
Roosevelt's
statement to carry more emphasis. You can use the String object's
toUpperCase() method to convert each character in the string to its
capital equivalent (the method has no effect on uppercase letters,
spaces, and punctuation marks). So, if you did this:
String strongQuote = quote.toUpperCase();
you'd have a second String object, contained in the variable
strongQuote, that held "WE HAVE NOTHING TO FEAR BUT FEAR ITSELF."
There's a similar method, toLowerCase(), that converts a string to a
sequence of lowercase characters.
----------------------------------------------
USING ESCAPED CHARACTERS IN STRINGS
Last time, we played with string concatenation by using this code:
String quote = "We have nothing to fear but fear itself" +
", said President Roosevelt.";
That yields "We have nothing to fear but fear itself, said
President
Roosevelt." We need a way to distinguish the actual quote from the
attribution. We should do this with quotation marks, but if we just
stuck quotation marks into the strings, the Java compiler would
interpret them as delimiting the strings.
If we use the escape sequence for quotation marks, though, we can
avoid this problem. Here's how it works:
String quote = "\"We have nothing to fear but fear itself" +
",\" said President Roosevelt.";
The sequence \" denotes a quotation mark that's part of the string,
not part of its definition. The code above yields what we want when it
is printed:
"We have nothing to fear but fear itself,"
said President Roosevelt.
Note that each \" sequence counts as a single character for
indexing
and character-counting purposes.
----------------------------------------------
BOOLEAN COMPARISONS OF STRINGS
Here's a neat piece of truth. You might expect that if you made the
two declarations
String aString = "ABCDE";
String bString = "ABCDE";
and then did a boolean comparison of the two string variables, like
this:
aString == bString)
that the comparison would yield the boolean value true. Not so.
Even
though the strings are the same, character for character, the
variables refer to different String objects and so are different. The
comparison yields false. On the other hand, if you did this:
String aString = "ABCDE";
String bString = aString;
and then compared the two variables, the comparison would yield
true.
----------------------------------------------
GETTING RID OF EXTRA SPACES
If you've ever done any work that involves taking input from a user by
way of a command-line interface or a text field in a form or Web page,
you know that users can put all kinds of extra characters in their
input. Extra spaces (leading and trailing) are among users' favorites.
Say, for example, you expected a variable to contain a name, but in
fact it contained the string
" Kate "
That could really mess up your formatting. The String object makes
it
easy to get rid of leading spaces, trailing spaces, or both. Here's
how you'd do it:
String name = " Kate ";
name = name.lTrim();
This results in name holding "Kate ". The lTrim() method strips
spaces
from the left side of the string. The rTrim() method does the same on
the right side of the string. To do both sides at once, use the trim()
method:
String name = " Kate ";
name = name.trim();
This results in name holding "Kate", which is what you want.
----------------------------------------------
AN INTRODUCTION TO OBJECTS
An object is a thing--something you can think about as a unit. You can
think of an object as anything you can name with a noun.
For example, let's say we want to talk about a particular
bicycle--the
bicycle Miguel Indurain was riding when he finished the 1996 Tour de
France. This is one bike, a particular bicycle distinct from all
others. The bike is a definable object.
We can think of it in terms of a hierarchy of objects.
1) Definable things.
2) Vehicles.
3) Wheeled vehicles.
4) Bicycles.
5) Racing bicycles.
6) The particular racing bicycle Miguel Indurain was riding when he
finished the 1996 Tour de France.
We could design the hierarchy differently, but this is one way to
do
it. The important thing to understand is that Java organizes its
objects in hierarchies such as this one.
----------------------------------------------
GETTING FAMILIAR WITH FIELDS
An object is a readily identifiable thing. Identifiable things have
characteristics that we can describe. In the language of object
orientation, such characteristics are called fields (sometimes they're
called properties, too).
For example, we might discern the following fields about a
particular
object (in this case, Miguel Indurain's bicycle).
- What is the color of the bicycle Miguel Indurain was riding when
he finished the 1996 Tour de France? That bicycle is red.
- What is the weight of that bicycle? That bicycle weighs 12 pounds.
- Is that bicycle for sale? No, it is not.
(By the way, these replies are all guesses, for you nitpicking
cyclists out there.)
The point of this is that objects have characteristics we can
inspect,
just as Java objects have fields. You've already seen a couple of
them, in the form of the length properties of the Array and String
objects.
----------------------------------------------
AN INTRODUCTION TO METHODS
We've seen that objects have describable, inspectable characteristics
called properties. Objects also can do things. Every kind of object
can do a particular set of things that may or may not be unique to
that object. Let's imagine, for example, that we have the bicycle
Miguel Indurain was riding when he finished the 1996 Tour de France. I
will instruct you to make that bike do things. Ready?
- Apply the bike's rear brake. Okay, you say.
- Release the bike's rear brake. Okay.
- Pedal the bike forward 20 yards. Okay.
- Put the bike in its lowest gear. Okay.
- Turn the bike's handlebars 15 degrees to the right. Okay.
- Sell the bicycle for a sum not less than $5,000.
All those are things you can do with the object we defined.
Most of the actions I asked you to perform are generic to
multi-speed
bicycles, but the last item asks you to do something with Indurain's
bike that you probably couldn't do with that old Schwinn you keep out
in the shed. Likewise, if I had asked you to start the bike's motor,
you would have protested, since that's not something you can do with a
bicycle.
Java objects have methods that work much the same way. Each object
has
a set of methods you can invoke individually to cause certain things
to happen. You've used methods to a limited degree already, in
converting the case of characters in strings and stripping extra
spaces from them.
----------------------------------------------
HOW JAVA REPRESENTS THE OBJECT HIERARCHY
Java has a much more limited knowledge of the world than you and I. It
wouldn't know a Zip drive from a tube of hair oil. The objects it
knows are all figments of computer memory, but those figments are what
concerns you when you're trying to build programs. The way you think
of different kinds of bicycles, for example, Java thinks of strings.
Likewise, the way you conceive of toasters, Java understands windows
in a graphical user interface (GUI).
Java identifies its objects the same way you do: via a hierarchy of
progressively more specific objects. Java knows that a window, for
example, has certain characteristics, such as its size and whether it
is capable of being resized. The language knows how to make browser
windows do certain things, such as open or close. Java knows the
characteristics (which it calls properties) and capabilities (which it
calls methods) of a whole bunch of objects that have to do with the
various kinds of data you can manipulate with a Java program.
The syntax may look a little bit unusual at first. Java identifies
objects by a series of special words separated by periods. Here's an
example:
java.lang.Math
Now don't panic. That hierarchy simply refers to the Math object,
which is a part of the java.lang set of objects (a set of objects is
called a package in this case). See? Not too hard at all.
----------------------------------------------
REFERRING TO FIELDS IN JAVA
Once you've used the correct Java syntax to identify the object you
want to work with, you can go on to specify the field you want to
inspect or the method you want to employ. You do that by tacking
another period on the end of your object reference, then specifying
the name of the field or method to which you want to refer.
For example, whenever the Java Virtual Machine (JVM) is active, an
object called Math exists and is available for reference. The Math
object has a field called PI, which is equal to the number
3.141592553589793. Math is an object, PI is one of its fields, and the
value of PI is always 3.141592553589793.
Whenever you need to use the constant pi in your calculations, you
can
refer to Math.PI and save yourself the trouble of entering the whole
value in your code. That's the syntax for referring to a field: the
name of the object, followed by a period and the name of the property.
Accordingly, these two calculation are the same:
double area = Math.PI * radius * radius;
double area = 3.141592553589793 * radius * radius;
----------------------------------------------
REFERRING TO METHODS IN JAVA
To refer to a method of a Java object, you use much the same syntax
you use to refer to a property. In fact, the only syntactic difference
is that methods always have parentheses after them (the parentheses
sometimes contain extra stuff, but not always).
For example, it so happens that the Math object has a number of
methods--one of which is called random(). The random() method
generates a number (at random, for all intents and purposes) that is
greater than or equal to 0.0 and less than 1.0. The generated number
is of type double. Accordingly, to invoke that method, we'd use this
syntax:
Math.random()
The following is a valid bit of code involving this method:
double oneToTen = 10 * Math.random();
This code generates a double value between 0.0 and
9.999999999999999.
----------------------------------------------
SENDING ARGUMENTS TO METHODS
As we've discussed recently, all references to an object's methods are
followed by parentheses, as in
double randomValue = Math.random();
Some methods, however, require raw material to process. These
pieces
of raw material are called arguments.
For example, there's a method of the Math object, sin(), which
returns
(in double form) the sine of a number you specify in the parentheses.
Accordingly, the code
double sine = Math.sin(90);
results in the variable sine holding the value 1.0.
----------------------------------------------
DEALING WITH MULTIPLE ARGUMENTS
You've already seen that you can send values to a method for
processing by putting them in the parentheses following the method's
name. Sometimes (well, quite often, actually), methods require
multiple arguments. In those situations, you just separate the
arguments with commas.
The Math object, for example, has a method called min() that
returns
the smaller of the two specified integers. Accordingly, the code
int smaller = Math.min(15,14);
results in the variable smaller holding 14.
Interestingly, the Math object has four min() methods. In addition
to
the one that evaluates values of type int, there are others for values
of types double, float, and long. Thankfully, the Java Virtual Machine
(JVM) evaluates what kind of values are being sent to min() and
automatically invokes the proper method in response.
----------------------------------------------
OBJECTS VERSUS CLASSES
As we've recently discussed, an object is a particular thing (my
bicycle, as distinct from your bicycle and all other bicycles, for
example). In terms of programming, an object is a particular instance
of a kind of logical structure. In fact, you can declare a String
object that contains one sentence, and another String object that
contains a line from a poem, and you have two distinct String objects
floating around (you'd still have two objects if they both contained
the same thing, by the way). But obviously, the two String objects
have something in common.
Indeed--they both come from the same class. You can think of a
class
as a cookie-cutter. Once you've created a class, you can use it to
create numerous instances of its particular kind of object. The class
contains the names and definitions of all methods that objects of that
class will implement, as well as the names and associated values of
the fields. There are, however, two kinds of fields and two kinds of
methods that classes can include. (More on that next time.)
----------------------------------------------
FIELD TYPE 1: INSTANCE VARIABLES
Objects may have fields, which are inspectable values (or references
to values). When you define a field in a class (a class being the
template from which instances of that class--objects--are created),
you may want to allow each instance to have unique values for its
fields.
For example, if you were creating a class that was to be used to
create objects that represented checks drawn against your checking
account, you'd want each check (each instance of the class) to have
its own value for the amount paid. Similarly, each check would have
its own values for date and payee, even though those values would
occasionally be the same on different checks.
Fields that are unique to individual objects are called instance
variables. When you create an object from a class, instance variables
can have initial values, but those values can be changed without
affecting identically named fields in other instances of the same
class.
Using the checking example again, you might create two check
objects
(or two instances of the check class). Both might have initial "amount
paid" values (contained, say, in a field called amountPaid) of 0.
Shortly, though, one instance of the class might have its amountPaid
field changed to 100.00, while the other could be changed,
independently, to 19.95.
----------------------------------------------
FIELD TYPE 2: CLASS VARIABLES
Whereas instance variables vary among instances of the class that
defines them, class variables remain consistent across all instances
of a given class.
For example, going back to the example of a class that is used to
define objects that represent checks drawn against a checking account,
all such Check objects would have the same account number. Therefore,
it would make sense to declare the "drawnOnAccount" field as a class
variable. Thereafter, for all instances of the Check class, the
drawnOnAccount value would be the same.
Although using a class variable makes logical sense in this case,
it
also makes practical sense. There's only one piece of memory devoted
to the drawnOnAccount field of the Check class, rather than a piece of
memory holding that value independently for each instance.
Furthermore, you can refer to a class's class variables even when no
instances of the class exist.
Note that class variables are not immutable. That means you can
change
them all you want, but the change will appear across all instances of
the class (after all, there's only one space in memory to hold that
value). There is, however, a way to make class variables
unchangeable--such as in cases like Math.PI, where the value of Pi
never changes. (We'll get to that another day.)
----------------------------------------------
INSTANCE METHODS AND CLASS METHODS
Just as fields may be divided into instance variables and class
variables, all methods are either instance methods or class methods.
The big difference is that class methods may be called even when no
instances of their class exist, while you can only refer to instance
variables when you've created an object with the class in which
they're defined. Most methods are instance methods. Class methods are
usually utility methods, such as the methods of the Math object.
Remember, class methods can only operate on basic data types and
class
variables. You'll get an error if you try to make a class method
operate on an instance variable, because class methods shouldn't
depend at all on having objects around.
----------------------------------------------
WRITING CLASSES IN CODE
Writing Java code is all about defining classes. You write code that
defines classes, then the Java Virtual Machine (JVM) keeps those class
definitions in mind and can create objects from them (or allow
references to their class variables and class methods) any time. The
basic syntax for declaring a class looks like this:
class ClassName
{
// Defining code goes here.
}
That is, the word "class" is followed by a unique name, which in
turn
is followed by a pair of curly braces that contain the code that
defines the class. The class name can't be the name of any other
class, nor a Java keyword (such as "double" or "catch"). Also, it's
customary (but not necessary) for a class name to begin with a capital
letter.
----------------------------------------------
ADDING INSTANCE VARIABLES TO A CLASS
Recently, we defined classes and objects using the example of a
checking account. Now, let's take a look at the syntax that would
implement our Check class, which will be used to create objects
representing checks drawn on a bank account. These objects will need
some instance variables, unique to each instance of the class,
representing the payee, the amount, and a memo field (we'll ignore
dates for now). Here's how we'd declare those fields:
class Check
{
double amount = 0.0;
String payee = "";
String memo = "";
// Further defining code goes here.
}
No big deal, really. You just declare those variables and their
data
types in the normal way. No further adornment is needed. Every
instance of the Check class (that is, every Check object) will have
fields called amount (initially 0.0), payee (initially an empty
string), and memo (also initially an empty string). Each field may be
manipulated independently of the fields in other instances of the
Check object.
----------------------------------------------
ADDING CLASS VARIABLES TO A CLASS
Recently, we've been discussing objects and variables using the
example of a checking account. Checks drawn on a given account have
several things in common, one of which is the bank account number of
the payor (the person writing the check and giving it to a payee). It
stands to reason that in a class whose objects represent individual
checks, the field containing the payor's account number would be a
class variable--that is, it would be the same across all instances of
the class and accessible even if no instances of the class existed at
a given moment.
Here, then, is how we'd modify our class declaration to bring about
this effect:
class Check
{
// Instance variables follow:
double amount = 0.0;
String payee = "";
String memo = "";
// Class variables follow:
static int accountNumber = 234234;
// Further defining code goes here.
}
As you can see, all that is required to make a field a class
variable
is to precede its declaration with the word static. This makes the
variable (and its value) the same across all instances of the class
Check. Don't forget, though, that changing the variable in one
instance of the class causes the same change to show up in all other
instances. However, as you'll see next time, there is a way to make
the value unchangeable.
----------------------------------------------
MAKING A CLASS VARIABLE IMMUTABLE
We've seen how to make a field a class variable by preceding its
declaration in the class definition with the word static. The only
drawback is that static doesn't prevent the value associated with that
variable from changing. For that, you need another keyword: final.
Placing final before static in the declaration of a class variable
(which should include a value assignment, for all practical purposes)
makes the variable's value unchangeable.
Here, then, is our Check class, improved with the final keyword in
front of the declaration of the accountNumber variable:
class Check
{
// Instance variables follow:
double amount = 0.0;
String payee = "";
String memo = "";
// Class variables follow:
final static int accountNumber = 234234;
// Further defining code goes here.
}
----------------------------------------------
ADDING A METHOD TO A CLASS--PART 1 OF 2
Most objects will have methods in addition to their fields. To define
a method in a class, you just add a special block of code inside the
curly brackets that surround the class's code. The generic syntax for
a method declaration is this:
returnDataType methodName(arguments)
{
// Method code.
}
In this example, returnDataType is a data type--either one of the
basic data types (int, long, char, and so on) or a class (String,
JDialog, whatever). It represents the kind of data that the method
returns, or sends back to the point from which it was called. Some
methods don't return any value--in which case they should have the
keyword void in place of returnDataType.
Continuing, methodName is a unique name by which to identify the
method. Strictly speaking, it need not be absolutely unique among the
methods in its class, but there are special conditions for duplicating
method names. The parentheses, in turn, contain arguments, which
represent values that must be sent to the method for processing. (More
on those arguments another day.)
----------------------------------------------
ADDING A METHOD TO A CLASS--PART 2 OF 2
Again using the example of our Java checking account, let's say you
want to add a method to the Check class that returns the number of the
bank account to which the Check applies. You could define the method
like this:
class Check
{
// Instance variables follow:
double amount = 0.0;
String payee = "";
String memo = "";
// Class variables follow:
final static int accountNumber = 234234;
// Methods follow:
int getAccountNumber()
{
return accountNumber;
}
// Further defining code goes here.
}
In this case, the method getAccountNumber() is declared in order to
return a value of type int and to take no arguments. The only line of
code in the class is the keyword return and the name of the variable
accountNumber, which means that accountNumber's value is to be
returned to wherever this method is called.
----------------------------------------------
DECLARING A CLASS METHOD WITH STATIC
You may have noticed that in the latest version of the Check class
(discussed in the previous tip), the getAccountNumber() method
referred only to the accountNumber class variable (which in turn is
declared with static). Because of the static status, it makes sense to
declare the getAccountNumber() method to be a class method, accessible
even when no objects of class Check have been instantiated. To do
this, we use basically the same syntax we use to make a field a class
variable, preceding the method declaration with the keyword static.
(Note that class methods can only refer only to class variables and
constants. If you try to refer to instance variables, you'll run into
trouble when someone attempts to run the class method when no
instances of the class exist.)
Here, then, is the (slightly) modified class:
class Check
{
// Instance variables follow:
double amount = 0.0;
String payee = "";
String memo = "";
// Class variables follow:
final static int accountNumber = 234234;
// Methods follow:
static int getAccountNumber()
{
return accountNumber;
}
// Further defining code goes here.
}
----------------------------------------------
SETTING UP A METHOD THAT TAKES ARGUMENTS
A lot of times, you'll want to send values to a method so that the
method can use them in performing its work. These values are called
arguments. To declare a method as one that takes an argument, use this
syntax:
returnDataType methodName(argumentType argumentName)
You've seen the stuff at the beginning of this line, but the
material
in the parentheses may be new. In this case, argumentType represents
the data type of the argument, while argumentName represents the name
by which the argument will be known inside the method. If you want to
accept more than one argument, separate the type/name pairs with
commas.
Accordingly, here's our Check class (from the example we've been
using
the last week or so), modified with a setAmount() method that takes an
argument.
class Check
{
// Instance variables follow:
double amount = 0.0;
String payee = "";
String memo = "";
// Class variables follow:
final static int accountNumber = 234234;
// Methods follow:
static int getAccountNumber()
{
return accountNumber;
}
void setAmount(double newAmount)
{
amount = newAmount;
return;
}
// Further defining code goes here.
}
One more thing to note: In setAmount(), that final return on a line
by
itself is optional. It signifies that the method (which is declared as
void and therefore returns no value) is finished executing, and
execution should return to the point at which this method was called.
However, encountering a method's closing curly bracket has the same
meaning, so the return in non-branching void methods is there only to
help clarify the source code.
----------------------------------------------
ENDOWING A CLASS WITH A CONSTRUCTOR
A constructor is a special kind of method that serves to create an
instance (an object) of the class in which the constructor appears. A
constructor always has the same name as the class it instantiates, and
a constructor never has a return data type (nor is it declared to be
void).
Usually, constructors serve only to set instance variables to
values
specified as arguments in the call to the constructor. Accordingly,
here's our Check class (from the Java checking account example we've
been using recently), with a new constructor:
class Check
{
// Instance variables follow:
double amount = 0.0;
String payee = "";
String memo = "";
// Class variables follow:
final static int accountNumber = 234234;
// Methods follow:
static int getAccountNumber()
{
return accountNumber;
}
void setAmount(double newAmount)
{
amount = newAmount;
return;
}
//Constructor follows:
Check (double initialAmount, String initialPayee, String
initialMemo)
{
amount = initialAmount;
payee = initialPayee;
memo = initialMemo;
}
// Further defining code goes here.
}
Now, with this constructor in place, we can create a new object of
class Check by using a call such as this:
Check check834 = new Check(100.00, "Ruth Anne Krinklemeyer",
"Song and dance");
This statement creates a new Check object (attached to the variable
check834) with three initial values that represent the amount, payee,
and memo.
----------------------------------------------
INCLUDING MULTIPLE CONSTRUCTORS
You can have multiple constructors in a given class, which in turn
allows objects of the class to be created with different sets of
information. In the case of our Java checking account, for example, it
would be reasonable to allow the creation of new Check objects without
specifying any contents for the new object's memo field. To allow that
to happen, we must create a second constructor that doesn't expect a
memo argument. Here's how it looks:
class Check
{
// Instance variables follow:
double amount = 0.0;
String payee = "";
String memo = "";
// Class variables follow:
final static int accountNumber = 234234;
// Methods follow:
static int getAccountNumber()
{
return accountNumber;
}
void setAmount(double newAmount)
{
amount = newAmount;
return;
}
//Constructors follow:
Check (double initialAmount, String initialPayee,
String initialMemo)
{
amount = initialAmount;
payee = initialPayee;
memo = initialMemo;
}
Check (double initialAmount, String initialPayee)
{
amount = initialAmount;
payee = initialPayee;
}
// Further defining code goes here.
}
In this case, the second Check constructor doesn't expect a memo
value, as does the first constructor. Accordingly, you could call the
two constructors (one with memo, and one sans) with this code:
Check check834 = new Check(100.00, "Ruth Anne Krinklemeyer",
"Song and dance");
Check check835 = new Check(19.95, "Late-Night TV Marketing
Company");
The Java Virtual Machine (JVM) can route the instantiation call to
the
proper constructor, based on the number and type of arguments included
in the call.
----------------------------------------------
CALLING ONE CONSTRUCTOR FROM ANOTHER
While it's possible to write multiple constructors for the same class,
you'll frequently find that the settings you make with each of a
class's several constructors are similar. In our check example, the
payor and the checking account number will pretty much always be the
same. Let's modify our check class so it has several constructors:
- A "blank check" constructor that specifies only payor and account
number
- A "standard" constructor that specifies the above data, plus the
payee and an amount
- A "standard plus memo" constructor that includes the above, plus a
memorandum string
Let's start with the blank check constructor. We'll eliminate a lot
of
the variables and methods we put in earlier--they'd just get in the
way now.
class Check
{
String payor = "Ruth Ann Krinklemeyer";
String accountNumber = "123-123X";
double amount = 0.0;
String payee = "";
String memo = "";
// Further defining code goes here.
}
That's the default constructor--the one that's called when someone
instantiates the class without any arguments. Next time, we'll move on
and refer to that default constructor from another constructor that
does take arguments.
----------------------------------------------
THIS() REFERENCES THE DEFAULT CONSTRUCTOR
Last time, we created a class--having only a default constructor that
creates a "blank check"--that looks like this:
class Check
{
String payor = "Ruth Ann Krinklemeyer";
String accountNumber = "123-123X";
double amount = 0.0;
String payee = "";
String memo = "";
// Further defining code goes here.
}
Now, let's modify that class so it includes a constructor that
creates
a check with the regular information, plus a payee and an amount.
Here's how that would look:
class Check
{
String payor = "Ruth Ann Krinklemeyer";
String accountNumber = "123-123X";
double amount = 0.0;
String payee = "";
String memo = "";
Check(String namedPayee, double namedAmount)
{
this();
payee = namedPayee;
amount = namedAmount;
}
// Further defining code goes here.
}
The key here is this(). The this() call refers to the current
object--in this case, Check. When we call this() in the two-argument
constructor, it calls the default constructor (the one that takes no
arguments and sets the payor and accountNumber variables). The
two-argument constructor then fills in the other two variables'
values.
----------------------------------------------
CALLING SEVERAL CONSTRUCTORS IN A CHAIN
We want to modify our Check class so that you can declare an instance
of the class with three arguments: a payee, an amount, and a memo
field. If we design a constructor that can take and assign the memo
field, we can leave the rest of the work up to other constructors,
thanks to a special use of the this() call. Here's how:
class Check
{
String payor = "Ruth Ann Krinklemeyer";
String accountNumber = "123-123X";
double amount = 0.0;
String payee = "";
String memo = "";
// Further defining code goes here.
}
Now, let's modify that class so it includes a constructor that
creates
a check with the regular information, plus a payee and an amount.
Here's how that would look:
class Check
{
String payor = "Ruth Ann Krinklemeyer";
String accountNumber = "123-123X";
double amount = 0.0;
String payee = "";
String memo = "";
Check(String namedPayee, double namedAmount)
{
this();
payee = namedPayee;
amount = namedAmount;
}
Check(String namedPayee, double namedAmount,
String namedMemo)
{
this(namedPayee, namedAmount);
memo = namedMemo;
}
// Further defining code goes here.
}
The newly added constructor makes reference to this() in this way:
this(namedPayee, namedAmount);
It tells the Java interpreter to instantiate the current class
(Check)
with its two-argument constructor. Two of the three arguments that
came to the three-argument constructor are sent to the other
constructor, and the assignment of the third is handled locally.
Note that the two-argument constructor uses this() as well. It's a
chain of references.
----------------------------------------------
ADDING A CONSTRUCTOR THAT DUPLICATES AN EXISTING OBJECT
At some point in the execution of your checkbook-management program,
you might want to duplicate an existing instance of the Check object.
One of the ways to do this is with a special constructor that takes a
Check object as an argument. You can make the constructor copy the
instance variables out of the argument object and assign them to the
new object's instance variables. Such a constructor for the Check
object might look like this (ignoring the rest of the class):
Check(Check checkToCopy)
{
this();
amount = checkToCopy.amount;
payee = checkToCopy.payee;
memo = checkToCopy.memo;
}
You've seen the use of the dots before--they separate an object's
name
from the names of the variables and (in cases other than this one)
methods it contains.
----------------------------------------------
Assigning Subclasses to Superclass Variables
Say you have a class called Vehicle, which has a subclass called
Motorcycle. You can make variables of type Vehicle hold objects of
type Motorcycle, but you can't make Motorcycle variables hold
Vehicle objects (not without jumping through hoops, anyway). This
code is valid, assuming the Vehicle and Motorcycle classes exist:
<pre>
Vehicle vehicleHolder;
Motorcycle harley = new Motorcycle();
vehicleHolder = harley;
</pre>
No problem. Even though vehicleHolder is technically a Vehicle
object, it can hold instances of any of its subclasses. All
Motorcycle objects are also Vehicle objects.
- Using Explicit Casting -
So, now we know the above is valid JavaScript. This is because all
Motorcycle objects are also Vehicle objects, but not all Vehicle
objects are Motorcycle objects. You can account for this with
what's called explicit casting, in which you acknowledge that
you're creating an instance in which a superclass fits into a
subclass. This code is valid:
<pre>
Motorcycle harley;
Vehicle conveyance = new Vehicle();
harley = (Vehicle) conveyance;
</pre>
The Class name in parenthesis is called an explicit cast.
*****
Invoking a Servlet Bean is Similar to Invoking Servlets
by Venkat Subbarao
To invoke a Servlet Bean from the browser, simply type (into the
location text box) the URL for the Bean. To call a Servlet Bean
from an applet, create a URL specifying the Bean address and then
call the ShowDocument() method using this URL. The source code for
this looks like:
<pre>
String urlstring = "http://machineaddress/servlet/myBean";
URL Location = new URL(urlstring);
getAppletContext.showDocument(Location,"_blank");
</pre>
TODAY: What’s Up With Get and Set?
by David Wall
You may have noticed that recent examples have included "get" and
"set" functions. You may wonder why you would have a getWhatever()
method that returns the value of variable whatever and a setWhatever()
method that alters its value. Why wouldn't it be easier to just alter
the fields directly, by referring to the name of whatever instance you
were concerned with, and the name of the variable? In other words, how
is...
Check.setValue(45);
..different from
Check.value = 45;
Well, in simple cases, get and set methods are inefficient. Their
advantage becomes more apparent in larger programs that might require
modification. You might have a class that has getMass() and setMass()
methods, and programs that referred to those methods that send and
expect values in kilograms. If, for some reason, you had to change the
internal workings of your program to use English units (the English
unit of mass is the slug, interestingly), you could keep the external
callers happy with relative ease by doing the conversion in the get
and
set methods. It's a maintenance thing.
*****
JSP-Java Beans for Powerful, Reusable Web Applications
By Venkat Subbarao
Java Bean architecture provides a way for developing reusable
software
components. Java Servlet Pages (JSP) prepares a framework for
executing
the Java code on the Web server. By combining both technologies, you
can easily develop and deploy powerful, reusable server applications.
This week, I will explain how to implement Java Beans with JSP.
First, let's look at how the Web server executes the JSP files.
Java
Servlet Pages are text files with JSP extensions. You develop them
with XML like tags, which embed the Java code. Whenever a Web server
encounters such a file, it forwards the request to the Servlet engine.
The Servlet engine has three major tasks: The first one is to parse
the
jsp file to identify the Java code in it. The second is to generate
the Java source and class files, and save them in a temporary
directory. The third task is to execute the code and return the
results
to the client.
Next, let's see what Java Bean Architecture has to offer. The
architecture provides the framework for developing software components
that follow the set and get design patterns. This architecture defines
a Java Bean as an object with a set of attributes. The values for
these
attributes can be changed by using the setXXX () methods, and the
attributes can be accessed using getXXX () methods. Moreover, when an
attribute value is changed, the propertyChanged event is triggered,
which defines the further action the object has to implement.
Finally, let's combine the technologies. Let's say you would like
to
display a product description from an e-commerce site. To simplify the
problem, we'll assume that the product description is saved in a text
file on the Web server.
In order to implement JSP-JavaBeans technology, the first task
would be
to design a ProductDescriptonBean; this is a Java Bean that takes the
product name as an input parameter and returns the description for it.
Accordingly, design the Bean to have two attributes: productname and
productdescription. Define the get and set methods for these
attributes. Add an additional private method, which takes in product
name as the attribute, opens the corresponding product file, and
returns the description.
Next, you'll have to embed the Java Bean in a JSP Page. To
facilitate
this, JSP Technology defines XML like tags. To find out which tags
Are available, please visit the Java Soft Web site at
http://www.javasoft.com/products/jsp/tags/11/tags11.html.
To get the complete source code for this example, please visit
http://www.invision.com/profiles/vsubbarao/venkatsubbarao.html
<jsp:useBean id="Bean1" scope="session"
class="venkat.ProductDescriptionBean" />
Set the attribute value for the Java Bean
<jsp:setProperty name="bean1" property="productName" param="name" />
Finally, get the productName, productDescription attributes from
the
Java Bean and format it using the HTML tags.
<H2> Product :<jsp:getProperty name="Bean1" property="productName" />
</H2>
<H3>Product Description is <jsp:getProperty name="Bean1"
property="productDescription" /> </H3>
JSP-Java Bean Technology has several advantages over Servlets. For
example, Business Logic can be built as components, which can then be
reused in different JSP Pages. Unlike Servlets, you can separate
Business Logic from the display format. Moreover, you can dynamically
link Business Logic to a JSP page at run time. In the problem above,
for instance, you can easily talk to a database to get the required
information by simply changing the Bean name in the JSP File. These
technologies will be further advantageous if you can develop a service
-oriented architecture -- that is, identifying the services the JSP
has
to offer and defining them as attributes for the Java Bean.
Next Week: Separating Business Logic from the Display Format with a
Java
Bean.
Introduction to Packages
by David Wall
Java is big into organizing things. Object-orientation, as you've
probably figured out, is largely a system of containers, into which
things fit neatly, and a system for referring to the values and
methods
that the containers hold. People who like object-orientation tend to
like Lego blocks (for more on this idea, read Douglas Coupland's
excellent contemporary novel, Microserfs).
Classes beget objects and objects can relate to one another through
inheritance, but classes can have relationships with one another
through
other mechanisms. One of the best ways to group classes into families
is
with packages. Packages are arbitrary collections of classes you
define
with a combination of keywords and file locations.
Say, for example, that you have a set of classes that have to do
with
image data, such as that which might be contained in a GIF or JPEG
file.
One class is called BrighterImage, and it represents a slightly
brighter
version of some image that's sent to it. The BrighterImage class lives
in a file called BrighterImage.class. To associate the BrighterImage
class with other classes that might (indeed, which must) reside in
other
files, you can put this line at the top of BrighterImage.class:
package Image;
By convention, package names start with capital letters. The
package-
defining line (such as the one above, consisting of the keyword
package,
a basically arbitrary name, and a semicolon) must be the first in the
source code file (BrighterImage.java) that defines BrighterImage.class
(with the exception of blank lines and comments, that is).
You can further organize your classes by adding subsidiary
groupings.
For example, if you have some classes that have to do with JPEG files,
and others that have to do with PNG files, you can lead the respective
source code files with these lines:
package Image.JPEG;
package Image.PNG;
The dot notation should be familiar, but it denotes something
important
here: Directory structure. If class BrighterImageJPEG opened with the
line...
package Image.JPEG;
..it would have to be in a folder called JPEG, which would have to
be a
sub-folder of the folder called Image.
Next Week: Packages Affect Inheritance
*****
Customizing HTML Pages Using JSP and XML
by Venkat Subbarao
In the present E-Business world, it has become important to style
HTML
pages according to customer preference. A software distribution
company
can now provide information to the customer on the items s/he is
interested in, rather than making the customer search for those items
every time they put an order in. You can achieve this goal by
implementing JSP and XML together. XML technology is designed to save
the structured data on the Web. The main advantage is that any
language
providing a parser for the XML language can process the file and
easily
access the required information. In the current scenario, a software
distribution company saves a customer's preferences in an XML file and
uses this file in a JSP in order to customize the HTML and dynamically
print the data on to the browser. The code for JSP looks like:
(For complete code please visit:
http://www.venforyou.com/itworld.html?week=march_2week)
(For introduction on JSP please visit:
http://www.venforyou.com/itworld.html?week=feb_1week)
//Import the parser files. (In this application I used IBM Parser)
<%@ page isThreadSafe="false" import="java.util.*,
com.ibm.xml.parser.*,
org.w3c.dom.*, venkat0213.ProductDescription,venkat0213.*" %>
//Create the document object from the XML File
Parser reqparser = new Parser(filename);
reqparser.setWarningNoDoctypeDecl(false);
reqparser.setWarningNoXMLDecl(false);
reqparser.setPreserveSpace(false);
reqparser.setKeepComment(false);
TXDocument reqdoc = reqparser.readStream(fileinputstream);
//Parse through the document object to get software preferences.
TXElement rootelement = (TXElement)reqdoc.getDocumentElement();
NodeList customerlist = rootelement.getElementsNamed("customer");
.....
String customername = customermap.getAttribute("name");
.....
String id = osmap.getAttribute("id");
//Use the information and print the HTML Page dynamically.
if (id .equals("1")) {
displayvalue[1] = "Symantec Visual Cafe 2.1";
displayvalue[2] = "Microsoft Word 2000";
}
.
<%= displayvalue[i] %>
For simplicity, I hardcoded the information in JSP. Usually, you
can
generate a select statement from the preferences and display the
results.
Next Week: Designing an XML Document to Save Customer Information
Overriding Inherited Methods
by David Wall
Last week, we saw that by convention, all Java objects have a
method
called toString() that's invoked in situations in which the object has
to behave like a string. What do you do, though, when you have a class
with subclasses? Subclasses inherit the mothods of their superclass,
right?
You may recall that we defined a class, PoliticalCandidate, whose
toString() method looked like this:
public String toString() {
return "Hi! I'm " + name + ". Please like me.";
}
That's the default behavior of all PoliticalCandidate objects. What
if
we wanted subclasses of the PoliticalCandidate class to behave
differently? Say we had this subclass, which is typical of several
(sorry for my American bias):
public class DemocratCandidate extends PoliticalCandidate
{
// Class variables:
public String party = "Democrat";
public String hair;
// Constructor:
public DemocratCandidate(String candidatesName, String candidatesHair)
{
super(candidatesName);
hair = candidatesHair;
}
// Methods:
public String toString() {
return "Howdy! I'm " + name + ". I understand how you feel. Please
like
me.";
}
}
Another subclass, RepublicanCandidate, might have this method:
public String toString() {
return "Hello. I'm " + name + ". I have a stern demeanor. Please like
me.";
}
The point of this illustration is that a method in a subclass
overrides
a method in its superclass with a similar name, return value, and set
of
attributes (the name, return value, and set of attributes of a method
are collectively called its signature). This code...
RepublicanCandidate candidateA = new RepublicanCandidate("Guy
Sincere");
DemocratCandidate candidateB = new DemocratCandidate("Larry
Lamppost");
PoliticalCandidate darkHorse = new PoliticalCandidate("Charlie
Grinster");
System.out.println(candidateA);
System.out.println(candidateB);
System.out.println(darkhorse);
..yields this output:
Hello. I'm Guy Sincere. I have a stern demeanor. Please like me.
Howdy! I'm Larry Lamppost. I understand how you feel. Please like me.
Hi! I'm Charlie Grinster. Please like me.
Next Week: Packages
*****
The Implementation of Constrained Properties
by Venkat Subbarao
Last week I told you that using constrained properties requires a
low-level understanding of how Java Bean technology implements them.
The
Java Bean scenario starts with a JavaServerPage (JSP), which creates
an
instance of Java Bean. It adds vetoable and property change listeners
to
the Bean. It also tries to set the property to the Bean. Bean, having
an
instance of support class, notifies the listeners that the property is
changed, and listeners veto the property if it is not valid.
Now I'll liken the process to family life, for lack of a better
analogy.
Construction Company (JSP) creates an empty house (the Java Bean) and
adds family members to it (listeners). Two parents (Vetoable
Listeners)
and two kids (Property Change Listeners) react to any changes in the
property of the house. For instance, whenever the COLOR (bound and
constrained property) is changed, the family has to alter their
furniture in their respective rooms. Parents have the power to veto
the
COLOR if it doesn't suit their own furniture. On the other hand, Kids
(Property Change Listeners) can alter their furniture when the COLOR
changes.
House uses two messengers to carry the property changes to
listeners.
When COLOR changes, Messenger1 (VetobaleChangeSupport class) informs
the
"parents," one after the other, to make sure they both agree. If so,
then Messenger2 (PropertyChangeSupport class) informs the "kids," one
after the other, that COLOR has changed and the kids gets their
furniture.
The advantages of such an implementation are clear. You can add a
butler
to the process or remove one of the family members without affecting
the
functionality. On the contrary, having multiple Vetoable Listeners may
hinder the performance. This is because Messenger1 cannot keep track
of
the order in which it sends messages to the parents. When color
changes,
for instance, Messenger1 sends the message to parent1, who redesigns
his
room according to the new COLOR and okays it. Then Messenger1 sends
the
message to parent2, who redesigns the room, finds the COLOR not
suitable, and rejects it. Parent1 has to throw away the new design and
stick with the old design. In other words, all the efforts made by
parent1 to adapt to new color are wasted. With multiple vetoable
listeners, important resources are wasted when the listener down the
line rejects the value.
Another problem may arise due to the bad design of the Bean.
Technically, a Bean can veto its own property by adding itself as a
listener. For similar reasons, as mentioned above, such a design could
result in unexpected results triggering a chain of events, wasting the
valuable CPU.
Next Week: Customize HTML Pages Using JSP and XML
THIS WEEK: Using toString() Methods
by David Wall
Objects are an important part of Java, but they don't lend
themselves to
certain important tasks. For example, if you try to put an object in
the
parentheses here...
System.out.println();
..nothing good would happen were it not for a Java convention. The
convention states that every object should have a method to work with,
like the one shown above, called toString() that provides a string for
methods. All of the core Java classes (the ones you get with the Java
Development Kit) have toString() methods -- look and see. So, let's
outfit our PoliticalCandidate class with a toString() method. Here's
how
it looks in modified form:
public class PoliticalCandidate
{
// Class variable:
public String name;
// Constructor:
public PoliticalCandidate(String providedName) {
name = providedName;
}
// Methods:
public String toString() {
return "Hi! I'm " + name + ". Please like me.";
}
}
With that in place, you can create an instance of
PoliticalCandidate
like this:
PoliticalCandidate favored = new PoliticalCandidate("Charlie
Grinster");
..and then use this statement:
System.out.println(favored);
..to get this output:
Hi! I'm Charlie Grinster. Please like me.
That's neat, I think -- the toString() method gives your objects a
way
to behave properly in situations in which they're required to act like
strings.
Next Week: What do you do when you have subclasses, and those need
to
have toString() methods, too? The solution is a feature of Java called
method overriding.
*****
Error Handling with VetoChangeException of JavaBeans
by Venkat Subbarao
Java Beans implements Bound and Constrained properties with the
help of
Listener interfaces and Support classes. Listener interfaces are of
two
types: VetoableChangeListener and PropertyChangeListener. Of the two,
VetoableChangeListener provides a method for vetoing the property
change
and makes the bean reject the value assigned to it.
PropertyChangeListener lets you adjust for the change. Accordingly,
there are two types of Support Classes: VetoableChangeSupport and
PropertyChangeSupport. These classes maintain the list of listeners,
so
those listeners can be informed of the property change.
In the following example code, myVetoableChange is a listener,
which
implements the vetoableChange method. This method defines the logic
for
the valid values. It verifies whether a property is valid or not by
checking to see whether a file with that name exists.
For complete source code, please visit
http://www.venforyou.com/source/itworld/feb13-01.html
class myVetobaleChange implements java.beans.VetoableChangeListener
{
public void vetoableChange(java.beans.PropertyChangeEvent event)
throws PropertyVetoException
{
String filenamenew = dirname+F_S+(String)event.getNewValue();
try {
BufferedReader productFile = new BufferedReader(new
FileReader(new File(filenamenew)));
}
catch(Exception ee){
System.out.println("FILE NOT EXISTS");
throw new PropertyVetoException("Product file Not
Exists",event);
}
}
}
Although constrained properties may appear simple to implement for
handling error logic, extreme caution should be taken when using such
a
property. For instance, making a Bean itself veto a property change
could result in unexpected and undesirable consequences, and
implementing multiple vetoable listeners may hinder the performance by
consuming the CPU Time.
Next Week: Implementation Of Constrained Properties
Defining Abastract Methods
by David Wall
It's campaign season in the United States and I figure, What better
way
to explore the political process than through Java?
Let's implement a superclass called PoliticalCandidate that
represents
characteristics and capabilities that all political candidates have in
common. However, since actual candidates usually belong to a political
party, we'll use inheritance to differentiate among various kinds of
candidates.
The superclass, PoliticalCandidate, is declared like this:
public class PoliticalCandidate {
public abstract void vocalizeSlogan();
}
What's that? You see, all political candidates have the capacity to
vocalize their slogans, so we've defined the superclass as including a
vocalizeSlogan() method. But you'll notice that there's no actual code
there. You'll also notice that the word "abstract" precedes the method
name. That means that the method is defined in the superclass just so
it
can be inherited and modified in the subclasses. Hence, the public
access attribute as well.
Having defined the superclass that way, we can declare several
subclasses, one for each political party. The subclasses are
DemocratCandidate, RepublicanCandidate, and GreenCandidate.
DemocratCandidate, which is typical of the subclasses, is declared
like
this:
public class DemocratCandidate extends PoliticalCandidate {
public void vocalizeSlogan() {
System.out.println("Babies are cute. Down with criminals!");
}
}
There, the vocalizeSlogan() method is fleshed out with useful code.
*****
Getting Started With EJB
This week, I'd like to present an overview of Enterprise Java Bean
Architecture. EJB allows us to develop and deploy server side software
components. It is different from other architectures in that it
defines
standards, not only for a Bean Developer but also for an application
server provider. It builds a contract, or bond, between a bean and the
application server by dividing the responsibilities between them.
Let's look at the working of an application server that follows EJB
standards. Application Servers provide a container, which creates,
destroys, and maintains beans. If you are familiar with database
connection pooling, you know that you can improve performance of the
application by using a fixed number of connections and swapping them
if
necessary. Container works similarly. When the application server is
started, container creates multiple instances of each Bean; when a
client makes a request for a Bean, it associates this bean instance
with
an EJBObject. The Client and Application Server talk through the
EJBObject interface.
The Container is responsible for creating, maintaining and
destroying
the beans. Moreover, it can implement low-level transactions, database
connection pooling, and security. On the contrary, the developer of
the
bean is responsible for the business logic and may not even use the
database information in his code. He can define the mapping between
the
bean properties and the database column using the Descriptor tool
provided by the application server. If that is the case, all control
is
transferred to the container, making the container responsible for
generating the necessary code for the database transactions.
For more information on how the EJB Server works, please visit
http://www.venforyou.com/main_publications.html
(Migrating for RMI to EJB Column).

Using Access Attributes To Restrict Importability
When you use an import statement to bring in the classes in a
package,
like this...
import mathModels.*;
..you make the classes in that package available for use in the
importing class. You make them available, that is, unless they have
import restrictions on them. You see, Java allows you to make rules
about how a class may be used remotely. Furthermore, Java has rules
about how classes may be referred to by other classes within the same
package.
Members of a class may have any of three access attributes
(keywords
that regulate accessibility rules), or no stated access attribute at
all. The three access attributes are:
- public
- private
- protected
Public members are accessible from any class, either in the same
package
or in another class that imports the package that includes the class
containing the member defined as public. That's awkward, but correct.
To
put it another way, any class may access any public member via an
import
statement.
Members without a stated access attribute (neither public, private,
nor
protected) are accessible from any class in the same package, but they
can't be accessed through import statements.
Private members cannot be accessed via import statements. In fact,
they
can't even be accessed by other classes in the same package. Private
members exist only within the classes that define them.
Within their package, protected members are like members with no
stated
access attribute -- they may be accessed freely. Outside their
package,
though, they may be invoked only as superclasses for subclasses that
inherit their members.

Whether a pop-up window can be displayed from an applet. The answer
is yes, and today I will show you how. To begin, editing some
properties on the applet may need password authentication. You can
implement such a business requirement using pop-up dialogs. A
ValidatePassword pop-up dialog consists of two methods: Constructor,
which takes in the DialogProcessor interface as an argument, and the
DialogProcessor, which contains the method dialog that can call back
on the applet. The code for DialogProcessor looks like this:
public class ValidatePassword extends Dialog
{
public ValidatePassword(Frame frd, Dialogprocessor pr)
{
super(frd,"Save As",true);
.....
}
}
Applet constructs the dialog and displays it. The source code for
it looks like:
Frame fr1 = new Frame();
Dialog dlg1 = new ValidatePassword(fr1,this);
fr1.setVisible(false);
dlg1.setSize(100,100,200,200);
dlg1.show();

Follow these steps.
1. Download the latest JDK(Java Development Kit) at
http://www.java.sun.com/products
2. Read the free Java tutorial, at
http://java.sun.com/docs/books/tutorial/index.html (bookmark it,
so you will easily find it again).
3. Avoid Microsoft's J++ product, which is in the words of
Microsoft's own employees "polluted Java". It is designed to undermine
standard Java, and has many deliberate platform-specific
incompatibilities, including new keywords in the language.
4. To get some tips on getting started with a programming homework
assignment, look at
http://www.concentric.net/~pats/beginner.html.

1. Are you successfully running the javac compiler?
Try
Type the javac at the command prompt
to see if it prints out a message about correct usage. If not,
invoke javac using the full pathname, or set your PATH variable to
include the directory that contains javac.
2. Is the CLASSPATH environment variable used correctly?
In JDK 1.0.2, beginners had to set CLASSPATH, and it had to include
both system libraries and your programs.
In JDK 1.2, CLASSPATH is no longer needed for system libraries. You do
want CLASSPATH to point to the directories containing any "user
classes" you're using. Getting started, you will probably want at a
minimum "." (the current directory) in your CLASSPATH. When CLASSPATH
is wrong, javac will tell you it can't find definitions for classes
you reference in the source file.
There are five common mistakes that cause your VM (java or browser)
to be unable to execute your classes
- First, did you write an applet or an application? If an applet,
you must make sure that you did extend the java.applet.Applet class.
Your starting code should be in the init routine. If you wrote an
application, your starting code should be in a routine called
main(). Don't mix applets with applications until you have a bit
more experience.
- You must declare your main class as "public". If you don't,
unfortunately some systems will still run the code, while others
won't. The main class is either the one with the main() method in,
or in the case of an Applet, the class that extends Applet.
- Your class name and the file name must match exactly, even
letter case. If your class is HelloWorld, your source file must be
HelloWorld.java and your class file will be "HelloWorld.class".
- If an Applet, and you used ftp to transfer the classes to the
server, you must ftp all the classes, and you must use BINARY
transfer not ASCII.
- Errors in setting the CLASSPATH (and/or codebase in an applet).
Even seasoned programmers do this, pointing inside a package or
mistyping a path delimiter.
If you are running an applet, you should check the following
further points:
- If your class isn't loading, recheck the HTML applet tag.
- If you are writing to System.out, the results are displayed in
the browser's java console. You'll have to create a window if you
want one.
- Make sure your browser is compatible with the Java language
features you are using. Internet Explorer and older versions of
Netscape's browsers have omitted some support for JDK 1.1. Try your
applet in the JDK's appletviewer first.

The CLASSPATH environment variable tells the VM's class loader
where to find classes that are directly or indirectly invoked,
including system classes. The CLASSPATH variable should