How do I access private fields using getters and setters in Java?

You can use getter and setter methods to read and update private fields. A getter returns a field’s value, while a setter changes it.

These methods let a class control how its data is accessed and updated.

In this example, you will create a Book class with a private title field. A setter will prevent the title from being null or blank.

Source code

public class GetterSetterExample {
    void main() {
        Book book = new Book("Learning Java");

        IO.println("Original title: " + book.getTitle());

        book.setTitle("Exploring Java");

        IO.println("Updated title: " + book.getTitle());
    }
}

class Book {
    private String title;

    Book(String title) {
        this.title = validateTitle(title);
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = validateTitle(title);
    }

    private static String validateTitle(String title) {
        if (title == null || title.isBlank()) {
            throw new IllegalArgumentException(
                    "Title must not be null or blank.");
        }

        return title;
    }
}

Explanation

The title field is private:

private String title;

Code in GetterSetterExample cannot access this field directly. For example, the following statement would cause a compilation error:

book.title = "Exploring Java";

Instead, the class provides methods for reading and updating the value.

Reading a value with a getter

The getTitle() method returns the current title:

public String getTitle() {
    return title;
}

The calling code uses it like this:

IO.println("Original title: " + book.getTitle());

A getter commonly uses the prefix get followed by the field name, such as getTitle().

Updating a value with a setter

The setTitle() method accepts a new title:

public void setTitle(String title) {
    this.title = validateTitle(title);
}

It validates the input before assigning it to the field. If validation fails, the assignment does not happen, and the existing title stays unchanged.

The calling code updates the title using:

book.setTitle("Exploring Java");

Validating the title

Both the constructor and setter call the same validation method:

private static String validateTitle(String title) {
    if (title == null || title.isBlank()) {
        throw new IllegalArgumentException(
                "Title must not be null or blank.");
    }

    return title;
}

The method rejects null, empty strings, and strings containing only whitespace.

The || operator evaluates the second condition only when the first condition is false. If title is null, Java skips title.isBlank(), avoiding a NullPointerException.

The validation method is private because it is an implementation detail. It is static because it does not use any object’s fields.

Run the example

Compile and run the file:

javac GetterSetterExample.java
java GetterSetterExample

Output

Original title: Learning Java
Updated title: Exploring Java

Private fields with controlled access are an example of encapsulation. Add setters only for values that callers should be allowed to change. A field that should remain fixed can be initialized through a constructor and exposed through a getter.

How do I set initial object values using a constructor in Java?

A constructor initializes an object when you create it using the new keyword. You can pass values to the constructor to set the object’s initial state.

In this example, you will create a Book class with a constructor that accepts a title and an author.

Source code

public class ConstructorExample {
    void main() {
        Book firstBook = new Book("Learning Java", "Alice");
        Book secondBook = new Book("Exploring Java", "Bob");

        firstBook.printDetails();
        IO.println();
        secondBook.printDetails();
    }
}

class Book {
    private final String title;
    private final String author;

    Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    void printDetails() {
        IO.println("Title: " + title);
        IO.println("Author: " + author);
    }
}

Explanation

The Book class declares two fields:

private final String title;
private final String author;

The private modifier limits direct access to these fields to the Book class. The final modifier means each field can be assigned only once.

The constructor receives the initial field values:

Book(String title, String author) {
    this.title = title;
    this.author = author;
}

A constructor has the same name as its class and does not declare a return type, not even void.

Here, the parameter names match the field names. The keyword this refers to the current object, so this.title identifies the field while title identifies the parameter.

For example:

this.title = title;

This statement assigns the value of the title parameter to the current object’s title field.

The following expression creates a book and passes two arguments to its constructor:

new Book("Learning Java", "Alice")

The constructor sets the new object’s title to "Learning Java" and its author to "Alice".

Each call to new Book(...) creates a separate object with its own field values.

Run the example

Compile and run the file:

javac ConstructorExample.java
java ConstructorExample

Output

Title: Learning Java
Author: Alice

Title: Exploring Java
Author: Bob

What happens to the default constructor?

Java provides a default constructor only when a class declares no constructors.

Since this Book class declares a constructor with two parameters, the following expression causes a compilation error:

new Book()

To create a Book, supply the title and author, or explicitly add a constructor with no parameters.

How do I create an object from a class in Java?

A class defines the data and behavior of its objects. You can create an object using the new keyword, then access its fields and call its methods.

In this example, you will create two objects from a Book class. Each object stores its own title and author.

Source code

public class ObjectCreationExample {
    void main() {
        Book firstBook = new Book();
        firstBook.title = "Learning Java";
        firstBook.author = "Alice";

        Book secondBook = new Book();
        secondBook.title = "Exploring Java";
        secondBook.author = "Bob";

        firstBook.printDetails();
        secondBook.printDetails();
    }
}

class Book {
    String title;
    String author;

    void printDetails() {
        IO.println("Title: " + title);
        IO.println("Author: " + author);
        IO.println();
    }
}

Explanation

The Book class declares two fields and one method:

class Book {
    String title;
    String author;

    void printDetails() {
        IO.println("Title: " + title);
        IO.println("Author: " + author);
        IO.println();
    }
}

