Learn Java

Lesson 2Phase 1: First steps

Variables, types, and input/output

Storing values in variables with a fixed type, and why Java checks types before the program even runs.

By Updated 55 min

  • int
  • double
  • boolean
  • char
  • String
  • declaration

A program spends most of its time remembering values and moving them around: a name, an age, a price. To remember a value, you give it a name and put it in a box called a variable. Java adds one rule to that box. You say up front what kind of value it will hold, and Java holds you to it. This lesson is about that rule, the kinds of value Java offers, and how a program prints values and reads what a person types.

By the end of this lesson
  • Declare a variable with a type and a value, and change its value later.
  • Explain what static typing means: a variable's type is fixed, and Java checks it before the program runs.
  • Choose between int, double, boolean, char and String for a value, and write a literal of each.
  • Predict what happens to a variable that was copied from another one.
  • Print values with println and print, and join text and values with +.
  • Read a line the user types with IO.readln.
From before
From your first Java program you have the classic skeleton, a public class Main with a main method inside it, and System.out.println(...) to print a line. You also met the IO class, whose readln method this lesson puts to work. Everything new happens on the lines between the braces of main.

A variable is a named box#

A variableis a named place in the computer's memory that holds a value. Picture a box with a label: the label is the variable's name, and the box holds one value at a time. In Java, the box has one more thing written on it, the type of value it may hold. Here is a variable being created:

Main.java
1public class Main {
2 public static void main(String[] args) {
3 int age = 12;
4 System.out.println(age);
5 }
6}
Prints
›12

Read the line int age = 12; from left to right:

  • int is the type. This box holds a whole number.
  • age is the name. You use it to reach the box later, as println(age) does.
  • = 12 puts the value 12 in the box. In Java, a single = means “store this”; it does not ask whether two things are equal.
  • The semicolon ends the statement.

That word typemeans “what kind of value”: a whole number, a number with a decimal point, true or false, a single letter, some text. You write the type when you create the box. Step through the program above and watch age appear, holding 12, as its line runs.

Coming from Python or JavaScript?
There you write x = 5 with no type, and the same name can later hold text. In Java you write int x = 5;: the type comes first, x can only ever hold whole numbers, and the statement ends with a semicolon.

Static typing: the type is fixed for life#

Once you declare int x, the name x holds whole numbers for the rest of the program. You can change which number is in the box as often as you like:

Main.java
1public class Main {
2 public static void main(String[] args) {
3 int x = 5;
4 System.out.println(x);
5 x = 10;
6 System.out.println(x);
7 }
8}
Prints
›5
›10

It prints 5 and then 10. The value changed. The type did not: the box is still an int box. Add the line x = "hi"; at the end of main, compile it, and Java refuses to build the program at all:

Terminal
read along
1$ javac Main.java
2Main.java:7: error: incompatible types: String cannot be converted to int
3 x = "hi";
4 ^
51 error

This is static typing. “Static” means fixed: each variable's type is settled when you write the code, and the compiler checks every line against it before the program is allowed to run. A line that puts text in a number box never reaches anyone using your program.

Key idea

In Java the value in a variable can change, but its type cannot. You commit to the type once, when you declare the variable, and the compiler checks every use of it before the program runs.

The Run button checks less than javac
The engine behind the Run buttons in this course runs your code step by step, but it does not do the compiler's type checks. It would run x = "hi"; without complaint. To see Java reject a line like that, compile it with javac or type it into JShell, as in your first Java program. The type check lab further down this page shows javac's verdicts too.
Two jobs in one line
The line int x = 5; does two things at once: it declares the variable (creates an int box named x) and initializes it (puts 5 inside). You can also do them on separate lines, as you will see below.
Quick check
A program starts with int x = 5;. Which of these later lines does Java accept?

The types you will reach for#

Java has a small set of built-in basic types called primitive types. Primitive here means the simplest building blocks, not made out of anything smaller. These are the ones you will use all the time. Read the list once; you only need the rough idea of each, not the exact limits.

  • int holds a whole number with no decimal point, like 0, 12 or -7. It covers anything up to about two billion in either direction, and it is your default for counting things.
  • long also holds whole numbers, but far beyond two billion, such as the number of nanoseconds in a day. A long value is written with an L on the end: long big = 9000000000L;. Without the L, Java reads the number as an int, finds it too large for one, and refuses to compile the line.
  • double holds a number with a decimal point, like 4.5, 3.14159 or -0.001. It is your default whenever fractions are involved.
  • float is a smaller, less precise decimal type. You will rarely need it; prefer double. Its values end in f: 3.5f.
  • boolean holds exactly one of two values, true or false. It is the type of a yes-or-no answer, and every decision a program makes comes down to one.
  • char holds a single character, written in single quotes: 'A', '7', '?'.
Single quotes for char, double quotes for text
'A' in single quotes is a char: one character. "A" in double quotes is a String: a piece of text that happens to be one character long. They are different types, and mixing up the quotes is one of the most common early errors.

And then there is String

For text of any length, a word or a whole sentence, you use String, written with double quotes: String name = "Mira";. Strictly speaking String is not a primitive type. It is a class, a richer kind of type that comes with its own methods, which you explore in strings. For now, treat it as the type for text.

Why the capital S
String starts with a capital letter while int, double and the rest are lowercase. That capital is a quiet sign that String is a class rather than a primitive type. What that means arrives with objects; nothing to act on yet.
Quick check
A library app needs to remember whether a book is out on loan. Which type fits best?

Writing values directly: literals#

A literal is a value written straight into your code, like the 5 in int x = 5; or the "Mira" in a string. The literal is the value itself; the variable is the box you put it in. Java has a few families of literal:

  • Integer literals are whole numbers such as 42 or -7. You can also write them in hexadecimal with 0x (0x1F), in binary with 0b (0b1010), and in octal with a leading 0 (045). Plain decimal is what you will use almost always.
  • Floating-point literals are numbers with a decimal point such as 3.14, or in exponent form such as 1.2e3 (1.2 times 10 to the power 3). An f on the end makes a float; without it you get a double.
  • Character literals are one character in single quotes, like 'a' or '%'.
  • String literals are text in double quotes, like "Hello".
  • Boolean literals are the two words true and false.
  • The null literal, null, means “no object at all”. It fits only types that hold objects, such as String, never int or double.
Main.java
1public class Main {
2 public static void main(String[] args) {
3 int million = 1_000_000;
4 int hex = 0x1F;
5 int binary = 0b1010;
6 int octal = 010;
7 long big = 9_000_000_000L;
8 double sci = 1.2e3;
9 float small = 3.5f;
10
11 System.out.println(million);
12 System.out.println(hex);
13 System.out.println(binary);
14 System.out.println(octal);
15 System.out.println(big);
16 System.out.println(sci);
17 System.out.println(small);
18 }
19}
Prints
›1000000
›31
›10
›8
›9000000000
›1200.0
›3.5

It prints 1000000, 31, 10, 8, 9000000000, 1200.0 and 3.5. However you write a number, Java keeps only its value, and println shows that value in ordinary decimal. Look at octal: 010 printed 8, because the leading zero made it an octal number. Never pad a number with zeros to line it up.

Underscores make big numbers readable
You can put underscores between the digits of a number to group them, purely for your eyes: 1_000_000 is easier to read than 1000000, and the compiler ignores the underscores. They may only go between digits, so a number cannot start or end with one.

Escape sequences: special characters inside text

Some characters are hard to type directly inside a string, such as a line break or a double quote. For these, Java uses an escape sequence: a backslash \ followed by a letter that stands for the special character. The ones you will use most are \n for a new line, \t for a tab, \" for a double quote inside a string, and \\ for a backslash itself.

Main.java
1public class Main {
2 public static void main(String[] args) {
3 System.out.println("Line one\nLine two");
4 System.out.println("Name:\tMira");
5 System.out.println("She said \"hello\" to me.");
6 }
7}
Prints
›Line one
›Line two
›Name: Mira
›She said "hello" to me.
Why the quotes need escaping
A double quote normally ends a string. To put a quote inside a string, escape it: "She said \"hi\"". Without the backslashes, Java thinks the string ended early and reports an error.

Which values fit which types?

Now put the types and the literals together. The lab below puts a value into a variable of each type and shows what javac says about it. Guess each verdict before you pick it.

Type check labjavac --release 25

Pick a value and a variable type. The verdicts are what the real javac compiler says.

Value
Type of x
int x = 65;

✓ Compiles

System.out.println(x) prints 65

65 is already an int value, so it fits its own box exactly.

Tried 1 of 42 pairs. 1 compiles.
intlongdoublebooleancharString654.5true'A'"A""65"9000000000L

Once you have tried a few, look at the grid. A number moves into a wider number type on its own, an int into a long or a double, but never into a narrower one, because it might lose something on the way. Text and true or false fit only their own type. The one surprise, char x = 65;, comes from a char being a number underneath, which the end of this page shows.

Declaring, then assigning#

You do not have to fill the box on the same line you create it. You can declare a variable first and assign it a value on a later line. Once declared, the name exists, so the second line does not repeat the type.

Main.java
1public class Main {
2 public static void main(String[] args) {
3 int score; // declare: an int box named score, still empty
4 score = 100; // assign: now put 100 in it, no type word here
5 System.out.println(score);
6 }
7}
Prints
›100

The first line makes the box, and the second fills it. Step through it: after the first line the memory view shows score with no value yet, and the next line stores 100 in it. The assignment line is just score = 100; with no int in front. Writing the type again would try to declare a second box with the same name, which Java does not allow.

Assignment copies the value

When you write b = a, Java copies the value that is in a right now into b. After that, the two boxes are separate. Decide what this program prints before you run it.

Predict the outputCopy.java
1public class Main {
2 public static void main(String[] args) {
3 int a = 5;
4 int b = a;
5 a = 10;
6 System.out.println("a is " + a);
7 System.out.println("b is " + b);
8 }
9}

After a changes to 10, what do the two lines print?

b stays 5. The line int b = a; copied the 5 that was in a at that moment. It did not tie the two names together, so changing a afterwards leaves b alone. Step through it in the playground and watch the two boxes in the memory view.

That rule makes a classic job, swapping the values of two variables, a little puzzle. If you write left = right; first, the old value of left is gone. The fix is a third, temporary variable that keeps a copy.

Put the lines in orderSwap.java
Put the lines in order so the program swaps the two drinks and prints coffee tea. The variable temp keeps a copy of one value while the other moves.

Tap a line, then tap where it should go. Or use the arrows.

Name variables so the code reads well
Java programmers write variable names in camelCase: start with a small letter and give each later word a capital, as in age, totalPrice or isStudent. Pick names that say what the value is. price tells the next reader far more than p or x2.
var: letting Java work out the type
When a variable gets its value on the same line, you can write var instead of the type: var age = 12; creates an int, because 12 is an int. The type is still fixed, so a later age = "twelve"; is still refused. This course mostly writes types out, because seeing them helps while you learn. Modern Java syntax covers var in full.

All the types, side by side, running#

Here is one program that declares a variable of each kind and prints them. Press Run and step through it. Watch each box appear with its value as its line runs, and watch the last assignment change age from 12 to 13.

Main.java
1public class Main {
2 public static void main(String[] args) {
3 int age = 12;
4 double price = 4.5;
5 boolean isStudent = true;
6 char grade = 'A';
7 String name = "Mira";
8
9 System.out.println(name + " is " + age);
10 System.out.println("Price: " + price);
11 System.out.println("Student? " + isStudent);
12 System.out.println("Grade: " + grade);
13
14 age = age + 1;
15 System.out.println(name + " is now " + age);
16 }
17}
Prints
›Mira is 12
›Price: 4.5
›Student? true
›Grade: A
›Mira is now 13

That program prints:

  • Mira is 12
  • Price: 4.5
  • Student? true
  • Grade: A
  • Mira is now 13

The line age = age + 1; reads the current value of age (12), adds 1 to get 13, and stores that back in the same box. The right-hand side is worked out first, using the old value, and only then does the result go into the box.

Printing: println, print, and joining with +#

You already have System.out.println(...). The ln on the end stands for line: after printing, it moves to a fresh line. Its sibling System.out.print(...) prints the same way but stays on the current line, so whatever is printed next continues right after it.

Main.java
1public class Main {
2 public static void main(String[] args) {
3 System.out.print("Hello, ");
4 System.out.print("world");
5 System.out.println("!");
6 System.out.println("Next line");
7 }
8}
Prints
›Hello, world!
›Next line

The first three calls land on one line, because the two print calls do not end the line; only the println after them does. So the output is Hello, world! and then Next line. A println() with nothing in the parentheses prints no text at all, only the line break, which is a handy way to finish a line that print started.

Joining values with the + sign

Inside the parentheses you can stitch pieces together with +. When at least one side of a + is a String, Java treats the +as “join into text”: it turns the other side into text and glues the two together. This is called concatenation, a long word for joining strings end to end.

Main.java
1public class Main {
2 public static void main(String[] args) {
3 String name = "Mira";
4 int age = 12;
5 System.out.println(name + " is " + age + " years old");
6 }
7}
Prints
›Mira is 12 years old

That prints Mira is 12 years old. The number 12 is an int, but because it sits next to String pieces joined by +, Java writes it out as the text 12. Mind the spaces inside the quotes: " is " has a space on each side on purpose, so the words do not run together.

Spaces live inside the quotes
Java does not add spaces between joined pieces for you. name + age prints Mira12 with no gap. If you want a gap, put it inside a string: name + " " + age.

The same + also adds numbers, and Java works through a line of them from left to right. So what a + does depends on what is to its left at that moment. Try this one before you run it.

Predict the outputFruit.java
1public class Main {
2 public static void main(String[] args) {
3 System.out.println(1 + 2 + " apples and " + 1 + 2 + " pears");
4 }
5}

The same 1 and 2 appear twice. What does the line print?

It prints 3 apples and 12 pears. Working from the left, 1 + 2 are both numbers, so they add up to 3. Then 3 + " apples and " has text on one side, so it joins, and from then on the left side is always text. The second 1 and 2 are joined one after the other as the characters 1 and 2. To add them as numbers inside a sentence, put them in parentheses: "total " + (1 + 2) gives total 3.

Key idea

+ adds when both sides are numbers and joins when either side is a String. Java reads the chain from left to right, and once text appears, every + after it joins.

ExerciseSpaces.java
This program prints Mirais12years old. Fix the spaces so the first line reads Mira is 12 years old, then add a second line that prints Mira lives in Lisbon using the variables.

Reading what the user types#

Printing is output: the program telling the person something. Input goes the other way, with the program reading what the person types. The IO class from your first program has a method for it. IO.readln("What is your name? ") prints the question, waits for the user to type a line and press Enter, and hands back what they typed as a String, which you can store in a variable.

Main.java
1public class Main {
2 public static void main(String[] args) {
3 String name = IO.readln("What is your name? ");
4 String city = IO.readln("Where do you live? ");
5 System.out.println("Hello, " + name + " from " + city + "!");
6 }
7}
Prints
›What is your name? Mira
›Where do you live? LisbonHello, Mira from Lisbon!

The box labelled Keyboard input holds what the user types, one line for each press of Enter. Here the user types Mira and then Lisbon, and the program prints Hello, Mira from Lisbon!. Change the input and run it again: the same program now greets someone else. That is what variables are for. The program does not know the name in advance; it keeps a box for it.

Coming from Python?
IO.readln(prompt) does the job of Python's input(prompt).
Reading numbers
IO.readln always hands back text. If the user types 12, you get the String "12", not the number. Reading numbers takes one more step, which you meet in making decisions, and Scanner and console applications covers keyboard input in full.
ExerciseLikes.java
Finish the program so it reads two lines, a name and then a favorite food, and prints one sentence such as Mira likes mangoes. The tests type different answers, so build the sentence from the variables.

Try it

Answer each one in your head or on paper first, then open the answer.

1
Which type would you choose for each of these, and why: a person's age, the price of a coffee, whether a light is on, and the first initial of a name?
2
In your own words, what does static typing mean, and when does Java catch a type mistake?
3
What does this print? System.out.println("Total: " + 3 + 4);
4
Write the two lines that declare an int called count without a value, then assign it 5 on the next line. Why is there no int on the second line?
5
You write char c = "A"; and Java refuses it. What is wrong, and how do you fix it?
6
After int x = 3;, int y = x; and y = y + 1;, what are x and y?

Practice

Work through these on your own. Each one builds on this page.

1
Declare one variable of each type from this lesson (int, double, boolean, char and String) describing yourself: an age, a height in meters, whether you like Java so far, a favorite letter, and your name. Print each one on its own line with a label, like System.out.println("Age: " + age);.
2
Write a program that reads three lines with IO.readln (a name, a city and a hobby) and prints a small profile card: a line of dashes, three labelled lines such as Name: Mira, and the line of dashes again. Run it with different input, then once with an empty line for the hobby. What does the card show for it?
3
Start with int a = 1; and int b = 2;. Swap their values using a third variable, print both, and check that you get 2 1. Then explain in one sentence why writing a = b; followed by b = a; does not work.
4
Type int age = 12 into JShell, then age = "twelve". Read the error it gives you, then write one sentence explaining how this error is the static typing rule from this lesson doing its job.

Further reading#

Spotted a mistake, or a part that did not make sense? Report it by email