Start learning free

LESSON 181 OF 344 · OBJECT-ORIENTED PROGRAMMING

Access Modifiers in Java: public, private and Getters

Lesson Read the full explanation

TL ; DR:

  • An access modifier controls who can see a member of a class. The two you'll use most are public (anyone) and private (only this class).


  • Make data private so callers can't break invariants. Expose what they need through public methods (often called getters and setters):

    class Dog {
        private String name;
    
        public Dog(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    }
    

  • Outside the class, rex.name is a compile error. Use rex.getName() instead.



Full lesson:

So far every field we wrote was public. That's convenient, but leaks internals. If you later decide to validate or compute the value differently, every caller in the codebase breaks.


Encapsulation

Encapsulation is the idea that an object's data should be hidden behind methods. The class controls how it's read and written; outside code only sees the API.

class Account {
    private double balance;

    public void deposit(double amount) {
        if (amount < 0) throw new IllegalArgumentException();
        balance += amount;
    }
}

The four Java modifiers

publicVisible everywhere.
privateVisible only inside the same class.
protectedSame package + subclasses.
(no modifier)Package-private — only the same package.

For now, focus on public and private.


Your task

The Dog class's name field is now private. Add a public String getName() method that returns it.

Dog's name: Rex
STEP 1 OF 2
    Ctrl + Enter to check

    JAVA · OBJECT-ORIENTED PROGRAMMING

    Access Modifiers in Java, explained

    Why control access

    So far every field was public. That is convenient, but it exposes the inside of the class. Any code anywhere can change dog.name to anything, and if you later decide to check or compute that value differently, every piece of code that touches the field has to change with it.

    An access modifier is a keyword that decides which code may see a member of a class. The members are its fields, methods and constructors.

    Encapsulation

    Encapsulation is the practice of hiding an object's data behind methods. The class controls how its data is read and written, and outside code only sees the public methods. Here is an account that never allows a negative deposit:

    class Account {
        private double balance;
    
        public void deposit(double amount) {
            if (amount < 0) throw new IllegalArgumentException();
            balance += amount;
        }
    }
    

    Because balance is private, the only way to change it is deposit, and deposit enforces the rule. If the field were public, any caller could write account.balance = -500; and break it. Rules like this one are called invariants, and private fields are how a class protects them.

    The four levels

    ModifierWho can use the member
    publicCode anywhere.
    privateOnly code inside the same class.
    protectedCode in the same package, and subclasses.
    (no modifier)Only code in the same package. This is called package-private.

    For now, focus on public and private. The usual pattern is to make fields private and give outside code only the methods it needs.

    Getters and setters

    A method that returns a private field is called a getter, and one that assigns it is a setter. By convention they are named getName and setName, or isActive for a boolean getter. A getter is the simplest case:

    public String getName() {
        return name;
    }
    

    Code inside the class can use the private field directly, so the getter just returns it. Code outside the class cannot:

    Dog rex = new Dog("Rex");
    System.out.println(rex.name);
    

    This fails to compile with the error name has private access in Dog. The allowed way to read the value is rex.getName().

    A class that offers only a getter makes the field read-only from outside: callers can see the name but never change it. Adding a setter is a choice, and a setter can validate its argument, which a public field never could.

    The lesson's exercise, step by step

    The starter code gives Dog a private name field and a constructor. The mainFunction prints rex.getName(), but no such method exists yet. There are two steps:

    1. Declare the getter. Below the constructor, write public String getName(). It is public so that Solution may call it, and its return type is String because the field is a String.
    2. Return the field. The body is return name;. Inside Dog, the private field is accessible directly.

    The finished program:

    class Dog {
        private String name;
    
        public Dog(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    }
    
    class Solution {
        public void mainFunction() {
            Dog rex = new Dog("Rex");
            System.out.println("Dog's name: " + rex.getName());
        }
    }
    

    It prints:

    Dog's name: Rex
    

    The constructor is public too. A constructor can be made private as well, but then no code outside the class could call new Dog("Rex").

    Details worth knowing

    • Private means private to the class, not to the object. Code in the Dog class can read the private field of any other Dog object, not just its own.
    • The default is not public. A member with no modifier is visible only inside its package, so it is easy to leave something less visible than intended.
    • Private methods are common. Helper methods that only the class itself needs should be private too, so they can change freely later.
    • Changing a field is a bigger change than it looks. If the field is private, you can rename it or store it differently, as long as getName() still returns the right result.

    Common mistakes

    • Reading the field from outside. rex.name in Solution is a compile error once the field is private. Use rex.getName().
    • Making the getter private. A private getter is visible only inside Dog, so the call in Solution fails with the same kind of error.
    • Using the wrong return type. public void getName() can't return the name. The return type must be String.
    • Forgetting return. A body of just name; is not a valid statement, and a missing return in a non-void method is a compile error.
    • Adding a setter to every field out of habit. A setter that does nothing but assign the field gives back most of what private protects. Add one only when outside code really needs to change the value.
    • Mismatched names. The getter can have any name, but sticking with getName for a field called name follows the convention that other Java code and tools expect.

    Key takeaways

    • An access modifier controls which code may use a member of a class.
    • public means everywhere, and private means inside the same class only. protected and package-private sit in between.
    • Make fields private and expose what outside code needs through public methods. That is encapsulation.
    • A getter such as public String getName() { return name; } gives read access to a private field.
    • Touching a private member from another class is a compile error, not a runtime one.
    Keep going with JavaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free