Variables, primitive types and printf
Declaring variables, the eight primitive types, char arithmetic, casting and formatted output with printf. This is where you learn the difference between 7 and 7.0 in output questions.
Variables are the program’s memory. Every variable has a type, and the type decides both what it can store and how it is printed. Writing 7 instead of 7.0 in an output question, or thinking the result of 'A' + 1 is B, comes from not knowing the rules on this page.
Golden rules:
- Type first, name second:
int age = 19;. You write the type once, then you only use the name. - A decimal literal is a double.
2.5is a double,2.5fis a float. - Small to large is automatic, large to small needs a cast: int → double happens by itself, double → int needs
(int). - A char is really a number.
'A' + 1gives an int: 66. - In printf,
%.2frounds; the(int)cast truncates.
Declaring and assigning variables
int age; // declaration
age = 19; // assignment
int goals = 3, assists = 5; // declaration + initial value (initialization)
double gpa = 3.25;
char grade = 'B';
boolean passed = true;
System.out.println(age + " " + goals + " " + assists + " " + gpa + " " + grade + " " + passed);
age = age + 1; // the right side is computed first, then written to age
System.out.println(age);
19 3 5 3.25 B true
20
= is not mathematical equality, it is assignment: compute the value on the right, put it in the box on the left. That is why age = age + 1 makes sense: take the old value, add one, write it back.
Variable name rules: it can contain letters, digits, _ and $, it cannot start with a digit, and it cannot be a reserved word (keyword) such as int or class. By convention it starts with a lowercase letter and words are joined with capital letters: totalScore, studentCount (camelCase).
PITFALL · variable with no value. If you write
int count;and thenSystem.out.println(count);without ever giving it a value, it does not compile:variable count might not have been initialized. Local variables inside a method have no default value.
The eight primitive types
Java has eight basic (primitive) types. In the exam int, double, char and boolean appear most; for the others it is enough to know that they exist and their order.
| Type | Size | What it stores | Example literal | Range |
|---|---|---|---|---|
byte | 1 byte | small integer | 100 | -128 … 127 |
short | 2 bytes | integer | 3000 | -32768 … 32767 |
int | 4 bytes | integer (default) | 42 | -2147483648 … 2147483647 |
long | 8 bytes | large integer | 3000000000L | about ±9.2 × 10^18 |
float | 4 bytes | decimal (less precise) | 2.5f | |
double | 8 bytes | decimal (default) | 2.5 | |
char | 2 bytes | single character | 'A' | 0 … 65535 |
boolean | true/false | true, false |
The ranges were taken from Java’s own constants:
System.out.println(Byte.MIN_VALUE + " " + Byte.MAX_VALUE);
System.out.println(Integer.MIN_VALUE + " " + Integer.MAX_VALUE);
System.out.println(Long.MAX_VALUE);
-128 127
-2147483648 2147483647
9223372036854775807
String is not primitive. It is a class, written with double quotes: "Ali". A char uses single quotes and is a single character: 'A'. 'Ali' does not compile.
Overflow
If you go past the limit of int, Java gives no error; the number comes back from the other end:
int m = Integer.MAX_VALUE;
m = m + 1;
System.out.println(m);
-2147483648
A char is a number
Every character has a code (Unicode). Three are enough to memorize: 'A' = 65, 'a' = 97, '0' = 48. When you do arithmetic with a char, the result is an int.
char c = 'A';
System.out.println(c + 1); // char + int = int
System.out.println((char) (c + 1)); // convert back to char
System.out.println('a' + 'b'); // 97 + 98, two numbers
System.out.println("" + 'a' + 'b'); // String first, then concatenation
char c2 = 'A';
c2++; // ++ stays a char
System.out.println(c2);
System.out.println((int) '0');
66
B
195
ab
B
48
PITFALL · sum of two chars. The result of
'a' + 'b'is195, notab.+does addition when neither side is a String. If you want concatenation, put""at the start.
Type conversion and casting
Widening conversion: from a smaller type to a larger one happens automatically, with no data loss. The order is: byte → short → int → long → float → double.
Narrowing conversion: from larger to smaller. Because data can be lost, the compiler insists that you write a cast. A cast truncates the fractional part, it does not round.
int i = 7;
double dd = i; // widening, automatic
System.out.println(dd);
double x = 9.99;
int t = (int) x; // narrowing, cast required
System.out.println(t);
System.out.println((int) -3.7); // truncates toward zero
System.out.println((int) 3.7 + (int) 2.6); // 3 + 2
System.out.println((int) (3.7 + 2.6)); // (int) 6.3
System.out.println(Math.round(3.7)); // this is how you round
7.0
9
-3
5
6
4
If you do not write the cast:
int x = 2.5 * 2;
float f = 1.5;
Narrow.java:3: error: incompatible types: possible lossy conversion from double to int
int x = 2.5 * 2;
^
Narrow.java:4: error: incompatible types: possible lossy conversion from double to float
float f = 1.5;
^
2 errors
Even if 2.5 * 2 = 5.0, its type is double; the compiler looks at the type, not the value.
Formatted output with printf
System.out.printf takes a format string and puts the arguments, in order, in place of the specifiers (format specifiers) that start with %. Unlike println, it does not move to a new line automatically; for a line break you write %n (or \n).
| Specifier | Used for | Example | Output |
|---|---|---|---|
%d | int, long | printf("%d", 42) | 42 |
%f | double (6 digits) | printf("%f", 2.5) | 2.500000 |
%.2f | double, 2 digits | printf("%.2f", 78.456) | 78.46 |
%s | String | printf("%s", "Ali") | Ali |
%c | char | printf("%c", 'Z') | Z |
%b | boolean | printf("%b", false) | false |
%5d | width 5, right-aligned | printf("[%5d]", 42) | [ 42] |
%-5d | width 5, left-aligned | printf("[%-5d]", 42) | [42 ] |
%8.2f | width 8, 2 digits | printf("[%8.2f]", 3.14159) | [ 3.14] |
String name = "Deniz";
int score = 87;
double avg = 78.456;
System.out.printf("%s scored %d points%n", name, score);
System.out.printf("Average: %.2f%n", avg);
System.out.printf("Average: %.1f%n", avg);
Deniz scored 87 points
Average: 78.46
Average: 78.5
PITFALL ·
%.2frounds, a cast truncates.printf("%.1f", 78.456)→78.5. But(int) 78.9→78. Do not mix the two up.
TIP · the comma on a Turkish computer. printf uses the system’s locale. On a computer set to Turkish,
%.2fmay print78,46with a comma. English is accepted in the exam: write a dot.
Worked example: swap
To exchange the values of two variables you need a third box. Otherwise one of them is lost.
int a = 3, b = 8;
int temp = a; // save the value of a
a = b;
b = temp;
System.out.println(a + " " + b);
8 3
a b temp
start 3 8 -
temp = a 3 8 3
a = b 8 8 3
b = temp 8 3 3
Common mistakes
| Wrong idea | The truth |
|---|---|
String is a primitive type | It is a class; there are 8 primitives, all lowercase |
char c = "A"; | char uses single quotes: 'A' |
'A' + 1 → B | 66; for B use (char) ('A' + 1) |
(int) 9.99 → 10 | 9, a cast truncates |
int x = 5.0; compiles, the value is a whole number | It does not compile; the type is double |
float f = 1.5; | You must write 1.5f |
MAX_VALUE + 1 gives an error | It silently becomes MIN_VALUE |
| printf moves to a new line | It does not; add %n |
printf("%d", 2.5) | %d is for integers only; use %f for a double |
a = b; b = a; swaps | Both become b; use temp |
Test yourself
Exam-style questions. Solve them on paper first, then reveal the answer.
What is printed?
int p = 5;
int q = p;
p = 10;
System.out.println(p + " " + q);Show answer
In the line q = p, the current value of p (5) is copied into q. Changing p afterwards does not affect q. Primitive variables are not linked to each other.
What is printed?
System.out.printf("%d-%d%n", 7, 3);Show answer
printf writes the format string as is, and puts the arguments in order wherever it sees %d: first 7, then 3. - is an ordinary character. %n is the line break.
What is printed?
System.out.printf("Total: %.2f%n", 12.0 / 7);Show answer
12.0 / 7 = 1.7142857... %.2f shows 2 digits after the decimal point and rounds: 1.714 → 1.71.
What is printed?
System.out.printf("[%4d][%-4d]%n", 7, 7);Show answer
%4d writes the number right-aligned in a field of 4 characters: 3 spaces + 7. %-4d with the minus sign aligns left: 7 + 3 spaces. The square brackets are only there so you can see the spaces.
What is printed?
char ch = 'C';
System.out.println(ch + 2);
System.out.println((char) (ch + 2));Show answer
E
The code of the character 'C' is 67. The result of char + int is an int: 67 + 2 = 69, so the number is printed. In the second line 69 is converted back to char: 69 = 'E'.
What is printed?
System.out.println('x' + "y" + 'z');
System.out.println('x' + 'y' + "z");Show answer
241z
First line: 'x' + "y" → the String "xy", then + 'z' → "xyz". In the second line the first operation from left to right is on two chars: 'x' (120) + 'y' (121) = 241, a numeric sum. Then 241 + "z" = "241z".
What is printed?
double v = 5.9;
int w = (int) v * 2;
int w2 = (int) (v * 2);
System.out.println(w + " " + w2);Show answer
A cast applies only to what is immediately to its right. (int) v = 5 (truncated), 5 * 2 = 10. In the second one the parentheses come first: 5.9 * 2 = 11.8, then (int) → 11.
What is printed?
int r = 2147483647;
r++;
System.out.println(r);Show answer
2147483647 is the largest int value (Integer.MAX_VALUE). Adding one causes overflow and the value wraps around to the smallest int, -2147483648. Java gives no error, it wraps silently.
What is printed?
int k = 4;
double z = k / 8;
double z2 = k / 8.0;
System.out.println(z + " " + z2);Show answer
k / 8 is two ints: 4 / 8 = 0, which becomes 0.0 when assigned to a double. k / 8.0 is a double division: 0.5.
Which lines cause a compile-time error?
int a = 2.5 * 2; // line 1
double b = 7; // line 2
float c = 1.5; // line 3
long d = 100; // line 4Show answer
Line 1: 2.5 * 2 is a double and cannot be assigned to an int automatically (possible lossy conversion from double to int). Line 3: the literal 1.5 is a double and does not fit in a float; you must write 1.5f. Lines 2 and 4 are widening: int → double and int → long are automatic and safe.
The code below is meant to swap s1 and s2. What is printed, and what is the fix?
int s1 = 1, s2 = 2;
s1 = s2;
s2 = s1;
System.out.println(s1 + " " + s2);Show answer
With s1 = s2 the old value of s1 (1) is lost, and both become 2. Then s2 = s1 is 2 again. A correct swap needs a temporary variable (temp): int temp = s1; s1 = s2; s2 = temp; → 2 1.
What is printed?
System.out.printf("%s is %d years old and has a %.1f GPA%n", "Ali", 20, 3.456);Show answer
The arguments fill in order: %s ← "Ali", %d ← 20, %.1f ← 3.456 rounded to one digit: 3.5. The number and types of the arguments must match the specifiers; if you pass a double for %d, the program fails while running.
Verification: All code snippets were run with JDK 26 (verify/SEN1001/W02a.java). The compile errors were obtained by compiling verify/SEN1001/err/Narrow.java and Uninit.java with javac. The printf outputs were produced with the en_US locale.