Variables and Data Types — Primitives, Type Conversion, var, and Default Values
In this tutorial, you will learn about Variables and Data Types. We cover key concepts, practical examples, and best practices to help you master this topic.
Java variables are strongly typed containers for data, with eight primitive types and a unified type system. Unlike dynamically typed languages, every variable in Java has a fixed type determined at compile time — the compiler enforces that you never assign a string to an integer variable, which eliminates entire categories of runtime errors.
What You'll Learn
- The eight primitive types and their memory sizes
- Implicit (widening) and explicit (narrowing) type conversion
- Local variable type inference with
var - Default values for fields vs local variables
Why It Matters
Understanding the primitive types is essential because Java's performance, memory footprint, and correctness depend on choosing the right type. Using int when byte suffices wastes memory; using float when double is needed loses precision.
Real-World Use
Every program you write will declare variables. Financial applications use BigDecimal for currency, game engines use float for 3D coordinates, and high-performance systems use byte arrays for network buffers.
The Eight Primitive Types
Java has eight primitive types, divided into four categories:
| Category | Type | Size | Range / Values |
|---|---|---|---|
| Integer | byte |
8 bits | -128 to 127 |
| Integer | short |
16 bits | -32,768 to 32,767 |
| Integer | int |
32 bits | -2^31 to 2^31-1 |
| Integer | long |
64 bits | -2^63 to 2^63-1 |
| Floating | float |
32 bits | ~ ±3.4e-38 to ±3.4e38, 6-7 decimal digits |
| Floating | double |
64 bits | ~ ±1.7e-308 to ±1.7e308, 15-16 decimal digits |
| Character | char |
16 bits | 0 to 65,535 (Unicode UTF-16 code unit) |
| Boolean | boolean |
JVM-dependent | true or false |
Integer Types
byte b = 100; // 8-bit, good for small numbers or raw bytes
short s = 30_000; // 16-bit, rarely used directly
int i = 2_000_000_000; // 32-bit, the default for whole numbers
long l = 9_000_000_000_000_000_000L; // 64-bit, note the L suffix
Underscores in numeric literals (Java 7+) improve readability and are ignored by the compiler.
The L suffix is required for long literals exceeding int range. Without it, the compiler treats the literal as int and reports an error.
Floating-Point Types
float f = 3.14f; // 32-bit, note the f suffix
double d = 3.14159265358979; // 64-bit, the default for decimals
Without the f suffix, 3.14 is a double literal and cannot be assigned to a float without a cast. Double is the default for floating-point literals because it provides far greater precision.
The char Type
char c1 = 'A'; // single quotes for characters
char c2 = '\u0041'; // Unicode escape for 'A'
char c3 = 65; // integer literal, also 'A'
A char is a single 16-bit Unicode character. It is not a string — you must use single quotes. char can also hold values from 0 to 65,535, making it an unsigned integer underneath.
The boolean Type
boolean active = true;
boolean completed = false;
Booleans are not numeric — you cannot write if (1) in Java (unlike C/C++). The JVM does not specify a size for boolean; it often uses an int (4 bytes) in practice.
Type Conversion
Widening (Implicit) Conversion
Java automatically converts smaller primitive types to larger ones when there is no risk of losing information:
byte b = 42;
int i = b; // byte -> int: OK, implicit
long l = i; // int -> long: OK, implicit
double d = l; // long -> double: OK (possible precision loss for very large longs)
The widening order is: byte -> short -> int -> long -> float -> double and char -> int.
Narrowing (Explicit) Conversion
Converting a larger type to a smaller type requires a cast because data can be lost:
long big = 1_000_000_000_000L;
int i = (int) big; // truncates: i becomes -727,379,968 (overflow)
double pi = 3.14159;
float f = (float) pi; // loses precision
int ch = (int) 'A'; // char to int: 65
Always check the range before casting. (int) big does not throw an exception — it silently wraps around due to integer overflow.
Type Promotion in Expressions
When evaluating expressions, Java automatically promotes smaller operands:
byte a = 10;
byte b = 20;
int result = a + b; // a and b are promoted to int before addition
short x = 5;
int y = 2;
double z = x / y; // int division first: 5/2 = 2, then promoted to 2.0
Any operation on byte, short, or char produces an int. You cannot assign the result back without a cast:
byte a = 10;
byte b = 20;
byte c = a + b; // COMPILE ERROR: int cannot be converted to byte
The var Keyword (Java 10+)
var allows local variable type inference — the compiler infers the type from the initializer:
var name = "Alice"; // inferred as String
var count = 42; // inferred as int
var price = 19.99; // inferred as double
var list = new ArrayList<String>(); // inferred as ArrayList<String>
var is not a dynamic type. The inferred type is fixed at compile time:
var value = "Hello";
value = 42; // COMPILE ERROR: String cannot be converted to int
Restrictions:
- Only valid for local variables (not fields, method parameters, or return types)
- Requires an explicit initializer —
var x;does not compile - Cannot be used with
nullinitializer — the compiler cannot infer a type
Default Values
In Java, fields (class-level variables) have default values. Local variables do not.
| Type | Default Value |
|---|---|
byte |
0 |
short |
0 |
int |
0 |
long |
0L |
float |
0.0f |
double |
0.0d |
char |
'\u0000' (null character) |
boolean |
false |
| Reference types | null |
public class Defaults {
int x; // default 0
boolean flag; // default false
String name; // default null
public void show() {
int y; // NOT initialized — compile error if used
// System.out.println(y); // does not compile
}
}
Common Mistakes
- Using
intfor monetary values.intanddoubleboth lose precision for money. UseBigDecimalfor currency. - Forgetting the
Lsuffix forlongliterals.long x = 9999999999;fails because the literal exceedsintrange. Write9999999999L. - Assuming
booleanis numeric.if (1)is invalid in Java. Always use explicit boolean conditions. - Believing
varmakes Java dynamically typed. The type is still fixed at compile time —varis just syntax sugar for writing the type explicitly. - Assuming local variables have defaults. They do not. The compiler forces you to initialize them before use.
Practice Questions
1. What is the difference between float and double?
float is 32 bits with ~7 decimal digits of precision; double is 64 bits with ~15-16 decimal digits. Double is the default for floating-point literals.
2. Why does byte b = 10; byte c = b + b; fail to compile?
The expression b + b promotes both operands to int, producing an int result. Assigning an int to a byte requires a narrowing cast: byte c = (byte) (b + b);.
3. What is the default value of an int field?
0. Fields are automatically initialized; local variables are not.
4. Can var be used for method parameters?
No. var is restricted to local variables with initializers.
5. What range of values can a byte hold?
-128 to 127.
Challenge Question:
Write a program that declares variables of all eight primitive types, assigns them values, and then attempts to assign each to every other type — both with and without casts. Document which conversions compile and which values change. Explain why byte -> int works but int -> byte requires a cast.
FAQ
{{< faq "Is String a primitive type?" "No. String is a class in java.lang. It is not a primitive, but it has special language support — string literals (\"hello\"), concatenation with +, and the string pool for efficient memory management." >}}
Mini Project
Write a program DataTypes.java that:
- Declares a
byte,short,int,long,float,double,char, andboolean - Prints the minimum and maximum values for each numeric type using the
MIN_VALUE/MAX_VALUEconstants (e.g.,Integer.MIN_VALUE) - Demonstrates overflow: add 1 to
Integer.MAX_VALUEand print the result - Demonstrates floating-point imprecision: add
0.1ten times and compare with1.0 - Converts a
doubletointwith a cast and shows the truncated value - Uses
varto declare at least three local variables of different inferred types
Run the program and observe the outputs. The overflow and floating-point precision outputs are especially instructive.
What's Next
Now that you understand how to store data, the next lesson shows you how to transform it. Lesson 5 covers operators — arithmetic, relational, logical, bitwise, and assignment operators — along with precedence rules that determine the order of evaluation in complex expressions.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro