Skip to main content.

Web Based Programming Tutorials

Homepage | Forum - Join the forum to discuss anything related to programming! | Programming Resources

Java Unleashed Second Edition

Chapter 6 -- Java Language Fundamentals

Chapter 6

Java Language Fundamentals

by Michael Morrison


CONTENTS


Java is an object-oriented language. This means that the language is based on the concept of an object. Although a knowledge of object-oriented programming is necessary to put Java to practical use, it isn't required to understand the fundamentals of the Java language. This chapter focuses on the language and leaves the object-oriented details of Java for Chapter 8, "Classes, Packages, and Interfaces."

If you already have some experience with another object-oriented language such as C++ or Smalltalk, much of Java will be familiar territory. In fact, you can almost consider Java a new, revamped C++. Because Java evolved from C++, many of the similarities and differences between Java and C++ will be highlighted throughout the next few chapters. Additionally, Appendix D provides a more thorough look at the differences between Java and C++.

This chapter covers the essentials of the Java language, including a few sample programs to help you hit the ground running.

Hello, World!

The best way to learn a programming language is to jump right in and see how a real program works. In keeping with a traditional introductory programming example, your first program is a Java version of the classic "Hello, World!" program. Listing 6.1 contains the source code for the HelloWorld class, which also is located on the CD-ROM that accompanies this book in the file HelloWorld.java.


Listing 6.1. The by Michael Morrison HelloWorld class.

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

After compiling the program with the Java compiler (javac), you are ready to run it in the Java interpreter. The Java compiler places the executable output in a file called HelloWorld.class. This naming convention might seem strange considering that most programming languages use the .EXE file extension for executables. Not so in Java! Following the object-oriented nature of Java, all Java programs are stored as Java classes that are created and executed as objects in the Java runtime environment. To run the HelloWorld program, type java HelloWorld at the command prompt. As you may have guessed, the program responds by displaying Hello, World! on your screen. Congratulations! You just wrote and tested your first Java program!

Obviously, HelloWorld is a very minimal Java program. Even so, there's still a lot happening in those few lines of code. To fully understand what is happening, let's examine the program line by line. First, you must understand that Java relies heavily on classes. In fact, the first statement of HelloWorld reminds you that HelloWorld is a class, not just a program. Furthermore, by looking at the class statement in its entirety, you can see that the name of the class is defined as HelloWorld. This name is used by the Java compiler as the name of the executable output class. The Java compiler creates an executable class file for each class defined in a Java source file. If there is more than one class defined in a .java file, the Java compiler stores each class in a separate .class file.

The HelloWorld class contains one method, or member function. For now, you can think of this function as a normal procedural function that happens to be linked to the class. The details of methods are covered in Chapter 8, "Classes, Packages, and Interfaces." The single method in the HelloWorld class is called main(), and should be familiar if you have used C or C++. The main() method is where execution begins when the class is executed in the Java interpreter. The main() method is defined as being public static with a void return type. public means that the method can be called from anywhere inside or outside the class. static means that the method is the same for all instances of the class. The void return type means that main() does not return a value.

The main() method is defined as taking a single parameter, String args[]. args is an array of String objects that represents command-line arguments passed to the class at execution. Because HelloWorld doesn't use any command-line arguments, you can ignore the args parameter. You learn a little more about strings later in this chapter.

The main() method is called when the HelloWorld class is executed. main() consists of a single statement that prints the message Hello, World! to the standard output stream, as follows:

System.out.println("Hello, World!");

This statement may look a little confusing at first because of the nested objects. To help make things clearer, examine the statement from right to left. First, notice that the statement ends in a semicolon, which is standard Java syntax borrowed from C/C++. Moving to the left, you see that the "Hello, World!" string is in parentheses, which means it is a parameter to a function call. The method being called is actually the println method of the out object. The println method is similar to the printf method in C, except that it automatically appends a newline (\n) at the end of the string. The out object is a member variable of the System object that represents the standard output stream. Finally, the System object is a global object in the Java environment that encapsulates system functionality.

That pretty well covers the HelloWorld class-your first Java program. If you got lost a little in the explanation of the HelloWorld class, don't be too concerned. HelloWorld was presented with no previous explanation of the Java language and was only meant to get your feet wet with Java code. The rest of this chapter focuses on a more structured discussion of the fundamentals of the Java language.

Tokens

