Java Variables Explained: Types, Scope, var, final, and Common Errors

目次

1. What Are “Variables” in Java?

When you start learning Java, one of the first important concepts you encounter is the “variable.”
In short, a variable is a container used to temporarily store values (data) inside a program so you can reuse them as many times as needed.

However, in Java, you’ll quickly get stuck if you memorize variables as just “boxes.”
That’s because Java variables are handled together with a “type” (the kind of data).

In this section, we’ll organize the role of variables and the Java-specific way of thinking (the importance of types) for beginners.

1.1 What You Can Do with Variables (Store Values and Reuse Them)

With variables, a program can move from “one-off calculations” to “meaningful processing.”

For example, you can write numbers directly like this:

System.out.println(100 + 20);

This works, but the values have no meaning, so whoever reads the code later (including your future self) will struggle.
You won’t know “What is 100?” or “What is 20?”

By using variables, you can give values meaning.

int price = 100;
int tax = 20;
System.out.println(price + tax);

Using variables like this provides the following benefits:

  • Easier to understand the intent (names like price and tax convey meaning)
  • You can reuse values repeatedly (no need to write the same value over and over)
  • Easier to change later (if the tax rate changes, you only change the variable’s value)
  • You can keep intermediate results (break complex logic into smaller steps)

Especially as a beginner, it’s fine to think of “variables = naming values.”
However, in Java, the next concept—“types”—always comes as a set.

1.2 Java Variables Are Used with “Types” (Type Safety)

In Java, variables are generally created in the following form:

type variableName = value;

Example:

int age = 20;
String name = "Sagawa";

The key point here is the type.

  • int is an integer (e.g., 20, 100, -5)
  • String is a string (e.g., “Hello”, “Java”)

In Java, when you create a variable, you explicitly declare “what kind of value this variable can hold.”
Because of this system, Java has strengths like the following.

What Does “Type-Safe” Mean?

Because you specify types, Java can stop you when you try to put the wrong kind of value into a variable.

For example, if you try to put a string into an int variable, you’ll get a compile-time error.

int age = "20"; // This is an error

This isn’t inconvenient—it’s actually helpful.
Instead of “breaking after you run the program,” you can “detect mistakes before running it.”

Beginners sometimes feel “Java has a lot of errors” because of this, but if you change your perspective:

  • Java finds type mismatches early
  • The larger the project, the more types help reduce accidents

This idea—“types and variables come as a set”—is one of the most fundamental basics of Java.

Note: Even with “Variables,” There Are “Values” and “References”

Java variables are broadly handled in two ways:

  • Primitive types: handle the value itself (e.g., int, double, boolean)
  • Reference types: handle not the value itself, but the location (reference) where the value is stored (e.g., String, arrays, classes)

We won’t go deep here, but this is a common point of confusion for beginners, so it’s worth mentioning up front.

For example, String is a reference type.
It may look like you are “storing a string,” but strictly speaking, you’re holding “a reference to a string object.”

This difference also relates to topics you’ll learn later, such as “== vs equals” and “how final behaves.”

2. Variable Basics: The Difference Between Declaration, Assignment, and Initialization

To understand Java variables correctly,
it’s important to organize the differences between “declaration,” “assignment,” and “initialization.”

Beginners often use these three words as if they mean the same thing,
but in reality, they have clearly different roles.

If you keep this ambiguous,
you’re more likely to fall into the state of
“I don’t know why it’s an error” or “I don’t know why I can’t use it.”

2.1 Declaration: Getting Ready to Use a Variable

Declaration means telling Java:
“I’m going to use a variable with this name,” and “its type is this.”

The most basic declaration looks like this:

int count;

At this point, only these two things have happened:

  • Create a variable named count
  • Decide that its type is int (an integer)

No value has been stored yet.

This is a common beginner misconception:
declaring a variable alone does not make it “ready to use.”

2.2 Assignment: Putting a Value into a Variable