The fields title and author hold the data for each book. The printDetails() method prints that data.

The following statement creates a Book object:

Book firstBook = new Book();

Each part has a purpose:

Part Purpose
Book Declares the variable’s type
firstBook Names the variable that refers to the object
new Book() Creates and initializes a new Book object

Because Book does not declare a constructor, Java provides a default constructor with no parameters.

After creating the object, you can assign values to its fields using the dot operator:

firstBook.title = "Learning Java";
firstBook.author = "Alice";

You also use the dot operator to call a method:

firstBook.printDetails();

The second call to new Book() creates a separate object:

Book secondBook = new Book();

Each object has its own instance fields. Setting the title of secondBook does not change the title of firstBook.

Both classes are placed in the same source file. Only ObjectCreationExample is declared public, so the file is named ObjectCreationExample.java.

Run the example

Compile and run the file:

javac ObjectCreationExample.java
java ObjectCreationExample

Output

Title: Learning Java
Author: Alice

Title: Exploring Java
Author: Bob

This example assigns fields directly to show how objects work. In the next example, you will use a constructor to supply these values when creating each object.

How do I pass a variable number of arguments to a method in Java?

You can use varargs to let a method accept any number of arguments of the same type. Declare a varargs parameter by adding three dots (...) after its type.

In this example, you will create a method that adds integers. You can call it with two numbers, several numbers, or no numbers.

Source code

public class VarargsExample {
    void main() {
        IO.println("Sum of two numbers: " + sum(10, 20));
        IO.println("Sum of four numbers: " + sum(5, 10, 15, 20));
        IO.println("Sum with no arguments: " + sum());

        int[] numbers = {3, 6, 9};
        IO.println("Sum of array elements: " + sum(numbers));
    }

    int sum(int... numbers) {
        int total = 0;

        for (int number : numbers) {
            total += number;
        }

        return total;
    }
}

Explanation

The sum() method declares a varargs parameter:

int sum(int... numbers) {

The declaration int... numbers lets callers pass zero or more int values. Inside the method, numbers is an int[] array.

For example, this call passes two values:

sum(10, 20)

Inside the method, numbers contains 10 and 20.

The method starts with a total of zero, then adds each element:

int total = 0;

for (int number : numbers) {
    total += number;
}

The statement total += number adds the current number to total. After the loop finishes, the method returns the total.

When you call the method without arguments:

sum()

Java supplies an empty array. The loop has no elements to process, so the method returns 0.

You can also pass an existing array directly:

int[] numbers = {3, 6, 9};
sum(numbers);

The method reads the array elements and returns 18.

Run the example

Compile and run the file:

javac VarargsExample.java
java VarargsExample

Output

Sum of two numbers: 30
Sum of four numbers: 50
Sum with no arguments: 0
Sum of array elements: 18

Rules to remember

A method can have only one varargs parameter, and it must be the last parameter.

For example, this declaration is valid:

int sum(String label, int... numbers)

This declaration is invalid because another parameter appears after the varargs parameter:

int sum(int... numbers, String label)

Use varargs when callers should be able to supply different numbers of values without creating an array explicitly.

How do I overload a method in Java?

Method overloading lets you define multiple methods with the same name but different parameter lists. You can use it to perform a similar task with different inputs.

In this example, you will create three add() methods to add two integers, three integers, or two floating-point numbers.

Source code

public class MethodOverloadingExample {
    void main() {
        int twoIntegerSum = add(10, 20);
        int threeIntegerSum = add(10, 20, 30);
        double twoDoubleSum = add(2.5, 3.75);

        IO.println("Sum of two integers: " + twoIntegerSum);
        IO.println("Sum of three integers: " + threeIntegerSum);
        IO.println("Sum of two doubles: " + twoDoubleSum);
    }

    int add(int first, int second) {
        return first + second;
    }

    int add(int first, int second, int third) {
        return first + second + third;
    }

    double add(double first, double second) {
        return first + second;
    }
}

Explanation

All three methods are named add(), but their parameter lists differ:

Method Parameters
add(int first, int second) Two integers
add(int first, int second, int third) Three integers
add(double first, double second) Two doubles

When you call an overloaded method, the compiler selects the applicable version based on the number and types of the arguments.

The following call passes two int values:

int twoIntegerSum = add(10, 20);

It selects add(int, int) and returns 30.

This call passes three int values:

int threeIntegerSum = add(10, 20, 30);

It selects add(int, int, int) and returns 60.

Finally, this call passes two double values:

double twoDoubleSum = add(2.5, 3.75);

It selects add(double, double) and returns 6.25.

Run the example

Compile and run the file:

javac MethodOverloadingExample.java
java MethodOverloadingExample

Output

Sum of two integers: 30
Sum of three integers: 60
Sum of two doubles: 6.25

Rules to remember

Overloaded methods must differ in the number, types, or order of their parameter types.

Changing only the parameter names does not create a different overload. Changing only the return type is also insufficient. For example, these two declarations cannot appear together in the same class:

int add(int first, int second) {
    return first + second;
}

double add(int first, int second) {
    return first + second;
}

Both methods have the same name and parameter types, so the compiler reports an error.