Variables, Data Types and Literals in Java
Java has eight primitive types and everything else is a reference. Knowing which is which explains assignment, defaults and equality.
-
Java Basics
- Introduction to Java
- Setting Up Java and Writing Your First Program
- Variables, Data Types and Literals in Java
- Type Casting and Type Conversion in Java
- Operators and Expressions in Java
- Input and Output in Java
- Comments, Keywords and Naming Conventions in Java
- Control Flow in Java: if, else and switch
- Loops in Java: for, while and do-while
- Methods
- Arrays and Strings
-
OOP
- Classes and Objects in Java
- Constructors in Java
- The this Keyword in Java
- The static Keyword in Java
- Encapsulation in Java
- Access Modifiers in Java
- Inheritance in Java
- Method Overriding and super in Java
- Polymorphism in Java
- Abstraction, Abstract Classes and Interfaces in Java
- Composition, Aggregation and Association in Java
- The Object Lifecycle in Java
- Core Java
- Exception Handling
-
Collections
- The Java Collections Framework
- List in Java: ArrayList, LinkedList, Vector and Stack
- Set in Java: HashSet, LinkedHashSet and TreeSet
- Map in Java: HashMap, LinkedHashMap and TreeMap
- How HashMap Works Internally in Java
- Queue and Deque in Java: ArrayDeque and PriorityQueue
- Iterators in Java
- Comparable and Comparator in Java
- Collections Utilities and Choosing the Right Collection
- Generics
- Java 8+
- Stream API
- Date and Time
- File and I/O
-
Multithreading
- Threads in Java: Processes, Runnable and Thread
- Thread Lifecycle in Java
- Synchronization in Java: synchronized and volatile
- Locks and Atomic Classes in Java
- Race Conditions and Deadlocks in Java
- The Executor Framework and Thread Pools in Java
- Future and CompletableFuture in Java
- Concurrent Collections in Java
- The Java Memory Model
- JVM and Memory
- Advanced Java
- Networking
- JDBC
- Testing
What a variable is
A variable is a named, typed storage location. In Java the type is fixed when the variable is declared and can never change, which is what statically typed means in practice.
int count = 10; // declaration with initialisation
double price; // declaration
price = 249.75; // assignmentThe two families of type
Every Java type is either a primitive or a reference. There is no third option.
- A primitive variable holds the value itself.
- A reference variable holds a reference to an object stored elsewhere. Its own value is that reference, never the object.
The eight primitive types
| Type | Size | Range or values | Default |
|---|---|---|---|
byte | 8 bit | -128 to 127 | 0 |
short | 16 bit | -32768 to 32767 | 0 |
int | 32 bit | about -2.1 to 2.1 billion | 0 |
long | 64 bit | about -9.2 to 9.2 quintillion | 0L |
float | 32 bit | approximate decimal | 0.0f |
double | 64 bit | approximate decimal | 0.0d |
char | 16 bit | a single UTF-16 code unit | the null character |
boolean | unspecified | true or false | false |
Defaults apply to fields and array elements only. A local variable has no default, and reading one before assignment is a compile error rather than a bug at runtime.
Reference types
Classes, interfaces, arrays, enums and records are all reference types. Their default value is null.
String city = "Chennai"; // a reference to a String object
int[] scores = new int[3]; // a reference to an array object
String missing = null; // a reference that points at nothingConstants with final
final int MAX_RETRIES = 3;
// MAX_RETRIES = 4; // compile error
static final double TAX_RATE = 0.18; // a class level constantfinal fixes the variable, not the object it points to. A final reference to a mutable list can still have elements added to it.
Local variable type inference with var
Since Java 10 the compiler can infer the type of a local variable:
var total = 0; // inferred as int
var names = new ArrayList<String>(); // inferred as ArrayList of Stringvar is not dynamic typing. The type is fixed at compile time exactly as if it had been written out. It is allowed only for local variables that have an initialiser, never for fields, parameters or return types.
Literals
int decimal = 1_000_000; // underscores are for readability only
int hex = 0xFF; // 255
int binary = 0b1011; // 11
long big = 9000000000L; // the L suffix is required
float rate = 1.5f; // the f suffix is required
char letter = 65; // the character A, from its code unit
boolean valid = true;A whole number literal is an int unless suffixed with L, and a decimal fraction is a double unless suffixed with f. Forgetting either suffix is a frequent early error.
Text blocks
Since Java 15 a multi line string can be written without escaping every line break:
String message = """
Order received.
Thank you.""";Common mistakes
int average = 7 / 2;gives 3. Integer division discards the remainder before any assignment happens.double d = 0.1 + 0.2;is not exactly 0.3. Binary floating point cannot represent those values precisely, so money should useBigDecimalor whole minor units.- Assuming an uninitialised local variable is zero.
- Declaring a variable far from where it is used, which widens its scope for no reason.
Best practices
- Declare a variable at the point of first use and give it the narrowest scope that works.
- Prefer
intanddoubleunless a specific reason argues otherwise. Smaller types rarely save anything meaningful. - Use
finalfor values that must not change, and write constants in upper case with underscores. - Use
varonly when the initialiser already makes the type obvious to a reader.
Practice
- Predict the output of
System.out.println(5 / 2 + " " + 5 % 2 + " " + 5.0 / 2); - Why does
byte b = 200;fail to compile whilebyte b = 100;succeeds? - Write a declaration for a constant holding the number of seconds in a day, choosing the type deliberately.
- Explain why
final List<String> namesdoes not make the list unmodifiable.
Conclusion
Primitives hold values and references hold the addresses of objects. That distinction decides how assignment, comparison and default values behave, and almost every confusing result later traces back to it.