Assignment means putting a value into a variable that has already been declared.

count = 10;

This = does not mean “equals” in math.
It means put the value on the right into the variable on the left.

So the flow becomes:

int count;   // declaration
count = 10;  // assignment

That’s the idea.

Note: You Can’t Assign to an Undeclared Variable

The following code results in an error:

count = 10; // Error: count has not been declared

In Java, the order must be declaration → assignment.

2.3 Initialization: Assigning a Value at the Time of Declaration

Initialization means doing declaration and assignment at the same time.

int count = 10;

This is semantically the same as these two lines:

int count;
count = 10;

In Java—both in real work and in learning—
in most cases, it’s fine to assume you’ll use “initialization.”

That’s because it has the following benefits:

  • The variable becomes usable the moment it’s created
  • It prevents errors caused by uninitialized variables
  • The code becomes easier to read

So as a beginner,
it’s recommended to build the habit of
“initialize variables at the time you declare them.”

2.4 Why You Can’t Use a Variable with Only a Declaration (Local Variable Rules)

In Java, there are very strict rules for local variables (variables inside methods).
Java is particularly strict here.

The following code results in a compile-time error:

int number;
System.out.println(number); // Error

The reason is clear:

Local variables cannot be used unless they are initialized

That rule exists.

Java treats the state “we don’t know what’s inside number” as
a dangerous state and stops it as an error before execution.

This may feel strict to beginners, but in large-scale development,
it’s a very important safety mechanism.

2.5 Declaring Multiple Variables at Once (With Caution)

In Java, you can declare multiple variables of the same type together.

int x, y, z;

You can also write it like this:

int a = 1, b = 2, c = 3;

This is syntactically correct, but it can reduce readability, so be careful.

Especially for beginners and team development, it’s safer to write:

int a = 1;
int b = 2;
int c = 3;

as one variable per line.

2.6 Section Summary

Key points to remember from this section:

  • Declaration: decide the variable’s name and type
  • Assignment: put a value into a variable
  • Initialization: declare and assign at the same time
  • Local variables cannot be used unless initialized
  • As a beginner, use “declaration + initialization” as the default

3. Understanding Variable “Types” (Primitive Types and Reference Types)

When working with Java variables, you cannot avoid understanding types.
What often confuses beginners is:

  • Why there are so many types
  • Why numbers have both int and double
  • How String differs from numeric types

In this section, we’ll organize Java types from two perspectives:
“primitive types” and “reference types.”

3.1 Java Types Fall into Two Big Categories

Java variable types can be broadly classified into the following two categories:

  1. Primitive types
  2. Reference types

Once you understand this classification, topics you’ll learn later—like “== vs equals,” “how final behaves,” and “how memory works”—become much easier to understand.

3.2 What Are Primitive Types? (Types That Hold the Value Itself)

Primitive types are types that directly hold the value itself.

Let’s look at a few common primitive types:

int count = 10;
double price = 19.99;
boolean isActive = true;

These variables store
the “value itself” inside the variable.

Commonly Used Primitive Types

TypeMeaningExample Use
intIntegerCounts, age, number of times
longLarge integerAmounts of money, IDs
doubleDecimalPrices, ratios
booleanTrue/falseFlag checks
charSingle characterCharacter processing

As a beginner, it’s enough to first master int, double, and boolean.

3.3 Characteristics and Caveats of Primitive Types

Primitive types have the following characteristics:

  • They hold the value itself
  • They are fast to process
  • You cannot assign null
  • The size is fixed

For example, in the code below,
a and b hold completely independent values.

int a = 5;
int b = a;
b = 10;

In this case:

  • a stays 5
  • b changes to 10

That’s the result.

This is because the value itself was copied.

3.4 What Are Reference Types? (Types That Handle Where the Value Lives)

On the other hand, reference types
are types that handle not the value itself, but the location (reference) where the value exists.

Typical reference types include:

String name = "Java";
int[] numbers = {1, 2, 3};
  • String
  • Arrays
  • Classes
  • Interfaces
  • Collections such as List / Map

All of these are reference types.

Understanding Reference Types with an Image

A reference-type variable holds:

  • not the actual object itself,
    but
  • an “address” pointing to where the actual object is stored

That’s the mental model.

3.5 What Happens When You Assign Reference Types?

Look at the following code:

String a = "Hello";
String b = a;
b = "World";

In this case:

  • a is “Hello”
  • b is “World”

That’s the result.

If you only look at this, you might think,
“Isn’t that the same as primitive types?”

Then what about the next example?

int[] array1 = {1, 2, 3};
int[] array2 = array1;

array2[0] = 100;

The result is:

  • array1[0] → 100
  • array2[0] → 100

This happens because array1 and array2 refer to the same array.

With reference types:

  • Assigning variables can make them “point to the same actual object”
  • Changing the contents can affect everything that references it

That’s the key characteristic.

3.6 Common Beginner Confusion Points

Let’s summarize the common stumbling points:

  • Primitive types
    → the value is copied
  • Reference types
    → the reference (location) is copied

This difference is strongly related to the following topics:

  • The difference between == and .equals()
  • What happens when you use final
  • How passing values as method arguments affects scope and behavior

For now, it’s enough to remember just this:
reference types can sometimes share the same actual object.

3.7 Section Summary

  • Java types are divided into primitive types and reference types
  • Primitive types handle “the value itself”
  • Reference types handle “the location (reference) of the value”
  • With reference types, assignment and changes can affect other variables

4. Variable Kinds (Where They Live) and Scope (Where They Are Valid)

In Java, variables don’t just differ by “type.”
Their behavior also changes depending on where they are declared (where they live).

If you don’t understand this difference, you may get confused by things like:

  • “I can’t use the variable I declared earlier”
  • “It has the same name, but the value is different”
  • “I don’t understand why I can’t reference it here”

In this section, we’ll organize
variable kinds and scope for beginners.

4.1 What Is Scope? (Where a Variable Can Be Used)

Scope means
the range where a variable can be used.

In Java, scope is strictly determined by:

  • where the variable is declared
  • the range of curly braces { }

The basic rule is very simple:

A variable can only be used inside the block where it is declared

4.2 Local Variables (Variables Inside Methods)

Local variables are variables declared inside methods or blocks (such as if and for).

public void sample() {
    int x = 10;  // local variable
    System.out.println(x);
}

This x has these characteristics:

  • Valid only inside the sample method
  • Disappears when the method finishes

Example of Scope with Blocks

if (true) {
    int y = 5;
    System.out.println(y);
}

System.out.println(y); // Error

Because y is declared inside the if block, it cannot be used outside of it.

Important Rules for Local Variables

Local variables have strict rules:

  • You cannot use them unless initialized
  • No default values are automatically assigned
int value;
System.out.println(value); // compile-time error

This is part of Java’s safety design to prevent using “undefined values.”

4.3 Fields (Instance Variables)

Fields are variables declared inside a class but outside methods.

public class Sample {
    int count;  // field (instance variable)

    public void printCount() {
        System.out.println(count);
    }
}

Fields have different characteristics from local variables:

  • Each instance of the class has its own copy
  • They are automatically initialized with default values
  • They can be used from any method in the class

Default Values for Fields

Depending on the type, the following default values are automatically set:

  • int → 0
  • double → 0.0
  • boolean → false
  • Reference types → null

So the following code does not produce an error:

public class Sample {
    int count;

    public void print() {
        System.out.println(count); // 0
    }
}

However, relying too much on default values is not recommended.
Explicit initialization makes the code’s intent clearer.

4.4 static Variables (Class Variables)

A variable with static becomes
a variable shared across the entire class.

public class Counter {
    static int total = 0;
}

