Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java packages and access control: a boundary you can compile

Last updated: 28 Sept 20263 min read
tutorial
IntermediateBy AITrove Editorial

A package groups named Java types and participates in type identity and access control; importing a type shortens its name but does not grant access to it.

The name includes the package

com.aitrove.billing.Invoice and com.aitrove.shipping.Invoice are different types. Their simple class names match, but their fully qualified names do not. Importing one does not combine the two APIs.

The source declares its package on the first non-comment declaration line. javac -d chooses where compiled class files are written and creates the matching package directory structure. The runtime entry name must include the package.

Public exposes a top-level type outside its package. Package-private, expressed by omitting an access modifier, limits ordinary access to that package. Private members belong to the enclosing class access rules. Protected has package and subclass rules; it is not simply public for every subclass object reference.

Compile and run with the full name

Save this program as BillingPackageCheck.java. From that file’s directory, run javac -d build BillingPackageCheck.java, then java -cp build com.aitrove.billing.BillingPackageCheck.

The program prints its declared package and validates an invoice count. The package statement does not move the source file by itself. A normal build tool keeps source directories consistent with package names to make lookup predictable.

Package names are not a security sandbox. They organise API access during ordinary compilation and runtime linkage. A service still needs authentication and authorisation for external requests.

Working program

Java
package com.aitrove.billing;

public class BillingPackageCheck {
    static int validatedCount(int invoiceCount) {
        if (invoiceCount < 0) throw new IllegalArgumentException("Negative count");
        return invoiceCount;
    }
    public static void main(String[] args) {
        System.out.println(BillingPackageCheck.class.getPackage().getName());
        System.out.println(validatedCount(4));
    }
}

Output

Output
com.aitrove.billing
4

Cost and design choices

Access checks are not a collection traversal algorithm; assigning an O(n) runtime cost to an import statement would be meaningless. The business calculation shown performs a constant amount of work and uses constant local space.

Package-private types can keep implementation details out of a public API. That reduces the surface callers depend on and makes later refactoring less likely to break consumers.

For modular applications, module exports add another visibility boundary. This lesson targets ordinary Java 8 package behavior; it does not pretend package declarations alone implement the module system introduced later.

Connected lessons

Continue with Compile and run Java, API boundaries, Class members.

Common Mistakes

  • Do not run a packaged class using only its simple name.
  • Do not assume import overrides access restrictions.
  • Do not place unrelated public classes in one source file with conflicting filenames.
java
packages
Storage details