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
Syntax
type variableName = value;
type -> the int, String)
variableName -> the
Declaring vs Initialising
- Variable tells the compiler the name and type of the variableThe act of defining a variable's name and type without assigning a value.
- Variable assigns an initial value to the variable You can declare and initialise variables at the same timeAssigning an initial value to a variable at the time of declaration or later.
int age = 27;
String name = "Jordan";
This example will:
-
Create a variable called
agethat will store theint27. -
Create a variable called
namethat will store theString(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:
-
A basic data type built into the language, such as int, float, or char.
-
A data type that stores a reference to an object in memory, rather than the object itself.
The key difference is where and how the value is stored:
-
Primitive values live on the
A region of memory that stores method calls and primitive variables, managed in a last-in-first-out manner. -
Objects live in the
, and the variable holds a reference to the heap in the stack.A region of memory used for storing objects and class instances, managed by the garbage collector.
1. Primitive Types
There are 8 primitive types:
| Type | Size | Range / Notes | Example | Description |
|---|---|---|---|---|
byte | 8-bit | -128 to 127 | byte b = 1; | Very small integer |
short | 16-bit | -32,768 to 32,767 | short s = 2; | Small integer |
int | 32-bit | -2,147,483,648 to 2,147,483,647 | int i = 10; | Most common integer type |
long | 64-bit | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | long l = 100000L; | Large integer |
float | 32-bit | Approx. ±3.4e38, 6–7 decimal digits precision | float f = 3.14f; | Decimal (requires f suffix) |
double | 64-bit | Approx. ±1.8e308, 15 decimal digits precision | double d = 3.14; | More precise decimal |
char | 16-bit | Unicode 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'

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.
| Type | Size | Mutability | Example | Description |
|---|---|---|---|---|
Boolean | 1-bit | Immutable | Boolean isTrue = true; | Wrapper for boolean |
Byte | 8-bit | Immutable | Byte b = 1; | Wrapper for byte |
Short | 16-bit | Immutable | Short s = 2; | Wrapper for short |
Character | 16-bit | Immutable | Character c = 'A'; | Wrapper for char |
Integer | 32-bit | Immutable | Integer i = 10; | Wrapper for int |
Long | 64-bit | Immutable | Long l = 100000L; | Wrapper for long |
Float | 32-bit | Immutable | Float f = 3.14f; | Wrapper for float |
Double | 64-bit | Immutable | Double d = 3.14; | Wrapper for double |
String | N/A | Immutable | String s = "hello"; | Textual data |
Array | N/A | Mutable | int[] 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.An object whose state cannot be changed after it is created. -
Arrays are
, you can change their contents even though the reference points to the same memory.An object whose state can be changed after creation.
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

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

Type Conversion
The automatic conversion of a smaller data type into a larger compatible type. Another term for type promotion, converting to a larger type without loss of data.
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
Manually converting a value from one data type to another. A type of casting that converts from a larger data type to a smaller one, potentially losing data.
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 a value exceeds the maximum or minimum limit of its data type, causing it to wrap around. 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
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
finalto declare constants. - Be careful with type conversions to avoid data loss.
Learn more: