skip to content

Explain the one-public-class-per-file rule and how a .java file's name relates to its classes.

level: juniorimportance: must knowfreq 68%

answer

  1. At most one public top-level type per file
  2. File name == public class name (case-sensitive) + .java
  3. Extra classes allowed if package-private
  4. No public class → file name is unconstrained
  5. Each top-level class → its own .class file

basics

~20 s

A single .java file can have at most one public top-level class, and the file must be named exactly after that public class (plus .java). You can add more non-public (package-private) classes in the same file.

solid answer

~40 s

Java enforces that a source file contains at most one public top-level type, and if there is one, the file's name must match that type's name exactly, case-sensitively, with a .java extension — so public class BankAccount must live in BankAccount.java. This lets the compiler and JVM locate a public type from its name alone without scanning every file. A file may contain additional top-level classes as long as they are package-private (no public modifier); these are compiled to their own .class files. A file with no public class can be named anything (still .java), though convention names it after its primary type. Each top-level class compiles to a separate ClassName.class file regardless of how many share a source file.

go deeper

for a junior

Knows the public class must match the file name and there is one public class per file.

for a middle

Knows package-private classes may share the file, the match is case-sensitive, and each top-level class yields its own .class file.

for a senior

Explains the toolchain rationale (name-to-file lookup), the no-public-class naming freedom, and the style guidance to keep one class per file.

for a principal

Discusses organizational trade-offs of co-locating helper types vs splitting files, package design, and how this interacts with module/package visibility at scale.

## The rule Java imposes a strict relationship between **source files** and the **public classes** inside them: 1. A single `.java` source file may declare **at most one `public` top-level type** (class, interface, enum, or record). 2. **If** the file has a public top-level type, the file's **name must exactly equal that type's name**, plus the `.java` extension — and the match is **case-sensitive**. So a `public class BankAccount` *must* be in a file named `BankAccount.java`. Putting it in `bankaccount.java` or `Account.java` is a compile error. ## Why this rule exists The Java compiler and the JVM frequently need to find the source or bytecode for a type given only its name (for example, when another class refers to `BankAccount`). By guaranteeing that a public type named `Foo` lives in `Foo.java`, the toolchain can map a name directly to a file on disk without scanning the contents of every file in a directory. It is a deliberate, name-based lookup optimization baked into the language spec. ## What else can share the file A source file is allowed to contain **multiple top-level classes**, but only one of them may be `public`. The others must be **package-private** (declared with no access modifier). For example: ```java // File: Order.java public class Order { // public — matches the file name private final LineItem item = new LineItem(); } class LineItem { // package-private — legal in the same file int quantity; } ``` Here `LineItem` is a helper type used only by `Order`; keeping it package-private and co-located is allowed. However, the common style guidance is **one top-level class per file** for readability, even though the language permits more. ## Files with no public class If a file declares **no** public type, the file may technically be named anything (still ending in `.java`). For instance, two package-private classes could live in a file named `Helpers.java`. Convention still names the file after its principal type, but the compiler does not require it here because there is no public name to match. ## One class, one .class file Regardless of how many top-level classes share a source file, **each top-level class compiles to its own `.class` file** named after that class. Compiling `Order.java` above produces both `Order.class` and `LineItem.class`. (Nested classes additionally produce `Outer$Nested.class` files — a separate topic.) ## Common mistakes - Renaming the file but not the public class (or vice versa) — the names must stay in lockstep. - Getting the case wrong: `MyClass` in `myclass.java` fails on case-sensitive filesystems and is non-portable everywhere. - Trying to make two classes in one file `public` — only one may be.

  • Can a file with two package-private classes and no public class be named freely?
    Yes — with no public type to match, the compiler does not constrain the file name (still .java). Convention names it after the main type anyway.
  • How many .class files come from a source file with one public and one package-private top-level class?
    Two — one per top-level class, each named after its class.

saying these in an interview costs you the question

  • Saying you can have two public classes in one file
  • Thinking the file-name match is case-insensitive
  • Believing only one class total is allowed per file (only one PUBLIC)
  • Confusing one-public-per-file with one-class-per-.class-file (the latter is always true per top-level class)

context