Variables in Java
All data used by a program is stored in the computer’s memory. On a typical PC with 8 GB of RAM, there are roughly 8 billion 1-byte locations where data can be stored. Each one of those locations has an address (number) to locate it so that the CPU can fetch and store data there. A good analogy is a street where you live: each house on the street has a unique number (address) that identifies it.
As a programmer, it would be tedious if we had to refer to memory locations using numerical addresses in our code. Instead, programming languages support variables. A variable is a named memory location where data is stored.
Java is a statically typed language. This means that before we can use a variable in our program we need to give it a name and define the specific kind of value it can store (e.g., an integer, real number, Boolean value etc.). After a variable is declared in Java its name and type cannot change but the value stored in the variable can change as the program runs. Some languages, like Python, are dynamically typed which means that variables don’t need to be declared in advance before they are used and they can store any type of data while the programs runs.
Types of Data
As shown in the table below, there are several important primitive data types in Java. A primitive data type is used to store a single value as efficiently as possible.
Data Type | Description | Java Keyword | Memory Used | Range of Values |
Integers | negative and positive whole numbers, including 0 | int | 4 bytes
(32 bits) |
from -2,147,483,648 to 2,147,483,647 |
Real Numbers | negative and positive floating-point numbers, including 0.0 | double | 8 bytes
(64 bits) |
from 1.7976931348623157 E+308 to 4.9 E-324 |
Boolean | true or false | boolean | 1 bit | false, true |
Character | a single Unicode character | char | 2 bytes
(16 bits) |
any Unicode character enclosed in single quotes, or its Unicode value; i.e., ‘A’ or 65 |
Here’s an example demonstrating how to declare and initialize a variable of each of these types:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class Variables { public static void main( String[] args ) { int age; age = 17; double courseMark = 97.89; boolean topStudent = true; char firstInitial = 'V'; System.out.println( "Age is " + age ); System.out.println( "Mark is " + courseMark + "%" ); System.out.println( "Top Student " + topStudent ); System.out.println( "Initial is " + firstInitial + "." ); } } |
Age is 17
Mark is 97.89%
Top Student true
Initial is V.
Line 3 demonstrates declaring a variable (age) by giving it a name and specifying its type. In terms of style, it’s best to declare variables at the top of the block in which they are declared. Line 4 is an assignment statement that gives the variable age a starting value of 17.
The left side of an assignment statement must always be a variable name; for example 17 = age; is a syntax error in Java. It’s also important to ensure that variables have been initialized (i.e., have a defined starting value) before attempting to display them or use them in a calculation. Try commenting out line 4 and see what happens when you compile.
Lines 6 through 8 show how to declare and assign a starting value to a variable all in one step. Notice that char data is enclosed in single quotation marks (‘), not double quotes (“). Once these four variables have been assigned their initial values, you can imagine them in memory like this:
Lines 10 to 13 display the contents of the four variables. Note the use of the + operator to append the output string with each variable, this is called concatenation.
The Whole Truth
I have introduced you to the int, double, boolean, and char primitive data types, but there are 4 more: byte, short, long, and float. As a learner, the four I’ve left out are not critical at this point.
Strings
The char data type allows us to store a single character but often we need to work with sequences of characters called strings. In Java, a String is a special type of data called an object created from a class called String. An object can store data like a variable, but also includes methods to manipulate the data. We’ll learn about String methods later.
1 2 3 4 5 6 7 |
public class Strings { public static void main( String[] args ) { char firstInitial = 'J'; String lastname = "Bond"; System.out.println( firstInitial + ". " + lastname ); } } |
J. Bond
Note that String is capitalized on line 4 to differentiate it from a primitive data type which is always lowercase. Unlike char variables, string data must be enclosed in double “ quotation “ marks. Also, a string may be empty “” or contain any number of characters, including just one. This means, in the example above, that firstInitial could have been declared as a String instead.
The lastname variable is declared to be of type String. This means that it may only refer to a String object in memory, not any other type of object. Variables that refer to objects in memory are called reference types. A reference type variable is different from a primitive type because it does not store a data value, instead it stores the memory address of where the actual data is located in RAM. This memory address (or pointer) is represented with an arrow in the illustration below:
The null Keyword
We know that it’s important to assign a starting value to variables before using them in our program. Sometimes we’ll know what value the variable should contain when it’s created and sometimes we won’t. In cases where we don’t know, it’s common to assign starting values like 0 (for int), 0.0 (for double), and false (for boolean). Assigning variables a value that we know is safer than leaving their values undefined.
For reference types, like String variables, the null keyword is used to mean that the reference variable does not currently refer to an object in memory (yet). Consider:
1 2 3 4 5 6 7 8 9 |
public class NullRef { public static void main( String[] args ) { String lastname = null; System.out.println( lastname ); lastname = "Bond"; System.out.println( lastname ); } } |
null
Bond
Line 3 is declaring a String reference variable called lastname and assigns it a value of null. Here’s an illustration of what this looks like in memory:
On line 5, when we print lastname, “null” is displayed. If we had not assigned the value null to lastname on line 3, the Java compiler would give an error that lastname had not initialized – try it! On line 6, we create a String object in memory and assign lastname the reference (memory address) to it, as illustrated earlier.
Naming Conventions
Before moving on, we should talk about how to properly name your variables. Java has three syntax rules for variable naming:
-
- Variable names may contain only letters, digits, $, and _ but must never start with a digit. No other symbols or spaces are allowed.
- Java is case-sensitive; the variable name age is considered different from Age.
- You may not use a Java keyword (i.e., a reserved word) for a variable name; for example, public, class, static, or void. There are about 50 keywords in Java.
If you break one of the rules above you will get a compiler error.
As a programmer, there are also three style conventions that you should follow to make your code as readable as possible.
-
- Choose names that are as meaningful as possible. Avoid single-letter variables and cryptic abbreviations.
- Although technically allowed, the $ and _ characters should be avoided.
- Use camelCase. If a variable name consists of just one word it should be all lowercase. If it consists of more than one word, capitalize the first letter of each word after the first word. For example, topStudent, or savingsAccountBalance. The uppercase letters are supposed to be the humps on the camel’s back – can you spot them?
Implicit Casting
Consider the following statement:
1 |
double courseMark = 99; |
Even though 99 is an integer (it does not include a fractional part, not even .0) we can assign it to this double variable without a problem. This is called implicit casting. In other words, the Java compiler automatically converts the 99 to 99.0 before the assignment. There is no danger in doing this because no precision will be lost.
Implicit casting is also called a widening conversion because you are going from a data type with less precision (fewer bytes) to greater precision (more bytes). For example, char data will be implicitly cast to int, and int to double without losing information about the overall magnitude of the data value being stored.
Explicit Casting
But consider the opposite situation, where data might be lost if a value gets converted.
1 |
int age = 17.5; // Syntax Error! |
Here the Java compiler will give a syntax error because it cannot convert 17.5 into an int value without losing the fractional part. This line will not compile. As a programmer if you really need to do something like this, and you are confident that the lost precision will not cause a problem later in your logic, you can use a technique called explicit casting. To do this you simply add the data type in parenthesis ( ) before the data you need to explicitly cast, like this:
1 |
int age = (int)17.5; // explicitly cast 17.5 to 17 |
Explicit casting from a real number to an integer will truncate (not round) the value. That is, 17.5 will not become 18, the .5 will be truncated (thrown away) and 17 will remain. Another name for explicit casting is a narrowing conversion because you may lose information about the data value being stored. Essentially, what you are doing is telling the Java compiler that you are aware that precision will be lost, but that you want to do it anyway!
There is a trick to have an explicitly casted double value rounded instead of truncated, you simply add 0.5 to the value being explicitly cast like so:
1 2 |
double exactAge = 17.5; int approxAge = (int)(exactAge + 0.5); |
Here approxAge will have a value of 18.
By the way, it’s not possible to convert to or from a boolean type or between any primitive type and a reference type (like Strings) using implicit or explicit casting.
You Try!
-
- Add an entry for “1-2 Variables” in your Learning Journal and answer the following questions:
- Explain how declaring variables in Java is different from what you are used to in Python.
- Write a program that attempts to display the value of a variable before you have given it an initial value. What error message do you get?
- Consider the following variable names:
Which names will cause a compiler error? Which ones break a style rule? - Research the byte, short, long, and float primitive data types. Create a summary chart for them similar to the one in the notes above.
- Update your glossary with terms you are unfamiliar with from the notes above.
- Add an entry for “1-2 Variables” in your Learning Journal and answer the following questions: