SEN1001 · Week 2 · Introduction to Java Applications /Elementary Programming

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.

variabledeclarationassignmentinitializationprimitive typeliteralwidening conversionnarrowing conversioncastingoverflowformat specifierprintf

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:

  1. Type first, name second: int age = 19;. You write the type once, then you only use the name.
  2. A decimal literal is a double. 2.5 is a double, 2.5f is a float.
  3. Small to large is automatic, large to small needs a cast: int → double happens by itself, double → int needs (int).
  4. A char is really a number. 'A' + 1 gives an int: 66.
  5. In printf, %.2f rounds; 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 then System.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.

TypeSizeWhat it storesExample literalRange
byte1 bytesmall integer100-128 … 127
short2 bytesinteger3000-32768 … 32767
int4 bytesinteger (default)42-2147483648 … 2147483647
long8 byteslarge integer3000000000Labout ±9.2 × 10^18
float4 bytesdecimal (less precise)2.5f
double8 bytesdecimal (default)2.5
char2 bytessingle character'A'0 … 65535
booleantrue/falsetrue, 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' is 195, not ab. + 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).

SpecifierUsed forExampleOutput
%dint, longprintf("%d", 42)42
%fdouble (6 digits)printf("%f", 2.5)2.500000
%.2fdouble, 2 digitsprintf("%.2f", 78.456)78.46
%sStringprintf("%s", "Ali")Ali
%ccharprintf("%c", 'Z')Z
%bbooleanprintf("%b", false)false
%5dwidth 5, right-alignedprintf("[%5d]", 42)[ 42]
%-5dwidth 5, left-alignedprintf("[%-5d]", 42)[42 ]
%8.2fwidth 8, 2 digitsprintf("[%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 · %.2f rounds, 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, %.2f may print 78,46 with 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 ideaThe truth
String is a primitive typeIt is a class; there are 8 primitives, all lowercase
char c = "A";char uses single quotes: 'A'
'A' + 1 → B66; for B use (char) ('A' + 1)
(int) 9.99 → 109, a cast truncates
int x = 5.0; compiles, the value is a whole numberIt does not compile; the type is double
float f = 1.5;You must write 1.5f
MAX_VALUE + 1 gives an errorIt silently becomes MIN_VALUE
printf moves to a new lineIt does not; add %n
printf("%d", 2.5)%d is for integers only; use %f for a double
a = b; b = a; swapsBoth become b; use temp

Test yourself

Exam-style questions. Solve them on paper first, then reveal the answer.

Question 1easy

What is printed?

int p = 5;
int q = p;
p = 10;
System.out.println(p + " " + q);
Show answer
10 5

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.

Question 2easy

What is printed?

System.out.printf("%d-%d%n", 7, 3);
Show answer
7-3

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.

Question 3easy

What is printed?

System.out.printf("Total: %.2f%n", 12.0 / 7);
Show answer
Total: 1.71

12.0 / 7 = 1.7142857... %.2f shows 2 digits after the decimal point and rounds: 1.714 → 1.71.

Question 4medium

What is printed?

System.out.printf("[%4d][%-4d]%n", 7, 7);
Show answer
[ 7][7 ]

%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.

Question 5medium

What is printed?

char ch = 'C';
System.out.println(ch + 2);
System.out.println((char) (ch + 2));
Show answer
69
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'.

Question 6hard

What is printed?

System.out.println('x' + "y" + 'z');
System.out.println('x' + 'y' + "z");
Show answer
xyz
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".

Question 7medium

What is printed?

double v = 5.9;
int w = (int) v * 2;
int w2 = (int) (v * 2);
System.out.println(w + " " + w2);
Show answer
10 11

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.

Question 8hard

What is printed?

int r = 2147483647;
r++;
System.out.println(r);
Show answer
-2147483648

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.

Question 9medium

What is printed?

int k = 4;
double z = k / 8;
double z2 = k / 8.0;
System.out.println(z + " " + z2);
Show answer
0.0 0.5

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.

Question 10medium

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 4
Show answer
line 1 and line 3

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.

Question 11medium

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
2 2

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.

Question 12easy

What is printed?

System.out.printf("%s is %d years old and has a %.1f GPA%n", "Ali", 20, 3.456);
Show answer
Ali is 20 years old and has a 3.5 GPA

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.

Review card

Declare: type name = value; int x = 5; double d = 2.5; char c = 'A'; boolean b = true; 8 primitives: byte short int long float double char boolean (String is NOT primitive) int ±2.1 billion · long 100L · float 2.5f · double is the default decimal A local variable with no value cannot be used → "might not have been initialized" Widening is automatic: int → long → double int x; double d = x; ✔ Narrowing needs a cast: int i = (int) 9.99; → 9 (TRUNCATES, does not round) (int) v * 2 → cast first (int)(v * 2) → multiplication first char + int = int: 'A'+1 = 66 (char)('A'+1) = 'B' 'a'+'b' = 195 ""+'a'+'b' = "ab" A=65 a=97 '0'=48 MAX_VALUE + 1 → MIN_VALUE (overflow, no error) printf: %d int %f double (6 digits) %.2f 2 digits ROUNDS %s String %c char %b boolean %n line break %5d right-align (width 5) %-5d left-align Swap: temp = a; a = b; b = temp;