This chapter is from the book

This chapter is from the book

Brief Summary of Java

Java programs are compiled into an intermediate format, known as bytecode,
and then run through an interpreter that executes in a Java Virtual Machine
(JVM).

The basic syntax of Java is similar to C and C++. All white space is treated
equally, indent level does not matter, statements end in a semicolon, and blocks
of code are enclosed between { and }.

Comments are enclosed between /* and */, or else begin with
//, in which case the rest of the line is a comment.

Data Types and Variables

The integer data types are byte, short, int, and
long, which correspond to numbers of 8, 16, 32, and 64 bits. The types
float and double store floating-point numbers; char
stores a 16-bit Unicode character, and boolean can hold one of two
values, true or false.

Variables are declared with a type and name, as in the following:

int myint;

They can be initialized at the same time:

char delimeter = '/';
boolean finished = false;

Variables can be declared anywhere they are used. The scope of a variable
usually extends to the end of the code block it was declared in.

Java allows variables to be converted between different numeric types by
casting, as in the following:

int a;
double d = (double)a;

You can also cast between objects, but that is beyond the scope of this
book.

Variables can be declared as final, which means that their value
cannot be changed after it is initialized:

final int MAX_LEN = 128;

Arithmetic expressions in Java are straightforward, with % used for
modulo:

k = a + b;
remainder = tot % users;

The ++ and -- operators exist. If they are used in prefix
notation, the expression is evaluated after the operation is done. In postfix
notation, the expression is evaluated before the operation is complete. So, with
the following code

d = 4;
e = ++d;
f = e--;

e and f are both set to 5.

Strings (and Objects)

Beyond the basic data types, everything in Java is declared as a class.
A class is a grouping of variables and methods (functions that
operate on those variables). The word object is often used to refer
to a class, but technically, a class is a description of an object and an
instance is an actual object.

You can define your own classes; Java includes many predefined ones. One such
class is String (or more precisely, java.lang.String), which
is used to store a constant string. Strings in Java are not just arrays of
charactersthey are a class that has defined methods for accessing and
modifying the characters.

The String class can serve as an example of how Java objects are
used. A String can be created from an array of characters, as
follows:

The expression new String(myArray) invokes what is called a
constructor for the class String. Constructors create a
new instance of an object, optionally taking parameters. How many parameters a
constructor takes, and the type and order of those parameters, are part of the
constructor's signature. Multiple constructors can exist for a given
class as long as they have different signatures. For example, another
constructor for String is called as follows:

String myString = new String(myArray, 2, 1);

That is, specifying an offset and count within myArray. You can
also call

String myString = new String();

This creates an empty string. (A String cannot be changed after
it's initialized, so it would stay empty.) The String class
actually has nine constructors, plus two more obsolete ones.

When Java sees a literal string in double quotes, it automatically creates a
String object, so you can write the following:

String newString = "text";

This is actually an assignment of one String to another. This
automatic creation of an object from a literal is unique to the String
class (all other literals, such as numbers, become primitive types), but it sure
is convenient.

No destructors exist in Java; objects are destroyed by the garbage
collector at some point after the last reference to them is removed (often
because the variables holding that reference go out of scope). A variable can be
assigned a keyword null to force a reference it is holding to be
removed:

anotherString = null;

However, the garbage collector makes no guarantees about how soon an object
will be destroyed once there are no references to it.

Java does not have explicit pointers; in a sense, all variables that refer to
objects are pointers. When you assign between two objects of the same type, you
actually assign a reference to the object on the right-hand side. To create a
new instance of an object, you need to call one of its constructors:

Classes define methods that can be called on an instance of that class. For
example, the String class has a method length() that returns
the length of the string:

String j = "abc123";
x = j.length();

As previously mentioned, a String cannot change after it's
initialized. Java has another class, StringBuffer, which holds strings
that can change. A StringBuffer can be constructed from a
String, or from a length, which specifies how many characters of
capacity it should start with:

In Java, the + operator can concatenate strings together. A sequence
such as the following

String greeting = "Hello";
greeting = greeting + " there";

is legal. Because the original String that greeting points
to cannot be modified, the concatenation actually involves the creation of a new
String, which greeting is then set to point to. Therefore, the
reference to the original "Hello" string is removed, which
eventually causes it to be destroyed.

TIP

The concatenation statement also involves some more behind-the-scenes magic
by the compiler. It creates a temporary StringBuffer, then calls the
StringBuffer.append() method for each expression separated by a
+ sign, then calls StringBuffer.toString() to convert it back
to the result String. As with the automatic creation of String
objects from constant strings, this is a special case on the part of Java, but
is there because string concatenation is so useful.

StringBuffer.append() is overloaded, so it can be passed any
primitive type. Thus, you can call the following

int j = 4;
String b = "Value is" + j;

and b will equal "Value is 4". In fact,
StringBuffer.append() works for any object by appending the result of
the object's toString() method, which can be overridden as needed
by the author of the object's class.

Arrays

Arrays in Java are declared with square brackets:

int[] intArray;

The array then has to be created:

intArray = new int[10];

intArray would then be indexed from 0 to 9.

Arrays can also be created at declaration time, if values are specified using
an array initializer:

int[] array2 = { 5, 4, 3, 2, 1 };

You can't explicitly specify the length in that case because it's
determined from how many values are provided.

You can get the number of elements in an array:

k = array2.length;

Note that this is not a method, so no parentheses appear after
length.

Arrays can also hold objects, so you can declare the following:

MyObject[] objarray;

This would then be created as follows (this could be combined with the
declaration):

objarray = new MyObject[5];

It is important to note that this creates only the array. You still need to
create the five objects:

for (k = 0; k < 5; k++) {
objarray[k] = new MyObject();
}

To create subarrays, create an array where each element is an array. The
first array can be declared and created in one step

int[][] bigArray = new int[6][];

and then each subarray needs to be created (each one can be a different
length, in fact):

for (m = 0; m < 6; m++) {
bigArray[m] = new int[20];
}

You can initialize arrays when they are declared:

short[][] shortArray = { { 1, 2, 3 }, { 4 }, { 5 , 6 } };

After that, shortArray[0] would be an array of three elements,
shortArray[1] would be an array of one element, and
shortArray[2] would be an array of two elements.

Finally, if the entries in the arrays are objects, they also have to be
constructed, as shown here:

a and b are member variables in the class. a is
defined with an access specifier of private, which means that it
is hidden from the view of external code. b is public, which
means that anyone can access it if they have an instance of MyClass.
For example

MyClass mc = new MyClass("hello");
String abc = mc.b;__// this is allowed, b is public
int def = mc.a;___// this is NOT allowed, a is private

We'll get back to access specifiers within the next few paragraphs. For
now, note that MyClass has two constructors, one of which takes an
int as a parameter, and the other takes a String (the second
one is the one called in the previous code sample). Both constructors initialize
a and b. Variables can also be initialized when they are
declared, so b could have been declared as follows:

public StringBuffer b = new StringBuffer();

Although, for this class, that would not be necessary because every
constructor initializes b.

Classes can also inherit from another class. A subclass inherits all the
state and behavior of its superclass (but not the constructors), although
it can override methods by providing new ones with the same name (unless those
methods were declared with the final keyword).

The access specifier of a class variable can be public,
private, protected, or package (the default).
public means that any code can access it; private means that
only methods in the class itself can access it; package means that any
code in the same "package" (which is a way to group classes) can
access it.

A variable marked protected can be accessed by the class,
subclasses, and all classes in the same package. Actually, to be more precise,
subclasses can only access a protected member inherited from a
superclass when the object is an instance of the subclass (which it usually will
be). They can't modify an instance of the superclass itself. (If you
didn't catch all that, don't worry too much about it.)

