DEV Community

Rajesh Bhola
Rajesh Bhola

Posted on

Part 1 - public, default, and Top-Level Class Rules in Java

When you write a Java class, you're not just defining methods and variables—you also tell the Java compiler and JVM how that class should behave.

For example:

  • Can this class be accessed from another package?
  • Can another class inherit from it?
  • Can objects of this class be created?
  • Should floating-point calculations follow strict IEEE standards?

These behaviors are controlled using class modifiers.

Understanding class modifiers is one of the fundamental Java concepts and is frequently tested in Java interviews. In this article, we'll focus on the modifiers applicable to top-level classes, especially public and default (package-private) access.

By the end of this guide, you'll understand:

  • What class modifiers are
  • Why Java needs them
  • Which modifiers are allowed for top-level classes
  • The difference between public and package-private classes
  • Common compiler errors
  • Best practices
  • Interview questions

What Are Class Modifiers?

A class modifier provides additional information about how a class behaves.

It tells the Java compiler and JVM things like:

  • Who can access the class
  • Whether inheritance is allowed
  • Whether objects can be created
  • Whether special JVM rules should be applied

Think of class modifiers as rules or permissions that define how a class can be used.

For example:

  • A public class can be accessed from anywhere.
  • A package-private (default) class can only be accessed within the same package.
  • A final class cannot be extended.
  • An abstract class cannot be instantiated.

Why Do We Need Class Modifiers?

Imagine you're building an online shopping application.

You might have the following classes:

Shopping Application

├── Customer
├── Product
├── Order
├── PaymentService
└── ValidationHelper
Enter fullscreen mode Exit fullscreen mode

Not every class should be accessible from every package.

For example:

  • Customer should be accessible throughout the application.
  • ValidationHelper should only be used internally.

Java class modifiers help enforce these design decisions.

Without modifiers, every class would be exposed unnecessarily, making the code harder to maintain and less secure.


What Is a Top-Level Class?

A top-level class is a class that is not declared inside another class.

Example:

public class Customer {

}
Enter fullscreen mode Exit fullscreen mode

This is a top-level class because it exists directly inside the source file.

On the other hand:

public class Customer {

    class Address {

    }

}
Enter fullscreen mode Exit fullscreen mode

Address is an inner class, not a top-level class.


Applicable Modifiers for Top-Level Classes

Java allows only five modifiers for top-level classes.

Modifier Allowed? Purpose
public Accessible from anywhere
Default (package-private) Accessible only within the same package
final Prevents inheritance
abstract Prevents object creation
strictfp Uses IEEE 754 floating-point rules

These are the only modifiers allowed.

If you use any other modifier, the compiler reports an error.


Illegal Modifiers for Top-Level Classes

The following modifiers cannot be applied to top-level classes:

  • private
  • protected
  • static

These modifiers are only applicable to inner classes.


Basic Example

Let's see what happens when we use an illegal modifier.

private class Test {

    public static void main(String[] args) {
        System.out.println("Hello");
    }

}
Enter fullscreen mode Exit fullscreen mode

Compile-Time Error

Test.java:1: error: modifier private not allowed here
private class Test
^
1 error
Enter fullscreen mode Exit fullscreen mode

Step-by-Step Explanation

Step 1

The Java compiler reads the class declaration.

Step 2

It checks whether private is valid for a top-level class.

Step 3

Since private is only allowed for inner classes, the validation fails.

Step 4

Compilation stops, and no .class file is generated.


How It Works

Java Source File
        │
        ▼
 Top-Level Class
        │
        ▼
Compiler validates modifiers
        │
        ▼
Valid? ─────────────► Generate .class file
  │
  ▼
Invalid
  │
  ▼
Compile-Time Error
Enter fullscreen mode Exit fullscreen mode

The compiler checks class modifiers before generating bytecode.


Rule 1: Only Five Modifiers Are Allowed

A top-level class can only be declared with one of these modifiers:

  • public
  • default (package-private)
  • final
  • abstract
  • strictfp

Example:

public class Customer {

}
Enter fullscreen mode Exit fullscreen mode

Step-by-Step Explanation

Step 1

The compiler encounters the public modifier.

Step 2

It verifies that public is valid for a top-level class.

Step 3

Validation succeeds.

Step 4

The class is compiled successfully.


Rule 2: private, protected, and static Are Illegal

Example:

protected class Customer {

}
Enter fullscreen mode Exit fullscreen mode

Compile-Time Error

modifier protected not allowed here
Enter fullscreen mode Exit fullscreen mode

Why?

A top-level class isn't a member of another class.

Therefore:

  • private has no meaning.
  • protected has no meaning.
  • static has no meaning.

Public Classes

A class declared with the public modifier can be accessed from:

  • The same package
  • Any other package (after importing it)

Program 1

package pack1;

public class Customer {

    public void display() {
        System.out.println("Customer information");
    }

}
Enter fullscreen mode Exit fullscreen mode

Compile:

javac -d . Customer.java
Enter fullscreen mode Exit fullscreen mode

Program 2

package pack2;

import pack1.Customer;

public class Main {

    public static void main(String[] args) {

        Customer customer = new Customer();
        customer.display();

    }

}
Enter fullscreen mode Exit fullscreen mode

Output

Customer information
Enter fullscreen mode Exit fullscreen mode

Step-by-Step Explanation

Step 1

Customer is declared as public.

Step 2

