Skip to main content
PProfileMatch

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 var and final appropriately

On this page

  1. Declaring variables
  2. The eight primitive types
  3. Strings
  4. `var` and `final`
  5. Type conversion and casting
  6. Common mistakes
  7. How this shows up in interviews and real projects

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.

TypeSizeHoldsExample
byte1 byteWhole numbers -128 to 127byte level = 120;
short2 bytesWhole numbers -32,768 to 32,767short year = 2025;
int4 bytesWhole numbers about -2.1 billion to 2.1 billionint age = 29;
long8 bytesVery large whole numbers (note the L suffix)long people = 8_000_000_000L;
float4 bytesDecimals, about 7 digits of precision (note the f suffix)float rating = 4.5f;
double8 bytesDecimals, about 15 digits of precisiondouble price = 499.99;
booleanJVM dependenttrue or falseboolean inStock = true;
char2 bytesA single UTF-16 character in single quoteschar grade = 'A';
Primitives.java
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.

StringsAndFinal.java
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.

Casting.java
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 with error: 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 gives error: variable count might not have been initialized.
  • Reassigning a final variable. TAX_RATE = 0.2; gives error: cannot assign a value to final variable TAX_RATE.
  • Comparing strings with `==`. The code compiles but returns false for equal text built at runtime. Use .equals().
  • A large literal without `L`. long big = 3000000000; fails with error: integer number too large. Write 3000000000L.
  • Double quotes for a char. char c = "A"; gives error: 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, boolean and char.
  • String is 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 final for values that must not change and var only when the type is obvious.
  • Avoid double for 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.

Ride this lesson

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.