Skip to main content

Java Variables & Data Types

Understanding variables and data types is foundational to programming in Java. This section breaks down what they are, how they're used, and some common pitfalls.


On this page you’ll learn:

  • How to declare and initialize variables
  • The difference between primitive and reference types
  • How to convert data types through promotion and casting

What is a Variable?

A

is a container that holds data during the execution of a program. In Java, every variable must be declared with a . Declaring a variable means telling the compiler what type of data you want to store and what you want to name that storage location.

Syntax

type variableName = value;

type -> the

of the variable (e.g. int, String)

variableName -> the

or name you assign to the variable.

Declaring vs Initialising

  • Variable tells the compiler the name and type of the variable
  • Variable assigns an initial value to the variable You can declare and initialise variables at the same time
int age = 27;
String name = "Jordan";

This example will:

  • Create a variable called age that will store the int 27.

  • Create a variable called name that will store the String (object) 'Jordan'

Or

You can declare the variable first and assign a value later.

int age;
age = 27;

Java Data Types

Java is a statically typed language, which means each variable’s type must be known at compile time. Java’s data types are divided into two groups:

The key difference is where and how the value is stored:

  • Primitive values live on the

  • Objects live in the

    , and the variable holds a reference to the heap in the stack.

1. Primitive Types

There are 8 primitive types:

TypeSizeRange / NotesExampleDescription
byte8-bit-128 to 127byte b = 1;Very small integer
short16-bit-32,768 to 32,767short s = 2;Small integer
int32-bit-2,147,483,648 to 2,147,483,647int i = 10;Most common integer type
long64-bit-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807long l = 100000L;Large integer
float32-bitApprox. ±3.4e38, 6–7 decimal digits precisionfloat f = 3.14f;Decimal (requires f suffix)
double64-bitApprox. ±1.8e308, 15 decimal digits precisiondouble d = 3.14;More precise decimal
char16-bitUnicode characters, e.g., 'A', '1', '\u0041'char c = 'A';A single character

When declaring a variable that is a primitive type the actual value is stored in the memory allocated to that variable

int a = 10;
int b = a;
b = 20;
// 'a' is still 10, because 'b' is a separate piece of memory copied from 'a'

Primitive Types

2. Reference Types (objects)

Reference types store a reference (memory address) that points to the actual object stored in the heap. The reference itself is stored in the stack, but the object it refers to lives in the heap.

TypeSizeMutabilityExampleDescription
Boolean1-bitImmutableBoolean isTrue = true;Wrapper for boolean
Byte8-bitImmutableByte b = 1;Wrapper for byte
Short16-bitImmutableShort s = 2;Wrapper for short
Character16-bitImmutableCharacter c = 'A';Wrapper for char
Integer32-bitImmutableInteger i = 10;Wrapper for int
Long64-bitImmutableLong l = 100000L;Wrapper for long
Float32-bitImmutableFloat f = 3.14f;Wrapper for float
Double64-bitImmutableDouble d = 3.14;Wrapper for double
StringN/AImmutableString s = "hello";Textual data
ArrayN/AMutableint[] arr = {1, 2, 3};Fixed-size, ordered collection

Mutability Notes:

  • Wrapper classes (Integer -> int, Double -> double, etc.) is an object representation of a primitive data type. These classes as well as Strings are immu

    table, meaning their value cannot be changed after creation. Any operation creates a new object.

  • Arrays are

    , you can change their contents even though the reference points to the same memory.

Immutable Example

String name = "Jordan";
String anotherName = name;

anotherName = "Alex";

// 'name' is still "Jordan" because 'String' is immutable
System.out.println(name); // Jordan
System.out.println(anotherName); // Alex

Reference Types Immutable

Mutable Example

int[] numbers = {1, 2, 3};
int[] moreNumbers = numbers;

moreNumbers[0] = 99;

// Both variables now point to the same array in memory
System.out.println(numbers[0]); // 99
System.out.println(moreNumbers[0]); // 99

Reference Types Mutable


Type Conversion

Java automatically converts smaller types to larger types without losing data as the larger type can fully represent the smaller type's range.

Order of promotion

byte → short → int → long → float → double

char

Example of promoting int to float and long

int i = 10;
long l= i;
float f = l;

System.out.println("int: " + i);
System.out.println("long: " + l);
System.out.println("float: " + f);

Output:

int: 10
long: 10
float: 10.0

Why is float considered larger than long in Java?

Even though long is a 64 bit integer, and float is a 32 bit floating point, Java treats float as "wider" as a float can represent a larger range of values Analogy: Imagine long is a list of whole numbers between 1 and 10:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Whereas a float (to 1 decimal place) could store:

1.0, 1.1, 1.2, ..., 9.8, 9.9, 10.0

This is already more distinct values than the integer-only long in this small range and in reality floats can store values in the millions, billions, and even tiny decimals like 0.000001.

Type Promotion Rules

  • Only works from smaller to larger types in terms of range, not just byte size
  • works between primitives of compatible types (char can be promoted to int and anything larger because it can be represented by a unicode number)
char c = 'A'; // 'A' in Unicode is 65
int i = c;

System.out.println("int: " + c);

Output:

65

Type casting is when you convert a value from a larger type to a smaller type. This cannot be done automatically and needs to be explicitly cast to the smaller value as there is a risk of data loss.

When casting is necessary

Casting can be used when you want to perform operations between different data types or you need to store a value of one type in a variable of another type.

double pi = 3.14;
int i = (int) pi;

System.out.println(i);

Output:

3

Example of when casting

int big = 130;
byte small = (byte) big; // byte range: -128 to 127

System.out.println(small);

Output:

-126

The byte value wraps around to the lower end of the range because 130 is too large for a byte.

This happens because Java uses

for signed integers. to represent signed integers.
In two’s complement, when a value exceeds the maximum (127 for a byte), it wraps around from the negative side of the range, producing -126 in this case.


Summary

  • Variables store data and must be typed.
  • Java has 8 primitive types and many reference types.
  • Use final to declare constants.
  • Be careful with type conversions to avoid data loss.

Learn more:

⬅ Back to Java Basics