Java Variables and Data Types
ProgrammingLesson 2 of 65 min read
What you'll learn
- Declare variables using Java's eight primitive types and choose the right one
- Work with String objects and understand why they are immutable
- Convert between types safely using widening and explicit casting
- Use
varandfinalappropriately
On this page
A variable is a named box that holds a value, and in Java every box has a type that decides what it can hold. Getting types right is the difference between a shopping cart that totals correctly and one that silently loses paise or overflows. This lesson covers the types you will use daily and the traps that catch beginners.
Declaring variables
A declaration states the type, then the name, then optionally a value: int age = 29;. Java is statically typed, so once age is an int it can never hold text. Names use camelCase by convention (orderTotal, not order_total), cannot start with a digit and cannot be a reserved word such as class.
The eight primitive types
Primitives hold raw values directly. Java has exactly eight of them. In practice you will use int, double, boolean and char constantly, long when numbers get large, and the others rarely.
| Type | Size | Holds | Example |
|---|---|---|---|
| byte | 1 byte | Whole numbers -128 to 127 | byte level = 120; |
| short | 2 bytes | Whole numbers -32,768 to 32,767 | short year = 2025; |
| int | 4 bytes | Whole numbers about -2.1 billion to 2.1 billion | int age = 29; |
| long | 8 bytes | Very large whole numbers (note the L suffix) | long people = 8_000_000_000L; |
| float | 4 bytes | Decimals, about 7 digits of precision (note the f suffix) | float rating = 4.5f; |
| double | 8 bytes | Decimals, about 15 digits of precision | double price = 499.99; |
| boolean | JVM dependent | true or false | boolean inStock = true; |
| char | 2 bytes | A single UTF-16 character in single quotes | char grade = 'A'; |
public class Primitives {
public static void main(String[] args) {
int age = 29;
long worldPopulation = 8_000_000_000L;
double price = 499.99;
float rating = 4.5f;
boolean inStock = true;
char grade = 'A';
byte level = 120;
short year = 2025;
System.out.println(age);
System.out.println(worldPopulation);
System.out.println(price);
System.out.println(rating);
System.out.println(inStock);
System.out.println(grade);
System.out.println(level + " " + year);
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
System.out.println(Long.MAX_VALUE);
System.out.println(Double.MAX_VALUE);
}
}Output
29 8000000000 499.99 4.5 true A 120 2025 2147483647 -2147483648 9223372036854775807 1.7976931348623157E308
Strings
String is not a primitive. It is a class, which is why it starts with a capital letter and comes with useful methods. Strings are immutable: methods like toUpperCase() never change the original, they return a new String. Forgetting this is a classic bug. Also, compare strings with .equals(), never ==, because == checks whether two variables point to the same object, not whether the text matches.
public class StringsAndFinal {
public static void main(String[] args) {
final double TAX_RATE = 0.18;
String item = "Laptop";
double price = 50000;
double total = price + price * TAX_RATE;
var message = item + " costs " + total + " with tax";
System.out.println(message);
String name = " Priya Sharma ";
System.out.println(name.trim().toUpperCase());
System.out.println(name.trim().length());
System.out.println(name.trim().substring(0, 5));
System.out.println(name.contains("Sharma"));
String a = "java";
String b = new String("java");
System.out.println(a == b);
System.out.println(a.equals(b));
String text = "hello";
text.toUpperCase();
System.out.println(text);
text = text.toUpperCase();
System.out.println(text);
String nothing = null;
System.out.println(nothing);
String blank = "";
System.out.println(blank.isEmpty());
System.out.println(String.format("%.2f", total));
}
}Output
Laptop costs 59000.0 with tax PRIYA SHARMA 12 Priya true false true hello HELLO null true 59000.00
Three details are worth noticing. final made TAX_RATE a constant, so any later assignment would not compile. var let the compiler infer that message is a String. And the line text.toUpperCase(); on its own did nothing useful because the result was thrown away.
`var` and `final`
var (Java 10+) tells the compiler to infer the type from the right-hand side. It works only for local variables with an initial value, and the variable is still statically typed: var count = 5; is an int forever. Use it when the type is obvious from the right side, and avoid it when it would hide what a value is.
final means the variable can be assigned exactly once. By convention, constants are written in UPPER_SNAKE_CASE. Making things final by default communicates intent and prevents accidental reassignment.
Type conversion and casting
Java converts automatically when no information can be lost (widening): an int fits inside a double. When information might be lost (narrowing), you must cast explicitly with (type), which tells the compiler you accept the risk. Also remember that dividing two ints performs integer division and discards the remainder.
public class Casting {
public static void main(String[] args) {
int total = 7;
int count = 2;
System.out.println(total / count);
System.out.println((double) total / count);
System.out.println(total / (double) count);
double price = 19.99;
int rounded = (int) price;
System.out.println(rounded);
System.out.println(Math.round(price));
int big = Integer.MAX_VALUE;
System.out.println(big + 1);
long safe = (long) big + 1;
System.out.println(safe);
int small = 10;
double widened = small;
System.out.println(widened);
System.out.println(0.1 + 0.2);
System.out.println('A' + 1);
System.out.println((char) ('A' + 1));
}
}Output
3 3.5 3.5 19 20 -2147483648 2147483648 10.0 0.30000000000000004 66 B
Read the output carefully. 7 / 2 is 3 because both operands are ints. Casting 19.99 to int truncates to 19; it does not round, so use Math.round when you want rounding. Adding one to Integer.MAX_VALUE silently overflows to the most negative int, with no error at all. And 'A' + 1 is 66 because arithmetic on a char promotes it to its numeric code, so you cast back to char to get B.
Common mistakes
- Assigning a double to an int.
int x = 9.5;fails witherror: incompatible types: possible lossy conversion from double to int. Cast it or change the type. - Using a variable before giving it a value. A local
int count;that is read before assignment giveserror: variable count might not have been initialized. - Reassigning a final variable.
TAX_RATE = 0.2;giveserror: cannot assign a value to final variable TAX_RATE. - Comparing strings with `==`. The code compiles but returns
falsefor equal text built at runtime. Use.equals(). - A large literal without `L`.
long big = 3000000000;fails witherror: integer number too large. Write3000000000L. - Double quotes for a char.
char c = "A";giveserror: incompatible types: String cannot be converted to char. Chars use single quotes.
How this shows up in interviews and real projects
Beginner interviews love questions on integer overflow, == versus .equals(), string immutability and why 0.1 + 0.2 is not 0.3. All four appear in the programs above. In real codebases the same ideas turn into bugs such as price calculations drifting by a fraction, IDs overflowing an int, and null strings reaching a method call. Next, Java If-Else, Switch and Loops puts these values to work in decisions.
Try it yourself
Build a small shopping-cart total. Declare a final double GST = 0.05, an int quantity, and a double unitPrice. Compute the subtotal, the tax and the grand total, and print the grand total formatted to 2 decimal places. Then print the average price per item as a double using a cast so it is not truncated.
Show a hint
Use String.format("%.2f", value) for formatting and (double) total / quantity for the average.
Key takeaways
- Java has eight primitives; day to day you mostly use
int,long,double,booleanandchar. Stringis an immutable class: methods return new strings, and you compare content with.equals().- Widening is automatic, narrowing needs an explicit cast and can truncate or overflow silently.
- Use
finalfor values that must not change andvaronly when the type is obvious. - Avoid
doublefor money; integer division discards the remainder.
Test yourself
A trick from this lesson's ride: Twins look alike (equals) but are not the same person (==). Four more tricks like it wait along the route, each followed by a question.
Frequently asked questions
What are the primitive data types in Java?
Java has eight primitive types: byte, short, int, long, float, double, boolean and char. They store raw values directly, unlike objects such as String. int and double are the most commonly used.
What is the difference between == and equals() in Java?
For objects such as String, == checks whether two references point to the same object in memory, while .equals() compares the actual contents. Use .equals() to compare text. For primitives, == compares the values directly.
Why does Integer.MAX_VALUE + 1 become negative in Java?
An int is stored in 32 bits, so when a result exceeds the maximum value it wraps around to the minimum value instead of throwing an error. This is called integer overflow. Use long or Math.addExact() when overflow is possible.