The Java language was meant to build upon the success of C++, but with added safety features and true cross-platform capabilities. Unlike C++, which gives programmers access to every part of the computer (along with the equal capability of screwing up every part of the computer), Java restricts access to the computer hardware. Although this limits Java's flexibility, it provides greater stability and reliability of Java programs.
The most appealing feature of Java is its cross-platform capabilities. Although porting a C++ program to run on other operating systems is possible, it's rarely easy or painless. Theoretically, Java lets you write a program once and then run it on multiple operating systems, a feature often described as Write Once, Run Everywhere (or more whimsically, Write Once, Test Everywhere).
Sun Microsystems developed Java and in response to Java's popularity, Microsoft developed a similar language with equivalent goals — C#. Like Java, C# is meant to build upon the C++ language while providing safety features to make it harder to write programs that could crash an entire computer.
To make programming easier, C# relies on the .NET framework. The idea behind .NET is to shield the programmer from the complexities of the operating system. Theoretically, the .NET framework can be ported to other operating systems, so C# could run on any operating system that can run the .NET framework. Realistically, .NET runs only on Windows, although programmers are trying to port the .NET framework for Linux too.
Although C/C++ remains the most popular programming language on the planet, both Java and C# are poised as programming languages of the future. Java is popular because it's platform independent, so Macintosh and Linux users can take advantage of Java. C# is most popular among Windows programmers because Microsoft has positioned C# as the future programming language for Windows.
Java forces object-oriented programming on you whether you like it or not. Every Java program consists of a class, such as
class programname { public static void main(String args[]) { System.out.println("This is a simple Java program."); } }
Because Java relies on object-oriented programming, a Java program looks more complicated than it should. Basically, the main program is considered a class that has a single main function. To print something, the preceding program uses a println
command, which is accessed through the System
class. Because Java forces object-oriented thinking on you, Java programs consist of multiple classes.
Like Java, C# also forces object-oriented thinking on every program you write.
using System; class MyClass {_static void Main() {_Console.WriteLine("This is a simple C# program."); } }
To write a comment in Java/C#, you have two choices. First, you can use the double slash character so that anything that appears to the right of the character is a comment, such as
using System;_ class MyClass _// This is a C# comment {_static void Main() _ {_Console.WriteLine("This is a simple C# program.");_ } }
The double slash character is handy for adding a comment to a single line. If you want to write a comment over multiple lines, you can use the /*
and */
characters, such as
/* This is a multiline comment to show people how easy Java can be to learn. */ class programname { public static void main(String args[]) { System.out.println("This is a simple Java program."); } }
Because Java and C# are closely derived from C/C++, they both declare variable data types the same way by first listing the data type and then listing the variable name, such as
datatype VariableName;
VariableName
can be any descriptive name. Both Java and C# are case-sensitive, so the variable TeamMembers
is a completely different variable than Teammembers
. Some programmers use uppercase letters to make variable names easier to find whereas others use all lowercase. To declare multiple variables, cram them all on a single line, separated by a comma, such as
datatype VariableName1, VariableName2, VariableName3;
Both Java and C# offer a string
data type (which isn't found in C/C++), which you can declare as this:
string variablename;
Like all variables, both Java and C# allow you to declare and initialize a variable at the same time, such as
string variablename = "text";
Whole numbers represent integers, such as −9, 62, or 10. A whole number can be positive or negative. The most common integer data type is int
and is used as follows:
int variablename;
Besides integer values, Java also offers a variety of other integer data types that can hold a different range of values, as shown in Table 2-1.
Table VI.2-1. Typical Storage and Range Limitations of Java Integer Data Types
Data Type | Number of Bytes | Range |
---|---|---|
byte | 1 | -128 to 127 |
short | 2 | -32,768 to 32,767 |
int | 4 | -2,147,483,648 to 2,147,483,647 |
long | 8 | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
C# also offers a variety of different integer data types, which can be signed (positive and negative values) or unsigned (only positive values), as shown in Table 2-2. To declare a signed or unsigned variable, use the signed
(or unsigned
) keyword, such as
signed int profit; unsigned short pets_owned;
Table VI.2-2. Typical Storage and Range Limitations of C# Integer Data Types
Data Type | Number of Bytes | Range |
---|---|---|
byte | 1 | Signed: −128 to 127 Unsigned: 0 to 255 |
short | 2 | Signed: −32,768 to 32,767 Unsigned: 0 to 65,535 |
int | 4 | Signed: −2,147,483,648 to 2,147,483,647 Unsigned: 0 to 4,294,967,295 |
long | 8 | Signed: −9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 Unsigned: 0 to 1.8×1019 |
Floating point values represent decimal values, such as 78.52 or −5.629. Just as you can limit the range of integer values a variable can hold, so can you limit the range of floating point values a variable can hold.
The three types of floating data types are float, double, and decimal (C# only), as shown in Table 2-3.
Table VI.2-3. Typical Floating Point Data Types
Data Type | Number of Bytes | Range |
---|---|---|
float | 4 | -1.4023 E-45 to 3.4028 E38 |
double | 8 | -4.9406 E-324 to 1.7977 E308 |
decimal (C# only) | 16 | -1.0 E-28 to 1.0 E28 |
The ranges of the different data types listed in Table 2-3 are approximate values.
The three types of operators used are mathematical, comparison, and logical. Mathematical operators calculate numeric results, such as adding, multiplying, or dividing numbers, as shown in Table 2-4.
Table VI.2-4. Mathematical Operators
Mathematical Operator | Purpose | Example |
---|---|---|
+ | Addition | 5 + 3.4 |
- | Subtraction | 203.9 - 9.12 |
* | Multiplication | 39 * 146.7 |
/ | Division | 45/ 8.41 |
% | Modula division (returns the remainder) | 35 % 9 = 8 |
Relational operators compare two values and return a True
or False
value. The six relational operators available are shown in Table 2-5.
Table VI.2-5. Relational Operators
Relational Operator | Purpose |
---|---|
== | Equal |
!= | Not equal |
< | Less than |
<= | Less than or equal to |
> | Greater than |
>= | Greater than or equal to |
The relational operator in Java/C# is two equal sign symbols (==
) whereas the relational operator in other programming languages is just a single equal sign symbol (=
). If you only use a single equal sign to compare two values in Java/C#, your program will work but not the way it's supposed to.
Logical operators compare two Boolean values (True
or False
) and return a single True
or False
value, as shown in Table 2-6.
Table VI.2-6. Logical Operators
Logical Operator | Truth Table |
---|---|
&& | True && True = True True && False = False False && True = False False && False = False |
|| | True || True = True True || False = True False || True = True False || False = False |
! | !True = False !False = True |
Both Java and C# have a special increment (++
) and a decrement (--
) operator, which simply adds or subtracts 1
to a variable. Typically, adding 1
to a variable looks like this:
j = 5; i = j + 1;
The increment operator replaces the + 1
portion with ++
, such as
j = 5; i = ++j;
In the preceding example, the value of i
is j + 1
or 6
, and the value of j
is also 6
.
If you place the increment operator after the variable, such as
j = 5; i = j++;
Now the value of i
is 5
, but the value of j
is 6
.
The decrement operator works the same way except that it subtracts 1
from a variable, such as
j = 5; i = --j;
In the preceding example, the value of i
is j - 1
or 4
, and the value of j
is also 4
.
If you place the decrement operator after the variable, such as
j = 5; i = j--;
Now the value of i
is 5
, but the value of j
is 4
.
Most programming languages use the equal sign to assign values to variables, such as
i = 59;
However, Java/C# also includes a combination assignment and mathematical operators, as shown in Table 2-7.
Table VI.2-7. Assignment Operators
Assignment Operator | Purpose | Example |
---|---|---|
+= | Addition assignment | i += 7 (equivalent to i = i + 7) |
-= | Subtraction assignment | i -= 4 (equivalent to i = i - 4) |
*= | Multiplication assignment | i *= y (equivalent to i = i * y) |
/= | Division assignment | i /= 3.5 (equivalent to i = i / 35) |
%= | Modulo assignment | i %= 2.8 (equivalent to i = i % 2.8) |
The simplest branching statement is an IF
statement that only runs one or more commands if a Boolean condition is True
, such as
if (condition) { Command; }
To make the computer choose between two mutually exclusive sets of commands, you can use an IF-ELSE
statement, such as
if (condition) { Command; } else { Command; }
Java and C# also offer an IF-ELSEIF
statement, which uses two or more Boolean conditions to choose which of two or more groups of commands to run, such as
if (condition1) { Command; } else if (condition2) { Command; }
Although the IF-ELSE
statement can only give the computer a choice of two groups of commands to run, the IF-ELSEIF
statement can offer the computer multiple groups of commands to run, such as
if (condition1) { Command; } else if (condition2) { Command; } else if (condition3) { Command; }
As an alternative to the IF-ELSEIF
statement, you can also use the SWITCH
statement, such as
switch (expression) { case value1: Command; break; case value2: Command; break; default: Command; }
The SWITCH
statement always needs to include the break
command to tell the computer when to exit the SWITCH
statement.
The preceding SWITCH
statement is equivalent to the following IF-ELSEIF
statement:
if (expression = value1) { Command; } else if (expression = value2) { Command; } else { Command; }
To check if a variable matches multiple values, you can stack multiple CASE
statements, such as
switch (expression) { case value1: case value2: Command; break; case value3: case value4; Command; break; default: Command; }
The preceding SWITCH
statement is equivalent to the following IF-ELSEIF
statement in C++:
if (expression = value1) || (expression = value2) { Command; } else if (expression = value3) || (expression = value4) { Command; } else { Command; }
One main difference between C# and Java is the way each language handles fall-through, where multiple CASE
statements can run if a break
command isn't inserted into each one. Consider the following SWITCH
statement in Java, which allows fall-through:
switch (age) { case 17: case 18: case 19; case 20; System.out.println("You're too young to drink."); case 21: System.out.println("You're old enough to drink."); }
In this example, the SWITCH
statement will print the following if the value of age is 17, 18, 19
, or 20
:
You're too young to drink. You're old enough to drink.
Because no break
command is right above the case 21:
statement, the Java program falls-through to the next CASE
statement. In C#, you must explicitly define the fall-through (if this is what you want), such as
switch (age) { case 17: case 18: case 19; case 20; System.out.println("You're too young to drink."); goto case 21; case 21: System.out.println("You're old enough to drink."); }
This C# SWITCH
statement explicitly tells the computer to fall-through to the case 21:
statement. If you omit the goto case 21
statement, the preceding C# SWITCH
statement won't work. By forcing you to explicitly define the fall-through in a SWITCH
statement, C# helps prevent mistakes in writing a SWITCH
statement incorrectly.
A looping statement repeats one or more commands for a fixed number of times or until a certain Boolean condition becomes True
. To create a loop that repeats for a fixed number of times, use the FOR
loop, which looks like this:
for (startvalue; endvalue; increment) { Command; }
If you wanted the FOR
loop to run five times, you could set the Start value to 1
and the End value to 5
, such as
for (i = 1; i <= 5; i++) { Command; }
If you don't know how many times you need to repeat commands, use a WHILE
loop, which looks like this:
while (condition) { Command; }
If the condition is True
, the loop runs at least once. If this condition is False
, the loop doesn't run.
A variation of the WHILE
loop is the DO-WHILE
loop, which looks like this:
do { Command; } while (condition);
The main difference between the two loops is that the WHILE
loop may run zero or more times, but the DO-WHILE
loop will always run at least once.
Somewhere inside a WHILE
and DO-WHILE
loop, you must have a command that can change the condition from True
to False
; otherwise, the loop will never end, and your program will appear to hang or freeze.
In Java/C#, every subprogram is a function that can return a value. The format of a typical Java function looks like this:
Datatype functionname (Parameter list) { Commands; Return value; }
The three parts of a C/C++ function are
Data type: Defines the type of value the function returns, such as an integer (int
) or floating point number (float
). If you define the data type as void, then the function doesn't return a value.
Parameter list: Defines any data and their data types that the function needs to work.
Return: Defines a value to return. This value must be the same data type specified right before the function name.
If a function doesn't return a value or require any data, it might look like this:
void myfunction () { Command; }
If the function needs to return an integer value, it might look like this:
int myfunction () { Command; return value; }
In the preceding example, value
represents any integer value.
To accept data, a function needs a parameter list, which simply lists a variable to hold data along with its specific data type, such as an integer or character. To create a function that accepts an integer and a character, you could do something like this:
int myfunction (int mynumber, char myletter) { Command; return value; }
The preceding function accepts two values by value, so the function can change the values of variables in its parameter list, but those changed values won't appear outside that function.
If you want a function to change the values of its parameters, define a parameter list by identifying which variables accept values by reference. To identify values passed by reference in C#, use the ref
keyword, such as
int myfunction (ref int mynumber, char myletter) { Command; return value; }
Through built-in libraries, Java and C# offer a variety of data structures beyond most programming languages. In Java, the most common data structures are arrays and linked lists. In C#, the .NET framework provides a variety of data structures including structures, arrays, collections, dictionaries, queues, and stacks.
Unlike Java, C# offers a structure, which acts like a variable that typically holds two or more variables. To create a structure, use the struct
keyword as follows:
struct name { public datatype variable; };
The name of a structure can be any descriptive name, such as people2get
or my_relatives
. Inside a structure, you must declare one or more variables. A typical structure might look like this:
struct MyGrades { public char grade; public int class_number; };
After defining a structure, you can declare a variable to represent that structure, such as
struct geology = MyGrades();
After declaring a variable as a structure, you can store data in the individual fields of a structure like this:
struct geology = MyGrades(); geology.grade = "A"; geology.class_number = 302;
Arrays in Java/C# are known as zero-based arrays, which means that the first element of the array is located at index number 0
, the second element of the array is located at index number 1
, and so on.
To create an array in Java, declare its data type and size, such as
datatype [] arrayname = new datatype[arraysize];
The array name can be any descriptive name. The array size defines how many items the array can hold. To create an array that can hold ten integers, you could define an array like this:
int [] mynumbers = new int[10];
You can create an array and store values in it at the same time by doing the following:
int [] mynumbers = new int[4] {25, 81, 4, 712};
This is equivalent to
int [] mynumbers = new int[4]; mynumber[0] = 25; mynumber[1] = 81; mynumber[2] = 4; mynumber[3] = 712;
Java offers a linked list class, which simplifies managing a linked list. By using a linked list, you can create other data structures, such as stacks and queues. To create a linked list, define a variable, such as
LinkedList listname = new LinkedList();
You can also define the data type to store in a linked list, such as
LinkedList <datatype>listname = new LinkedList<datatype>();
To add an item to a linked list, use the add, addFirst
, or addLast
method with the name of the linked list, such as
LinkedList shopping_list = new LinkedList(); shopping_list.add("Eggs"); shopping_list.addFirst("Milk"); shopping_list.addLast("Bacon");
The first item stored in the linked list would be "Milk"
, followed by "Eggs"
, and "Bacon"
.
To retrieve data from a linked list, you can use the getFirst, remove, removeFirst
, or removeLast
method. The getFirst
method retrieves data only from the linked list whereas the remove, removeFirst
, and removeLast
methods physically yank that data out of that linked list:
LinkedList shopping_list = new LinkedList(); shopping_list.add("Eggs"); shopping_list.addFirst("Milk"); System.out.println("First = " + shopping_list.removeFirst()); System.out.println("First = " + shopping_list.getFirst());
The preceding Java code would print the following:
First = "Milk" First = "Eggs"
C# includes queues, stacks, and hashtables, which you can create by using the same syntax, such as
Queue queuename = new Queue(); Stack stackname = new Stack(); Hashtable tablename = new Hashtable();
Each type of data structure uses different methods for adding and removing data. A queue uses the Enqueue
and Dequeue
methods to add and remove data. A stack uses the Push
and Pop
methods to add and remove data. A hashtable uses the Add
and Remove
methods to add and remove data.
Both Java and C# are true object-oriented programming languages (unlike C++), so you have no choice but to create and use objects in your programs. To create an object, you must define a class stored in its own file. A typical class definition looks like this:
class ClassName { datatype propertyname; void methodname() { Commands; } };
The class lists one or more properties and the type of data that property can hold, such as an integer or a floating point number. A class also lists one or more method names, which contains code for manipulating an object in some way.
After you define a class, you can create an object from that class by declaring a variable as a new class type, such as
className objectname = new className();
So if you created a furniture
class, you could create a table
object from that class as follows:
furniture table = new furniture();
To use inheritance in Java, use the extends
keyword, such as
class className extends classtoinheritfrom { // Code goes here };
To use inheritance in C#, use the colon to identify the class to inherit from, such as
class className : classtoinheritfrom { // Code goes here };