In JAVA, class name must always be the same as file name, but sometimes file contains multiple classes. Only single class(or interface) in file can be public, and it must have the same name as file. But how is the file name determined if it has multiple classes (or interfaces) that are not public?
interface Foo {}
class Bar{}
Some people seem to be confused about this question
I actually know that it'll work regardless if I choose Foo or Bar as a file name. However what interest's me is if there are some kind of convention of naming the class.
Why don't I name it whatever I feel like it? Because i'm actually writing an application that refactors code, and whenever it renames classes, i need to know how and when to change my filename.
So far i think the right way is:
if class has a public node, use it's name as filename,
else just pick the first node, so in this example Foo would win. So I simplify the question: is this the right way, or is there something more to it?
Quoting the Java Language Specification, section 7.6 Top Level Type Declarations :
If and only if packages are stored in a file system (§7.2), the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:
The type is referred to by code in other compilation units of the package in which the type is declared.
The type is declared public (and therefore is potentially accessible from code in other packages).
This restriction implies that there must be at most one such type per compilation unit. This restriction makes it easy for a Java compiler to find a named class within a package. In practice, many programmers choose to put each class or interface type in its own compilation unit, whether or not it is public or is referred to by code in other compilation units.
So, as you can see, it is not a requirement that "class name must always be the same as file name", as you said it.
It is simply a way to allow some compilers an easy way to find the class source code during compilation.
But, more importantly, it also help humans find the source code. If you see a reference to class com.example.Foo, you know exactly where to find it, because it's going to be in file com/example/Foo.java.
Non-public (package private) top-level classes, can technically be placed in files of any name, and multiple such classes can be bundled in a single file, but that makes them difficult to find. For this reason, I've seen a guideline (don't remember where) that said that you should always put top-level classes in their own file, with one exception:
If the non-public class is only used by one other class, it's ok to place it in the same compilation unit (.java file) as that other class.
Basically this means that you should consider any top-level class, whose name is not the file name, to be "file-scoped", even though it's technically packages-scoped.
There are 2 rules to follow:
1st Rule: The class can have either package (default) or public visibility
2nd Rule: Teh class which you have defined as public must be implemented in a .java source file with the same name, however classes that are non-public can be with other name in source files.
Related
This question already has answers here:
Java: Multiple class declarations in one file
(9 answers)
Closed 2 years ago.
Does it creates individual .class files when it gets compiled? Is it something right to do?
The Java Language Specification (JLS 7.6) states:
"It is a compile-time error if the name of a top level type appears as the name of any other top level class or interface type declared in the same package."
Since all top level type declarations in a file are members of the same package, it follows that if you declare two top-level types with the same name in the same file, then the second one is violating the above rule.
The spec also states the following:
"If and only if packages are stored in a file system (§7.2), the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:
The type is referred to by code in other ordinary compilation units of the package in which the type is declared.
The type is declared public (and therefore is potentially accessible from code in other packages)."
This means that (for such implementations) only one of the top-level types in a file can be public.
(Most Java compilers do enforce this restriction.)
However, if you don't break the restrictions above, the Java language allows you to declare multiple top level types in a single file.
Does it create individual .class files when it gets compiled?
Yes. Indeed, there is also a separate .class file generated for any nested or inner classes, and for any lambdas.
Is it something right to do?
It is generally thought to be a bad idea to do this. Some Java style guides explicitly say there should be one top-level type declaration per source file. Others are silent on this.
Since multiple types in a single source file are unusual in practice, most programmers don't expect this. Thus it is a readability concern, which is a practical reason not to do it.
Noob java question.
For my project, I have a class model defined in XML file, which I then transform into a model. For example:
<model>
<class name="abc"><field>one</field><field>two</field></class>
<class name="xyz"><field>f1</field><field>f2/field></class>
</model>
and this gets transformed into:
public class abc {
String _one;
String _two;
public String get_one() {
return _one;
}
... and so on you get an idea
Obviously, it would be a nuisance to transform each class into its own .java file. It would be much more manageable to pile them up in a single .java file. However, java has this requitement that each class must be defined in its own file, and the file name must match class name. Otherwise, compiler will show error: The public type XYZ must be defined in its own file
It's likely possible to define it like this:
public class ModelContainer {
public class abc {
...
}
public class xyz {
...
}
}
Is there another way? Ideally, I'm looking for a compiler switch or something of that kind, which would disable the requirement to have each class in its own file. I am using Eclipse if that makes any difference
If you're ok with using inner classes then yes, this will work but you'll have to obtain an instance of the outer class each time you want to instantiate an inner class:
public class ModelContainer {
public class abc {
...
}
public class xyz {
...
}
}
Also you can declare the nested classes as static, so it won't be necessary to instantiate the outer class first:
public class ModelContainer {
public static class abc {
...
}
public static class xyz {
...
}
}
Take a look at this post for additional details.
Interestingly enough, it's not actually a language requirement to have each top-level class in its own .java file:
If and only if packages are stored in a file system (§7.2), the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:
The type is referred to by code in other compilation units of the package in which the type is declared.
The type is declared public (and therefore is potentially accessible from code in other packages).
That said, since the compiler may enforce such a requirement, all portable code should conform to the practice.
Regarding your specific case, you should consider the one-top-level-class-per-file rule to be a language requirement. The usual approach is in fact to generate a separate .java file for each class (there are a number of annoying aspects to using nested classes, even static ones), but you could work around this by using nested classes if you have a better reason than not closing and opening files.
An alternate, but slightly more-sophisticated approach would be to skip creating Java source at all. You could use a bytecode library such as Javassist or ASM to create class files directly. Essentially, you would be compiling your XML declaration to executable code.
If you are creating simple value objects as shown, this would be pretty easy.
You seem to have a problem with generating large numbers of files, so you could write the class files directly into a JAR file (using the ZIP I/O classes) and generate your synthetic classes as a single library file.
(You might wish to mark these classes as synthetic, although the XML declaration could be considered source code, meaning that they are not technically synthetic.)
The compiler switch you want doesn't exist. Ensuring that each class is in a correctly-named file - and in the correct place in the directory hierarchy, assuming you're organizing your classes in packages - is always enforced by the Java compiler. Most Java devs wouldn't dream of turning this off, as this way of organizing one's source code is considered good practice. (Therefore Java devs have minor nightmares when attempting to navigate large, unruly projects in languages like C# that don't enforce this restriction.)
The only classes that don't need to obey this constraint are anonymous or inner classes, but your application shouldn't consist mostly of these.
I have a file Test.java and the following code inside it.
public class Abcd
{
//some code here
}
Now the class does not compile, but when I remove the public modifier , it compiles fine.
What is the reasoning behind Java allowing us to compile a class name that is different from the file name when it is not public.
I know it is a newbie question, but I'm not able to find a good explanation.
The rationale is to allow more than one top-level class per .java file.
Many classes—such as event listeners—are of local use only and the earliest versions of Java did not support nested classes. Without this relaxation of the "filename = class name" rule, each and every such class would have required its own file, with the unavoidable result of endless proliferation of small .java files and the scattering of tightly coupled code.
As soon as Java introduced nested classes, the importance of this rule waned significantly. Today you can go through many hundreds of Java files, never chancing upon one which takes advantage of it.
The reason is the same as for the door plates. If some person officially resides in the office (declared public) his/her name must be on the door tag. Like "Alex Jones" or "Detective Colombo". If somebody just visits the room, talks to an official or cleans the floor, their name does not have to be officially put on the door. Instead, the door can read "Utilities" or "Meeting room".
The Java specification states you can only have at most one public class per file. In this case, the class name should match the file name. All non-public classes are allowed to have any name, regardless of the file name.
I think allowing them is a prerequisite for nested classes. Anonymous Classes in particular dramatically reduce the number of .java files required. Without support for this, you would need lots of single method interface implementations in their own separate files from the main class they are used in. (I'm thinking of action listeners in particular)
There is a good explanation of all nested classes in the Nested Classes Java tutorial on Oracle's website, which has examples of each. It also has a reason they are useful, which I'll quote:
Why Use Nested Classes?
Compelling reasons for using nested classes include the following:
It is a way of logically grouping classes that are only used in one place: If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined.
It increases encapsulation: Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be
declared private. By hiding class B within class A, A's members can be
declared private and B can access them. In addition, B itself can be
hidden from the outside world.
It can lead to more readable and maintainable code: Nesting small classes within top-level classes places the code closer to where it is
used.
(emphasis mine)
I am not familiar with Java spec back in the early days, but a quick search shows inner classes were added in Java 1.1.
I look at it the other way round. The natural state of affairs would be for the programmer to pick both the class name and the file name independently. Probably in order to simplify finding public classes from outside a package during compilation, there is a special restriction that a public class be in a file with the corresponding name.
Note that Java is case-sensitive, but the filesystem need not be. If the file's base name is "abcd", but the class is "Abcd", would that conform to the rule on a case-insensitive filesystem? Certainly not when ported to a case-sensitive one.
Or suppose you happened to have a class called ABCD, and a class Abcd (let's not get into that being a bad idea: it could happen) and the program is ported to a case insensitive filesystem. Now you not only have to rename files, but also classes, oops!
Or what if there is no file? Suppose you have a Java compiler which can take input on standard input. So then the class has to be named "StandardInput"?
If you rationally explore the implications of requiring file names to follow class names, you will find that it's a bad idea in more than one way.
Also one other point that many answers missed to point out is that without the public declaration, the JVM would never know which classes' main method needs to be invoked. All classes declared in one .java file can all have main methods, but the main method is run on only the class marked as public. HTH
Because of a java file can contains more than one class, it may have two classes in one java file. But a java file have to contain a class as the same name as file name if it contains a public class.
Guys, I've come across such legal behaviour:
File B.java:
final class C {}
final class D {}
File A.java:
class B {}
public class A {}
Questions:
When class X is required to be placed into its own X.java file? Does class visibility/final matter here?
Is there any official spec on this class/java relation?
Thanks a lot.
The de-facto standard in most implementations is that a source file can only contain one top-level public type definition. The name of the source file must be the name of that type.
A source file can contain nested types, but by definition they're not a top-level public type.
This is recommended in, but not required by, the Java Language Specification.
JLS 7.6 Top Level Type Declarations
When packages are stored in a file system, the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:
The type is referred to by code in other compilation units of the package in which the type is declared.
The type is declared public (and therefore is potentially accessible from code in other packages).
This restriction implies that there must be at most one such type per compilation unit. This restriction makes it easy for a compiler for the Java programming language or an implementation of the Java virtual machine to find a named class within a package; for example, the source code for a public type wet.sprocket.Toad would be found in a file Toad.java in the directory wet/sprocket, and the corresponding object code would be found in the file Toad.class in the same directory.
Note that final has nothing to do with accessibility, so it's not a relevant issue in this matter.
Related questions
What should be the name of a Java source that contains more than one class?
See also
Java Tutorials/Packages/Managing Source and Class Files
Joseph D. Darcy's blog - Nested, Inner, Member, and Top-Level Classes
A public class ClassName must be in a file called ClassName.java.
Non-public classes have no such restriction.
A consequence of this is that a Java source file can have only one public class but as many non-public classes as you wish.
In Java, you can have only one top-level public class or interface in a source file, and the source file must have the same name as that class or interface.
This is not something that's in the Java language specification; this is an implementation-specific thing of Sun's (now Oracle's) implementation of the Java compiler. (Other implementations of the Java compiler might not require this).
The Sun/Oracle compiler allows at most one public top-level class per file, in which case the file name must be the class name.
The Java Language Specification does not mandate this behaviour, but explicitly allows it:
When packages are stored in a file
system (§7.2.1), the host system may
choose to enforce the restriction that
it is a compile-time error if a type
is not found in a file under a name
composed of the type name plus an
extension (such as .java or .jav) if
either of the following is true:
The type is referred to by code in
other compilation units of the package
in which the type is declared.
The type is declared public (and therefore
is potentially accessible from code in
other packages).
This restriction implies that there
must be at most one such type per
compilation unit. This restriction
makes it easy for a compiler for the
Java programming language or an
implementation of the Java virtual
machine to find a named class within a
package;
When i want to create a java class it is generating automatically a file with the same name of class.
But when it generate a class, it can change the file name different than class name..
Am i missing something?
(source: screencast.com)
Quoting the section 7.6 Top Level Type Declarations from the Java Language Specification:
When packages are stored in a file
system (§7.2.1), the host system
may choose to enforce the restriction
that it is a compile-time error if a
type is not found in a file under a
name composed of the type name plus an
extension (such as .java or .jav)
if either of the following is true:
The type is referred to by code in other compilation units of the package
in which the type is declared.
The type is declared public (and therefore is potentially accessible
from code in other packages).
This restriction implies that there
must be at most one such type per
compilation unit. This restriction
makes it easy for a compiler for the
Java programming language or an
implementation of the Java virtual
machine to find a named class within a
package; for example, the source code
for a public type wet.sprocket.Toad
would be found in a file Toad.java
in the directory wet/sprocket, and
the corresponding object code would be
found in the file Toad.class in the
same directory.
When packages are stored in a database
(§7.2.2), the host system must
not impose such restrictions. In
practice, many programmers choose to
put each class or interface type in
its own compilation unit, whether or
not it is public or is referred to by
code in other compilation units.
Because the language designers say so. It really is that simple. It's a convention and they force you to follow it.
The language specification itself does not dictate this (I've just had a look, and can find no reference to it), but it's generally enforced by tools. It makes it considerably easier for tools' dependency management, since it knows where to look for class B if class A has a reference to it. The convention extends to the directory structure echoing the package structure, but again, this is just a convention.
If I can change the world I wish c# designers also do that.
How much time can be saved from forcing guys to not create file classes.cs and put ALL code in it. Isn't it such as requirement of braces for If. Why language force me do that silly thing:
if (true)
{
}
instead of
if true
{
}
:-)