Chapter 7
Data Types and Other Tokens

by Joe Weber and Jay Cross

When working with computers, either for something as simple as writing a college paper or as complex as solving quantum theory equations, the single most important thing for the computer to do is deal with data. Data to a computer can be numbers, characters, or simply values. Java has several different types of data that it can work with, and this chapter covers some of the most important.

Java Has Two Types of Data Types

In Java, there are really two different categories in which data types have been divided:

Primitive types are discussed within this chapter. Reference types enclose things such as arrays, classes, and interfaces, which you get to later in this book.

Java has eight primitive types, each with its own purpose and use:

As you proceed through this chapter, I cover each of these types in detail. For now, take a look at Table 7.1, which shows the numerical limits each type has on it.

Table 7.1 Primitive Data Types in the Java Language
Type Description
Boolean These have values of either true or false.
byte 7-bit 2s-compliment integer with values between -27 and 27-1 (-128 to 127).
short 16-bit 2s-compliment integer with values between -215 and 215-1 (-32,768 to 32,767).
char 16-bit Unicode characters. For alphanumerics, these are the same as ASCII with the high byte set to 0. The numerical values are unsigned 16-bit values between 0 and 65535.
int 32-bit 2s-compliment integer with values between -231 and 231-1 (-2,147,483,648 to 2, 147,483,647).
long 64-bit 2s-compliment integer with values between -263 and 263-1 (-9223372036854775808 to 9223372036854775807).
float 32-bit single precision floating point numbers using the IEEE 754-1985 standard (+/- about 1039).
double 64-bit double precision floating point numbers using the IEEE 754-1985 standard (+/- about 10317).


Primitive types in Java are unique because, unlike many other languages, the values listed in Table 7.1 are always as shown here, regardless of what type of computer you are working on. This gives you, as a programmer, some added security and portability you might not always have in other languages.

Learning About Boolean Variables

The simplest data type that is available to you in Java is that of the Boolean. Boolean variables have two possible values--true or false. In some other languages, Booleans are 0 or 1. Or, as in C(++), false is 0 and all other numbers are true. Java has simplified this a bit, and the actual values are true and false.

Boolean variables are used mostly when you want to keep track of the state an object is in. For instance, a piece of paper is either on or off the table. So, a simple piece of code might be constructed that would say:

Boolean on_the_table = true;

Declaring a Variable

Before you go any further, let me first explain what the last line of code means. When you create a variable in Java, you must know at least a few things:

You can create any variable in Java in the same way as was just shown:

  1. State the data type that you will be using (Boolean).

  2. State the name the variable will be called (on_the_table).

  3. Assign the variable a value (= true).

  4. As with every other line of code in Java, terminate the line with a semicolon (;).

Identifiers--The Naming of a Variable

Refer to our first example:

Boolean on_the_table = true;

How does the computer work with the characters that make up on_the_table? on_the_table is called an identifier in programming lexicology. Identifiers are important because they are used to represent a whole host of things. In fact, identifiers are any phrases chosen by the programmer to represent variables, constants, classes, objects, labels, or methods. Once an identifier is created, it represents the same object in any other place it is used in the same code block.

There are several rules that must be obeyed when creating an identifier:

Table 7.2 shows several legal and illegal identifiers. The first illegal identifier is forbidden because it begins with a numeral. The second has an illegal character (&) in it. The third also has inappropriate character--the blank space. The fourth is a literal number (216) and cannot be used as an identifier. The last one contains yet another bad character--the hyphen, or minus sign. Java would try to treat this last case as an expression containing two identifiers and an operation to be performed on them.
Table 7.2 Examples of Legal and Illegal Identifiers
Legal Identifiers Illegal Identifiers
HelloWorld 9HelloWorld
counter count&add
HotJava$ Hot Java
ioc_Queue3 65536
ErnestLawrenceThayers non-plussed FamousPoemOfJune1888

Changing Boolean Variables

In Chapter 10, "Control Flow," you see how Boolean variables can be used to change the behavior of a program. For instance, if the paper is on the table, you do nothing, but if it has fallen onto the floor, you can tell the computer to pick it up.

