Java Lessons for Beginners

<<<<<<< Local Changes # Introduction

======= # Introduction

Why another book in Java

What am I using What’s with the structure, vocabulary and it looks like a lesson plan

By the way, why don’t you bundle the workbook and the videos Why not eclipse, or really, I won’t cover eclipse – maybe on the last part, as an appendinx

Is there Java 7. What about 8 Why the lateness of Objects

External Changes

Java Basic Concepts

Java™ refers to a couple of things. Firstly, it is a programming language. But it also a virtual machine and set of built-in code libraries. Lastly, it has a rich technology framework. All of these things comes in the package when you get the Java Development Kit (JDK). That is why Java is referred to as a platform.

One can simply download the JDK and build applications with it without requiring the use of third party technologies such database or network libraries. The Java platform comes with it out of the box. Batteries are included.

The Java language

Java is a compiled language. Like other languages such as C or C++, you will write your programming instructions in a source file using a somewhat English-like language. This source file will be compiled into an object file. An object file contains a set of instructions that a machine can understand and execute. In Java, an object file or executable file is called a byte code. The byte code is what a Java Virtual Machine, or JVM, can execute.

Byte codes cannot be executed directly by the OS (Operating System). You need to execute them within the context of the JVM. The JVM is an abstraction of the underlying OS. When you use commands in your program such as open a file, go to a URL or talk to a database, your program does not instruct the underlying OS directly. Your program is actually talking to the JVM and then JVM in turn hands that over to the underlying OS. That is the reason why there is one kind of JVM for each operating system is supported. When you go to the download page of Java, you will see a version of the JDK or JVM for Linux, Solaris, OSX and Windows.

You might think that there is a performance penalty for not dealing directly with the OS. And you are right, there is such a hit on performance, but that might be negligible now given the current advancements on the JVM. There are good reasons why Java is running on a virtual machine. [garbage collection]

Portable code

Java is portable at the byte code level. You can write and compile your program in one OS, say Windows and run it on another OS without requiring any modification. Sun Microsystem’s ( the former custodian of the Java technology) came up with the WORA slogan during the early days of Java. WORA stood for Write Once Run Anywhere.

Java programs are built from classes. A class is a program structure that is used to organize other program elements such as functions or methods, statements, expressions, variables, literals etc. It is a very effective structure for code organization but it is more than than. It plays a central role in Object Oriented Programming or OOP, which will be explored at length in dedicated chapters of this book.

A class is the smallest compilable unit of code in Java. You cannot write much outside the class leave for things such as comments, imports and package directives. Everything else must be written inside a class. The JDK comes with a complete set of tools to compile and run Java programs. Once you manage to write your code using any programmer’s editor, you can compile that program using javac — the java compiler. Once compiled, you can run the resulting java byte code inside the JVM using java — this is the runtime engine or JRE. The JRE also comes as part of the JDK.

Virtual Machine

Garbage collection and other services

Editions

You can use Java to build applications for a variety of architectures. Java comes in several editions. The JSE (Java Standard Edition) which is the topic of this book, can be used to build Desktop applications. Java Enterprise Edition (JEE) can be used to build web applications, web services, high availability back-end processes etc. Java Mobile Edition (JME) can be used to build apps for mobile or embedded devices. Although for mobile devices like Android phones/tablets, you might want to consider the Android SDK. By the way, the native language for the Android platform is Java.

Beginning to program

The Hello World program is traditionally the first program people write when learning a new language. The Hello World tradition dates back to late 1960s when Dennis Ritchie published “The C Programming Language” book. In Java, the code looks like this

// Hello.java

class Hello {

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

}


All the code does is to print “Hello World” to the screen. This code is probably the simplest program you can ever put together in the Java language. But it still presents a lot of difficulty to the beginning programmer. It contains strange words and is structured in a way that is hard to explain to beginners. But we have to start somewhere and this is simplest place start. We will try to manage the difficulty by ignoring many parts of this program.

The objective of this chapter are modest. To be familiar with the structure of a Java program. To know which tools are used to turn source codes into executable files (compiler) and how to run executable files in a Java environment.

Getting Started

To get started, we will write, compile and run the simplest program we can possibly create. This is the Hello World program you have seen earlier. This program is a desktop application, more specifically, it is a command line program. It will be invoked and executed on a terminal window. A terminal window is sometimes referred to also as a CLI or command line interface. There are many kinds of applications you can make using Java e.g. web application, mobile apps, rich GUI apps on the desktop, but lets’s use the CLI because it’s the simplest and it doesn’t require a lot of setup.

A Java program is written on a source file. It is a simple text file that has an extension .java. It contains programming instructions that are valid Java commands and expressions. Creating the source file can be managed by using very simple text editors such as Notepad on Windows, TextEdit on Macs and GEdit, Vim or Emacs on Linux.

Our first code will print to the terminal screen a simple “Hello World” message. To manage that, we need to write a Java class. Inside that class, we need a program entry point, which is typically a method or a function. Most programming languages require a program entry point. And more often, that entry is named main. Java is no different, you will need a main function to serve as the point of entry.

Inside the main function is an instruction to print the words “Hello World” to STDOUT which is the terminal window.

class Hello {

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

}


You cannot do much in Java without defining a class [Work] explain that this is simply plumbing code or boiler plate code for now, and that it will be explained later.

If you wrote the source code in a file named Hello.java, the next step is to compile the source code. The purpose of compilation is to turn the human readable source code into something that a machine can understand and execute.

To compile a source file, you will use the Java compiler mdash; javac. Javac is a program that comes with installation of the Java Development Kit (JDK). You will invoke using the terminal window, on the same directory or folder where you created the source file Hello.java. A terminal window, run the command

javac Hello.java


If you did not make any mistakes in copying the sample code above, the terminal window would probably stall for a just a little while during the compilation process and then silently fall back to the command prompt. The compilation process will produce a file called Hello.class — this is the Java byte code.

The Java byte code is a machine readable file version of your source file. If you try to open it up using an editor, its contents will be garbled. It is not meant to be read by humans. They are meant to be ran inside the JRE or Java Runtime Environment.

The JRE is a virtual machine (VM). It sits on top of the operating system. It interprets the byte code then executes the instructions. Each operating system will have their corresponding JRE. This is the reason why you need to pick and choose your operating system when you download either the JRE or the JDK. To execute our sample program, we need to invoke the JRE and pass along the name of our class file. You do not need to specify the extension of the class file. On a terminal window, run the command

java Hello


The java executable starts an instance of the virtual machine, loads up the byte code (the class file), goes inside the main function and starts executing the instructions. The virtual machine will stop when it runs out of instructions to execute.

In our sample program, we only have one instruction, so the virtual machine will stop after the first instruction. If we had two instructions, then the VM will halt after the second instruction.

class Hello {

public static void main(String[] args) {
System.out.println("Hello World");
System.out.println("How are you doing");
}
}


Notice that after the message “How are you doing” there are no more instructions. The curly brace is not an instruction. The pair of curly braces is called a block. Blocks are used to group somethings together. In the case of the main function, it groups statements together. Everything inside the block of the main function belongs to that function — by the way, Java programmers don’t refer to main as a function, they call it a method. From hereon, lets use the term method rather than function.

Boiler plate codes

In the sample code, only the println() statement is important for us. It is the only thing that does something — that produces something. But you cannot write just the println() and forget about all the other codes in the sample program. The other pieces of code like the class and the entry point method declaration are necessary codes. While they don’t do anything visible to you, you need to put them in because Java requires them as a minimum in order to compile and run even the simplest of codes.

Class and Method blocks

Java is an object oriented language. That does not mean much right now. It does not make much sense either. And it won’t until we get to the discussions of objects, types and classes. The only reason for the mention of object orientation is to explain, at least in passing that Java uses the class mechanism as a way to organize codes. There is nothing you can do in Java without writing a class block. Everything you will write in Java has to be enclosed in a class. The class is the atomic compilation unit. There is nothing smaller that will compile. You cannot write much outside it either.

A class is defined using the reserved word class followed by a name. In the case of our sample code, we gave it the name Hello. You can use any name you like provided you follow some fundamental guidelines — there are rules on how to create names or identifiers, we will discuss them later.

A Java class is a block. A block has a pair of curly braces. Anything inside that block comprises the definition of the class. That means, anything inside it belongs to the class. In later chapters, the full details on how Java classes work will be discussed.

The other piece of boiler-plate is the entry point method

public static void main(String []args) {

}


A method is a subroutine. It is also a block. It groups statements or commands into one coherent unit so that when you call or invoke the method from somewhere else, all the statements contained in the block will be executed.

Java is a bit finicky about defining an entry point. You have write it exactly how it appears in the sample code lest you will have a messy compilation error. We won’t go into the details of why it is static, public and void. We Also won’t go into the gory detail of what String []args means — at least not yet. The objective of this chapter is simply to try out and sample the coding workflow in Java.

Lets conclude this chapter with a pictorial summary.

Coding workflow

Also remember that a Java program takes the general form

// A comment