This total has these characteristics:

  • Only one exists per class
  • Shared by all instances

Mental Model for static Variables

  • Instance variables → each person’s wallet
  • static variables → a company’s shared safe

That model makes it easier to understand.

Cautions for static Variables

static variables are useful, but storing too much state can cause bugs.

  • It’s hard to track where changes happened
  • Testing becomes harder
  • Problems are more likely in concurrent processing

As a beginner, it’s recommended to limit usage to things like:

  • Constants
  • Shared configuration values

and similar purposes.

4.5 Watch Out for Variables with the Same Name (Shadowing)

Look at the following code:

public class Sample {
    int value = 10;

    public void test() {
        int value = 5;
        System.out.println(value);
    }
}

In this case, the output is 5.

This is because
the local variable is hiding the field (shadowing).

Since this is a common source of confusion for beginners:

  • Avoid duplicate variable names
  • Don’t reuse the same name unless it’s intentional

That discipline matters.

4.6 Section Summary

  • Scope means “the range where a variable can be used”
  • Local variables are valid only inside blocks and must be initialized
  • Fields are automatically assigned default values
  • static variables are shared across the class
  • Be careful about shadowing caused by variables with the same name

5. Using var (Type Inference) Correctly in Java 10+

Introduced in Java 10, var is
a way to let the compiler infer the type of a variable.

It may look convenient, but if misused, it can easily lead to “hard-to-read code.”
So it’s important to understand the rules and when to use it.

5.1 What Is var? (How It Works Without Writing the Type)

In normal Java, you declare a variable like this:

String message = "Hello";

With var, you can write:

var message = "Hello";

At this point, Java looks at the right-hand side "Hello" and decides:

  • This variable is of type String

The important point is that var is not dynamic typing.

  • The type is determined at compile time
  • The type does not change at runtime

So think of var as “shorthand that lets you omit the type.”

5.2 Where You Can and Can’t Use var

var can only be used in strictly defined places.

Where You Can Use It

  • Local variables only
public void sample() {
    var count = 10;
}

Where You Can’t Use It

All of the following usages result in errors:

var x;                 // No initialization → error
var y = null;          // Cannot infer the type → error

class Sample {
    var value = 10;    // Cannot be used for fields → error
}

The reason for these restrictions is clear: to avoid reducing readability and safety.

5.3 Benefits of Using var

var shines when
the type tends to get long.

ArrayList<String> list = new ArrayList<String>();

With var:

var list = new ArrayList<String>();

It becomes much cleaner.

In other words, var is useful when:

  • Generics are long
  • The type is obvious from the right-hand side

Used this way, it can improve readability.

5.4 Pitfalls of var (Common Beginner Mistakes)

var is convenient, but if beginners overuse it, the following issues can occur.

The Type Becomes Hard to See

var data = getData();

From this line alone, you can’t tell:

  • What type data is
  • What it contains

In cases like this, it’s safer to write the type explicitly.

Data data = getData();

It Can Become an Unintended Type

var number = 10;   // int

Beginners often run into cases like,
“I thought it would be long.”

When you don’t write the type explicitly, your intent and the actual inferred type can diverge, so be careful.

5.5 How to Decide Whether to Use var

If you’re unsure, use these criteria:

  • If the type is obvious from the right-hand side → var is OK
  • If the type carries important meaning → write the type explicitly
  • Beginner-friendly / learning code → write the type as much as possible
  • Team development → follow the coding standards

Especially during learning,
writing the type helps deepen understanding,
so you don’t need to force yourself to use var.

5.6 Section Summary

  • var is shorthand for type inference
  • It is not dynamic typing; the type is fixed at compile time
  • It’s only for local variables and requires initialization
  • It’s important to distinguish when it improves vs reduces readability

6. “I Don’t Want to Change This Value”—final and the Idea of Constants

In Java, the design idea of “once a value is decided, don’t let it be changed later” is very important.

