(Updated January 5, 2025)
Table of contents
-
Overview
Components of the Language
Data Types
Arithmetic Operators and Precedence
String Class
Named Constants and Variables
VIDEO – Basic Java Program
Basic Input/Output
Escape
Increment, Decrement, Concatenation and Comments
The Dot Operator
VIDEO – Java Program Demonstrating Basic I/O
Quiz
Exercises
Overview
This is an extensive chapter. Many components of the Java programming language are presented throughout. Although the quiz can measure comprehension and retention, the best approach is to consume this chapter in small portions.
Take your time and remember that this is a 10,000-foot view of the language. Refer to this chapter often when determining the use of certain data types and operators. This chapter will always be here, so do not worry if it is not all sticking at once.
Remember that, as with anything new, we have to start somewhere. So, we begin with the language’s fundamental components.
Components of the Language
The Java language is relatively small when you look at the parts that make up the core aspects of the language. First, we will discuss the rules and the meaning of the language. Like any foreign language, some rules govern how the language may be written, and there is understanding or sense derived from how the words are arranged. For example, saying, “The car belongs to Bill.” We know that the subject, car, and the object, Bill, are arranged such that we can derive the meaning of Bill owning a vehicle. We can derive further meaning if there are surrounding sentences of a paragraph in which this original sentence belongs. Perhaps we would learn that Bill’s car is large or small, it’s color, or if it is gas, diesel, or electric.
Every language has syntax rules that govern how the language may be written. The semantic rules help us to determine meaning. Java is broken down into three basic parts, or tokens, for writing the language. These tokens are symbols, reserved words and identifiers.
Symbols are simply the characters we use in everyday writing. Punctuation, arithmetic, and relational symbols are used throughout the program. Table 1 lists some categories of symbols. Note that regardless of the number of characters used to make the symbol, it is considered one symbol.
Punctuation | . | , | ; | “ | ! |
Arithmetic | + | – | * | / | % |
Relational | <= | != | > | < | == |
Table 1: Some symbols used in Java.
Reserved words, also called keywords, are a standard set of words that are set aside specifically for the Java language. You may not reuse these words as identifiers. The compiler will let you know that using the reserved word is inappropriate by signaling a syntax error when you compile your program. When using an IDE, you will also know that the word is reserved when the word you are using has a different color from the identifiers. Some reserved words are listed in Table 2.
for | while | do | if | else |
switch | case | int | float | char |
throws | return | implements | double | void |
Table 2: A partial list of reserved words.
A complete list of reserved words can be found here.
Identifiers are used to label things. These things are often variables, methods, or literals. Like the rest of the Java language, identifiers are case-sensitive. The identifiers you create may contain letters, digits, the underscore character (_), and the dollar sign ($). Your identifiers, however, must not begin with a digit. They can begin with any of the other characters. It is conventional to limit the underscore and dollar sign to special purpose identifiers or use the underscore where spaces ordinarily appear in everyday language. A few acceptable identifiers are shown in Table 3.
sum | totalWords | Sum |
Total_Words | Word_Count$ | myLittleVariable |
Table 3: Examples of unique and valid identifiers.
Data Types
There are three primitive data type categories: integral, floating-point and boolean. You may already know what these types are just from their names. Integral types are whole number quantities, floating-point allows for precision by representing a fractional portion, and boolean indicates truth value.
Integral
There are five integral types and their properties are displayed in Table 4.
Data Type | Range of values | Size in bytes (bits) |
---|---|---|
char | 0 to 65535 | 2(16) |
byte | -128 to 127 | 1(8) |
short | -32768 to 32767 | 2(16) |
int | -2147483648 to 2147483647 | 4(32) |
long | -922337203684547758808 to 922337203684547758807 |
8 (64) |
Table 4: Values and sizes of integral data types.
The only integral data type that has special written properties is char
. The values that represent this type use single quotes to denote that value as a char
literal. A few examples of these literals are ‘+’, ‘A’, ‘(‘ and ‘n’. Without the single quotes the plus symbol may be mistaken for an arithmetic operator, or the open parenthesis as part of the Java language, or the letters mistaken for identifiers.
Characters are stored as Unicode (https://www.unicode.org). Characters are numeric quantities, and the characters we use with single quotes are human consumable forms, so we do not need to memorize the entire character set. The table of values to characters is standardized and represents a collating sequence for several character ranges.
Since part of Unicode follows the original ASCII collating sequence, three starting points need to be mentioned. The digit ‘0’ (48), capital ‘A’ (65) and lower case ‘a’ (97). Following ‘0’ is the digit ‘1’, then ‘2’ and so on. The same goes for the two starting points for the alphabet. If ‘A’ is 65, then ‘B’ is 66 and ‘C’ is 67.
Floating-point
There are two floating-point data types and their properties are displayed in Table 5.
Data type | Range of values | Significant Digits | Size in bytes (bits) |
---|---|---|---|
float | -3.4E+38 to 3.4E+38 | 6 or 7 | 4(32) |
double | -1.7E+308 to 1.7E+308 | 15 | 8 (64) |
Table 5: Properties of floating point data types.
Boolean
The boolean data type has only two possible values. They are true
and false
.
Literals
The term literal has been mentioned above and requires more to be said on the topic. The term literal means representing exact meaning whereby the intent is clear. When we say
x = 7;
We know the variable contains the value 7 when we are done. Or
c = 'A';
There is no doubt regarding the case of the letter A. We use the term literal for any value not expressed by acquisition from another source. For example with
x = y;
There is no literal value since y
already contains some value to be assigned to x
. Some examples of literal values are shown below:
int i = 35;
long l = 734L; // The use of L or l denotes a long type.
int o = 013; // octal for 11.
int x = 0x80; // hexadecimal for 128.
float f = 3.14f; // the f denotes a float type and avoids type conflict with double.
double d = 3.14d; // the d is optional since Java assumes double for this literal.
boolean b = true;
char c = '#'; // single quotes for chars
String n = "Bill"; // double quotes for strings
Arithmetic Operators and Precedence
There are five arithmetic operators as shown in Table 6. These operators may be used to construct expressions. An expression is something simple like 3+2 or 8/5. So our expressions are made up of operators and operands. Operands are the values the operators work with. The previous examples are known as integer expressions. They are integer expressions because they have two integers as their operands, and the result will be an integer. Note that operands can be literals, identifiers, and other expressions.
Operator | Purpose |
---|---|
+ | addition |
– | subtraction |
* | multiplication |
/ | division |
% | modulus (remainder) |
Table 6: Arithmetic operators.
The operators in Table 6 are also known as binary operators. Not because they work with binary numbers, but because they require two operands. You are probably familiar with the unary operators –
and +
. These can be seen when discussing the value -3. See how the minus sign has only one operand? It says that the value of 3 is negative as opposed to positive.
Why is it necessary to talk about unary and binary operators? Consider the expression
x = 4 - -3;
Some would look at this and say, “Syntax error!” Quite the contrary. It says four take away a negative three or four minus negative 3 which is the equivalent of 4 plus 3. The result is 7.
Operator precedence is an issue when multiple operators are mixed within the same expression. Operator precedence allows us to know the order in which the operators will be applied to the values. Of course, we can alter the default precedence rules by simply using parentheses. The higher precedence operators nearest the top are done first. When many arithmetic operators of the same precedence, the operators will be evaluated from left to right.
Table 7 shows the complete Java precedence order for operators. Again, precedence is higher toward the top. All operators are evaluated left to right except assignments which are evaluated right to left.
Operator Precedence (highest to lowest) postfix exp++ exp-- unary ++exp --exp +exp -exp ~ ! multiplicative * / % additive + - shift << >> >>> relational < > <= >= instanceof equality == != bitwise AND & bitwise XOR ^ bitwise OR | logical AND && logical OR || ternary ? : assignment = += -= *= /= %= &= ^= |= <<= >>= >>>=
Table 7: Java precedence list.
Expressions With Mixed Types and Type Conversion
There will come a time when you will have values of varying types from varying sources. When this happens, we have to keep some simple rules in mind for how things will be evaluated and what the resultant type will be.
We can apply the rules to each operator such that:
- If the operands of an operator are the same type, then the result is that type (
int
plusint
yields anint
). - If the operands of an operator are of different types (
int
andfloat
, for example), then the result is the type with higher precision (int
plusfloat
yields afloat
).
Rule number 2 is also known as implicit type coercion.
If we need to change a type temporarily for a specific purpose, we can also use a cast or explicit type coercion. The cast acts as a temporary type of conversion. First, the most straightforward expression to the right of the cast is evaluated then the cast is applied. The following few examples show how to perform a cast.
Java Code Example | Result |
---|---|
(int)7.9 |
yields 7 since the double is converted to an int . (The value 7.9 is considered to be a double value.) |
(float)25/6 |
yields 4.1666665 since int 25 is converted to float and divided by the int 6 (see rule 2, above). |
(float)(25/6) |
yields 4.0 since the two int s are divided which yields no precision and the 4 is converted to 4.0 (see rule 1, above). |
String Class
The String
class was briefly mentioned above and is a complex data type that is used to represent data that a single char
cannot, such as a person’s name, a street address, or the name of a country.
Strings are easy to represent. They use double quotes to denote the string’s value, much like single quotes indicate a char
literal value.
String name, street, country;
name = "Bill";
street = "23 Route 2";
country = "United States";
The empty string or null string is represented as empty double quotes (""
) and has a length of zero. The characters that make up a string are individually addressable. This means for the string "Bill"
:
'B'
is at position 0'i'
is at position 1'l'
is at position 2- and the second
'l'
is at position 3
The length of the string is 4 since 4 characters make up that name.
Classes use methods to obtain additional information from objects or to place information into them. The next example uses length()
and charAt()
from the String
class.
//declare some variables
String name;
int len;
// assign some values
name = "Bill";
len = name.length();
// get chars and print results
System.out.println(name.charAt(0));
System.out.println(name.charAt(1));
System.out.println(name.charAt(2));
System.out.println(name.charAt(3));
System.out.println("The length of the string is " + len);
This is a small demonstration of what can be done with strings. We cover the String
class in greater detail in Chapter 3.
Named Constants and Variables
When we need to keep track of things, we usually organize the information to allow us to find it again. Ideally, the data a Java program uses needs to be held somewhere so that it can be referenced on demand by some name. These values are kept in memory, and names are assigned so that we are not responsible for remembering where the data is stored in memory.
Named constants allow you to use a word to represent a value. Consider the value Pi, which is estimated to be 3.14159. This value can easily be represented in a float
, so consider the following constant declaration.
final double PI = 3.14159;
A declaration announces to the compiler, “I plan on using this named location in memory for the following purpose: PI is a constant representing 3.14159.” It is a constant because of the reserved word final
applied to the declaration.
The declaration is read aloud as “PI is a double whose final value is 3.14159.” Attempts to change a constant will yield an error from the compiler.
On the other hand, Variables allow the data to change while keeping the same name. Consider the following variable declaration.
int sum;
This says, “sum
is a variable of type int
.” By default, there is no value assigned to a variable. Its starting value is considered to be undefined and you should never assume it to be zero. So perhaps we really should have said, “sum
is an int
variable whose starting value is undefined.”
If you want a guarantee, use the following:
int sum = 0;
This says, “sum
is an int
variable whose starting value is zero.” The equal sign is also known as the assignment operator. The assignment operator will get quite a workout as values are always changing in your variables. Instead of saying, “sum equals zero,” which implies a statement of equality, it would be more correct to say, “sum gets the value of zero.” This more closely represents what is really happening.
Literals – precise values represented in the code like
32
, 3.14
, 'a'
and "Bobby"
.Constants – named containers of information whose value is fixed. This is typically achieved with the
final
modifier.Consider the program in Example 1.
public class Variables {
public static void main (String[] args) {
// declaring some ints and a double.
int test1, test2, test3, sum;
double average;
// direct assignment of values
test1 = 90;
test2 = 85;
test3 = 87;
// sum assigned as the result of an expression.
sum = test1 + test2 + test3;
// calculate the average preserving precision.
average = sum / 3.0;
System.out.println("The average is " + average);
}
}
Example 1: Program to calculate an average using variables.
The output from this program is:
The average is 87.33333333333333
There are several things to note about this program.
- Several variables of type
int
are declared on the same line by using commas to separate the names. - The value contained in
sum
is divided by thedouble
value 3.0 to force an implied coercion of the result to thedouble
type, which is then stored inaverage
. - The value contained in
average
is appended to the end of the string literal in the output statement. (There are no quotes aroundaverage
) - The plus sign (+) is used to join the two parts of the output. It is the concatenation operator.
- The variable
sum
could be eliminated. Consider for a moment how you would rewrite the average calculation if you eliminatedsum
.
Video showing a basic Java program.
Basic Input/Output
System.out
refers to the standard output stream object and println()
(read print-line) is a method of that object. For our purposes we can think of standard output as the screen. The println()
method always moves the cursor to the beginning of the next line after printing whatever is provided in the parentheses.
It is essential to review the chronology of the program in Example 1.
- The variables are declared.
- Values are assigned for the three test grades.
- The sum is calculated.
- The average is calculated and displayed.
Putting the output statement first, we have nothing to display. When working through any solution, keep in mind the steps necessary to solve a problem. This example is rudimentary, and you can expect your programming projects to be more complex than this. Still, the premise is the same: determine what must happen first, what must occur after that, etc.
Consider what you would do if you had to read values from the user instead of assigning them directly using literals. The Scanner
class is a simple way to read data from an input stream. In particular, we will use System.in
which is the standard input stream object. Since we can view the standard input stream as the keyboard, we will declare our Scanner
class object as follows:
static Scanner kb = new Scanner(System.in);
This declaration says, “kb
is a static reference variable of type Scanner
that gets the value of a new Scanner
object wrapped around System.in
“. We intend to use kb
to read input from the user.
import java.util.Scanner;
public class UserInput {
static Scanner kb = new Scanner(System.in);
public static void main(String[] args) {
int test1, test2, test3;
double average;
// altername prompting and reading from the user.
System.out.print("Enter test 1: ");
test1 = kb.nextInt();
System.out.print("Enter test 2: ");
test2 = kb.nextInt();
System.out.print("Enter test 3: ");
test3 = kb.nextInt();
// calculate and print results.
average = (test1 + test2 + test3) / 3.0;
System.out.println("The average is " + average + ".");
}
}
Example 2: Program modified to read values from the user.
The program in Example 2 is fundamentally the same as Example 1, with test data read from the user using the Scanner
object created and assigned to the reference variable kb
. A sample run with the user-provided values in bold is shown here:
Enter test 1: 90
Enter test 2: 85
Enter test 3: 87
The average is 87.33333333333333.
There are some items to note about this program:
- The variable
sum
was eliminated. - The
nextInt()
method ofkb
returns the input in the form of an integer and stores the value in the variable to the left of the assignment operator. - There is an alternation of prompt, read, prompt, read. This is necessary to inform the user what to do next.
- An additional method,
print()
, is used to hold the cursor on the same line as the prompt. Recall thatprintln()
moves the cursor to the next line.
import
statement. In order to use the Scanner
class, we must import the class from the package that defines it. That package is java.util
. It is common to require more than one class from a package and although we could import java.util.*
, we will simply use java.util.Scanner
. Import only what you need.Another package (and its associated classes and methods) is automatically imported for every Java class you write. It is known as java.lang
.
Integers are not the only things we would want to read. What about characters, words, lines of text, and precision values? Additional methods assist with this. Some common Scanner
class methods are shown in Table 7.
Scanner Method | Purpose |
---|---|
nextInt() |
Read next value as an integer. |
nextDouble() |
Read next value as a double. |
next() |
Read next word. |
nextLine() |
Read next complete line up to, but excluding, newline. |
next().charAt(0) |
Read next character. (The next() method returns a String object which then has the charAt() method applied to that String object to obtain the first character). |
Table 7: A sample of Scanner methods.
So how do these methods know where one piece of data ends and the next one begins? Well, undoubtedly because of our use of the Enter key. More to the point, these methods break on whitespace. This means the methods will end identification of the requested data type when a space, tab, carriage return, or newline is discovered during processing except nextLine()
, which only breaks on the newline character. This is not particularly useful knowledge since we will be using the Enter key for our input handling. This will be useful, however, when file handling becomes necessary.
Consider the last item in Table 7. If you recall from our String
class discussion, every character has a position. The charAt(0)
method call retrieves the first character returned by the next()
method. This is possible because charAt()
is a String
method and next()
returns a String
. This is also necessary to get a single character from the user since no method exists in the Scanner
class that does this naturally. In other words, there is no nextChar()
method.
Connecting method calls together in a single statement is a common practice. There will be examples of method calls related to the dot operator throughout this book.
Escape
Have you considered how we store the single quote character in a char
variable if single quotes are used to define characters? Or, how do we print a double quote character if double quotes define the boundaries of a String
value? Can we print a blank line other than using the following?
System.out.println("");
It is often necessary to print characters otherwise reserved for a particular use. All issues raised are quickly resolved with escape sequences. Escape sequences are represented by a leading backslash (\) which changes the meaning of the very next character.
Consider the following:
char squote;
String fiveBlankLines;
squote = '\'';
fiveBlankLines = "\n\n\n\n\n";
The character sequence \'
escapes the single quote character making it simply a single quote and not part of the delimiting quotes for a character literal. The assignment statement actually stores a single quote character into squote
. A similar concept is applied to the sequence \n
, making the n special – this n represents the newline character. A list of escape sequences is shown in Table 8.
Escape Sequence | Purpose |
---|---|
\n | Newline. Moves cursor to beginning of next line. |
\t | Tab. Moves cursor to next tab stop. |
\\ | Backslash. Represents a backslash. |
\” | Double quote. Represents a double quote within a string or character literal. |
\’ | Single quote. Represents a single quote within a string or character literal. |
\b | Backspace. Move cursor back one character. |
\r | Return. Move cursor to beginning of current line. |
Table 8: Common escape sequences.
Increment, Decrement, Concatenation and Comments
Some additional aspects of the Java language that require mention but not a great deal of detail are listed here.
The increment (++
) and decrement (‐‐
) operators are unary operators similar to unary plus and unary minus. One important difference is ++
and ‐‐
may appear on either side of the expression element. This defines pre- or post- for the operator.
Consider the following:
int x=4, y=6, z, a;
// placement doesn't matter
x++; // x is now 5
--y; // y is now 5
// now placement matters
z = x++; // assign x to z before incrementing
a = ++y; // increment y then assign to a.
System.out.println("x is " + x + "\ny is " + y + "\nz is " + z + "\na is " + a);
Recall from our code examples where the plus (+) operator was used inside the println()
method. Again, this is the concatenation operator for String
objects.
Further examples of concatenation are shown here:
String name, greeting, statement;
name = "Bill";
greeting = "Good morning";
statement = greeting + ", " + name + ".";
The concatenation operator is used to take the parts of the verbal statement and put them together, forming a new String
object assigned to statement
as “Good morning, Bill.” complete with punctuation.
Lastly, comments are the favorite tool of any good programmer to document their program, especially complex or non-intuitive solutions. Comments come in two forms – the //
form and the /* */
form.
int x; //comment to end of line describing purpose of x
/*
This comment is allowed to span lines.
It is pretty useful when the necessary programming note
requires much more detail than a single line will allow.
*/
x = 10;
As you can see, the //
comment is only a comment until the end of the line. and the /*
…*/
comment may span multiple lines. Note that there are no spaces between any of the comment characters.
The Dot Operator
You may have noticed at this point that there is a period or dot between class names or reference variables and the methods we wish to access, such as in:
System.out.println("Hello!");
and
x = kb.nextInt();
The dot between kb
and nextInt()
is known as the member access operator. This operator indicates that we wish to access or call the nextInt()
method, which is a member of kb
. More to the point, since kb
refers to a Scanner
class object, we are actually accessing the nextInt()
method of the Scanner
class.
The dot is required otherwise we would have code that looks like this:
Systemoutprintln("Hello!");
and
x = kbnextInt();
Both are legal identifiers and could represent actual methods created by the user, but certainly is not what was intended by the code.
Video showing basic I/O capabilities.
Quiz
Exercises
[Note: All of this can be done using the basic template from Chapter 1.]
- (Beginner) Declare a
String
calledname
. - (Beginner) Declare an
int
calledi
, adouble
calledd
andboolean
calledb
. - (Beginner) Assign appropriate values to each variable and use
println()
to display the contents of each, separately. - (Intermediate) Intentionally create errors in some statements to see how the compiler conveys its knowledge of the issue. These should include:
- Missing punctuation.
- Assigning inappropriate values to variables.
- Leaving quotes or parenthesis unbalanced.
- (Advanced) Declare a
Scanner
calledkb
as in the notes and use it to read in values to populate the variables noted above. [You may have to read ahead a bit!]