class ClassName {

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


Comments are statements that the compiler will ignore. Programmer’s put them in the code to add information or context either for their own benefit or others. Comments in Java can be managed in three ways. The double forward slash, when used will cause the compiler to ignore all the characters to its left all the way to the end of the line. There are two other ways to do comments. The next code sample uses all three styles of commenting.

// Single line comment
// Comments can appear outside the class block

/*

Multiline comments. Everything in between the paired slash and star character
Are ignored by the compiler.  This kind of comment is similar to the one found
In the C language

*/

/**

Another style multiline comments.  This is the Java style comment.
This can be used if you want to generate documentations using your 
Source code. There is a tool in Java called javadoc that looks for these
Type of comments and generates program documentation.

*/

class ClassName {

// Comments can appear inside classes

public static void main(String[] args) {
STATEMENTS
// Comments can appear inside methods
}

}


Your programs needs a ClassName. Its programmer defined so you have to come up with a name. In our example this name was Hello. The ClassName and the name of the file are usually the same, but they don’t have to be. You probably noticed that I named the files Hello.java and the class inside it was named Hello.

Most Java programs have methods. In the example the method’s name was main. This is also a special method. Java requires an entry point for our program if we intend to run it from the terminal. Ignore the static, void and public for the moment. We are not ready for that discussion.

Blocks are defined using a pair of curly braces. You have seen two in the example. The Hello class as a block and we wrote the main method inside it. Methods are always defined inside class blocks. You cannot write them outside the class. The main method also has a block where we can write executable statements. You can write statements outside the method as long as they are still within the class block. You will see some examples of that in the later chapters.

Statements. You will issue your instructions by writing statements like System.out.println. This particular instruction prints something into the terminal screen. Don’t forget to finish off the statements with a semicolon.

Activity

Crate a new class. Make the class name different from filename. Compile it. List the contents of directory where you created your program. What do you notice? Did you notice that the resulting byte code file did not follow the name of the source file. Instead it followed the name of the class. Byte codes are named after class definitions and not after the source file.

Create another source file, say Goo.java. Define three classes inside it, like this

// Goo.java

class Boo {
}

class Coo {
}

class Doo{
}


Compile Goo.java and see how many byte code files were created. Did you notice that there were 3 byte codes produced — Boo.class, Coo.class and Doo.class. You can define more than one class in a source file. But note that this is bad practice. If you are scanning your folders for class definitions, it is better there is a one-to-one correspondence between byte codes and actual source files.

Glossary

1. JVM
2. JRE
3. CLI
5. Virtual machine
6. Compilation Error
7. NoClassDefFoundError

Programming Concepts

Think of a program like a recipe for cooking. It’s an oversimplification but the analogy will do. A recipe is a series of instructions or tasks that needs to be carried out one after another. There is a start and a finish. You put somethings in and you get something out. There is a definite order on how instructions are to be carried out lest you will produce something unsavoury.

Creating a program follows roughly the same workflow like a recipe. You need to write a series of instructions for the machine to carry out. Like in the recipe, the order of instructions also need to be precise and deliberate. Let’s study another example

// Filename : Instructions.java

class Instructions {

public static void main(String[] args) {

System.out.println("Red");
System.out.println("Green");
System.out.println("Blue");
System.out.println("Apples");
System.out.println("Oranges");
System.out.println("Bananas”);

}
}


If you will follow this example, you can create a new source file and name it Instructions.java then compile and run as we did in the previous chapter.

$javac Instructions.java $ java Instructions


The code is very similar to our HelloWorld sample, although this one has more statements. It has six actually. Once compiled and ran, it will produce the following output

Red
Green
Blue
Apples
Oranges
Bananas


The output was rendered pretty consistent with the order on how they were defined in our source code. The colors Red, Green and Blue were printed first then followed by the fruits Apples, Oranges and finally Bananas. They appeared like that because we defined it in that order. The compiler is very obedient when it comes these things. When you execute one command after another, that is called a sequence. That’s pretty basic. But that is also one of the three ways on how to execute code. The other two are branching and repetition or looping. We will get there soon enough, but before we do, let’s tweak the code a bit.

// filename : InstructionsToo.java

class InstructionsToo {

public static void main(String[] args) {

System.out.println("Red");
System.out.println("Green");
System.out.println("Blue");

printFruits();

}

static void printFruits() {

System.out.println("Apples");
System.out.println("Oranges");
System.out.println("Bananas");

}

}


The code above produces exactly what the first sample code outputs. But it does so quite differently. Now there are two methods in the class — one is the main method and another method called printFruits. Segregating or grouping your programming instructions is considered good practice. It makes the code a bit more structured. A bit more modular. The revised code grouped all the statements that has to do the printing fruits into its own subroutine. If we didn’t do that,

While Java requires that you define a main method as an entry point, it does not restrict you from defining other methods. You can define as many methods as you like. But don’t get crazy with it. It is easy to get carried away. Deciding on how your code should be organized is a design skill that will you acquire overtime — but I digress. Back to the method discussion.

A Java method is some sort of heading. It’s a name. An identifier. Noticeably, this identifier has a pair of parens. That’s what makes it a method. When you invoke a method using it’s name, the flow of program control jumps to the first executable instruction inside the method block — the method block begins after the opening curly brace. It will keep on executing every instruction in that block until it reaches the last instruction.

At least for the moment, do not worry about the keywords void and static. We will get to them soon enough. The printFruits is declared void because the method does not need to return any value once it is finished. It is declared static because Java has a rule that a static method such as main can only call other static methods. Again, don’t worry about these things because they will be dealt with in the succeeding chapters. Were simply trying to understand code organization and program flow.

Order of Execution

One more point needs to said about order of execution. The examples thus far, prints out the colors Red, Green, Blue then prints out the fruits Apples, Oranges and Banana because that is the order in which they appeared in the source code. That principle may be true if we only had one main function and we wrote all our statements inside it. Inside a method block, the order of execution follows the order of statement definition. This principle is no longer true when you have one or more methods in your code.

Let’s consider the next example. All the statements responsible for printing — the println are now written inside dedicated methods. There are no printing statements inside the main function.

// filename : InstructionsThree.java

class InstructionsThree {

public static void main(String[] args) {

printColors();
printFruits();

}

static void printFruits() {

System.out.println("Apples");
System.out.println("Oranges");
System.out.println("Bananas");

}

static void printColors() {

System.out.println("Red");
System.out.println("Green");
System.out.println("Blue");

}

}


The println statement that output the fruits Apples, Oranges and Bananas appear before the println statement outputting the colors. That is at least the order in how they are defined in the code. Running this sample code yields the same results as our previous colors and fruits sample.

Red
Green
Blue
Apples
Oranges
Bananas


The colors are still printed before the fruits even if the colors were defined the last in our source code. The order of definition in the source code is not anymore consistent with the order of print out during runtime. The explanation for this behavior is found inside the main method.

Take a closer look at the main method of InstructionsThree.java. Remember that when you invoked java InstructionsThree, the program flow enters the main function. It will execute all statements in that function in the order they were defined — we called printColors first before we called printFruits. That is why the colors were printed before the fruits during runtime.

Program Flow

The order of execution was determined by the order of definition inside the main method. The main method was the sole controller of what statement gets executed before any other statement. The location of the method definition does not matter. It is only the order and sequence of statements inside main that matters. If you think that main is being executed first because it is the first method that is defined in the source code, try to change the location of main and put it somewhere in the bottom, like this

// filename : InstructionsThree.java

class InstructionsThree {

static void printFruits() {

System.out.println("Apples");
System.out.println("Oranges");
System.out.println("Bananas");

}

static void printColors() {

System.out.println("Red");
System.out.println("Green");
System.out.println("Blue");

}

public static void main(String[] args) {

printColors();
printFruits();

}
}


It will not change a thing. When you run Java executable, it will always look for the main method and the main method only. So it does not matter where main is defined in your source code.

Branch Repetition Sub routine Input output Math

Activity

Try to mispell main method. See what happens

Basic Types and Variables

Our goals for this chapter are; Learn a thing or two about variables. How they are created, defined, manipulated and printed. Also we will know a couple of things about what kinds of data we can use in the Java language.

Java is both an imperative language and an Object Oriented language. As an imperative language it relies on changing the value of some information inside the program until it accomplishes the desired results. It’s action oriented. Command oriented.

Imperative languages depends on the programmer’s precision of instruction. You might wonder what could be in contrast to imperative programming. I could tell you about declarative programming and how it differs with imperative style but that is digressing from our topic. For now, you might want to simply put that down in your todo list . Take a look at it once you are more comfortable with Java and already possesses more than a passing knowledge of imperative programming. Let’s go back to types and variables.

Programmers create things inside the code. We refer to it as data. Data is manipulated by using operations such as addition, subtraction, division, multiplication etc. Sometimes we mash up data together like in the case of words or Strings. Sometimes we keep the data a in a permanent storage like a disk and at other times we retrieve them. This is an oversimplification of what programmer’s do but you see the point. There is an acronym called CRUD. It stands for create, read, delete and update. Most applications programmer’s are very familiar with it because at a high level, a lot of the applications you will make will exhibit this functionality. Create the data, retrieve it, modify it sometimes and on rare occasions, we discard it.

In order to create data in Java, we need to know what kinds of data we can work with.

Java lets us work a wide different kinds of data. You can define numbers, Strings, date and characters just to name a few. We can even handle data that deals with truth and falsity. At a basic level, we can work with the following;

Basic Types

Numbers for counting. You can use byte, short, int and long. These are integer type. They only differ on how large a value they can carry. The byte can carry the smallest value and the the long can carry the largest value. These integer types are signed. You can store negative or positive numbers in them.

The byte can store numbers from -128 to 127; short can handle numbers from -32,768 up to 32,767. An int can handle - 2,147,483,648 up until 2,147483,647 and finally a long can store anywhere from -9,223,372,036,854,775,808 up to 9,223,372,036,854,775,807.

Numbers for measuring. The float and double are decimal types. Like integer types, you can also store both positive and negative values in them. The double type can store larger values than the float type, but that is not all there is in the story. It has something to do with precision of the decimal digits. As a simple rule, if you need to be precise to up until 7 decimal digits (or below), use the float type. Anything more than that should prompt you to consider the double — it can handle up to 15 digit precision on the decimal point. There is a standards body that defines the behavior for floating point number. If you are interested in further reading, I refer you the IEEE 754 standard

Truth and falsity. Sometimes you will need to compare data. Test for equality or inequality. The results of these tests are either true or false. You can store these kinds of data in Java’s *boolean type.

Character. Java can deal with words or Strings like “Tuesday”, it can also deal with individual letters like (‘J’,’a’,’v’,’a’). Java uses the char type to handle individual characters. Notice that Strings are surrounded by double quotes and characters use the single quote.

To use variables in your program, you need to declare and then define them. Like this

  int i;


The statement declares a variable named i and it tells us that its an int type. It can handle quite a large number. The variable name is something you need to come up with. It is programmer defined. There are some basic rules to follow on how to name variables. There is a dedicated chapter that discusses such rules.

  int j;
j = 0;


The code above declares variable j on one line and defines the value on the next line. In the example, j is a variable name and 0 is a literal value — a numeric literal. It’s value is fixed. When the compiler sees literal values, it does not require any computation to resolve its worth.

  int k = 1;


You don’t have to declare and define on separate statements. A variable declaration and definition can be managed into a single line, like the example above.

The following code illustrates how to declare and define variables and how to assign literal values to them.

    byte b = 1;
short s = 2;
int i = 3;
long l = 4;
float f = 5.0F;
double d = 6.0;
char c = 'a';
boolean bool = true;


The code above is not mysterious at all with the exception of that line which defined a float variable. Why did I have to write it as 5.0F? Because the literal value 5.0 is treated as a double type, not a float type. That was why we needed to be explicit about the type of the literal value. That begs the question on how we declared the double variable. Why didn’t we have to say 6.0D — we could have but we didn’t need it. A literal value with decimal portion is automatically a double type.

Upcasting and integer literal values

If variables have types, so does literal values. The compiler is pretty good at figuring out what kind of value you are trying to define when you write literals.

