Step 1 of 7 · Reading · ~4 min
Learn
Getting Started
Variables and Types
Java is statically typed: every variable has a type fixed when it is declared, and the compiler checks every use before the program runs. By the end of this lesson you can pick the right numeric type, predict what happens when a value does not fit, and convert between types on purpose.
Declaring a variable
int count = 5;
String city = "Oslo";
count = count + 1; // fine: same type
count = "six"; // compile error: String cannot be converted to int
A declaration is type name = value;. After that the name only ever holds values of that type. Python lets count become a string later; Java refuses at compile time, which is the point.
The primitive types
| Type | Size | Holds |
|---|---|---|
byte | 8 bits | -128 to 127 |
short | 16 bits | -32,768 to 32,767 |
int | 32 bits | about -2.1 billion to 2.1 billion |
long | 64 bits | about +/- 9.2 quintillion (literals end in L) |
float / double | 32 / 64 bits | decimals (double is the default choice) |
char | 16 bits | one character, in single quotes: 'A' |
boolean | 1 value | true or false |
String is not on this list. It is a class, an object with methods, and uses double quotes. Single quotes are for one char only.
Overflow: the silent trap
Integer types have a fixed range, and arithmetic that leaves it does not fail. It wraps around:
int top = Integer.MAX_VALUE; // 2147483647
System.out.println(top + 1); // -2147483648
No exception, no warning, just a wrong number. The subtler version is declaring a long and assuming that makes the math safe:
int w = 100000, h = 100000;
long wrong = w * h; // 1410065408
long right = (long) w * h; // 10000000000
In w * h both operands are int, so the multiplication happens in 32 bits and overflows before the result is stored. The long on the left only receives the damaged value. Converting one operand first, (long) w, makes the whole multiplication 64-bit.
Casting: widening and narrowing
Moving to a bigger type is automatic (widening). Moving to a smaller or less precise type must be written with a cast, because data can be lost (narrowing):
double ratio = 7; // widening, no cast: 7.0
int whole = (int) 3.99; // narrowing: 3 -- truncated toward zero, not rounded
int neg = (int) -3.99; // -3
byte small = (byte) 200; // -56 -- the bits wrap
Mixed arithmetic widens to the larger operand: int + long is a long, int + double is a double. Integer division is its own trap: double d = 7 / 2; stores 3.0, because 7 / 2 is computed as int first.
final and var
final int LIMIT = 100; // cannot be reassigned
var total = 0L; // the compiler infers long
final forbids reassignment (for an object it protects the reference, not the contents). var (Java 10+) infers the type from the initializer; the variable is still statically typed, and var works only for local variables that have an initializer.
Wrapper types
Each primitive has an object twin: Integer, Long, Double, Boolean, Character. Collections and generics only hold objects, so ArrayList<Integer> uses the wrapper and Java converts automatically (autoboxing). A wrapper can be null, and unboxing a null into an int throws NullPointerException.
Common mistakes
- Trusting
long x = a * b;whenaandbareint. Cast one operand before the operation. - Forgetting
L:long big = 3000000000;is an error because the literal is read as anintfirst. - Expecting
(int)to round. It truncates:(int) 2.99is2. - Using a local variable before assigning it. Locals have no default value.
Your exercise
Read two integers and print their sum. The twist is the range: each value fits in an int, but the sum may not, and the output must be the true mathematical sum. Decide where the conversion has to happen before the addition.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…