# Variables and Data Types

Course: [Java](https://www.devtutorials.ai/learn/java) · Section: Getting Started
Source: https://www.devtutorials.ai/learn/java/getting-started/variables-and-data-types

> Create variables and constants, choose between Java's primitive and non-primitive types, read input with Scanner, and convert between types with casting, parse methods and String.valueOf.

## Introduction to Data Types

A data type defines the kind of value that a variable can store in a program.

When creating a variable, you must specify its data type so that Java knows how much memory to allocate and what operations can be performed on that value.

Different data types are used to represent different kinds of information in a program.

## Real-World Example

Think about creating a profile on a website. The profile needs to store different kinds of information:

- A person’s name is stored as text.
- Their age is stored as a whole number.
- Their height can be stored as a decimal number.
- Whether they are logged in is stored as true or false.

Each value needs a suitable data type. In Java, the data type tells the program what kind of value a variable can store.

## What You Will Learn

In this lesson, you will learn:

1. How to create, fill and change a variable.
2. Where a variable can be used (its scope), and how `var` works.
3. How to make a value that never changes with `final`.
4. The eight primitive data types, and the main non-primitive types.
5. How to write literal values: numbers, text, characters, `true`, `false` and `null`.
6. How to print output and read input with `Scanner`.
7. How Java converts one type to another, both automatically and by casting.
8. How to turn text into numbers with parse methods, and numbers into text.

## Start With a Working Example

Press **Run**.

```java runnable title="Three variables, three kinds of value"
public class Main {
    public static void main(String[] args) {
        String name = "Asha";
        int age = 21;
        double height = 1.62;

        System.out.println(name);
        System.out.println(age);
        System.out.println(height);
    }
}
```

Expected output:

```text
Asha
21
1.62
```

The program creates three variables. Each one holds a different kind of value: text, a whole number and a decimal number.

Then it prints each value on its own line.

### Try This

Change `21` to your own age. Press Run again. Only the second line changes.

## Variables

A variable is a named storage location used to hold data in a program. Think of it like a labeled box that stores a value. The value can be changed whenever needed while the program runs. Variables are used to store information such as names, ages, prices, scores, and user input.

Every variable has a name and a data type. The name helps identify the variable, while the data type determines what kind of value it can store.

Every variable in Java has three parts:

- a **type**, such as `int`;
- a **name**, such as `age`;
- a **value**, such as `21`.

### Declaration

A declaration introduces a variable by giving it a type and a name.

```text
int age;
```

This statement declares a variable named age that can store a whole number. The variable does not yet have a value that the program can use.

### Initialization

**Initializing** a variable means giving it its first value.

```text
int age;      // declaration
age = 21;     // initialization
```

Most of the time, you do both in one line:

```text
int age = 21;
```

Java will not let you use a variable before it has a value. This stops you from reading an empty box by mistake.

### Assignment

**Assignment** means putting a new value into a variable that already exists. You use the `=` sign.

```java runnable title="One variable, three different values over time"
public class Main {
    public static void main(String[] args) {
        int score = 10;
        System.out.println("Start: " + score);

        score = 25;
        System.out.println("After level 1: " + score);

        score = score + 5;
        System.out.println("After bonus: " + score);
    }
}
```

Expected output:

```text
Start: 10
After level 1: 25
After bonus: 30
```

The variable keeps its name. Only its value changes.

Look at `score = score + 5;`. Java works out the right side first (`25 + 5`). Then it stores the answer, `30`, back into `score`.

In Java, `=` does not mean "is equal to". It means "store this value". To compare two values, you use `==`, which you will learn in a later lesson.

### Scope

The **scope** of a variable is the part of the program where you can use it.

A variable lives inside the curly braces `{ }` where it was declared. Outside those braces, it does not exist.

Think of a classroom whiteboard. What you write on it is visible inside that room. Students in the next room cannot see it.

```java runnable expect-error title="A variable cannot be used outside its braces"
public class Main {
    public static void main(String[] args) {
        int total = 100;

        if (total > 50) {
            int bonus = 20;
            System.out.println(total + bonus);
        }

        System.out.println(bonus);
    }
}
```

The program does not compile. `bonus` was created inside the `if` block. So it does not exist on the last line.

`total` works in both places. It was declared in the outer block, so the inner block can see it too.

In simple words: a variable can be used inside its own braces, and inside any braces nested within them.

### Type Inference (var)

Normally, you write a variable’s type before its name. When the starting value already makes the type clear, you can use var and let Java determine the type for you. This is called type inference.

```java runnable title="var lets Java work out the type from the value"
public class Main {
    public static void main(String[] args) {
        var city = "Chennai";
        var students = 32;
        var price = 49.5;

        System.out.println(city + " has " + students + " students.");
        System.out.println("Ticket price: " + price);
    }
}
```

Expected output:

```text
Chennai has 32 students.
Ticket price: 49.5
```

Java decides that `city` is a `String`, `students` is an `int` and `price` is a `double`.

The type is still fixed. You cannot later store text in `students`.

`var` has two rules:

- It only works for variables inside a method.
- You must give a value on the same line. `var count;` does not compile, because Java has nothing to look at.

## Constants

A **constant** is a variable whose value never changes after it is set.

### Why Constants Are Needed

Some values should stay the same for the whole program. The number of days in a week is one. A tax rate is another.

If such a value can change, one wrong line of code can change it by accident. The program then gives wrong answers, and the mistake is hard to find.

A constant stops that. Java refuses to compile any line that tries to change it.

Constants also give a number a clear name. `DAYS_IN_WEEK` tells the reader much more than `7`.

### final Keyword

You make a constant with the `final` keyword.

```java runnable title="A final value used in a calculation"
public class Main {
    public static void main(String[] args) {
        final int DAYS_IN_WEEK = 7;
        int weeks = 4;

        System.out.println("Days in 4 weeks: " + (weeks * DAYS_IN_WEEK));
    }
}
```

Expected output:

```text
Days in 4 weeks: 28
```

Now try to change the constant:

```java runnable expect-error title="Java refuses to change a final value"
public class Main {
    public static void main(String[] args) {
        final int DAYS_IN_WEEK = 7;
        DAYS_IN_WEEK = 8;
        System.out.println(DAYS_IN_WEEK);
    }
}
```

The compiler reports that it cannot assign a value to the final variable `DAYS_IN_WEEK`.

By habit, constant names use capital letters, with underscores between words.

## Primitive Data Types

A data type tells Java what kind of value a variable can store.

Think about filling containers with water. A small glass can hold a small amount, while a large bottle can hold more. You choose a container based on the amount of water you need to store.

Java has eight **primitive** data types. Primitive means simple and built in. Each one holds a single plain value, not an object.

### byte

`byte` holds a very small whole number, from -128 to 127.

It uses 1 byte of memory. It is used when memory matters, for example when reading raw file data.

### short

`short` holds a small whole number, from -32,768 to 32,767.

It can store values larger than byte, but it is not commonly needed in everyday Java programs.

### int

`int` holds a whole number, from about -2.1 billion to about 2.1 billion.

It uses 4 bytes. **It is the default choice for whole numbers.** Use it for ages, counts and scores.

### long

`long` holds a very large whole number, up to about 9.2 quintillion.

It uses 8 bytes. Use it when an `int` is too small, such as for world population or time in milliseconds.

You put an `L` at the end of a big `long` value: `long views = 8000000000L;`.

### float

`float` holds a decimal number with about 7 digits of accuracy.

It uses 4 bytes. You put an `f` at the end of the value: `float rating = 4.5f;`.

### double

`double` holds a decimal number with about 15 digits of accuracy.

It uses 8 bytes. **It is the default choice for decimal numbers.** Use it for prices, heights and averages.

### char

`char` holds one single character, such as a letter, a digit or a symbol.

You write it in **single** quotes: `char grade = 'A';`.

### boolean

`boolean` holds only one of two values: `true` or `false`.

Use it for yes/no facts, such as `boolean isLoggedIn = true;`.

### All Eight in One Program

```java runnable title="One variable of each primitive type"
public class Main {
    public static void main(String[] args) {
        byte level = 12;
        short year = 2026;
        int population = 1500000;
        long views = 8000000000L;
        float rating = 4.5f;
        double price = 199.99;
        char grade = 'A';
        boolean isPassed = true;

        System.out.println("byte:    " + level);
        System.out.println("short:   " + year);
        System.out.println("int:     " + population);
        System.out.println("long:    " + views);
        System.out.println("float:   " + rating);
        System.out.println("double:  " + price);
        System.out.println("char:    " + grade);
        System.out.println("boolean: " + isPassed);
    }
}
```

Expected output:

```text
byte:    12
short:   2026
int:     1500000
long:    8000000000
float:   4.5
double:  199.99
char:    A
boolean: true
```

### Primitive Types at a Glance

| Type | Size | Holds | Example |
|---|---|---|---|
| `byte` | 1 byte | -128 to 127 | `byte level = 12;` |
| `short` | 2 bytes | -32,768 to 32,767 | `short year = 2026;` |
| `int` | 4 bytes | about ±2.1 billion | `int count = 500;` |
| `long` | 8 bytes | about ±9.2 quintillion | `long views = 8000000000L;` |
| `float` | 4 bytes | decimals, about 7 digits | `float rating = 4.5f;` |
| `double` | 8 bytes | decimals, about 15 digits | `double price = 199.99;` |
| `char` | 2 bytes | one character | `char grade = 'A';` |
| `boolean` | 1 bit of information | `true` or `false` | `boolean isOpen = true;` |

**Easy Way to Remember:** For whole numbers, use `int`. For decimals, use `double`. Reach for the others only when you have a reason.

## Non-Primitive Data Types

Think about an online shopping order. One order needs to store several pieces of related information, such as the customer’s name, the selected products, and the delivery address.

A single primitive type cannot hold all this information together. Java uses non-primitive data types for values that contain text, multiple items, or related information.

For example:

- A String stores the customer’s name.
- An array stores the selected products.
- A class can represent the complete order, including the customer, products, and delivery details.

Non-primitive data types are also called reference types. A reference helps Java locate and use the stored value.

A reference variable can also contain null. This means the variable does not currently refer to a value.

### Reference Types

Reference types are used for values that are more complex than primitive values.

| Reference type | What it stores                                        |
| -------------- | ----------------------------------------------------- |
| String         | Text, such as a name or message                       |
| Array          | Multiple values of the same type                      |
| Class          | Related information and actions defined as a new type |

## Input and Output

Output is what your program shows. Input is what the user gives it.

### System.out.print()

`System.out.print()` prints a value and stays on the same line.

### System.out.println()

`System.out.println()` prints a value and then moves to a new line.

```java runnable title="print stays on the line, println ends it"
public class Main {
    public static void main(String[] args) {
        String item = "Notebook";
        int quantity = 3;

        System.out.print("Item: ");
        System.out.println(item);
        System.out.print("Quantity: ");
        System.out.println(quantity);
    }
}
```

Expected output:

```text
Item: Notebook
Quantity: 3
```

Each `print` sets up a label. The `println` after it adds the value and ends the line.

### Scanner Class

To read what the user types, you use the `Scanner` class.

`Scanner` lives in the `java.util` package. So you import it at the top of the file:

```text
import java.util.Scanner;
```

Then you create one `Scanner` that reads from the keyboard:

```text
Scanner sc = new Scanner(System.in);
```

`System.in` means "the keyboard". Now `sc` can read what the user types.

In this course, the editor reads input from the **Standard Input** box beside the code, one line at a time. If the box runs out, a popup asks you for the next line. The console then shows each input line, the way a terminal shows what you type.

### Reading Strings

`nextLine()` reads a whole line of text, including spaces.

`next()` reads only one word. It stops at the first space.

```java runnable title="Read a full name with nextLine" stdin="Asha Kumar"
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("Enter your full name: ");
        String name = sc.nextLine();

        System.out.println("Welcome, " + name + "!");
    }
}
```

In the console you will see:

```text
Enter your full name: Asha Kumar
Welcome, Asha Kumar!
```

Change `nextLine()` to `next()` and run it again. You will only get `Asha`, because `next()` stops at the space.

### Reading Numbers

`Scanner` has a method for each number type:

| Method | Reads |
|---|---|
| `nextInt()` | an `int` |
| `nextLong()` | a `long` |
| `nextDouble()` | a `double` |
| `nextFloat()` | a `float` |
| `nextBoolean()` | a `boolean` |

```java runnable title="Read a whole number and a decimal" stdin="3\n45.50"
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("How many books? ");
        int books = sc.nextInt();

        System.out.print("Price of one book? ");
        double price = sc.nextDouble();

        System.out.println("Total: " + (books * price));
    }
}
```

In the console you will see:

```text
How many books? 3
Price of one book? 45.50
Total: 136.5
```

`nextInt()` gives a real number, not text. So Java can multiply it straight away.

### Common Input Mistakes

The most common mistake is calling `nextLine()` right after `nextInt()`.

`nextInt()` reads the number but leaves the rest of that line behind. The next `nextLine()` then reads that empty leftover, not your next line.

```java runnable title="The skipped nextLine problem, and the fix" stdin="21\nAsha"
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("Age: ");
        int age = sc.nextInt();
        sc.nextLine(); // throw away the rest of the age line

        System.out.print("Name: ");
        String name = sc.nextLine();

        System.out.println(name + " is " + age);
    }
}
```

In the console you will see:

```text
Age: 21
Name: Asha
Asha is 21
```

Remove the line `sc.nextLine(); // throw away...` and run it again. The name comes out empty, because `nextLine()` read the leftover of the age line.

Other input mistakes to watch for:

- **Typing text where a number is expected.** `nextInt()` stops the program if the user types `abc`.
- **Forgetting the import.** Without `import java.util.Scanner;`, Java reports that it cannot find `Scanner`.
- **Typing a decimal for `nextInt()`.** `4.5` is not a whole number, so `nextInt()` fails.

## Naming Conventions and Comments

Java has a few rules for names that you must follow. It also has habits that every Java developer follows.

### Rules You Must Follow

- A name can use letters, digits, `_` and `$`.
- A name cannot start with a digit. `2ndPlace` is not allowed.
- A name cannot be a Java keyword, such as `int` or `class`.
- Names are case sensitive. `age` and `Age` are two different variables.

### Habits Everyone Follows

| Kind of name | Style | Example |
|---|---|---|
| Variable | camelCase | `totalMarks`, `firstName` |
| Constant | UPPER_SNAKE_CASE | `MAX_SPEED`, `TAX_RATE` |
| Method | camelCase | `calculateTotal()` |
| Class | PascalCase | `Student`, `BankAccount` |

**camelCase** starts with a small letter, and each new word starts with a capital.

Choose names that say what the value means. `totalPrice` is clear. `tp` or `x` is not.

### Comments

A **comment** is a note for people. Java ignores it.

- `// text` is a single-line comment.
- `/* text */` can cover many lines.
- `/** text */` is a documentation comment. Tools use it to build help pages.

Write comments that explain **why**, not **what**. `// 18% tax for this region` is useful. `// multiply` is not.

## What is Type Conversion?

**Type conversion** means changing a value from one data type to another.

For example, you might turn the `int` value `5` into the `double` value `5.0`.

## Why Type Conversion Is Needed

Values often arrive in one type, but you need them in another.

- You divide two whole numbers but want a decimal answer.
- You read a number as text, but need to do maths with it.
- You want to show a number inside a message.

Without conversion, Java would refuse to mix these types.

## Automatic vs Manual Conversion

Java converts types in two ways:

- **Automatic (implicit):** Java does it for you, because nothing can be lost.
- **Manual (explicit):** you must ask for it, because data might be lost.

Think of pouring water. Pouring from a cup into a bucket is always safe. Pouring from a bucket into a cup might spill. Java only does the safe pour by itself.

## Implicit Conversion (Widening)

### Automatic Type Conversion

When you put a smaller type into a bigger type, Java converts it automatically. You do not write anything extra.

### Widening Conversion

This is called **widening**, because the value moves into a wider (bigger) type.

### Converting Smaller Types to Larger Types

```java runnable title="Smaller types fit into bigger ones automatically"
public class Main {
    public static void main(String[] args) {
        int apples = 12;
        long bigApples = apples;
        double decimalApples = apples;

        char letter = 'A';
        int letterCode = letter;

        System.out.println(bigApples);
        System.out.println(decimalApples);
        System.out.println(letterCode);
    }
}
```

Expected output:

```text
12
12.0
65
```

The `int` fits in a `long` and in a `double` without any change. The `double` just shows `.0`.

A `char` is stored as a number inside the computer. The letter `A` has the code `65`.

### Conversion Rules

Widening follows this order, from small to big:

```text
byte → short → int → long → float → double
              ↑
            char
```

Java converts automatically from left to right. It will not go from right to left by itself.

Two more rules:

- `boolean` never converts to or from a number.
- When you mix types in a calculation, Java converts the smaller one to the bigger one first. So `5 + 2.0` becomes `5.0 + 2.0`, and the answer is a `double`.

## Explicit Conversion (Casting)

### What is Casting?

**Casting** means telling Java to convert a value to a type you choose.

You need it when moving from a bigger type to a smaller one. Java will not do this by itself, because data might be lost.

### Narrowing Conversion

Moving from a bigger type to a smaller type is called **narrowing**.

Without a cast, Java refuses:

```java runnable expect-error title="Java will not narrow a double to an int by itself"
public class Main {
    public static void main(String[] args) {
        double price = 99.75;
        int rupees = price;
        System.out.println(rupees);
    }
}
```

The compiler reports a "possible lossy conversion from double to int". It is warning you that the `.75` would be lost.

### Explicit Type Casting Syntax

You write the target type in brackets, just before the value:

```text
(targetType) value
```

```java runnable title="A cast tells Java you accept the change"
public class Main {
    public static void main(String[] args) {
        double price = 99.75;
        int rupees = (int) price;

        int total = 7;
        int people = 2;
        double share = (double) total / people;

        System.out.println(rupees);
        System.out.println(share);
    }
}
```

Expected output:

```text
99
3.5
```

`(int) price` keeps only the whole part. It does **not** round. So `99.75` becomes `99`.

`(double) total / people` turns `7` into `7.0` first. Then the division gives a decimal answer, `3.5`.

### Data Loss During Conversion

Casting can lose data in two ways.

The first is losing the decimal part, which you just saw.

The second is overflow. A value too big for the smaller type wraps around and gives a strange number.

```java runnable title="Two ways a cast can lose data"
public class Main {
    public static void main(String[] args) {
        double temperature = 36.9;
        int wholeTemp = (int) temperature;

        int bigNumber = 300;
        byte smallNumber = (byte) bigNumber;

        System.out.println(wholeTemp);
        System.out.println(smallNumber);
    }
}
```

Expected output:

```text
36
44
```

`36.9` loses its decimal part and becomes `36`.

`300` is too big for a `byte`, which stops at `127`. So it wraps around and becomes `44`. The original value is lost.

In simple words: cast only when you are sure the value fits, or when losing the extra part is what you want.

## Parse Methods

A **parse method** turns text into a number or a boolean.

You need this when a value arrives as a `String`, for example from a file, a web form or a text box.

### Integer.parseInt()

`Integer.parseInt("42")` turns the text `"42"` into the `int` `42`.

### Long.parseLong()

`Long.parseLong("9000000000")` turns text into a `long`.

### Double.parseDouble()

`Double.parseDouble("19.99")` turns text into a `double`.

### Float.parseFloat()

`Float.parseFloat("2.5")` turns text into a `float`.

### Boolean.parseBoolean()

`Boolean.parseBoolean("true")` turns text into a `boolean`.

It returns `true` only for the text `true`, in any mix of capitals. Any other text gives `false`.

```java runnable title="Five parse methods turn text into values"
public class Main {
    public static void main(String[] args) {
        int quantity = Integer.parseInt("42");
        long distance = Long.parseLong("9000000000");
        double price = Double.parseDouble("19.99");
        float rating = Float.parseFloat("2.5");
        boolean isMember = Boolean.parseBoolean("TRUE");
        boolean isGuest = Boolean.parseBoolean("yes");

        System.out.println(quantity + 8);
        System.out.println(distance);
        System.out.println(price * 2);
        System.out.println(rating);
        System.out.println(isMember);
        System.out.println(isGuest);
    }
}
```

Expected output:

```text
50
9000000000
39.98
2.5
true
false
```

`quantity + 8` gives `50`, not `428`. That proves `quantity` is now a real number, not text.

`"yes"` is not the word `true`, so `parseBoolean` returns `false`.

If the text is not a valid number, a parse method stops the program with a `NumberFormatException`. For example, `Integer.parseInt("12a")` fails. So does `Integer.parseInt("4.5")`, because `4.5` is not a whole number.

## String Conversion

Sometimes you need the opposite: turning a number or a boolean into text.

### String.valueOf()

`String.valueOf()` turns almost any value into a `String`.

### toString()

`toString()` also returns a value as text. For numbers, you call it on the wrapper class, like `Integer.toString(42)`.

Every object in Java has a `toString()` method too.

```java runnable title="Turning numbers back into text"
public class Main {
    public static void main(String[] args) {
        int year = 2026;
        double score = 87.5;

        String yearText = String.valueOf(year);
        String scoreText = Double.toString(score);
        String idText = Integer.toString(7);

        System.out.println(yearText + 1);
        System.out.println("Score: " + scoreText);
        System.out.println("ID-" + idText);
        System.out.println(yearText.length());
    }
}
```

Expected output:

```text
20261
Score: 87.5
ID-7
4
```

`yearText + 1` gives `20261`, not `2027`. That is because `yearText` is now text, and `+` joins text together.

`yearText.length()` gives `4`, the number of characters in `"2026"`.

### Conversion Summary

| From | To | How |
|---|---|---|
| Small number type | Bigger number type | Automatic (widening) |
| Big number type | Smaller number type | Cast: `(int) value` |
| `String` | Number | `Integer.parseInt()`, `Double.parseDouble()` and so on |
| `String` | `boolean` | `Boolean.parseBoolean()` |
| Number or `boolean` | `String` | `String.valueOf()` or `Integer.toString()` |

## Common mistakes

The following mistakes are common when declaring variables and choosing data types. Each row shows what you see, why it happens and how to fix it.

| Symptom | Cause | Fix |
|---|---|---|
| `variable total might not have been initialized` | The variable has no value yet | Give it a value when you declare it |
| `possible lossy conversion from double to int` | A decimal is stored in an `int` | Use `double`, or cast with `(int)` |
| `cannot find symbol` for a variable | It is used outside its braces (scope) | Declare it in the outer block |
| `cannot assign a value to final variable` | The code changes a constant | Remove the change, or remove `final` |
| `NumberFormatException` | `parseInt` was given text that is not a whole number | Check the text before parsing it |
| A name read after a number comes out empty | `nextLine()` read the leftover of the number line | Call `sc.nextLine()` once after `nextInt()` |

## What to Remember

- A variable has a type, a name and a value. Declare it, give it a value, then use it inside its own braces.
- Use `final` for values that must never change. Name constants in `UPPER_SNAKE_CASE`.
- Java has eight primitive types. Use `int` for whole numbers and `double` for decimals by default.
- `String`, arrays and classes are non-primitive types. They hold references to objects and can be `null`.
- Small types widen to big types automatically. Big types need a cast, and a cast can lose data.
- Parse methods turn text into numbers. `String.valueOf()` and `toString()` turn values back into text.

Next: Operators