There are two ways in which you can change a Boolean variable. Because Booleans are not represented by numbers, you must always set a Boolean to either true or false. The first way to do this is explicitly. For instance, if you have a variable called My_First_Boolean, to change this variable to false you would type:

My_First_Boolean = false;

If you compare this line to the declaration of on_the_table earlier, notice that they are very similar.

The next way to assign a Boolean variable is based on an equation or other variable. For instance, if you wanted My_First_Boolean to have the same value as on_the_table, you might type a line like this:

My_First_Boolean= on_the_table;

You can also make the variable have a value based on the equality of other numbers. For instance the following line would make My_First_Boolean false:

My_First_Boolean = 6>7;

Because 6 is not greater than 7, the equation on the right would evaluate to false. Later in Chapter 10, "Control Flow," you learn more about this type of equation.


NOTE: Boolean types are a new feature in Java, not found in C and C++. To some, this stricter adherence to typing may seem oppressive. On the other hand, pervasive ambiguity may be eliminated, which has resulted in countless lost man-hours from the world's intellectual workforce in the form of chasing many hard-to-detect programming errors.


The Various Flavors of Integer

The next set of primitive types in Java are all known as Integer types:

As you saw in Table 7.1, each of these types has a different limit to the numbers it can carry. For instance, a byte cannot hold any number that is greater than 127, but a long can easily hold the amount of the national debt. It can actually hold one million times that number.

There are different reasons to use each different type, and you should not just use a long for every variable just because it is the biggest. For one thing, it is unlikely that most of the programs you write will need to deal with numbers large enough to take advantage of the size of a long number. More importantly, large variables such as longs take up much more space in the computer's memory than do variables like short.

Limits on Integer Values

Integers can have values in the following ranges:
Integer Minimum Value Default Value Maximum Type Value
byte -128 (byte) 0 127
short -32,768 (short) 0 32,767
int -2,147,483,648 0 2,147,483,647
long -9,223,372,036,854,775,808 9,223,372,036,854,775,807
char 0 0 65535


NOTE: The maximum number for a long is enough to provide a unique ID for one transaction per second for every person on the planet for the next 50 years. It is also the number of grains in about a cubic mile of sand. Yet, if a project is undertaken to count the black flies in Maine, surely the cry will arise for 128-bit integers.

