Notifications

No notifications

/Phase 1

Variables & Primitive Types

Strong, Static Types — The Java Way 🎯

Every variable in Java has a type. The compiler knows it, checks it, and refuses to run if it's wrong. This catches a huge class of bugs at compile time.

The Eight Primitives

TypeSizeRange / Notes
byte8-bit-128 to 127
short16-bit±32,767
int32-bit±2.1 billion (default integer)
long64-bithuge — needs L suffix: 100L
float32-bitneeds f suffix: 3.14f
double64-bitdefault floating-point
char16-bitone Unicode char: 'A'
boolean1 bittrue or false

int     age      = 19;
long    bigNum   = 9_000_000_000L;
double  pi       = 3.14159;
float   ratio    = 1.5f;
boolean isOnline = true;
char    grade    = 'A';

Strings Are Objects (Not Primitives)

String name = "Asha";          // capital S — it's a class
int    len  = name.length();   // call methods on it

final — Java's const

final double PI = 3.14159;     // can't reassign
final int[] arr = {1, 2, 3};   // can't reassign arr, but arr[0] = 9 is fine

var — Local Type Inference (Java 10+)

var n     = 42;                // int
var name  = "Asha";            // String
var list  = new ArrayList<Integer>();  // ArrayList<Integer>

var is local-only — works inside methods, NOT for fields, parameters, or return types. It's still strict static typing — the type is just inferred.

On this page

Detailed Theory

Java's type system is one of its biggest selling points. Static + strong typing → most type errors are caught at compile time, not in production at 3am.

Primitives vs Reference Types

Java has two big categories:

FamilyExamplesStorage
Primitiveint, double, boolean, char, ... (8 types)Direct value on the stack
ReferenceString, arrays, ArrayList, your own classesPointer-on-stack to object on heap

int    a = 5;             // primitive — value 5
String s = "hi";          // reference — points to a String on the heap

Default Values (for fields, NOT local variables)

TypeDefault
Numeric primitives0 (or 0.0)
booleanfalse
char'\u0000' (null char)
Reference typesnull

> ⚠️ Local variables have NO default. int x; System.out.println(x); → compile error.

Integer Literals

int    decimal = 42;
int    hex     = 0x2A;        // 42
int    octal   = 052;          // 42
int    binary  = 0b101010;     // 42 (Java 7+)
int    nice    = 1_000_000;    // underscores for readability
long   big     = 9_000_000_000L;  // L because it overflows int

> Don't write integers with leading zeros: 010 is octal 8, not decimal 10. Foot-gun.

Floating-Point Literals

double pi = 3.14159;       // double by default
float  pf = 3.14159f;      // 'f' makes it float
double e  = 2.7e0;          // scientific notation

double bad = 0.1 + 0.2;
System.out.println(bad);   // 0.30000000000000004

For money use BigDecimal, never double.

Strings

Strings are immutable. Every "modification" creates a new String.

String name = "Asha";
String upper = name.toUpperCase();    // new String — name unchanged

int len = name.length(); char first = name.charAt(0); boolean ok = name.equals("Asha"); // value equality boolean ok2 = name.equalsIgnoreCase("ASHA"); String list = String.join(", ", "a", "b", "c"); String big = "%-8s %4d".formatted("Asha", 19); // Java 15+

> ⚠️ Never compare strings with == — that compares references. Always .equals().

String a = "hi";
String b = new String("hi");
System.out.println(a == b);          // false — different objects
System.out.println(a.equals(b));     // true — same content

Text Blocks (Java 15+)

String json = """
    {
      "name": "Asha",
      "age": 19
    }
    """;

Multi-line, no escaping required. Perfect for SQL, JSON, HTML.

Casting & Conversion

Implicit (widening — always safe)

int    i = 100;
long   l = i;          // int  → long, fine
double d = l;          // long → double, fine

Explicit (narrowing — could lose data)

double d = 3.99;
int    i = (int) d;    // 3 — truncates, doesn't round
long   big = 1_000_000_000_000L;
int    over = (int) big;  // overflow, garbage value

String ↔ Number

int    n = Integer.parseInt("42");
double d = Double.parseDouble("3.14");

String s1 = String.valueOf(42); // "42" String s2 = Integer.toString(42); // "42" String s3 = "" + 42; // "42" (concatenation trick)

Wrapper Classes & Autoboxing

Each primitive has a corresponding object-type wrapper:

PrimitiveWrapper
intInteger
longLong
doubleDouble
booleanBoolean
charCharacter

Java automatically converts (autoboxing / unboxing):

Integer x = 5;          // autobox: int → Integer
int     y = x;           // unbox: Integer → int

List<Integer> nums = new ArrayList<>(); nums.add(42); // 42 (int) → Integer (autobox)

You need wrappers because Java generics like List require objects, not primitives.

> ⚠️ Wrapper comparison gotcha:

Integer a = 1000, b = 1000;
System.out.println(a == b);            // false! (cache only -128..127)
System.out.println(a.equals(b));       // true ✅

final — Constants & Promises

final double TAX = 0.18;     // can't reassign
TAX = 0.20;                   // ❌ compile error

final int[] arr = {1, 2, 3}; arr[0] = 10; // ✅ array contents are mutable arr = new int[5]; // ❌ but reference is final

Convention: ALL_CAPS for top-level constants.

var — Local Type Inference (Java 10+)

var name = "Asha";                       // String
var n    = 42;                            // int
var list = new ArrayList<String>();       // ArrayList<String>
var map  = Map.of("a", 1, "b", 2);        // Map<String, Integer>

Restrictions:

  • ✅ Local variables only.
  • ❌ Fields, method parameters, return types, lambdas.
  • var x; (must initialise).
  • var x = null; (no inferable type).
> Use var when the type is obvious from the right side. Skip when it hides intent.

Variable Scope

A variable lives between its declaration and the closing } of its block.

public static void main(String[] args) {
    int outer = 1;
    if (outer > 0) {
        int inner = 2;
        System.out.println(outer + inner);   // 3
    }
    // inner not visible here
}

Naming Conventions

ThingStyleExample
VariablescamelCasefirstName, totalAmount
ConstantsUPPER_SNAKEMAX_RETRIES
MethodscamelCasegetName()
ClassesPascalCaseUserAccount
Packageslowercasecom.example.app

Cheat-Sheet

NeedCode
Whole numberint n = 42;
Big wholelong big = 9_000_000_000L;
Decimaldouble d = 3.14;
One charchar c = 'A';
Yes / Noboolean ok = true;
TextString s = "hi";
Constantfinal double PI = 3.14;
Inferredvar x = 5;
Cast(int) 3.9 == 3
ParseInteger.parseInt("42")
Compare stringsa.equals(b) (NOT a == b)

You now know Java's type system end-to-end. Next: I/O — reading input and printing output.