Java Default Access Modifier: Package-Private Access Explained

0

Java provides four levels of access control: public, protected, private, and default access. Default access is sometimes called package-private access because it allows a member to be accessed from classes within the same package while preventing direct access from classes in other packages.

The interesting part is that default access has no keyword. If you declare a field, method, constructor, or nested class without an access modifier, Java automatically gives it package-private access.

Default access means: accessible within the same package, but not directly accessible from a different package.

Why Does Default Access Exist?

Not every class or member needs to be publicly available. Sometimes several classes inside the same package need to cooperate closely, while code outside that package should not depend on those implementation details.

Default access provides exactly that boundary. It lets related classes share functionality without exposing it as part of the application's wider public API.

Think of a company's internal team room. Employees belonging to that team can use the resources inside, but people from outside the team do not automatically have access. A Java package can work in a similar way.

Default Access Has No Keyword

Unlike public, private, and protected, default access is not written using a keyword.

class Employee {

    String name;

    void displayName() {
        System.out.println(name);
    }
}

Here, neither name nor displayName() has an explicit access modifier. Therefore, both receive default package-private access.

Default Field Example

class Student {

    String name = "Riya";
}

If another class belongs to the same package, it can access the name field directly.

class StudentService {

    void showStudent() {

        Student student = new Student();

        System.out.println(student.name);
    }
}

Because Student and StudentService belong to the same package, StudentService can access the default-access field.

Default Method Example

Methods can also use default access simply by omitting an access modifier.

class Calculator {

    int multiply(int a, int b) {
        return a * b;
    }
}

Another class in the same package can call multiply().

class CalculatorService {

    void calculate() {

        Calculator calculator = new Calculator();

        int result = calculator.multiply(5, 4);

        System.out.println(result);
    }
}

The method is not public, but that does not matter because both classes are in the same package.

Default Access Across Packages

The package boundary becomes important when another class belongs to a different package.

package store;

public class Product {

    String name = "Laptop";

    void display() {
        System.out.println(name);
    }
}

Suppose another class belongs to the app package.

package app;

import store.Product;

public class Main {

    public static void main(String[] args) {

        Product product = new Product();

        // Not allowed: name has package-private access
        // System.out.println(product.name);

        // Not allowed: display() has package-private access
        // product.display();
    }
}

The Product class itself is public, so Main can create a Product object. However, its name field and display() method remain inaccessible because they have default access and belong to another package.

A public class can contain package-private members. Making the class public does not automatically make all of its members public.

Default Access and Packages

Packages are therefore central to understanding default access. The package acts as the access boundary.

Location Default Member Access
Same class Allowed
Same package Allowed
Subclass in same package Allowed
Different package Not allowed directly
Subclass in different package Not allowed directly

Default Access vs protected

Default and protected access are often confused because both allow access from classes in the same package. The important difference appears outside the package.

A protected member can be accessed by an appropriate subclass in another package. A default-access member cannot be directly accessed from another package, even by a subclass.

Access Situation Default protected
Same class Allowed Allowed
Same package Allowed Allowed
Subclass in another package Not allowed Allowed under protected rules
Unrelated class in another package Not allowed Not allowed

Default Access and Classes

A top-level class can also have default access. If no access modifier is specified, the class becomes package-private.

class InternalService {

    void execute() {
        System.out.println("Internal operation");
    }
}

InternalService can be used by other classes in the same package but cannot be directly imported and used from a different package.

This can be useful when a class is an implementation detail rather than part of the package's public API.

Default Constructor Access

Constructors can also have default access.

class Account {

    Account() {
        System.out.println("Account created");
    }
}

The constructor can be called from classes in the same package, but not directly from classes in another package.

Real-World Use of Default Access

Imagine a large application divided into packages such as authentication, payment, reporting, and inventory. Inside the payment package, several helper classes may need to communicate with each other. Some of those helpers should not become part of the application's external API.

Default access is useful in this situation. It allows the payment package to share internal functionality while keeping those implementation details hidden from unrelated packages.

package payment;

class PaymentValidator {

    boolean validate(double amount) {
        return amount > 0;
    }
}

PaymentValidator does not need to be public if it is only an internal helper used by other classes inside the payment package.

Common Beginner Mistakes

  • Thinking default access is another keyword in Java. It is actually the absence of an explicit access modifier.
  • Assuming default members are accessible everywhere inside the application.
  • Confusing default access with protected access.
  • Assuming a public class automatically makes its fields and methods public.
  • Ignoring package structure when debugging an access-related compiler error.

Best Practices

  • Use default access when functionality is intentionally limited to a package.
  • Keep implementation helper classes package-private when they are not part of the public API.
  • Use public only when external packages genuinely need the type or member.
  • Use private when functionality belongs strictly to the declaring class.
  • Design package boundaries carefully so internal implementation details do not become unnecessary dependencies.

Interview Insights

A common interview question is: “What is the default access modifier in Java?” The precise answer is that Java does not have a keyword named default for ordinary access control. When no access modifier is specified, the declaration receives package-private access.

Another common question is: “Can a default-access member be accessed by a subclass in another package?” No. Unlike protected access, default access is restricted to the declaring package.

Remember the distinction: default access is package-based, while protected access is package-based plus inheritance-aware.

Quick Revision

Concept Key Point
Default access Applies when no explicit access modifier is written.
Another name Package-private access.
Same package Members can be accessed directly.
Different package Members cannot be accessed directly.
Inheritance A subclass in another package does not gain direct access to default members.
Typical use Internal classes and members shared within a package.

Default access is easy to overlook because it has no keyword, but it plays an important role in Java's access-control system. It gives a package the ability to collaborate internally without exposing every implementation detail to the rest of the application. Once you understand that package boundary, the difference between default and protected access becomes much clearer—and designing clean Java packages becomes considerably easier.

Post a Comment

0Comments
Post a Comment (0)