NOTE:
If some operation creates a number exceeding the ranges shown here, no overflow or exception is created. Instead, the 2s compliment value is the result. (For a byte, it's 127+1=-128, 127+9 =-120, and 127+127=-2.) However, an ArithmeticException is thrown if the right-hand operand in an integer divide or modulo operation is zero.


Creating Integer Variables

All of the main four integer types can be created in nearly the same way (you learn about char later in this chapter). The following lines show how to create a variable of each of these types:

byte My_First_Byte = 10;
short My_First_Short = 15;
int My_First_Int = 20;
long My_First_Long = 25;

Notice that the declaration of the integer types is nearly identical to that for the Boolean variable and that it is exactly the same for all integer types. The one main difference is that an integer variable must be assigned a number, not true or false. Also, notice that an integer must be assigned a whole number, not a fraction. In other words, if you want to have a number like 5.5 or 5 2/3, you cannot do so with an integer. You learn more about these types of numbers in the section "Floating-Point Variables" later in this chapter.

Operations on Integers

You can perform a wide variety of operations on integer variables. Table 7.3 shows a complete list.
Table 7.3 Operations on Integer Expressions
Operation Description
=, +=, -=, *=, /= Assignment operators
==, != Equality and inequality operators
<, <=, >, >= Inequality operators
+, - Unary sign operators
+, -, *, /, % Addition, subtraction, multiplication, division, and modulus operators
+=, -=, *=, /= Addition, subtraction, multiplication, division, and assign operators
++, -- Increment and decrement operators
<<, >>, >>> Bitwise shift operators
<<=, >>=, >>>= Bitwise shift and assign operators
~ Bitwise logical negation operator
&, |, ^ Bitwise AND, OR, and exclusive or (XOR) operators
&=, |=, ^= Bitwise AND, OR, and exclusive or (XOR) and assign operators


Later in Chapter 10, "Control Flow," you learn about the equality and inequality operators that produce Boolean results. For now, let's concentrate on the arithmetic operators.

Operators

Operators are used to change the value of a particular object. For instance, say you wanted to add or subtract 5 from 10. As you soon see, you would use the addition or subtraction operator. They are described here in several related categories. C and C++ programmers should find the operators in Table 7.3 to be very familiar.

Arithmetic Operators

Arithmetic operators are used to perform standard math operations on variables. These operators include:
+ addition operator
- subtraction operator
* multiplication operator
/ division operator
% modulus operator (gives the remainder of a division)
Probably the only operator in this list that you are not familiar with is the modulus operator. The modulus of an operation is the remainder of the operand divided by the operandi. In other words, in the equation 10 % 5, the remainder is 0 because 5 divides evenly into 5. However, the result of 11 % 5 is 1 because (if you can remember your early math classes), 11 divided by 5 is 2 R 1, or 2 remainder 1.

Listing 7.1 shows an example of these operators in use.

Listing 7.1 Examples Using Arithmetic Operators

int j = 60;         	// set the byte j's value to 60
int k = 24;
int l = 30;
int m = 12L;
int result = 0L;

result = j + k;          	// result gets 84: (60 plus 24)
result = result / m;          	// result gets 7: (84 divided by 12)
result = j - (2*k + result); 	// result gets 5: (60 minus (48 plus 7))
result = k % result;          	// result gets 4: (remainder 24 div by 5)

Assignment Operators

The simplest assignment operator is the standard assignment operator. This operator is often known as the gets operator, because the value on the left gets the value on the right.
= assignment operator
The arithmetic assignment operators provide a shortcut for assigning a value. When the previous value of a variable is a factor in determining the value that you want to assign, the arithmetic assignment operators are often more efficient:
+= add and assign operator
-= subtract and assign operator
*= multiply and assign operator
/= divide and assign operator
%= modulus and assign operator
Except for the assignment operator, the arithmetic assignment operators work as if the variable on the left of the operator were placed on the right. For instance, the following two lines are essentially the same:

x = x + 5;
x += 5;

Listing 7.2 shows more examples of the operators in use.

Listing 7.2Examples Using Arithmetic Assignment Operators

byte j = 60;                    // set the byte j's value to 60
short k = 24;
int l = 30;
long m = 12L;
long result = 0L;

result += j;                    // result gets 60: (0 plus 60)
result += k;                    // result gets 84: (60 plus 24)
result /= m;                    // result gets 7: (84 divided by 12)
result -= l;                    // result gets -23: (7 minus 30))
result = -result;               // result gets 23: (-(-23))
result %= m;                    // result gets 11: (remainder 23 div by 12)

Increment/Decrement Operators

The increment and decrement operators are used with one variable (they are known as unary operators):
++ increment operator
-- decrement operator
For instance, the increment operator (++) adds one to the operand, as shown in the next line of code:

x++;

is the same as

x+=1;

The increment and decrement operators behave slightly differently based on the side of the operand they are placed on. If the operand is placed before the operator (for example, ++x), the increment occurs before the value is taken for the expression. So, in the following code fragment, the result of y is 6:

int x=5;
int y=++x;       // y=6 x=6

If the operator appears after the operand, the addition occurs after the value is taken. So y is 5 as shown in the next code fragment. Notice that in both examples, x is 6 at the end of the fragment.

int x=5;
int y = x++;   //y=5 x=6

Similarly, the decrement operator (--) subtracts one from the operand, and the timing of this is in relation to the evaluation of the expression that it occurs in.

Character Variables

Characters in Java are a special set. They can be treated as either a 16-bit unsigned integer with a value from 0-65535, or as a Unicode character. The Unicode standard makes room for the use of many different languages' alphabets. The Latin alphabet, numerals, and punctuation have the same values as the ASCII character set (a set that is used on most PCs and with values between 0-256). The default value for a char variable is \u0000.

The syntax to create a character variable is the same as for integers and Booleans:

char myChar = `b';

In this example, the myChar variable has been assigned the value of the letter `b'. Notice the tick marks (`) around the letter b? These tell the compiler that you want the literal value of b rather than an identifier called b.

Floating-Point Variables

Floating-point numbers are the last category of native types in Java. Floating-point numbers are used to represent numbers that have a decimal point in them (such as 5.3 or 99.234). Whole numbers can also be represented, but as a floating point, number 5 is actually 5.0.

In Java, floating-point numbers are represented by the types float and double. Both of these follow a standard floating point specification: IEEE Standard for Binary Floating-Point Arithmetic, ANSI/IEEE Std. 754-1985 (IEEE, New York). The fact that these floating-point numbers follow this specification--no matter what machine the application or applet is running on--is one of the details that makes Java so portable. In other languages, floating-point operations are defined for the floating-point unit (FPU) of the particular machine the program is executing on. This means that the representation of 5.0 on an IBM PC is not the same as on, say, a DEC VAX, and the limits on both machines are as shown in the following table.

Floating-Point Minimum Value Default Value Maximum Type Value
float 1.40239846e-45f 0 3.40282347e+38f
double 4.94065645841246544e-324d 0 1.7976931348623157e+308d


In addition, there are four unique states that floating-point numbers can have:

These states are required due to how the 754-1985 standard works and to account for number roll-over. For instance, adding 1 to the maximum number of a floating point will result in a positive infinity result.

Many of the operations that can be done on integers have an analogous operation that can be done on floating-point numbers. The main exceptions are the bitwise operations. The operators that may be used in expressions of type, float, or double are given in Table 7.4.
Table 7.4 Operations on float and double Expressions
Operation Description
=, +=, -=, *=, /= Assignment operators
==, != Equality and inequality operators
<, <=, >, >= Inequality operators
+, - Unary sign operators
+, -, *, / Addition, subtraction, multiplication, and division operators
+=, -=, *=, /= Addition, subtraction, multiplication, and division and assign operators
++, -- Increment and decrement operators

Arrays

There are three types of reference variables:

Classes and interfaces are so complicated that each gets its own chapter, but arrays are comparatively simple and are covered here with the primitive types.

An array is simply a way to have several items in a row. If you have data that can be easily indexed, arrays are the perfect means to represent them. For instance, if you have five people in a class and you want to represent all of their IQs, an array would work perfectly. An example of such an array is:

int IQ[] = {123,109,156,142,131};

The next line shows an example of accessing the IQ of the third individual:

int ThirdPerson = IQ[3];

Arrays in Java are somewhat tricky. This is mostly because, unlike most other languages, there are really three steps to filling out an array, rather than one:

  1. Declare the array. There are two ways to do this: place a pair of brackets after the variable type, or place brackets after the identifier name. The following two lines produce the same result:

    int MyIntArray[];
    int[] MyIntArray;

  2. Create space for the array and define the size. To do this, you must use the keyword new, followed by the variable type and size:
MyIntArray = new int[500];
  1. Place data in the array. For arrays of native types (like those in this chapter), the array values are all set to 0 initially. The next line shows how to set the fifth element in the array:
MyIntArray[4] = 467;

At this point, you may be asking yourself how we were able to create the five-element array and declare the values with the IQ example. The IQ example took advantage of a shortcut. For native types only, you can declare the initial values of array by placing the values between braces ({,}) on the initial declaration line.

Array declarations are composed of the following parts:
Array modifiers Optional The keywords public, protected, private, or synchronized.
Type name Required The name of the type or class being arrayed.
Brackets Required [ ].
Initialization Optional For more details about initialization, see Chapter 11.
Semicolon Required ;


Listing 7.3 shows several more examples of using arrays.

Listing 7.3Examples of Declaring Arrays

long Primes[] = new long[1000000];     // Declare an array and assign
                                       // some memory to hold it.
long[] EvenPrimes = new long[1];       // Either way, it's an array.
EvenPrimes[0] = 2;                     // Populate the array.

// Now declare an array with an implied `new' and populate.

long Fibonacci[] = {1,1,2,3,5,8,13,21,34,55,89,144};

long Perfects[] = {6, 28};             // Creates two element array.

long BlackFlyNum[];                    // Declare an array.
                                       // Default value is null.

BlackFlyNum = new long[2147483647];    // Array indexes must be type int.

// Declare a two dimensional array and populate it.
long TowerOfHanoi[][]={{10,9,8,7,6,5,4,3,2,1},{},{}};
long[][][] ThreeDTicTacToe;            // Uninitialized 3D array.

There are several additional points about arrays you need to know:

Whitespace

Of some importance to most languages is the use of whitespace. Whitespace is any character that is used just to separate letters on a line, such as a space, tab, line feed, or carriage return.

In Java, whitespace can be declared anywhere within the application's source code without affecting the meaning of the code to the compiler. The only place that whitespace cannot be is between a token, such as a variable or class name. This may be obvious, because the following two lines are obviously not the same:


int myInt;
int my   Int;

Whitespace is optional, but because proper use of it has a big impact on the maintainability of the source code for an application or applet, its use is highly recommended. Let's take a look at the ever popular HelloWorld application written with minimal use of whitespace:

public class HelloWorld{public static void main(String  args[]){System.out.println("Hello World!!");}}

Clearly, it is a little harder to ferret out what this application does, or even that you have started at the beginning and finished at the end. Choose a scheme for applying meaningful whitespace, and follow it. Then you stand a better chance of knowing which close curly brace (}) matches which open curly brace ({).

Comments

Comments are an important part of any language. Comments enable you to leave a message for other programmers (or yourself) as a reminder of what is going on in that particular section of code. They are not tokens and neither are any of their contents.

Java supports three styles of comments:

Traditional Comments

A traditional comment is a C-style comment that begins with a slash-star (/*) and ends with a star-slash (*/). Take a look at Listing 7.4, which shows two traditional comments.

Listing 7.4Example Containing Two Traditional Comments

/* The following is a code fragment
 * that is here only for the purpose
 * of demonstrating a style of comment.
 */
double pi = 3.141592654  /* close enough for now */ ;

As you can see, comments of this sort can span many lines or be contained within a single line (outside of a token). Comments cannot be nested. Thus, if you try to nest them, the opening of the inner one is not detected by the compiler, the closing of the inner one ends the comment, and subsequent text is interpreted as tokens. Listing 7.5 shows how this can become very confusing.

Listing 7.5 An Example of a Single Comment that Looks Like Two

/* This opens the comment
/* That looked like it opened another comment but it is the same one
 * This will close the entire comment                                            */

C++ Style Comments

The second style of comment begins with a slash-slash (//) and ends when the current source code line ends. These comments are especially useful for describing the intended meaning of the current line of code. Listing 7.6 demonstrates the use of this style of comment.

Listing 7.6 An Example Using Traditional and C++ Style Comments

for (int j = 0, Boolean Bad = false;   	// initialize outer loop
j < MAX_ROW;               	// repeat for all rows
j++) {
     for (int k = 0;          	// initialize inner loop
     k < MAX_COL;               	// repeat for all columns
     k++) {
          if (NumeralArray[j][k] > `9') {     	// > highest numeric?
               Bad = true;          	// mark bad
          } /* close if > `9' */
          if (NumeralArray[j][k] < `0') {     	// < lowest numeric?
               Bad = true;          	// mark bad
          } /* close if < `0' */
     } /* close inner loop */
} /* close outer loop */

javadoc Comments

The final style of comment in Java is a special case of the first. It has the properties mentioned previously, but the contents of the comment may be used in automatically generated documentation by the javadoc tool.


CAUTION:
Avoid inadvertent use of this style if you plan to use javadoc. The javadoc program will not be able to tell the difference.




javadoc comments are opened with /**, and they are closed with */. By using these comments in an appropriate manner, you will be able to use javadoc to automatically create documentation pages similar to those of the ava API. Listing 7.7 shows a javadoc comment.

Listing 7.7 An Example of a javadoc Comment

/** This class is for processing databases
  * Example use:
  *  xdb myDB = new xdb (myDbFile);
  *  System.out.println(xdb.showAll()); */

Literals--Assigning Values

When you learned about assigning a Boolean variable, there were only two possible values: true and false. For integers, the values are nearly endless. In addition, there are many ways an integer value can be represented, using literals. Note that literals are important, but generally dry material, so you may want to skip this section for now.

The easiest way to assign a value to an integer value is with its traditional Roman numeral:

int j = 3;

However, what happens when you want to assign a number that is represented in a different form, such as hexadecimal? In order to tell the computer that you are giving it a hexadecimal number, you need to use the hexadecimal literal. For a number like 3, this doesn't make much difference, but consider the number 11. Represented in hexadecimal (0x11), it has a value of 16! Certainly, you need a way to make sure the computer gets this right.

The following statements all contain various literals:

int j=0;
long GrainOfSandOnTheBeachNum=1L;
short Mask1=0x007f;
static String FirstName = "Ernest";
static Char TibetanNine = `\u1049'
Boolean UniverseWillExpandForever = true;

Clearly, there are several different types of literals. In fact, there are five major types of literals in the Java language:

Integer Literals

Integer literals are used to represent numbers of integer types. Because integers can be expressed as decimal (base 10), octal (base 8), or hexadecimal (base 16) numbers, each has its own literal. In addition, integer numbers can be represented with an optional uppercase L (`L') or lowercase L (`l') at the end, which tells the computer to treat that number as a long (64-bit) integer.

As with C and C++, Java identifies decimal integer literals as any number beginning with a non-zero digit (for example, any number between 1 and 9). Octal integer literal tokens are recognized by the leading zero (so 045 is the same as 37 decimal); they may not contain the numerals 8 or 9. Hexadecimal integer literal tokens are known by their distinctive `zero-X' at the beginning of the token. Hex numbers are composed of the numerals 0-9--plus the Latin letters A-F (case is not important).

The largest and smallest values for integer literals are shown below in each of these three formats:
Largest 32-bit integer literal 2147483647
  017777777777
  0x7fffffff
Most negative 32-bit integer -2147483648 literal
  020000000000
  0x80000000
Largest 64-bit integer literal 9223372036854775807L
  0777777777777777777777L
  0x7fffffffffffffffL
Most negative 64-bit integer 9223372036854775808L literal
  01777777777777777777777L
  0xffffffffffffffffL


CAUTION:
Attempts to represent integers outside the range shown in this table will result in compile-time errors.


Character Literals

Character literals are enclosed in single quotes. This is true whether the character value is Latin alphanumeric, an escape sequence, or any other Unicode character. Single characters are any printable character except hyphen (-) or backslash (\). Some examples of these literals are `a', `A', `9', `+', `_', and `~'.

Some characters, such as the backspace, would be difficult to write out like this, so to solve this problem, these characters are represented by what are called escape characters. The escape sequence character literals are in the form of `\b'. These are found within single quotes--a backslash followed by one of the following:

The Escape characters are shown in Table 7.5.
Table 7.5 Escape Characters
Escape Literal Meaning
`\b' \u0008 backspace
`\t' \u0009 horizontal tab
`\n' \u000a linefeed
`\f' \u000c form feed
`\r' \u000d carriage return
`\"' \u0022 double quote
`\'' \u0027 single quote
`\\' \u005c backslash


CAUTION:
Don't use the \u format to express an end-of-line character. Use the \n or \r characters instead.




Character literals mentioned in Table 7.4 are called octal escape literals. They can be used to represent any Unicode value from `\u0000' to `\u00ff' (the traditional ASCII range). In octal (base 8), these values are from \000 to \377. Note that octal numerals are from 0-7 inclusive. The following table shows some examples of octal literals:
Octal Literal Meaning
`\007' \u0007 bell
`\101' \u0041 `A'
`\141' \u0061 `a'
`\071' \u0039 `9'
`\042' \u0022 double quote


CAUTION:
Character literals of the type in the previous table are interpreted very early by javac. As a result, using the escape Unicode literals to express a line termination character--such as carriage return or line feed--results in an end-of-line appearing before the terminal single quote mark. The result is a compile-time error. Examples of this type of character literal appear in the meanings heading listed in the previous table.


Floating-Point Literals

Floating-point numbers can be represented in a number of ways. The following are all legitimate floating point numbers:
1003.45 .00100345e6 100.345E+1100345e-2
1.00345e3 0.00100345e+6
Floating-point literals have several parts, which appear in the following order as shown in Table 7.6.
Table 7.6 Floating-Point Requirements
Part Is It Required? Examples
Whole Not if fractional part is present. 0, 1, 2, ..., 9, Number Part 12345
Decimal Point Not if exponent is present. Must be there if there is a fractional part.
Fractional Can't be present if there is no decimal point. Must be there if there is no whole number part. 0, 1, 14159, 718281828, 41421, 9944 Part
Exponent Only if there is no decimal point. e23, E-19, E6, e+307, e-1
Type Suffix No. In the absence of a type suffix, the number is assumed to be double precision. f, F, d, D


Note that the whole number part does not have to be a single numeral; case is not important for the E which starts the exponent, or for the F or D which indicate the type. As a result, a given number can be represented in several different ways as a literal:

String Literals

Strings are not really native types. However, to finish the discussion of literals, it is also necessary to talk about them. String literals have zero or more characters enclosed in double quotes. These characters may include the escape sequences listed in the section "Character Literals" earlier in this chapter. Both double quotes must appear on the same line of the source code, so strings may not directly contain a newline character. To achieve the new line effect, you must use an escape sequence such as \n or \r.

The double-quote (") and backslash (\) characters must also be represented using the escape sequences (\" and \\).

One nice feature Java inherits from C++ is that if you need to use a longer string, a string may be created from concatenating two or more smaller strings with the string concatenation operator (+).


CAUTION:
While it is often convenient to use the + operator for strings, unfortunately the current implementation of the String class isn't very efficient. As a result, doing lots of string concatenations can waste memory resources.


Some examples of string literals are:

"Java"



"Hello World!\n"



"The Devanagari numeral for 9 is \u096f "



"Do you mean the European Swallow or the African Swallow?"



"****ERROR 9912 Date/Time 1/1/1900 00:01"



   + " predates last backup: all files deleted!"



"If this were an actual emergency"

Creating and Destroying Objects

Memory management is a topic that is very important to all computer languages. Whenever you create a new instance of a class, the Java runtime system sets aside a portion of memory in which to store the information pertaining to the class. However, when the object falls out of scope, or is no longer needed by the program, this portion of memory is freed to be used again by other objects.

While Java hides most of these operations from the programmer, it does provide you with some chances to optimize your code by performing certain additional tasks. While requiring you to allocate memory explicitly for each new object with the new operator, it also enables you to specialize your new object (by using its constructor methods) and ensures that it leaves no loose ends when it is destroyed.


NOTE: Unlike C and C++, which provide the programmer with a great deal of control over memory management, Java performs many of these tasks for you. Most notably, in its aptly called "garbage collection," Java automatically frees objects when there are no references to the given object, thereby making the C++ free() method unnecessary.


Creating Objects with the new Operator

When creating an instance of a class, it is necessary to set aside a piece of memory to store its data. However, when you declare the instance at the beginning of a class, you are merely telling the compiler that a variable with a certain name will be used in the class, not to actually allocate memory for it. Consequently, it is necessary to create the memory for the variable using the new operator. Examine the following code:

public class Checkers
{
     private GameBoard board;
     public Checkers() {
          board = new GameBoard("Checkers");
          board.cleanBoard();
          }
    ...

You see that although the variable board is declared in the third line, you must also allocate memory for it using the new operator. The syntax of a statement involving the new operator is:

instanceofClass = new ClassName(optional_parameters);

Quite simply, the line tells the compiler to allocate memory for an instance of the class and points variable to the new section of memory. In the process of doing this, the compiler also calls the class's constructor method and passes the appropriate parameters to it.


Pointers: Fact or Fiction?
Java claims not to possess pointers and, as a result, prevents the programmer from making some of the mistakes associated with pointer handling. Nevertheless, while it chooses not to adopt the pointer-based mindset, Java is forced to deal with the same issues of allocating memory and creating references to these locations in memory. Thus, while assigned a different name, references are Java's version of pointers. Although you cannot perform some of the intrusive operations with pointers as you can with C, there are striking parallels between pointer assignment and object creation. You must first declare a variable (the reference). Then you must allocate adequate memory and assign the reference to it. Furthermore, because you may later decide to set a reference equal to another type of the same variable (or null), Java's reference system is extremely similar to C's system of pointers.


While Java's implementation effectively hides the behavior of pointers from the programmer and shields you from their pitfalls, it is nevertheless a good idea to consider what is occurring behind the scenes when you create and refer to a variable.