When you submit a Java program to the Java compiler, the compiler parses the text and extracts individual tokens. A token is the smallest element of a program that is meaningful to the compiler. (Actually, this definition is true for all compilers, not just the Java compiler.) These tokens define the structure of the Java language. All the tokens that comprise Java are known as the Java token set. Java tokens can be broken into five categories: identifiers, keywords, literals, operators, and separators. The Java compiler also recognizes and subsequently removes comments and whitespaces.

The Java compiler removes all comments and whitespaces while tokenizing the source file. The resulting tokens are then compiled into machine-independent Java bytecode capable of being run from within an interpreted Java environment. The bytecode conforms to the hypothetical Java virtual machine, which abstracts processor differences into a single virtual processor. For more information on the Java virtual machine, check out Chapter 34, "Java Under the Hood: Inside the Virtual Machine." Keep in mind that an interpreted Java environment can be either the Java command-line interpreter or a Java-capable browser.

Identifiers

Identifiers are tokens that represent names. These names can be assigned to variables, methods, and classes to uniquely identify them to the compiler and give them meaningful names for the programmer. HelloWorld is an identifier that assigns the name HelloWorld to the class residing in the HelloWorld.java source file developed earlier.

Although you can be creative in naming identifiers in Java, there are some limitations. All Java identifiers are case sensitive and must begin with a letter, an underscore (_), or a dollar sign ($). Letters include both uppercase and lowercase letters. Subsequent identifier characters can include the numbers 0 to 9. The only other limitation to identifier names is that the Java keywords, which are listed in the next section, cannot be used. Table 6.1 contains a list of valid and invalid identifier names.

Table 6.1. Valid and invalid Java identifiers.

ValidInvalid
HelloWorld Hello World (uses a space)
Hi_Mom Hi Mom! (uses a space and punctuation mark)
heyDude3 3heyDude (begins with a numeral)
tall short (this is a Java keyword)
poundage #age (does not begin with letter)

In addition to the mentioned restrictions of naming Java identifiers, you should follow a few stylistic rules to make Java programming easier and more consistent. It is standard Java practice to name multiple-word identifiers in lowercase except for the beginning letter of words in the middle of the name. For example, the variable toughGuy is in correct Java style; the variables toughguy, ToughGuy, and TOUGHGUY are all in violation of this style rule. The rule isn't etched in stone-it's just a good rule to follow because most other Java code you run into follows this style.

Another more critical naming issue regards the use of underscore and dollar-sign characters at the beginning of identifier names. Using either of these characters at the beginning of identifier names is a little risky because many C libraries use the same naming convention for libraries, which can be imported into your Java code. To eliminate the potential problem of name-clashing in these instances, it's better to stay away from the underscore and dollar-sign characters at the beginning of your identifier names. A good use of the underscore character is to use it to separate words where you normally would use a space (Hi_Mom).

Keywords

Keywords are predefined identifiers reserved by Java for a specific purpose and are used only in a limited, specified manner. Java has a richer set of keywords than C or C++, so if you are learning Java with a C/C++ background, be sure to pay attention to the Java keywords. The following keywords are reserved for Java:

abstract double int super
boolean else interface switch
break extends longsynchronized
byte false native this
byvalue final new threadsafe
case finally nullthrow
catch float package transient
char forprivate true
class gotoprotected try
const ifpublic void
continue implements return while
default import short  
do instanceof static  

Literals

Program elements used in an invariant manner are called literals or constants. Literals can be numbers, characters, or strings. Numeric literals include integers, floating-point numbers, and booleans. Booleans are considered numeric because of the C influence on Java. In C, the boolean values for true and false are represented by 1 and 0. Character literals always refer to a single Unicode character. Strings, which contain multiple characters, are still considered literals even though they are implemented in Java as objects.

Note
If you aren't familiar with the Unicode character set, you should know that it is a 16-bit character set that replaces the ASCII character set. Because it is a 16-bit character set, there are enough entries to represent many symbols and characters from other languages. Unicode is quickly becoming the standard for modern operating systems.

Integer Literals

Integer literals are the primary literals used in Java programming. They come in a few different formats: decimal, hexadecimal, and octal. These formats correspond to the base of the number system used by the literal. Decimal (base 10) literals appear as ordinary numbers with no special notation. Hexadecimal numbers (base 16) appear with a leading 0x or 0X, similar to the way they do in C/C++. Octal (base 8) numbers appear with a leading 0 in front of the digits. For example, an integer literal for the decimal number 12 is represented in Java as 12 in decimal, 0xC in hexadecimal, and 014 in octal.

