Skip to content

Lesson 02 · Types, Variables & var

Objectives

After this lesson you will be able to:

  • Name the eight primitive types, their sizes, ranges, and default values.
  • Write numeric, character, and boolean literals correctly — including hex, octal, binary, underscores, and suffixes.
  • Distinguish local variables (definite assignment) from fields (auto-defaulted).
  • Apply widening vs. narrowing conversions and know when a cast is required.
  • Use var (local-variable type inference) and recognize where it is and isn't allowed.

The eight primitive types

Java has exactly 8 primitive types. Everything else is a reference type.

TypeSizeRange / valuesDefault (as a field)
booleanJVM-definedtrue / falsefalse
byte8-bit−128 … 1270
short16-bit−32 768 … 32 7670
char16-bit unsigned0 … 65 535 (a UTF-16 code unit)'�'
int32-bit≈ −2.1e9 … 2.1e90
long64-bit≈ −9.2e18 … 9.2e180L
float32-bitIEEE-754 single0.0f
double64-bitIEEE-754 double0.0d

Gotcha

char is unsigned and has no negative values. In arithmetic, char, byte, and short are promoted to int, so 'a' + 1 is the int 98, not the char 'b'.

Literals

java
int dec   = 100;
int hex   = 0xFF;        // 255
int oct   = 013;         // 11  ← leading zero = OCTAL, a classic trap
int bin    = 0b1010;     // 10
long big  = 9_000_000_000L;   // L suffix required; doesn't fit in int
double d  = 3.14;
float  f  = 3.14f;       // f suffix required, else it's a double
double e  = 1.5e3;       // 1500.0
char   c  = 'A';
char   u  = 'A';    // also 'A'
boolean b = true;

Underscores improve readability in numeric literals, with rules:

java
int ok   = 1_000_000;
int ok2  = 0b1010_0101;
// int bad1 = _1000;     // ✗ can't start with _
// int bad2 = 1000_;     // ✗ can't end with _
// double bad3 = 3._14;  // ✗ not adjacent to the decimal point
// long bad4 = 100_L;    // ✗ not adjacent to the suffix

Exam trap

int x = 013; is 11, not 13 — a leading 0 makes it octal. And int y = 09; does not compile (9 is not a valid octal digit). Hex (0x) and binary (0b) are far more common on the exam than octal, but octal shows up precisely to catch you.

Variables: declaration, defaults, and scope

java
int count;          // declared
count = 5;          // assigned
int total = 10;     // declared + initialized

The critical distinction:

  • Fields (instance/static variables) are automatically initialized to the defaults above.
  • Local variables are not. The compiler enforces definite assignment — you must assign a local before you read it, or it's a compile error.
java
void m() {
    int x;
    // System.out.println(x);  // ✗ compile error: variable x might not have been initialized
    x = 3;
    System.out.println(x);     // ✓
}

Scope is the block ({ ... }) a variable is declared in: local variables live until the end of their block; instance fields live with the object; static fields live with the class.

Conversions: widening, narrowing, and casts

Widening (smaller → larger) happens implicitly and never loses range:

byte → short → int → long → float → double
        char ↗
java
int i = 100;
long l = i;        // ✓ implicit widening
double d = l;      // ✓

Narrowing (larger → smaller) requires an explicit cast and may lose information:

java
double d = 9.99;
int i = (int) d;   // 9  (truncates toward zero, doesn't round)
long l = 130;
byte b = (byte) l; // -126 (overflow wraps around)

