I am a newbie learning Java. In Java every source file must contain a public class and that source file should have the same name as that public class. Moreover, no source file can contain two public classes. Why is this restriction?
-
4Without the specifics, this is a historical design artifact of the way Java was engineered. More recently designed languages, like C#, while similar to Java, do not have this restriction.– gahooaJan 16, 2012 at 17:33
-
13Isn't it to enforce best practices? I thought this was the only reason. In C#, you don't have this restriction on technical level, but still StyleCop will complain if file name and class name don't match or if you have several classes in the same file. Visual Studio is also heavily encouraging class-file relation (think class diagrams which create files for you, or when you rename the .cs file, Visual Studio asks you if you want to refactor the name of the class too).– Arseni MourzenkoJan 16, 2012 at 17:55
-
In an old-style compiled language, the linker finds all the references and external symbols. But Java isn't linked - you can load jars at run time if you want. Without a link step, trying to map class names to locations in the classpath is a lot faster if you know what file name to look for.– Paul TomblinJan 16, 2012 at 19:26
-
4@gahooa it is not a design artifact, it is a deliberate design decision. This makes many things much easier.– user1249Jan 16, 2012 at 19:32
-
1What about using grep?– userFeb 28, 2012 at 19:12
2 Answers
In one of his Java Specialists' Newsletters, Heinz Kabutz digs through the Oak Language Specifications. He writes:
Why is each public class in a separate file? (Section 1)
This is a question that I have frequently been asked during my courses. Up to now I have not had a good answer to this question. In section 1, we read: "Although each Oak compilation unit can contain multiple classes or interfaces, at most one class or interface per compilation unit can be public".
In the sidebar it explains why: "This restriction is not yet enforced by the compiler, although it's necessary for efficient package importation"
It's pretty obvious - like most things are once you know the design reasons - the compiler would have to make an additional pass through all the compilation units (.java files) to figure out what classes were where, and that would make the compilation even slower.
-
1To make compiling marginally faster? Really? Not because it makes your code much more organized? I highly doubt this is the correct answer. Jan 16, 2012 at 23:47
-
1@BlueRaja-DannyPflughoeft In 1998, I'm sure it made a much bigger difference– TheLQJan 17, 2012 at 4:12
Reasons I can think of
- Makes finding other classes slightly easier for the compiler in the beginning since it doesn't have to search all the potentially thousands of class files for a random public class, it can just go to the file.
- This probably doesn't matter anymore but just started the early convention that never changed
- In compilation a change to a file only affects that file. If there are multiple classes then everything has to be recompiled
- Best practice - Having multiple public classes in the same file makes things confusing. The purpose of files is to organize the source code, the purpose of folders is to organize the files. If all the classes of a particular package are in a single 100 MB super file then you've lost all the advantages and gained none of the benefits of files (plus adding lots of headache when editing)
-
1Classes and interfaces do not necessarily represent the most natural level of subdivisions for source code. Having many thousands of lines of code glommed into one file is inconvenient, but so is having nor is having 100 lines of "real" content (excluding comments or duplicated compiler directives) spread among a dozen source files. I wonder how it would work if a file named for the type had to either contain the definition or else identify the file that does?– supercatMar 22, 2014 at 19:43