Integer literals default to being stored in the int type, which is a signed 32-bit value. If you are working with very large numbers, you can force an integer literal to be stored in the long type by appending an l or L to the end of the number, as in 79L. The long type is a signed 64-bit value.

Floating-Point Literals

Floating-point literals represent decimal numbers with fractional parts, such as 3.142. They can be expressed in either standard or scientific notation, meaning that the number 563.84 also can be expressed as 5.6384e2.

Unlike integer literals, floating-point literals default to the double type, which is a 64-bit value. You have the option of using the smaller 32-bit float type if you know the full 64 bits are not required. You do this by appending an f or F to the end of the number, as in 5.6384e2f. If you are a stickler for details, you also can explicitly state that you want a double type as the storage unit for your literal, as in 3.142d. But because the default storage for floating-point numbers is double already, this addition isn't necessary.

Boolean Literals

Boolean literals are certainly welcome if you are coming from the world of C/C++. In C, there is no boolean type, and therefore no boolean literals. The boolean values true and false are represented by the integer values 1 and 0. Java fixes this problem by providing a boolean type with two possible states: true and false. Not surprisingly, these states are represented in the Java language by the keywords true and false.

Boolean literals are used in Java programming about as often as integer literals because they are present in almost every type of control structure. Any time you need to represent a condition or state with two possible values, a boolean is what you need. You learn a little more about the boolean type later in this chapter. For now, just remember the two boolean literal values: true and false.

Character Literals

Character literals represent a single Unicode character and appear within a pair of single quotation marks. Similar to C/C++, special characters (control characters and characters that cannot be printed) are represented by a backslash (\) followed by the character code. A good example of a special character is \n, which forces the output to a new line when printed. Table 6.2 shows the special characters supported by Java.

Table 6.2. Special characters supported by Java.

Description
Representation
Backslash
\\
Continuation
\
Backspace
\b
Carriage return
\r
Form feed
\f
Horizontal tab
\t
Newline
\n
Single quote
\'
Double quote
\"
Unicode character
\udddd
Octal character
\ddd

An example of a Unicode character literal is \u0048, which is a hexadecimal representation of the character H. This same character is represented in octal as \110.

Note
To find out more information about the Unicode character set, check out the Unicode home page at this URL:
Http://www.unicode.org

String Literals

String literals represent multiple characters and appear within a pair of double quotation marks. Unlike all the other literals discussed in this chapter, string literals are implemented in Java by the String class. This arrangement is very different from the C/C++ representation of strings as an array of characters.

When Java encounters a string literal, it creates an instance of the String class and sets its state to the characters appearing within the double quotes. From a usage perspective, the fact that Java implements strings as objects is relatively unimportant. However, it is worth mentioning at this point because it is a reminder that Java is very object oriented in nature-much more so than C++, which is widely considered the current object-oriented programming standard.

Operators

Operators, also known as operands, specify an evaluation or computation to be performed on a data object or objects. These operands can be literals, variables, or function return types. The operators supported by Java follow:

+
-
*
/
%
&
|
^
~
&&
||
!
<
>
<=
>=
<<
>>
>>>
=
?
++
--
==
+=
-=
*=
/=
%=
&=
|=
^=
!=
<<=
>>=
>>>=
.
[
]
(
)
 

Just seeing these operators probably doesn't help you a lot in determining how to use them. Don't worry-you'll learn a lot more about operators and how they are used in the next chapter, "Expressions, Operators, and Control Structures."

Separators

Separators are used to inform the Java compiler of how things are grouped in the code. For example, items in a list are separated by commas much like lists of items in a sentence. Java separators go far beyond commas, however, as you discover in the next chapter. The separators supported by Java follow:

{      } ;       ,       :

Comments and Whitespaces

Earlier in this chapter, you learned that comments and whitespaces are removed by the Java compiler during the tokenization of the source code. You might be wondering, "What qualifies as whitespace and how are comments supported?" First, whitespace consists of spaces, tabs, and linefeeds. All occurrences of spaces, tabs, or linefeeds are removed by the Java compiler, as are comments. Comments can be defined in three different ways, as shown in Table 6.3.

Table 6.3. Types of comments supported by Java.

TypeUsage
/* comment */ All characters between /* and */ are ignored.
// comment All characters after the // up to the end of the line are ignored.
/** comment */ Same as /* */, except that the comment can be used with the javadoc tool to create automatic documentation.