The tool for that is final.

Beginners often think “final is something you put on constants,” but in reality, it has a broader meaning.

6.1 What Is final? (Disallowing Reassignment)

A variable with final cannot be reassigned after you assign it once.

final int maxCount = 10;
maxCount = 20; // compile-time error

The rule is very simple:

  • You can initialize it
  • You cannot reassign it

That’s all you need to remember.

6.2 Why Use final on Local Variables?

Adding final to a local variable makes it clear that:

  • This variable does not change midway
  • The value is fixed

It helps express your intent clearly in the code.

final int basePrice = 100;
int total = basePrice + 20;

Writing it this way:

  • Helps prevent accidental changes
  • Makes the reader feel safer

Those are the benefits.

6.3 Using final on Fields

Adding final to a field makes it
an immutable value for that instance.

public class User {
    final String name;

    public User(String name) {
        this.name = name;
    }
}

In this case:

  • name can be set only once in the constructor
  • It cannot be changed afterward

This is an important design approach for stabilizing object state.

6.4 Important Note for final with Reference Types (Common Beginner Confusion)

This is a very important point:

final int[] numbers = {1, 2, 3};
numbers[0] = 100;   // OK
numbers = new int[]{4, 5, 6}; // Error

Why does this happen?

The reason is that final restricts “reassignment of the reference”.

  • Changing the contents of the array → OK
  • Changing which array the variable refers to → NG

In other words, final does not make the contents immutable.

If you don’t understand this, you may get confused and think:

  • “Why can it change even though it’s final?”
  • “Is this a bug?”

That’s why this distinction is important.

6.5 What Is a Constant? (static final)

In Java, what people commonly call a “constant” is typically defined with static final by convention.

public class Config {
    public static final int MAX_USERS = 100;
}

This kind of constant has the following characteristics:

  • Shared across the entire class
  • The value cannot be changed
  • You can give it a meaningful name

Naming Convention for Constants

Constants are generally written in the following style:

UPPER_SNAKE_CASE

Example:

static final double TAX_RATE = 0.1;

6.6 How to Decide When to Use final

As a beginner, the following criteria are easy to use:

  • If the value doesn’t need to change → add final
  • Config values / baseline values → use static final
  • If accidental changes would be problematic → add final

Especially in practice, a common mindset is:

“If you’re unsure, add final.”

In many cases, that’s a good balance.

6.7 Section Summary

  • With final, you cannot reassign the variable
  • You can use it for both local variables and fields
  • final on reference types does not mean “immutable contents”
  • Constants are defined with static final
  • final is a tool for writing safer, clearer code

7. Initial Values, Default Values, and Common Errors (Beginner Pitfall Recovery)

So far, you’ve learned about declarations, types, scope, var, and final.
In practice, however, there are many situations where “I understand it conceptually, but I still get errors.”

In this section, we’ll organize common beginner stumbling points along with the reasons.

7.1 Local Variables Do Not Get Default Values

First, a very important rule:

Local variables do not get automatic default values

The following code results in a compile-time error:

public void sample() {
    int x;
    System.out.println(x); // Error
}

The reason is simple: Java does not allow the state where “we don’t know what’s inside x.”

Correct Approach

public void sample() {
    int x = 0;
    System.out.println(x);
}

For local variables, strictly follow the rule: always initialize them yourself.

7.2 Fields Automatically Get Default Values

On the other hand, fields (instance variables and static variables)
are automatically assigned initial values.

public class Sample {
    int count;
    boolean active;
    String name;
}

The default values are as follows:

  • int → 0
  • double → 0.0
  • boolean → false
  • Reference types → null

So the following code does not produce an error:

public class Sample {
    int count;

    public void print() {
        System.out.println(count); // 0
    }
}

However, designs that rely on default values are not recommended.
They make intent harder to see and can easily become a breeding ground for bugs.

7.3 Errors Caused by null (NullPointerException)