    1   // an int
2   // still an int
0   // still an int
3L  // long
0l  // also a long
4F  // float
5f  // also a float
6D  // double 
7d  // still a double
true      // boolean
false     // boolean
'a'       // char
'\u0000'  // also a char
'\FFFF'   // also a char


You don’t need to worry about these literal values for the most part of your coding. If you mis declare it the compiler will be quick enough to remind you of your error.

Explain why

Long l = 1; does not have to be qualified with an L (because of automatic upcast) so explain an upcast

Literal values have types

Sttatically type — you have to tell the compiler what type first.

Some code samples.

LHS and RHS here

Discuss that these are native types. What are native types anyway?

Reference Types

Java has 8 basic types — also called native types. Beyond the basic types, Java allows us to define other types on our own — these are called reference types, this is on the realm of objects and classes, but steer clear from this right now

What a variable is, why you need to declare it, why you need to tell the compiler what type it is (statically typed)

What the general concept of a type is, it constraints or defines what kind of operation you can do with it. Java’s typing is intuitive, somewhat.

Keywords and Identifiers

Java programs are made up of words. Lots of words. Some of them are predefined and some you will have to make up yourself. The predefined words have special meaning to the Java compiler

Your Java source codes is made up of English-like statements and instructions. Remember from earlier chapters that you need to compile them so they can be understood and executed by the Java VM. That compilation process actually analyzes every character and every word of your source file. It breaks it up into constituent parts and then it tries to make sense of what you have written. Each word and character will be compared against a set of rules. If you wrote your code without violating any of these rules, then the compiler produces an executable version of your source file.

If you can remember typing a document in Microsoft Word or any other word processor, then it prompted you because there was something wrong in the grammar or spelling? What it did was to check every word you wrote including the punctuations. It compared your text to known rules of grammar. If you did not murder the English language you won’t see any squiggly lines on your text. This process is very similar to the compilation procedure of Java — or any programming language for that matter.

The Java language comes with an inventory of special words and symbols. You have seen some of them in earlier chapters. The words class, main, static, void for example and the characters curly braces semi-colon. These are the building blocks of a Java program. A Java code is made of words. Lots of words. Some of them predefined and some you will have to make up for yourself. The predefined words have special meaning to the compiler. These are called reserved words or keywords.

Java Keywords

You don’t need to memorize them, but I suspect that as you move further in programming, you will be able to commit most of them in memory.

Apart from keywords and program punctuations, you will need to supply some words that are needed in your codes. For example the name of class, a method or a variable. These words that a programmer needs to supply are called identifiers.

There are some fundamental rules that you need to observe when naming identifiers. They are simple enough but if you don’t follow them, it will result in a compilation error. For example, if we wrote something like this

class 1Hello {

}


The compiler will throw an Identifier expected error because the name of the class violated a rule on how to name identifiers. The first character of the identifier was a number. You cannot do that. So here are the rules.

The name cannot start with a number. As you have seen in the example.

You can only use alphanumeric characters, a-z, A-Z, 0-9. Don’t forget the rule above, even if you can use numbers as part of the name, you cannot use on the first character.

You cannot use special characters. You cannot use asterisk or the @ sign. Although you can use the dollar sign and the underscore. But even if you can do that, I suggest that you stay away from them because Java uses them for special purposes.

You cannot use a reserved word for an identifier. It will confuse the compiler. You also cannot use a Java literal like true, false or null.

Activity

Create a source a new Java source file. Name it anything you want. Experiment with the identifiers. Make them deliberately wrong then try to compile it.

class Hello {

int n@umber = 0;

}


Take note of the error message. Experiment on your own. Try out a number of really invalid identifiers like 1Hello, the-number, \$@notherNumber etc.

Next activity is to try misspelling some of the reserved words. Like this

class Hello {

publi static void main(String []args) {

}

}


Take note of the error message. Can you spot the error without compiling it? How about this next code.

class Hello {

public static void main(String[] args) {

System.out.println("Hello World")

}

}


This last activity is not about identifiers. You may have noticed that it was missing the semi-colon on the println statement. The compiler will actually tell you that it is expecting a semi-colon. By this time you probably have already noticed that Java statements are terminated by a semi-colon. It’s not optional. You really have to put it in. The semi-colon tells the compiler that you are finished with that statement. It is the equivalent of the period on the English language. It signals the completion of a sentence.

Glossary

1. Compilation error

Printing things

You’ve already seen the println method previous. We used it before. It is one the easiest built-in functions to utilize. All one needs to do to print is to pass something as a parameter to the println method, and it will do the rest. The println can handle a variety of data types. You don’t need to worry what kind of data to use, just throw it to println and let it do its work.

class PrintOne {

public static void main(String[] args) {

System.out.println("Line number one");
System.out.println("Line number two");

}

}


No surprises here. You have seen this code many times before. It prints “Line number one”, then adds new line before it prints out “Line number two” then adds another new line.

*    *    *

You can put expressions inside the println. Like this

System.out.println(1 * 2 * 3 * 4);
System.out.println(“1 + 2 = “ + 1 + 2);


Printing Expressions

Expressions inside the println method will be evaluated first before it gets printed. Any expression that results to a value can be printed inside the println — whether it is arithmetic, logical or simply combining Strings.

The second line in the second example is worth pointing out. The first plus sign after the enclosing double quote is not meant to perform an arithmetic addition — the second plus sign was meant to do that. The first plus sign was meant to perform String combination.

Once the arithmetic sum of 1 and 2 have been resolved, the result will be combined with the String “1 + 2 = “. In Java, if you add a String to anything, anything at all, whether it be a native or reference type, it gets converted into a String type. Hence, the quickest way to convert any number to String is to add an empty String to it.

10 + “”;


System.out.print

The println has a variant form called print — without the ln. It does basically the same thing but it does not add a new line to the output. Try this one out.

class PrintTwo  {
public static void main(String[] args) {
System.out.print("Line number one");
System.out.print("Line number two");
}
}


This sample prints “Line number oneLine number two”. It was mashed up. This behavior can come in handy depending on what you are doing. If you need to print things without adding a new line or carriage return, use the print method, if you need the line feed then use println.

*    *    *

There are things you can embed on Strings that can alter the printing behavior. They are called escape sequences or escape characters. The most common escape sequence you may encounter is the \n.

class Escape {

public static void main(String[] args) {
System.out.print("The quick brown\n fox jumped over the lazy\n dog");
}

}


Escape characters are written as part of the String literal. These characters start with a back slash and they affect the way the String is printed. In the sample code above, the \n escape character will add a line feed or carriage return then it will resume printing on the next line.

Formatting the print

There might be times when you will need to use a combination of variables and String literals during printing. Since we know that adding String to another data type produces a String, we can always write expressions like this.

class Positional {

public static void main(String[] args) {

int a = 1;
int b = 2;
int c = 3;

System.out.println("a = " + a + " b = " + b + " c = " + c);

}
}


There is nothing wrong with this technique except that it’s cumbersome and prone to error. You can almost get cross-eyed just looking at it and checking whether the the pairs of double quotes are correct. Fortunately, there are other ways to handle printing. These are printf and format. The printf and format method are equivalent in functionality, you can use either of one them to replace println or print.

Printf behaves exactly the same as its brothers println and print. All of them can handle whatever variable, literal or expression you throw to them. They will simply send it to STDOUT (your terminal). But there are two things that printf does exceptionally well. It can handle positional parameters and formatting.

class Positional {

public static void main(String[] args) {

int a = 1;
int b = 2;
int c = 3;

System.out.println("a = " + a + " b = " + b + " c = " + c);

System.out.printf("a = %d b = %d c = %d \n", a, b , c);

}
}


Printf lets you insert placeholders or format specifiers inside the String literal. These placeholders will be filled up by the actual values which are specified also inside the printf method. In the example, %d is a placeholder. There were three of them because there were three variables also to the right of the String literal. The first %d corresponds to the variable a. The second %d is for the variable b and the last %d corresponds to variable c.

The format specifier we used in the example was written as %d because it needed to handle int values. If we wanted it to deal with another type of data, we would have used a different specifier. You can format quite a few things with printf. It can deal with dates,

Program Flow

No matter how fast your computer processor is, it will be limited by the number of instructions it can execute at any point in time. That will be one. One instruction at a time. The Von Neumann architecture influenced quite a few programming languages. Java is one of them. You may write a thousand instructions in your code but they will flow in either one of these three modes.

1. Sequence - statements are executed one after another. The order of execution is affected by the order on how they appear in your source code
2. Branch - statements are executed only if certain conditions are true. Java uses the if and switch structures for this.
3. Loop - statements are executed while certain conditions are true. Java uses the for, while, do while and for each control structures to achieve looping.
class Sequence {

public static void main(String[] args) {

float fah = 89.0F;
float cel = 0.F;

cel = (5F/9F) * (fah - 32);
System.out.printf("%f F = %f C", fah, cel );

}

}


The sample above is a straightforward sequence. It defined two variables and values for Fahrenheit and Centigrade, respectively. It performed the calculation for the conversion and printed out the result of the conversion. No side-stepping, conditional executions or looping executions. Just start with the first command and work your way until there are no more statements to execute.

This is the most basic way of how your program will execute — in sequence. One statement after another until the code runs out of things run.

if statement

If you need to side step some instructions in your code, it can be achieved by using the if statement. This statement is like a gateway. If the state of the gate is true, then the statements inside the statement block gets executed. Otherwise, they will be skipped and program control will transfer to first statement immediately following the end of hte if statement block. That statement is the one immediately right after the closing curly brace of the if statement.

class Branch {

public static void main(String[] args) {

int num = 1547;
int rem =  num % 2;

if (rem == 1) {
System.out.printf("%,d is an odd number %n", num);
}
else if (rem == 0) {
System.out.printf("%,d is an even number %n", num);
}
else {
System.out.println("You will not get here");
}

}

}


The general structure of the if statement is as follows

if (expression) {
// STATEMENT
}


This is the only required form of the statement. The curly braces can even be skipped if you only have one statement to execute. But I suggest you do not skimp on the braces. It improves readability even if there is only one statement inside it. The expression part can be any expression that evaluates to either true or false.

In our code sample, we used the modulo operator. It is very similar to arithmetic division operator except the modulo operator gives out only the remainder portion.

The else if and the else clauses are optional. You can write your code only with an if statement — if that is what you only need. For example

class Branch {

public static void main(String[] args) {

int num = 1547;
int rem =  num % 2;

if (rem == 1) {
System.out.printf("%,d is an odd number %n", num);
}

}

}


This version of the code will still work. The else if and else are there if your test have many possible outcomes.

switch statement

The ability to route program flow using the if statement is pretty handy. There are some situations however, when you will deal with something more than just binary logic. Surely you can use lots of else-if clauses but there is another way to route program logic.

The switch statement can be used if you are dealing with lots of possible values. It beats the if-else-if structure in readability.

The next sample code prints what day of the week it is. It uses the built-in Calendar object from java.util. The get of the Calendar object returns an integer value which stands for the day of the week.

import java.util.Calendar;

class Switch {

public static void main(String[] args) {

Calendar now = Calendar.getInstance();
int dow = now.get(Calendar.DAY_OF_WEEK);

switch(dow) {
case 0:
System.out.println("Sunday");
break;
case 1:
System.out.println("Monday");
break;
case 2:
System.out.println("Tuesday");
break;
case 3:
System.out.println("Wednesday");
break;
case 4:
System.out.println("Thursday");
break;
case 5:
System.out.println("Friday");
break;
case 6:
System.out.println("Saturday");
break;
default:
System.out.println("You should not get here");
}
}
}


Using the switch statement to route program logic is simple. You need only to put the expression to test as an argument to the switch keyword, then line up the case statements inside the switch block — the body of the switch which is enclosed in a pair of curly braces is called a switch block.

Each case statement corresponds to a value. The first case statement is evaluated, if a match is found, then the statement inside the case is executed. If the first case statement did not have a match, the next case statement is evaluated, so on and so forth.

The default statement is optional, you don’t have to write it but it’s considered a defensive practice to do so. It just makes your code a bit more robust because it can deal with values outside the anticipated ones. You can only write one default statement inside the switch block. Only one is allowed by the compiler.

You may have noticed the break instruction on each of the case statements. The break keyword was put there so that we don’t execute any other statement when one of the case blocks evaluates to true. If you don’t issue the break instruction, Java will execute all the statements immediately following the case block that evaluated to true, all the way to end of the switch block. In most cases, that’s probably not your expected outcome.

*    *    *

Before JDK 1.7 was released, the switch statement could not handle Strings. Now it can. It is possible to write something like this

import java.util.Scanner;

class SwitchString {

public static void main(String[] args) {

System.out.println("Type a number :");

Scanner keyin = new Scanner(System.in);
String input = keyin.nextLine().trim();

switch(input) {
case "One":
System.out.println("You typed 1");
break;
case "Two":
System.out.println("You typed 2");
break;
case "Three":
System.out.println("You typed 3");
break;
default:
System.out.printf("You typed %s %n", input);
}
}

}


while loop

When you need to perform a group of statements or even just one statement repeatedly, you will need to know how to loop.

The basic idea is to have block that contains the statements you want to perform repeatedly. At the beginning (or end) or the block, you perform a check. You will check for a specific condition. If the condition evaluates to true you will execute the statements within the block. If the check turns out to be false, you skip the block entirely and jump to the next statement immediately after the block.

The while statement allows you to write loops. The general form is as follows.

while(condition){
// STATEMENT;
}


Let’s use it on a full example.

// While.java
class While {

public static void main(String[] args) {

int i = 0;

while(i < 10) {
System.out.printf("i = %d %n", i);
i = i + 1;
}

}
}


The While sample declares an int variable i, this is our counter. The expression i < 10 will is evaluated for the first time. Naturally i is less than 10, the initial value is zero so the first time we enter the loop, the condition evaluates to true. We then enter the body of the while block and perform the statements. The first statement prints out the current value of i. Then it increments i.

Once we reach the end of the while block (the closing curly brace), program control will transfer to beginning of the while block. It evaluates the condition again. This time i is not zero because we have incremented it the first time around. Now the value is 1. The condition still evaluates to true so we enter the while block for the second time. We print the value of the counter and then increment the counter again. This cycle will go on until such time that the counter i is no longer less than 10. When it is equal to 10, the condition evaluates to false and we skip the entire block. The program control transfers to the next line. But the next line is the end of the main method, there is no more to do. The program terminates at this point.

Why keep a counter? Because if you don’t, the loop will never terminate. If there is no way for the condition to turn out false, what you will get is a perpetual loop.

do while

The do while statement is very similar to the while statement. It also allows you to perform looping as long as certain conditions are true.

The fundamental but very important distinction between a while and do while loop is that do while will execute the statements inside the block at least once. That is guaranteed. The general form for this loop is as follows

do {
// STATEMENT;
} while(condition);


Notice that it checks the condition at the end of the block. The while statement checks for condition at the beginning of the block. When using a while loop, it maybe possible to not even execute the statements inside it. If the condition on the while loop evaluates to false, it will skip the entire loop at once.

The do while loop on the other hand checks for the condition at the end of the block. All the statements inside the loop would have been ran at least once before the condition expression is evaluated.

Let’s try this on a full code sample

class DoWhile {

public static void main(String[] args) {

int i = 0;

do {
System.out.printf("i = %d %n", i);
i = i + 1;
} while (i < 10);

}
}


It behaves exactly like the while sample before it. Now change the initial value of the counter i to 10. Try to run it again.

class DoWhile {

public static void main(String[] args) {

int i = 10;

do {
System.out.printf("i = %d %n", i);
i = i + 1;
} while (i < 10);

}
}


It prints i = 10 then the loop terminates. Now try changing the initial value of counter i in the while sample code, like this

class While {

public static void main(String[] args) {

int i = 10;

while(i < 10) {
System.out.printf("i = %d %n", i);
i = i + 1;
}

}
}


Our revised version of the while sample will not even print anything.

for loop

The for statement is another way to perform loops. The idea is to iterate over a group of statements inside the for block until some condition stops being true. The basic form of this loop structure is as follows.

for (begin_value ; condition ; step) {
// STATEMENT;
}


Unlike the while loop, the for loop includes a step expression as part of the structure. Think of the step as a counter — in fact, it is really a counter.

class ForLoop {

public static void main(String[] args) {

for (int i = 0; i< 10; i = i + 1) {
System.out.printf("i = %d %n", i);
}
}
}


The above code does exactly the same thing as in our while and do while example. It increases the value of a counter variable by one for each iteration.

The for loop is very expressive but can be quite terse. The example above is the probably the most basic way of using this loop. But you are not limited in using it as a code-thrifty version of the while loop. You can use it with more than one step variable.

class ForLoopTwo {

public static void main(String[] args) {

for (int i = 0, j = 10; i< 10; i = i + 1, j--) {
System.out.printf("i = %d | j = %d %n", i, j);
}
}
}


This example uses two step variables; i is incremented by one while the variable j is decreased by one during each iteration. You need to initialize the value of variable j as well if you will use it as step counter. The counters don’t always have to progress from 0 to a positive number. It can actually serve as a countdown variable. And it doesn’t always have to be an increment of 1. It is perfectly alright to use expressions like this

for (int x = 100; x < 10_000; x = x + 12) {
// STATEMENT
}


You also don’t always have to use the variables i or j. It can be anything. For some reason the variables i and j have become favorite variables when writing for loops.

The underscore in the integer literal 10_000 is legit if you are using JDK 1.7 above. It makes reading integer literals easier. Do not use the underscore in a literal if your JDK is 1.6 or below.

Methods

There was a time in programming history when codes were in a single source file. If we needed to jump to some parts of the code, we jump to it using constructions as goto, then go back to the place we were right before the jump. This programming style is a distant memory now. There may be a few places where goto is still used but the mainstream practice has adopted quite a few mechanisms to move away from goto laden codes.

As the lines of code grows longer, you will face an organization problem. Sometime ago, computer scientists adopted functional decomposition. It is a way to organize code in functional units. The basic idea is to group some statements and then give it a name. That is what a function is. A named section of the code. It is encapsulates a group of statement into a single name. It is a subroutine or procedure such that when you call the name of procedure it executes all the tasks inside that procedure. You can think of a method as a heading of some sort. If you call the heading, all instructions contained in that heading kicks into high gear.

Grouping your codes into functions is a form of abstraction. We chunk some statements together and label it with a name. So when we think of the label, we don’t have to remember all the gory details of its implementation. We just know it does what it does. Java can organize codes into functions. By the way, most of literature about the Java language do not use the term function — method is the preferred term.

Aside from methods, Java can also organize code using a much higher form of abstraction. It organizes code into classes and objects. This is the reason Java is called an OOP language (Object Oriented Programming). OOP is wider form abstraction. Methods encapsulate statements and variables. While classes encapsulate methods, statements and variables. It is a simplistic definition and quite wanting in details. But details is the least we need at this point in order to understand the concept of Java abstractions. We will devote our attention to method abstractions in this chapter. We will leave OOP discussions for later.

*    *    *

Consider the example below. It does very simple things. It prints some fruits, then prints the numbers 1,2 and 3 and then it prints some fruits again. Notice the repetition of the code. This kind of coding get hairy pretty quickly. It violates the DRY principle — Don’t Repeat Yourself.

class MethodsLong {

public static void main(String[] args) {

System.out.print("Apple");
System.out.print("Orange");
System.out.print("Banana\n");

System.out.print("One");
System.out.print("Two");
System.out.print("Three\n");

System.out.print("Apple");
System.out.print("Orange");
System.out.print("Banana\n");

}

}


If we apply some method abstractions to the code above, we can improve it just a bit

class MethodsLong {

public static void main(String[] args) {
printFruits();
printNumbers();
printFruits();
}

static void printNumbers() {
System.out.print("Apple");
System.out.print("Orange");
System.out.print("Banana\n");
}

static void printFruits() {
System.out.print("One");
System.out.print("Two");
System.out.print("Three\n");
}
}


The improved version of the code used methods to group related statements. We took all the fruit printing statements and tucked it away neatly inside a method named printFruits() and we did the same with all the number printing statements. The difference can be greatly noticed on the codes inside the main function. If we need to print numbers again, all we need to do is to call printNumbers instead of writing three println statements.

Using methods also benefits us in maintaing our code. In case we need to add another fruit to print, say mangoes, we only need to edit the printFruits method and make the change in a single location. This kind of code organization goes a long way in helping the programmer keep his sanity.

Method definition

To define a method

1. Give it a name. Method names are the responsibility of the programmer. You can choose any name you like provided you observe some simple rules about naming. A name can’t start with a number. Can’t contain special characters and it can’t be a Java reserved word.
2. Put parens as part of the name.
3. Give it a data type for return value. All Java methods need to declare what it returns. You can return native data types — byte, short, int, long, char, double, float and boolean. You can also return Reference types like *Strings, Date or any other type that you create. If you don’t want to return anything, declare the return type as void
4. Use a block to define the body of the method

The general form of a method is as follows

returnType methodName(argument1, argument2, ... argumentn) {
// variables 
// statements
}


Don’t mind the static keyword for now. That is a special modifier that we use to designate the storage class of a method — or a variable. The details of the storage class is unimportant for this chapter. The reason I declared printFruits and printNumbers as static is because we called it from method main. And main is static. A static method can only call other static methods. Like I said, those details are unimportant right now. We will get to the storage class discussion soon enough when we tackle OOP.

Data definitions inside methods

Methods can define data inside their bodies. Whatever data you define inside the block is accessible from within the block. But only within the block where the data was defined. Not from outside.

void foo() {
int i = 10;
System.out.println(i);
}

void goo() {

int j = 20;

System.out.println(j);
System.out.println(i); // not allowed 
}


The illustrated code above is illegal. The println(i) inside method goo is illegal because variable i is outside the scope of the method. Method goo can use variable j because it is within its scope.

Any data defined inside the method block is called a local variable. Its scope or access is limited locally to method which defines it.

Database programming with JDBC

Databases usually does not understand Java, they use a different language called SQL which is short for Structured Query Language. When you create programs that use databases you are dealing with two separate entities. Your application and the database.

Most of the time the database is not running within the same process or memory space as your application. Such is the situation when you use a client-server database like MySQL, SQLServer, PostgreSQL, Oracle, DB2 etc.

The high level steps of using a database from a Java application are as follows;

1. Load the specific driver of the database — the JDBC API needs to know what specific database you will use. You need to identify the specific class for the driver. You will download this class file from the database vendor. It usually is bundled in a .jar file. You need to include this jar file in the CLASSPATH
2. Establish a connection to the database — this is where you provide username, password and the location of the DB
3. Get a Statement object and execute some queries — send some SQL commands to the database
4. Do something with the result — iterate through Cursor
5. Close the connection to the database

JDBC is a standard API that you can use to connect your Java application to a database. It comes with Java Standard Edition. You will use the JDBC API to execute all of steps necessary in communicating with the database.

It’s important to remember that when you send a command to the database (DB), you are not talking to the DB directly. You are sending the instruction to JDBC API and it is translating your instructions into something that the DB natively understands. When the database responds to your instructions, it will send back something. Usually a data structure or the status of the command — sometimes both. The JDBC API translates the responses of the databases into something your application can understand and use. Think of the JDBC as a middleware. It stands in between your application and the database.

JDBC architecture

*    *    *

To illustate the programming concepts, we will build a small program that talks to a database. We will use SQLite. It is a lightweight desktop database. It does not operate the way MySQL or Oracle would, those DBs follow a client-server architecture. SQLite does not need an elaborate inter-process communication to work. All the data of a SQLite DB is kept on a simple file.

You will need to get two things from the internet. The SQLite program which can be downloaded from SQLite.org website and JDBC driver for SQLite which can be downloaded from the Xerial website.

[installation instructions here]

Preparing the database

Prepare a new work folder where you can put the Java source file, the JDBC driver and the database file. You can name it anything you like or you can follow the name in this sample. You will work on a terminal window for these examples.

Prepare a work folder in Windows

C:\> cd Users\yourname
C:\> mkdir jdbcsample
C:\> cd jdbcsample


Prepare a work folder in OSX or Linux

mkdir ~/jdbcsample
cd ~/jdbcsample


Next step is to create a file where we will store our initial set of SQL commands. We need to create a database then populate it with some values. Create a simple text file named dbsample.sql. Type the following commands inside dbsample.sql

dbsample.sql

CREATE TABLE user(
username varchar(50),
email varchar(100),
password varchar(20)
);

INSERT INTO user values(
'ted',
'tedhagos@gmail.com',
'I will not tell you'
);


Now we need to start the sqlite3 program and create the sample database.

sqlite3 sample.db < dbsample.sql


That last command launched the sqlite3 executable and read the contents of the file dbsample.sql. Once the contents of the SQL command file was read, a database named sample.db was created in the current directory. A table named user was also created. Now we can proceed to the Java part.

Building the sample code

Our sample code will use some classes from the JDBC API. We need to import these classes into our code. They are inside the package java.sql.

import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;


Set the proper database driver. Tell Java to load the sqlite JDBC driver. The org.sqlite.JDBC class is inside the jar file of JDBC driver — the one you downloaded from the Xerial site.

Class.forName("org.sqlite.JDBC");


Use the DriverManager class to make the DB connection. The arguments to the getConnection method will be different for each database. We don’t need to pass any username or password in this call because the database does not have any.

After a connection has been managed, it’s time to create a Statement object that we will use to send commands to the DB.

Connection cn = DriverManager.getConnection("jdbc:sqlite:sample.db");
Statement st = cn.createStatement();


The JDBC workflow uses the Factory pattern heavily. The bjects we used were not created using their own constructors. The Connection object is not created using new Connection(). The Statement object is not created using new Statement(). The control over the creation of objects were injected somewhere else.

The Factory pattern is part of a 24 Design patterns discussed in the book “Design Patterns” by Erich Gamma et. al. (also known as GoF or Gang of Four)

Once the Statement object has been created, we can start sending SQL commands to the DB. Use the ResultSet object to store the response of the database. The executeQuery() command we issued will return a 1 object. The data structure of Cursor is not readable directly from Java, hence the JDBC API wraps in the ResultSet object so we can traverse it in an object oriented way.

ResultSet rs = st.executeQuery("SELECT * FROM user;");


The ResultSet will let you retrieve the values stored on the current row. You can get the values by either specifyng the column number or the name of row.

while(rs.next()) {

System.out.print(rs.getString(1));
System.out.print(rs.getString(2));
System.out.println(rs.getString(3));

}


Just remember that the ResultSet structure is unlike an array. It does not start with zero. The first column will be referenced by 1 rather zero.

When you need to move to the next record, you can use next() method of the ResultSet object. Aside from moving the current record pointer, the next() method also returns a boolean value. It returns false when you are are at the last record. That is why used it as a condition for the while statement. Our simple loop will terminate when there are no more records to process.

Here is the full code for our example.

Full code of the JDBC sample

import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;

class DBSample {

public static void main(String []args){
Connection cn = null;
Statement st = null;
ResultSet rs = null;

try {

Class.forName("org.sqlite.JDBC");
cn = DriverManager.getConnection("jdbc:sqlite:sample.db");
st = cn.createStatement();
rs = st.executeQuery("SELECT * FROM user;");

while(rs.next()) {

System.out.print(rs.getString(1));
System.out.print(rs.getString(2));
System.out.println(rs.getString(3));

}
}
catch(ClassNotFoundException ce) {
ce.printStackTrace();
}
catch(SQLException sqle) {
sqle.printStackTrace();
}
finally {
try {
rs.close();
st.close();
cn.close();
}
catch(SQLException sqle) {
sqle.printStackTrace();
}
}
}
}


The JDBC API can throw a lot of Exceptions. Those statements that can actually throw errors are placed inside try try block.

Running the JDBC sample

You must include the JDBC Driver for SQLite in the CLASSPATH lest your app will run into a ClassNotFoundException. You can add the location of JDBC driver jar file to the Java classpath by passing the -classpath flag to the JRE.

Run these commands on Windows

javac DBSample.java
java -classpath ".;sqlite-jdbc-(VERSION).jar" DBSample


Run these on OSX or Linux

java -classpath ".:sqlite-jdbc-(VERSION).jar" DBSample


The commands above assumes that sqlite-jdbc-(VERSION).jar is in the same folder as your Java code. Also, replace VERSION with the actual version number of the JDBC driver.

Another way is to permanently include the JDBC jar file into the CLASSPATH. But you will need to modify the environment variables of your OS to do that. If your workstation is managed by an IT department you may need to ask permission to modify the environment variables. Which is why it is more manageable to simply use the -classpath flag.

1. CURSOR means CURrent Set Of Records. It is database terminology. It represents a data structure that is like a table or a two dimensional array. It contains records.