Two convenience rules the exam tests:

  • Compile-time constant narrowing is allowed without a cast if it fits: byte b = 10; ✓ but byte b = 130; ✗ (out of range), and int n = 10; byte b2 = n; ✗ (n isn't a constant).
  • Compound assignment operators include an implicit cast: byte b = 10; b += 5; ✓ — b += 5 is really b = (byte)(b + 5).
What prints? — overflow & truncation
java
int big = 200;
byte b = (byte) big;
double pi = 3.99;
int t = (int) pi;
System.out.println(b + " " + t);

Answer: -56 3. 200 as a byte wraps to -56 (200 − 256). Casting 3.99 to inttruncates to 3 (no rounding).

var — local-variable type inference (Java 10+)

var lets the compiler infer a local variable's type from its initializer. The variable is still statically typedvar is not "dynamic" and not a new runtime type.

java
var name = "Ada";        // inferred String
var count = 10;          // inferred int
var list = new ArrayList<String>();  // inferred ArrayList<String>

Where var is not allowed:

java
// var x;                 // ✗ no initializer
// var y = null;          // ✗ can't infer a type from null
// var z = { 1, 2, 3 };   // ✗ array-initializer shorthand has no type
  • Only for local variables (including the loop variable in for/enhanced-for). Not for fields, method parameters, or return types.
  • var is a reserved type name, not a keyword — you can still name a variable, method, or package var (though you shouldn't).
  • The inferred type is fixed at the initializer: var n = 1; makes n an int, so n = "x"; later won't compile.

SDET note

In tests, prefer var where the type is obvious from the right-hand side (var driver = new ChromeDriver();) to cut noise — but keep explicit types where the inferred type would be surprising or weaken a readers' (or an AI reviewer's) understanding of intent. Inference saves typing, not thinking.

Key Takeaways

  • 8 primitives: boolean byte short char int long float double. char is unsigned 16-bit; byte/short/char promote to int in arithmetic.
  • Literals: leading 0 = octal, 0x hex, 0b binary; long needs L, float needs f; underscores can't touch the ends, a decimal point, or a suffix.
  • Fields auto-default; locals must be definitely assigned before use.
  • Widening is implicit; narrowing needs a cast (truncates / wraps). Constant narrowing in range is allowed without a cast, and compound assignment casts implicitly.
  • var = local-only, needs an initializer, can't be null; it's inferred static typing, and it's a reserved type name, not a keyword.

Lesson Quiz

Lesson Quiz · Types, Variables & var0 / 10
  1. How many primitive types does Java have, and which of these is NOT one of them?

    • A7 primitives; String is the odd one out
    • B8 primitives; String is a reference type, not a primitive
    • C9 primitives; including String
    • D8 primitives; char is actually a reference type
  2. What is the value of int x = 013;

    • A13
    • B11
    • CCompile error
    • D1013
  3. Which numeric literals are valid? (select all that apply) (select all that apply)

    • A1_000_000
    • B0xFF
    • C1000_
    • D0b1010_0101
  4. Which statement about local variables vs. fields is TRUE?

    • ABoth are auto-initialized to defaults
    • BLocal variables are auto-initialized; fields are not
    • CFields are auto-initialized to defaults; local variables must be definitely assigned before use
    • DNeither is ever initialized automatically
  5. Given byte b = 10; which line compiles?

    • Ab = b + 5;
    • Bb += 5;
    • CBoth compile
    • DNeither compiles
  6. What prints? double d = 9.99; int i = (int) d; System.out.println(i);

    • A10
    • B9
    • C9.99
    • DCompile error
  7. Which uses of var are ILLEGAL? (select all that apply) (select all that apply)

    • Avar x = null;
    • Bvar n = 10;
    • Cvar nums = { 1, 2, 3 };
    • Dvar s = "hello";
  8. Where can var be used?

    • ALocal variables only
    • BLocal variables, fields, and method parameters
    • CMethod return types
    • DAnywhere a type is written
  9. What is the result of this fragment? (think about numeric promotion)

    char c = 'a';
    int n = c + 1;
    • An is the char 'b'
    • Bn is the int 98
    • CCompile error: cannot add to a char
    • Dn is the int 97
  10. Which conversions are implicit (no cast needed)? (select all that apply) (select all that apply)

    • Aint to long
    • Blong to int
    • Cint to double
    • Ddouble to float

Next: Operators & Expressions. Run the matching code in labs/.../m00_foundations/TypesAndVars.java.