Java Package Access Demo
Expert Insights on Package Access Control
As a software engineer, I often emphasize that understanding package access is not just about knowing keywords like public or protected β itβs about mastering how information is controlled and shared across modular boundaries. Package-level access is the first line of defense in ensuring code security, maintainability, and data encapsulation.
Before diving into how packages are built, itβs critical to understand how and when classes, methods, or variables can be seen or hidden from other parts of an application. This understanding forms the foundation of robust software design β ensuring that the right modules interact while sensitive components stay secure.
When properly used, access control through packages prevents accidental misuse, strengthens abstraction, and establishes clear boundaries of communication between components β a principle that scales from academic projects to real-world enterprise systems.
Role of Protected and Other Modifiers
The protected modifier in Java is particularly powerful because it enables controlled inheritance across package boundaries. While private ensures strict internal encapsulation, default allows visibility within the same package, and public provides open access globally β protected acts as a bridge between security and reusability.
In multi-package architectures, protected members can be inherited but not directly accessed by unrelated classes in other packages. This balance of visibility allows extensibility without compromising integrity, making it a cornerstone of object-oriented software engineering.
Class Definitions
package org.edu.nbkrist.cse.protect;
public class Protection {
int n = 1;
private int n_pri = 2;
protected int n_pro = 3;
public int n_pub = 4;
public Protection() {
System.out.println("base constructor");
System.out.println("n = " + n);
System.out.println("n_pri = " + n_pri);
System.out.println("n_pro = " + n_pro);
System.out.println("n_pub = " + n_pub);
}
}
package org.edu.nbkrist.cse.protect;
public class Derived extends Protection {
public Derived() {
System.out.println("derived constructor");
System.out.println("n = " + n);
System.out.println("n_pro = " + n_pro);
System.out.println("n_pub = " + n_pub);
}
}
package org.edu.nbkrist.cse.protect;
public class SamePackage {
public SamePackage() {
Protection p = new Protection();
System.out.println("n = " + p.n);
System.out.println("n_pro = " + p.n_pro);
System.out.println("n_pub = " + p.n_pub);
}
}
package org.edu.nbkrist.cse.protect2;
import org.edu.nbkrist.cse.protect.*;
public class Protection2 extends Protection {
public Protection2() {
System.out.println("Protection2 constructor");
System.out.println("n_pro = " + n_pro);
System.out.println("n_pub = " + n_pub);
}
}
package org.edu.nbkrist.cse.protect2;
import org.edu.nbkrist.cse.protect.*;
public class OtherPackage {
public OtherPackage() {
System.out.println("OtherPackage constructor");
Protection p = new Protection();
System.out.println("n_pub = " + p.n_pub);
}
}
Test Class & Output
package org.edu.nbkrist.cse.main;
import org.edu.nbkrist.cse.protect.*;
import org.edu.nbkrist.cse.protect2.*;
public class ProtectionTest {
public static void main(String[] args) {
System.out.println("Testing Protection class");
Protection p = new Protection();
Derived d = new Derived();
SamePackage sp = new SamePackage();
Protection2 p2 = new Protection2();
OtherPackage op = new OtherPackage();
}
}
Output:
Testing Protection class
base constructor
n = 1
n_pri = 2
n_pro = 3
n_pub = 4
derived constructor
n = 1
n_pro = 3
n_pub = 4
n = 1
n_pro = 3
n_pub = 4
Protection2 constructor
n_pro = 3
n_pub = 4
OtherPackage constructor
n_pub = 4