The default value for reference types is null.

String text;

If you call a method in this state, you’ll get a runtime error:

System.out.println(text.length()); // NullPointerException

This is one of the most common exceptions beginners run into.

Basic Countermeasures

  • Initialize whenever possible
  • Consider the possibility of null
  • Design to avoid using null unintentionally
String text = "";

Even initializing with an empty string can prevent many accidents.

7.4 Using a Variable Outside Its Scope

The following is another common error:

if (true) {
    int value = 10;
}

System.out.println(value); // Error

This is a scope-out reference problem.

  • value is valid only inside the if block
  • Outside the block, it doesn’t exist

Reconfirm that rule.

7.5 Confusion from Variables with the Same Name (Shadowing Revisited)

public class Sample {
    int value = 10;

    public void test() {
        int value = 5;
        System.out.println(value);
    }
}

This code prints 5.

Beginners often mistakenly think:

  • The field value will be used

But in reality,
the inner scope takes priority.

Since shadowing causes confusion:

  • Use distinct variable names based on roles

Keep that in mind.

7.6 Compile-Time Errors from Type Mismatches

The following assignment is not allowed:

int number = 3.14; // Error

This is because:

  • doubleint is not automatically converted

That’s the rule.

Correct Approach (When You Intend It)

int number = (int) 3.14; // 3

However, be careful that the decimal part is truncated.

7.7 Section Summary

  • Local variables must be initialized
  • Fields get default values, but don’t rely on them too much
  • null often causes runtime errors
  • You cannot use variables outside their scope
  • Type mismatches are prevented with compile-time errors

8. Summary: Key Points to Master First for Java Variables

In this article, we organized the topic of “Java variables” step by step,
focusing on points that beginners commonly find confusing.

Finally, let’s summarize the key takeaways
in a form that’s useful both for learning and real-world coding.

8.1 Think of Java Variables as a Set of “Type, Name, and Value”

Java variables always come with these three elements:

  • Type: what kind of value it holds
  • Name: what the value represents
  • Value: the actual data stored
int count = 10;

This single line contains the entire essence of Java variables.

8.2 Clearly Distinguish Declaration, Assignment, and Initialization

A common beginner pitfall is blurring the differences between these three terms:

  • Declaration: preparing to use a variable
  • Assignment: putting a value into it
  • Initialization: declaring and assigning at the same time

Especially for local variables,
remember the rule: you can’t use them unless initialized.

8.3 Be Aware of the Difference Between Primitive and Reference Types

Java types are broadly divided into two categories:

  • Primitive types: handle the value itself
  • Reference types: handle the location (reference) of the value

Keeping this difference in mind helps you naturally understand:

  • Value copying
  • How arrays and objects behave
  • What final really means

8.4 Understanding Scope Dramatically Reduces Errors

Variables can be used only within the place where they are declared.

  • Local variables → valid only inside blocks
  • Fields → available throughout the class
  • static variables → shared across the class

If you ever think “I don’t know why I can’t use it,”
first suspect scope.

8.5 Use var and final Based on Purpose

  • var
    → Use it only when the type is clear and readability improves
  • final
    → Use it to clearly express the intent “this value should not change”

Both are convenient, but be careful not to make “using them” the goal itself.

8.6 Guidelines for Beginners to Write Safely

During the learning phase, the following policies reduce mistakes:

  • Initialize variables when you declare them
  • Write types explicitly as much as possible
  • Use meaningful names
  • If unsure, try adding final

Even this alone moves you closer to readable and safe Java code.

8.7 Next Topics to Learn for Deeper Understanding

After you understand variables, it’s recommended to move on to:

  • Conditionals (if / switch)
  • Loops (for / while)
  • Arrays and collections (List / Map)
  • Methods and parameters
  • Object-oriented basics

Variables are the foundation of all Java code.

By understanding them thoroughly, your later learning becomes dramatically smoother.