The first type of comment (/* comment */) should be familiar if you have programmed in C before. All characters inside the /* and */ comment delimiters are ignored by the compiler. The second type of comment (// comment) should also be familiar if you have used C++. All characters appearing after the // comment delimiter up to the end of the line are ignored by the compiler. These two comment types are borrowed from C and C++. The final comment type (/** comment */) works in the same fashion as the C-style comment type, with the additional benefit that it can be used with the Java documentation generator tool, javadoc, to create automatic documentation from the source code. The javadoc tool is covered in Chapter 29, "Documenting Your Code." Following are a few examples of using the various types of comments:

/* This is a C style comment. */
// This is a C++ style comment.
/** This is a javadoc style comment. */

Data Types

One of the fundamental concepts of any programming language is data types. Data types define the storage methods available for representing information, along with how the information is interpreted. Data types are linked tightly to the storage of variables in memory because the data type of a variable determines how the compiler interprets the contents of the memory. You already have received a little taste of data types in the discussion of literal types.

To create a variable in memory, you must declare it by providing the type of the variable as well as an identifier that uniquely identifies the variable. The syntax of the Java declaration statement for variables follows:

Type Identifier [, Identifier];

The declaration statement tells the compiler to set aside memory for a variable of type Type with the name Identifier. The optional bracketed Identifier indicates that you can make multiple declarations of the same type by separating them with commas. Finally, as in all Java statements, the declaration statement ends with a semicolon.

Java data types can be divided into two categories: simple and composite. Simple data types are core types not derived from any other types. Integer, floating-point, boolean, and character types are all simple types. Composite types, on the other hand, are based on simple types and include strings, arrays, and both classes and interfaces in general. You learn about arrays later in this chapter. Classes and interfaces are covered in Chapter 8, "Classes, Packages, and Interfaces."

Integer Data Types

Integer data types are used to represent signed integer numbers. There are four integer types: byte, short, int, and long. Each of these types takes up a different amount of space in memory, as shown in Table 6.4.

Table 6.4. Java integer types.

TypeSize
byte 8 bits
short 16 bits
int 32 bits
long 64 bits

To declare variables using the integer types, use the declaration syntax mentioned previously with the desired type. Following are some examples of declaring integer variables:

int i;
short rocketFuel;
long angle, magnitude;
byte red, green, blue;

Floating-Point Data Types

Floating-point data types are used to represent numbers with fractional parts. There are two floating-point types: float and double. The float type reserves storage for a 32-bit single-precision number and the double type reserves storage for a 64-bit double-precision number.

Declaring floating-point variables is very similar to declaring integer variables. Following are some examples of floating-point variable declarations:

float temperature;
double windSpeed, barometricPressure;

Boolean Data Type

The boolean data type (boolean) is used to store values with one of two states: true or false. You can think of the boolean type as a 1-bit integer value (because 1 bit can have only two possible values: 1 or 0). However, instead of using 1 and 0, you use the Java keywords true and false. true and false aren't just conveniences in Java; they are actually the only legal boolean values. This means that you can't interchangeably use booleans and integers as you can in C/C++. To declare a boolean value, just use the boolean type declaration:

boolean gameOver;

Character Data Type

The character data type is used to store single Unicode characters. Because the Unicode character set is composed of 16-bit values, the char data type is stored as a 16-bit unsigned integer. You create variables of type char as follows:

char firstInitial, lastInitial;

Remember that the char type is useful only for storing single characters. If you come from a C/C++ background, you may be tempted to fashion a string by creating an array of chars. In Java, this isn't necessary because the String class takes care of handling strings. This doesn't mean that you should never create arrays of characters, it just means that you shouldn't use a character array when you really want a string. C and C++ do not distinguish between character arrays and strings, but Java does.

Casting Types

Inevitably, there will be times when you have to convert from one data type to another. The process of converting one data type to another is called casting. Casting is often necessary when a function returns a type different than the type you need to perform an operation. For example, the read member function of the standard input stream (System.in) returns an int. You must cast the returned int type to a char type before storing it, as in the following:

char c = (char)System.in.read();

The cast is performed by placing the desired type in parentheses to the left of the value to be converted. The System.in.read function call returns an int value, which then is cast to a char value because of the (char) cast. The resulting char value is then stored in the char variable c.

Caution
The storage size of the types you are attempting to cast is very important. Not all types can be safely cast to other types. To understand this, consider the outcome of casting a long to an int. A long is a 64-bit value and an int is a 32-bit value. When casting a long to an int, the compiler chops off the upper 32 bits of the long value so that it will fit into the 32-bit int. If the upper 32 bits of the long contain any useful information, that information will be lost and the number will change as a result of the cast. Information loss can also occur when you cast between different fundamental types, such as integer and floating-point numbers. For example, casting a double to a long results in the loss of the fractional information, even though both numbers are 64-bit values.

When casting, the destination type should always be equal to or larger in size than the source type. Furthermore, you should pay close attention to casting across fundamental types, such as from floating-point to integer types. Table 6.5 lists the casts that are guaranteed to result in no loss of information.

Table 6.5. Casts that result in no loss of information.

From Type
To Type
byte short, char, int, long, float, double
short int, long, float, double
char int, long, float, double
int long, float, double
long float, double
float double

Blocks and Scope

In Java, source code is broken into parts separated by opening and closing curly braces: { and }. Everything between curly braces is considered a block and exists more or less independently of everything outside of the braces. Blocks aren't important just from a logical sense-they are required as part of the syntax of the Java language. If you don't use braces, the compiler will have trouble determining where one section of code ends and the next section begins. From a purely aesthetic viewpoint, it would be very difficult for someone else reading your code to understand what was going on without the braces. For that matter, it wouldn't be very easy for you to understand your own code without the braces!

Braces are used to group related statements together. You can think of everything between matching braces as being executed as one statement. In fact, from an outer block, that's exactly what an inner block appears like: a single statement. But what's a block? A block is simply a section of code. Blocks are organized in a hierarchical fashion, meaning that code can be divided into individual blocks nested under other blocks. One block can contain one or more nested subblocks.

It is standard Java programming style to identify different blocks with indentation. Every time you enter a new block, you should indent your source code by a number of spaces-preferably two. When you leave a block, you should move back, or deindent, two spaces. This is a fairly established convention in many programming languages. However, indentation is just a style issue and is not technically part of the language. The compiler produces identical output even if you don't indent anything. Indentation is used for the programmer, not the compiler; it simply makes the code easier to follow and understand. Following is an example of the proper indentation of blocks in Java:

for (int i = 0; i < 5; i++) {
  if (i < 3) {
    System.out.println(i);
  }
}

Following is the same code without any block indentations:

for (int i = 0; i < 5; i++) {
if (i < 3) {
System.out.println(i);
}
}

The first code listing clearly shows the breakdown of program flow through the use of indentation; it is obvious that the if statement is nested within the for loop. The second code listing, on the other hand, provides no visual cues about the relationship between the blocks of code. Don't worry if you don't know anything about if statements and for loops; you'll learn plenty about them in the next chapter, "Expressions, Operators, and Control Structures."

The concept of scope is tightly linked to blocks and is very important when working with variables in Java. Scope refers to how sections of a program (blocks) affect the lifetime of variables. Every variable declared in a program has an associated scope, meaning that the variable is used only in that particular part of the program.

Scope is determined by blocks. To better understand blocks, take a look again at the HelloWorld class in Listing 6.1, earlier in this chapter. The HelloWorld class is composed of two blocks. The outer block of the program is the block defining the HelloWorld class:

class HelloWorld {
...
}

Class blocks are very important in Java. Almost everything of interest is either a class itself or belongs to a class. For example, methods are defined inside the classes they belong to. Both syntactically and logically, everything in Java takes place inside a class. Getting back to HelloWorld, the inner block defines the code within the main() method, as follows:

public static void main (String args[]) {
...
  }

The inner block is considered to be nested within the outer block of the program. Any variables defined in the inner block are local to that block and are not visible to the outer block; the scope of the variables is defined as the inner block.

To get an even better idea behind the usage of scope and blocks, take a look at the HowdyWorld class in Listing 6.2.


Listing 6.2. The HowdyWorld class.

class HowdyWorld {
  public static void main (String args[]) {
    int i;
    printMessage();
  }
  public static void printMessage () {
    int j;
    System.out.println("Howdy, World!");
  }
}

The HowdyWorld class contains two methods: main() and printMessage(). main() should be familiar to you from the HelloWorld class, except that in this case, it declares an integer variable i and calls the printMessage() method. printMessage() is a new method that declares an integer variable j and prints the message Howdy, World! to the standard output stream, much like the main() method did in HelloWorld.

You've probably figured out already that HowdyWorld results in basically the same output as HelloWorld because the call to printMessage() results in a single text message being displayed. What you may not see right off is the scope of the integers defined in each method. The integer i defined in main() has a scope limited to the body of the main() method. The body of main() is defined by the curly braces around the method (the method block). Similarly, the integer j has a scope limited to the body of the printMessage() method. The importance of the scope of these two variables is that the variables aren't visible beyond their respective scopes; the HowdyWorld class block knows nothing about the two integers. Furthermore, main() doesn't know anything about j, and printMessage() knows nothing about i.

Scope becomes more important when you start nesting blocks of code within other blocks. The GoodbyeWorld class shown in Listing 6.3 is a good example of variables nested within different scopes.


Listing 6.3. The GoodbyeWorld class.

class GoodbyeWorld {
  public static void main (String args[]) {
    int i, j;
    System.out.println("Goodbye, World!");
    for (i = 0; i < 5; i++) {
      int k;
      System.out.println("Bye!");
    }
  }
}

The integers i and j have scopes within the main() method body. The integer k, however, has a scope limited to the for loop block. Because k's scope is limited to the for loop block, it cannot be seen outside that block. On the other hand, i and j still can be seen within the for loop block. What this means is that scoping has a top-down hierarchical effect-variables defined in outer scopes can still be seen and used within nested scopes; however, variables defined in nested scopes are limited to those scopes. Incidentally, don't worry if you aren't familiar with for loops-you learn all about them in the next chapter, "Expressions, Operators, and Control Structures."

For more reasons than visibility, it is important to pay attention to the scope of variables when you declare them. Along with determining the visibility of variables, the scope also determines the lifetime of variables. This means that variables are actually destroyed when program execution leaves their scope. Look at the GoodbyeWorld example again: Storage for the integers i and j is allocated when program execution enters the main() method. When the for loop block is entered, storage for the integer k is allocated. When program execution leaves the for loop block, the memory for k is freed and the variable is destroyed. Similarly, when program execution leaves main, all the variables in its scope are freed and destroyed (i and j). The concepts of variable lifetime and scope become even more important when you start dealing with classes. You'll get a good dose of this in Chapter 8, "Classes, Packages, and Interfaces."

Arrays

An array is a construct that provides for the storage of a list of items of the same type. Array items can have either a simple or composite data type. Arrays also can be multidimensional. Java arrays are declared with square brackets: []. Following are a few examples of array declarations in Java:

int numbers[];
char[] letters;
long grid[][];

If you are familiar with arrays in another language, you may be puzzled by the absence of a number between the square brackets specifying the number of items in the array. Java doesn't allow you to specify the size of an empty array when declaring the array. You must always explicitly set the size of the array with the new operator or by assigning a list of items to the array at time of creation. The new operator is covered in the next chapter, "Expressions, Operators, and Control Structures."

Note
It may seem like a hassle to have to explicitly set the size of an array with the new operator. The reason for doing this is because Java doesn't have pointers like C or C++ and therefore doesn't allow you to just point anywhere in an array to create new items. Because the Java language handles memory management this way, the bounds-checking problems common with C and C++ have been avoided.

Another strange thing you may notice about Java arrays is the optional placement of the square brackets in the array declaration. You can place the square brackets after either the variable type or the identifier.

Following are a couple examples of arrays that have been declared and set to a specific size by using the new operator and by assigning a list of items in the array declaration:

char alphabet[] = new char[26];
int primes = {7, 11, 13};

More complex structures for storing lists of items, such as stacks and hash tables, are also supported by Java. Unlike arrays, these structures are implemented in Java as classes. You'll \get a crash course in some of these other storage mechanisms in Chapter 13, "The Utilities Package."

Strings

In Java, strings are handled by a special class called String. Even literal strings are managed internally by an instantiation of a String class. An instantiation of a class is simply an object that has been created based on the class description. This method of handling strings is very different from languages like C and C++, where strings are represented simply as an array of characters. Following are a few strings declared using the Java String class:

String message;
String name = "Mr. Blonde";

At this point, it's not that important to know the String class inside and out. You'll learn all the gory details of the String class in Chapter 12, "The Language Package."

Summary

In this chapter, you took a look at the core components of the Java language. Hopefully, you now have more insight about why Java has become popular in such a relatively short time. With vast improvements over the weaknesses of the C and C++ languages-arguably the industry's language standards-Java will no doubt become more important in the near future. The language elements covered in this chapter are just the tip of the iceberg when it comes to the benefits of programming in Java.

Now that you are armed with the fundamentals of the Java language, you are no doubt ready to press onward and learn more about the Java language. The next chapter, "Expressions, Operators, and Control Structures," covers exactly what its title suggests. In it, you learn how to work with and manipulate much of the information you learned about in this chapter. In doing so, you will be able to start writing programs that do a little more than display cute messages on the screen.