Another package imports it.

Step 3

An object is created successfully.

Step 4

The display() method executes normally.


What If the Class Is Not Public?

Suppose we remove the public modifier.

package pack1;

class Customer {

    public void display() {
        System.out.println("Customer information");
    }

}
Enter fullscreen mode Exit fullscreen mode

Now another package tries to use it.

Compile-Time Error

Customer is not public in pack1;
cannot be accessed from outside package
Enter fullscreen mode Exit fullscreen mode

The compiler prevents access because the class has package-private visibility.


Default (Package-Private) Classes

If you don't specify any access modifier, Java automatically assigns package-private (also called default) access.

Example:

package pack1;

class Customer {

    public void display() {
        System.out.println("Customer information");
    }

}
Enter fullscreen mode Exit fullscreen mode

This class can be accessed only within the pack1 package.


Accessing from the Same Package

package pack1;

public class Main {

    public static void main(String[] args) {

        Customer customer = new Customer();
        customer.display();

    }

}
Enter fullscreen mode Exit fullscreen mode

Output

Customer information
Enter fullscreen mode Exit fullscreen mode

Everything works because both classes belong to the same package.


Accessing from Another Package

package pack2;

import pack1.Customer;

public class Main {

    public static void main(String[] args) {

        Customer customer = new Customer();

    }

}
Enter fullscreen mode Exit fullscreen mode

Compile-Time Error

Customer is not public in pack1;
cannot be accessed from outside package
Enter fullscreen mode Exit fullscreen mode

Step-by-Step Explanation

Step 1

The compiler checks the visibility of Customer.

Step 2

It finds that Customer is package-private.

Step 3

The calling class belongs to another package.

Step 4

Compilation fails.


Access Specifier vs Access Modifier

If you've learned C or C++, you may know the terms access specifier and access modifier.

Java doesn't make this distinction.

C/C++ Java
Access Specifiers No separate concept
Access Modifiers All modifiers are simply called modifiers

So in Java:

  • public
  • private
  • protected
  • package-private (default)

are all considered access modifiers.


Public vs Default Class

Feature public Default (Package-Private)
Accessible within the same package
Accessible from another package
Requires import ❌ (cannot be imported outside package)
Interview importance ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐

Common Beginner Mistakes

Mistake 1: Declaring a Top-Level Class as private

Incorrect code:

private class Customer {

}
Enter fullscreen mode Exit fullscreen mode

Compile-Time Error

modifier private not allowed here
Enter fullscreen mode Exit fullscreen mode

Why?

Top-level classes cannot be private.

Correct Code

class Customer {

}
Enter fullscreen mode Exit fullscreen mode

or

public class Customer {

}
Enter fullscreen mode Exit fullscreen mode

Mistake 2: Forgetting the public Modifier

Developers often expect this to work:

package accounts;

class Customer {

}
Enter fullscreen mode Exit fullscreen mode

Later they try to use it from another package.

The compiler rejects it because the class has package-private visibility.


Mistake 3: Confusing Default Access with the default Keyword

Java's default access modifier is not the default keyword.

There is no default keyword for classes.

Instead, simply omit the access modifier.

Correct:

class Customer {

}
Enter fullscreen mode Exit fullscreen mode

Incorrect:

default class Customer {

}
Enter fullscreen mode Exit fullscreen mode

Compile-Time Error

illegal start of type
Enter fullscreen mode Exit fullscreen mode

Best Practices

  • Use public only for classes that form your application's public API.
  • Keep helper classes package-private whenever possible.
  • Prefer the least accessible modifier that satisfies your requirement.
  • Organize related classes into meaningful packages.
  • Avoid exposing implementation classes unnecessarily.

Interview Questions

1. Which modifiers are allowed for a top-level class?

Answer:

  • public
  • package-private (default)
  • final
  • abstract
  • strictfp

Why interviewers ask

To verify your understanding of Java language rules.

Common trap

Saying private or protected.


2. Can a top-level class be private?

Answer

No.

Only inner classes can be declared private.


3. What is package-private access?

Answer

A package-private class can only be accessed within its own package.


4. Can a package-private class be imported into another package?

Answer

No.

Even if you write an import statement, the compiler won't allow access.


5. Why are protected and static illegal for top-level classes?

Answer

Because these modifiers are meaningful only for class members or inner classes, not for top-level classes.


Quick Memory Trick 🧠

Remember the five valid top-level class modifiers using the mnemonic:

PDAFS

P → Public
D → Default (Package-Private)
A → Abstract
F → Final
S → Strictfp
Enter fullscreen mode Exit fullscreen mode

If a modifier isn't part of PDAFS, it cannot be used for a top-level class.


Key Takeaways

  • A class modifier defines how a Java class behaves.
  • Java allows only five modifiers for top-level classes.
  • public classes are accessible from any package.
  • Package-private (default) classes are accessible only within the same package.
  • private, protected, and static are illegal for top-level classes.
  • Choosing the correct access level improves encapsulation and maintainability.
  • Class modifiers are one of the most frequently asked Java interview topics.

What's Next?

In Part 2, we'll dive deep into the final modifier, covering:

  • final classes
  • final methods
  • final variables
  • Real-world examples
  • Common interview questions
  • Best practices

If you found this guide helpful, leave a ❤️ and follow for more beginner-friendly Java tutorials, interview questions, and practical coding examples.

Happy Coding!

Top comments (0)