Members of a class (variables or methods) can be declared with the keyword
static, which makes them "class members," as opposed to
"instance members," which is the case that's been described so
far. Class variables and class methods exist just once, as opposed to once per
instance. For example, a class could assign unique identifiers to each instance
it creates, as shown here:

Each instance of the class has its own counter member, but there is
only one global nextcounter.

A method on a class can be declared abstract, which means that it
defines the parameters and return value, but has no actual implementation. A
class can also be declared abstract; this is required if it defines at
least one abstract method. (It is also required if a class does not provide
implementation for any abstract methods declared in its superclasses.) An
abstract class cannot itself be instantiatedit exists to ensure that
subclasses follow the "contract" that it defines.

Closely related to classes are interfaces. The main difference between an
interface and an abstract class is that all the methods on an interface
must be abstract:

public interface identify {
String getName();
}

Other classes can now support an interface using the implements
keyword. Unlike inheritance, where a class can only inherit from one class,
classes can implement as many interfaces as they like, as long as they provide
implementations of all the interfaces' methods (or are declared
abstract):

Java likely has a class for almost any standard operation you want to do; the
documentation lists constructors and methods. For example, classes exist that
wrap all the primitive types, such as this one that wraps the short primitive in
a class called Short (note the capital "S" on the class
name), and provides various useful methods:

Short s = new Short(12);
String str = s.toString();

I won't go into more details about specific classes, except as needed in
the examples.

A try can have multiple catch blocks, each catching a
different exception. (There is a hierarchy of exception classes, leading back to
a class called Throwable. A catch block that catches a
particular exception also catches any exceptions that are subclasses of that
exception.)

If an exception happens and is caught, the catch block executes. The
finally block always executes, whether or not an exception happens, and
is usually used for cleanup code.

You can create and throw exceptions:

if (bytesleft == 0) {
throw new EOFException();
}

Java requires that methods that can throw an exception specify it in the
declaration of the method, using the throws keyword:

Method declarations must also list any exceptions that can be thrown by
methods they call, unless they catch the exception. Thus, a method that called
read_file() (as defined above) would need to either put it in a
try block with an associated catch block that caught
IOException, or specify in its own declaration that it throws
IOException. (This "catch or specify" rule does not apply to
a class of exceptions known as runtime exceptions, which inherit from the class
RuntimeException. This rule is detailed in the Java documentation.)

Importing Other Code

To use a class, you must import the package that defines it. This is
specified in the documentation of the class. For example, to use the
Timer class, include the following in the code:

import java.util.Timer;

This can include a wildcard:

import java.util.*;

Command-Line Applications and Applets

The examples used in this chapter are split between command-line applications
and applets designed to run in a web browser. A command-line application has to
contain a class that implements a main()method, which must be defined
as publicstatic, return type void, and receive the
command-line parameters as an array of String objects called
args (the first element in args is the first parameter,
etc.):

The paint() method is overridden from a superclass a few levels up
from Applet, and is used to display on the screen. The
Graphics class has many methods used to draw lines and shapes, display
text, change color, and so on.