ProgrammingJava Developer

What mechanisms for controlling visibility (access control) of class members exist in Java, how should they be applied correctly, and what nuances are important to consider when designing the architecture?

Pass interviews with Hintsage AI assistant

Answer.

In Java, access to fields, methods, and classes is controlled using access modifiers: private, default (package-private), protected, public.

History of the issue:

Early versions of Java used strict object encapsulation. Different levels of access were introduced for flexibility to support both complete closure and extensibility (inheritance and access within the package).

Problem:

Choosing the wrong modifier can lead to encapsulation violations, problems with inheritance, testing issues, or even security bugs if data becomes publicly accessible by mistake.

Solution:

Use the most restrictive modifier that your architecture allows. Fields are usually made private, with access provided through getter/setter methods. Methods are made public only if they are part of the API, and for extensibility — protected.

Code example:

public class Person { private String name; // private field protected int age; // accessible in package and subclasses String email; // package-private public String getName() { return name; } }

Key features:

  • private — accessible only within the class
  • package-private (no modifier) — accessible from all classes in the same package
  • protected — plus access for subclasses even from other packages
  • public — accessible to everyone

Tricky questions.

Can access modifiers be applied to local variables?

No. Access modifiers apply only to classes, methods, and fields/nested classes, but not to local variables.

Can a class inside a method be declared with the public modifier?

No. A local class cannot be declared with an access modifier; it always has visibility within the method.

Is a protected member accessible to a subclass in another package?

Yes, protected members are accessible to subclasses, even if they are in other packages, but not to regular classes in another package.

Common mistakes and anti-patterns

  • Using public fields (violating encapsulation)
  • "Accidental" package-private (forgotten modifier)
  • Excessive exposure of protected methods without necessity
  • Misusing public static fields to pass information between parts of the application

Real-life example

Negative case

All class fields are accidentally declared public — they are accessed directly from other classes, making it difficult to track where changes occur.

Pros:

  • Quick and easy access to data

Cons:

  • Difficulty in access control. No checking/validation logic
  • Easy to corrupt data

Positive case

All fields are private, and public methods control access with validation, while only necessary parts are made protected for extension in subclasses.

Pros:

  • Security, control, predictability
  • Flexibility of architecture

Cons:

  • Additional methods required (getter/setter)
  • Interaction becomes more complex during rapid prototyping