Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A package-private field in Java is a class member variable declared without an explicit access modifier (public, private, or protected). This absence of a modifier applies the default access level, restricting the field’s visibility and accessibility strictly to classes and interfaces residing within the exact same package boundary. Unlike protected fields, package-private fields are not inherited by subclasses located in different packages. The Java compiler enforces this restriction, resulting in a compilation error if a class in an external package attempts to reference the field.

Syntax and Declaration

The declaration omits any access modifier keyword, though it may still include annotations and non-access modifiers such as static, final, volatile, or transient.
package dev.system.core;

public class Node {
    // Standard package-private field declaration
    int connectionTimeout; 
    
    // Package-private field with non-access modifiers and annotations
    @Deprecated
    static final String NODE_PREFIX = "SYS_";
}

Visibility Matrix

The accessibility of a package-private field is evaluated by the compiler based on the package declaration of the accessing class. The access rules are absolute:
  • Same Class: Accessible
  • Same Package (Subclass): Accessible
  • Same Package (Non-subclass): Accessible
  • Different Package (Subclass): Not Accessible
  • Different Package (Non-subclass): Not Accessible

Compilation Behavior

The following multi-file example demonstrates the compiler’s enforcement of package-private boundaries.
// --- File: dev/system/core/Engine.java 
package dev.system.core;

public class Engine {
    // Package-private field
    int cycleCount = 0; 
}
// --- File: dev/system/core/Diagnostic.java 
package dev.system.core;

public class Diagnostic {
    public void runCheck(Engine engine) {
        // SUCCESS: Diagnostic is in the same package (dev.system.core)
        engine.cycleCount = 100; 
    }
}
// --- File: dev/system/external/Monitor.java 
package dev.system.external;

import dev.system.core.Engine;

public class Monitor extends Engine {
    public void readCycles() {
        // COMPILATION ERROR: cycleCount is not public in Engine; 
        // cannot be accessed from outside package.
        // Note: Inheritance does not bypass package-private restrictions.
        // System.out.println(this.cycleCount); 
    }
}

Reflection and JVM Enforcement

At the JVM level, access control checks for fields are performed during the resolution phase of linking. This typically occurs lazily at runtime when the symbolic reference to the field is first executed. If an illegal access attempt occurs at this level (e.g., due to modified bytecode), the JVM throws an IllegalAccessError. When accessing a package-private field dynamically via the Java Reflection API from outside its package, the API enforces the same boundaries, throwing an IllegalAccessException unless the access control checks are explicitly overridden using Field.setAccessible(true).
Master Java with Deep Grasping Methodology!Learn More