Java: Why separate class must be private - java

For example I have a file name call "A.java". Here its structure:
public class A{
}
private class B{
// no error
}
public class C{
//error : must declare at different file
}
I think this is Java rules. But, I really want to know: WHY java need to do that.
Thanks :)

You can find in section 7.6 of the JLS:
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.

There can only be one public class per .java file, as public classes must have the same name as the source file.
From your example: if you have file "A.java", only class A can be public.

It is defined in the Java Language Specification.

public class A{
}
private class B{
// no error
}
This shouldn't even work (see Java Language Specification):
It is a compile-time error if a top level type declaration contains
any one of the following access modifiers: protected, private, or
static
Are you sure you haven't declared class B as an inner class?
It doesn't make sens to declare a top-level class as private, since private restricts the visibility of members to the enclosing top-level class/interface. If your class is a top-level class (whether or not in its own file), you'd at least want package-level visibility (no modifier at all).

well,
you cannot have structure is a file called 'A.java' because you intended public class is named 'ClassA', then the file name must be ClassA.java. Now, as far as I understand, the idea behind this restriction is just to be organized. So you can have the physical origin of every class.
Without this restriction u can have a for example 'ClassC' coming from 'nowhere', and it could be really difficult to track the source code.
regards

Related

Java class naming rules

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.

Disable enforcement of "The public type xyz must be defined in its own file"

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.

Why only one public class per Java file? [duplicate]

In any Java file, why can we have only one public class whose name is same as the Java file name?
It forces all Java code to be organized in a certain way, which in the long run helps improve code readability.
The Java designers chose a strict approach that enforces their idea of good design practices, and this is part of that theme. Contrast that with the anything-goes attitude in Perl.
According to this source, it is for efficient compilation :
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.
The same applies also for imports of source files in IDEs. Another reason would be reasonable source sizes.
These are the rules. Although it is not quite true. You can define internal classes inside you "main" class like this:
public class A {
public class B {
...
}
}
Courtesy of Dr Heinz Kabutz and his excellent newsletter....
Why is each public class in a separate
file?
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.
We can have only one top level public either class or interface in any java compilation unit ( .java source file ).
But there can be any number of default classes/interfaces per src file.
why:
JLS leaves the option to the java compiler. And most of the compiler implementations force to have file name same as :
(1) the public class/interface name
(2) if there is a main method and no public class then any name
(3) If there is main method and public class then main method should be in that public class
(4) if there is no public class and no main method then any valid name which may or may not be matching with the class/interface names in the file.
From (2): If two public classes allowed, we should give the file two names which is terribly meaningless to file system.
From (3): If two public classes allowed, we should have two main methods which is terribly meaningless to java
Hence a Java source file can have one only public class.
I think the above 4 points are forced by compiler to make the job of both compiler and jvm to find particular java source file or class file easy-so-quick for the compilation/loading/linking. Java has such built in restrictions which developers should follow to have better programming.
Source: My readings and understanding.
To understand the basic reason behind these restrictions, let's suppose compiler doesn't give compile error for not naming file name same as public class name.
Suppose there is a package A
A
/ \
file1.java file2.java
file1.java
package A;
class file1
{
public static void main(String args[])
{
}
}
public class file3
{
public static void main(String args[])
{
}
}
Now as we know that a public class can also be accessed outside the package, now it will become the responsibility of a developer to make it accessible to the outside world. Let's see how:
Suppose package A is containing only Java files(no class files) and some class outside the package A tries to access public class file3, compiler will first try to find file3.class ( not available ), then it will try to find file3.java ( not available ). So even though file3 class is public in nature, it is not visible to the outside world. So if a compiler puts the restriction that if a file is containing public class, it should be named same as the public class name, then above issue can be resolved and the developer won't have to think of exposing public class to the outside world.
Compiler also puts the restriction that there should be atmost one public class per Java file, so that every public class can be accessed by the outside world.
Java utilizes this convention to find class/interface bytecode by starting at the classpath and scanning for the package hierarchy in subdirectories. Filesystem representation of this hierarchy also enforces some basic rules.
Any two Java classes or interfaces
in the same package cannot have the
same name. File names would
conflict.
Any two Java packages in
the same parent package could not
have the same name. Folder paths
would conflict.
A class has visibility to all classes in the same package without modification
to the classpath.
To have an understanding between the compiler and the programmer.It is a rule that the source code must have atmost one public class and that class must contain the main function.So without any confusion/restriction the compiler can access(public) the class and name the class name to the class file.Also since this class contains the main(), executing the class file will give correct flow
Public modifier with a class is exposed to the world that means any other class which is outside of the package can also access it to resolve dependency.
Now this dependency chain containing multiple classes are verified two times - one is while compilation ( one level of dependency is verified) & other one is while execution ( whole dependency chain is verified ).
Now suppose there is public class (class A) whose source file name is something different from class name. Now if some other class (say class B) depends on it , then while compilation of class B , java compiler will surely check where that class A is located & for that compiler has to go thru all the packages in search of class A ,which is time consuming.
Now suppose in the same scenario we give source file name of class A as A.java , then while compiling class B , compiler will search for class A & for that it only need to find source file whose name is A.java , so it doesn't need to go thru all packages ( which may contain multiple classes) it will now only search that package in which a source file A.java is present.
So from compilation time , performance point if view one source file should have one public class.
It enables a more efficient lookup of source (.java) and compiled (.class) files during compilation (import directive) and a more efficient classloading during execution. The idea being: if you know the name of a class, you know where it should be found for each classpath entry. No indexing required.
I think that this may be a possible reason.
There can be only one public class in a java file because the name of java file is same as the name of public class.And obviously we can't have a file with two different names.
It is how it has been designed and I am not sure if the reason is documented. But here is a good reason on why it is done that way. Let's assume we have two public classes Y & Z in a file named Y.java. Now, let's assume a different class X is using Z. Now, when we compile X, the compiler first tries to locate Z.class and if it cannot find it, then it tries to locate Z.java so that it can compile it automatically. But, since we only have Y.java, the class Z cannot be located and hence we get a compilation error. So, we do need to place them in separate files.
Class A{
}
public Class B{
}
So this is correct becoz A is not public and compiler will not confuse that which class compiler should execute.
public Class A{
}
public Class B{
}
So this is incorrect becoz here compiler get confused which class should execute becoz both are public.

When java class X required to be placed into a file named X.java?

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;

Why only 1 public class in Java file

In any Java file, why can we have only one public class whose name is same as the Java file name?
It forces all Java code to be organized in a certain way, which in the long run helps improve code readability.
The Java designers chose a strict approach that enforces their idea of good design practices, and this is part of that theme. Contrast that with the anything-goes attitude in Perl.
According to this source, it is for efficient compilation :
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.
The same applies also for imports of source files in IDEs. Another reason would be reasonable source sizes.
These are the rules. Although it is not quite true. You can define internal classes inside you "main" class like this:
public class A {
public class B {
...
}
}
Courtesy of Dr Heinz Kabutz and his excellent newsletter....
Why is each public class in a separate
file?
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.
We can have only one top level public either class or interface in any java compilation unit ( .java source file ).
But there can be any number of default classes/interfaces per src file.
why:
JLS leaves the option to the java compiler. And most of the compiler implementations force to have file name same as :
(1) the public class/interface name
(2) if there is a main method and no public class then any name
(3) If there is main method and public class then main method should be in that public class
(4) if there is no public class and no main method then any valid name which may or may not be matching with the class/interface names in the file.
From (2): If two public classes allowed, we should give the file two names which is terribly meaningless to file system.
From (3): If two public classes allowed, we should have two main methods which is terribly meaningless to java
Hence a Java source file can have one only public class.
I think the above 4 points are forced by compiler to make the job of both compiler and jvm to find particular java source file or class file easy-so-quick for the compilation/loading/linking. Java has such built in restrictions which developers should follow to have better programming.
Source: My readings and understanding.
To understand the basic reason behind these restrictions, let's suppose compiler doesn't give compile error for not naming file name same as public class name.
Suppose there is a package A
A
/ \
file1.java file2.java
file1.java
package A;
class file1
{
public static void main(String args[])
{
}
}
public class file3
{
public static void main(String args[])
{
}
}
Now as we know that a public class can also be accessed outside the package, now it will become the responsibility of a developer to make it accessible to the outside world. Let's see how:
Suppose package A is containing only Java files(no class files) and some class outside the package A tries to access public class file3, compiler will first try to find file3.class ( not available ), then it will try to find file3.java ( not available ). So even though file3 class is public in nature, it is not visible to the outside world. So if a compiler puts the restriction that if a file is containing public class, it should be named same as the public class name, then above issue can be resolved and the developer won't have to think of exposing public class to the outside world.
Compiler also puts the restriction that there should be atmost one public class per Java file, so that every public class can be accessed by the outside world.
Java utilizes this convention to find class/interface bytecode by starting at the classpath and scanning for the package hierarchy in subdirectories. Filesystem representation of this hierarchy also enforces some basic rules.
Any two Java classes or interfaces
in the same package cannot have the
same name. File names would
conflict.
Any two Java packages in
the same parent package could not
have the same name. Folder paths
would conflict.
A class has visibility to all classes in the same package without modification
to the classpath.
To have an understanding between the compiler and the programmer.It is a rule that the source code must have atmost one public class and that class must contain the main function.So without any confusion/restriction the compiler can access(public) the class and name the class name to the class file.Also since this class contains the main(), executing the class file will give correct flow
Public modifier with a class is exposed to the world that means any other class which is outside of the package can also access it to resolve dependency.
Now this dependency chain containing multiple classes are verified two times - one is while compilation ( one level of dependency is verified) & other one is while execution ( whole dependency chain is verified ).
Now suppose there is public class (class A) whose source file name is something different from class name. Now if some other class (say class B) depends on it , then while compilation of class B , java compiler will surely check where that class A is located & for that compiler has to go thru all the packages in search of class A ,which is time consuming.
Now suppose in the same scenario we give source file name of class A as A.java , then while compiling class B , compiler will search for class A & for that it only need to find source file whose name is A.java , so it doesn't need to go thru all packages ( which may contain multiple classes) it will now only search that package in which a source file A.java is present.
So from compilation time , performance point if view one source file should have one public class.
It enables a more efficient lookup of source (.java) and compiled (.class) files during compilation (import directive) and a more efficient classloading during execution. The idea being: if you know the name of a class, you know where it should be found for each classpath entry. No indexing required.
I think that this may be a possible reason.
There can be only one public class in a java file because the name of java file is same as the name of public class.And obviously we can't have a file with two different names.
It is how it has been designed and I am not sure if the reason is documented. But here is a good reason on why it is done that way. Let's assume we have two public classes Y & Z in a file named Y.java. Now, let's assume a different class X is using Z. Now, when we compile X, the compiler first tries to locate Z.class and if it cannot find it, then it tries to locate Z.java so that it can compile it automatically. But, since we only have Y.java, the class Z cannot be located and hence we get a compilation error. So, we do need to place them in separate files.
Class A{
}
public Class B{
}
So this is correct becoz A is not public and compiler will not confuse that which class compiler should execute.
public Class A{
}
public Class B{
}
So this is incorrect becoz here compiler get confused which class should execute becoz both are public.

Categories

Resources