Can anyone please explain the answer to the following question:
Given a correctly compiled class whose source code is:
package com.sun.test;
public class Commander {
public static void main(String[] args) {
}
}
Assume that the class file is located in /foo/com/sun/test/, the current directory is /foo/, and that the classpath contains "." (current directory). Which command line correctly runs Commander?
A. java Commander
B. java com.sun.test.Commander
C. java com/sun/test/Commander
D. java -cp com.sun.test Commander
E. java -cp com/sun/test Commander
And the best answer would be B. C also works on some platforms but is not recommended and is very uncommon (at least, I've not seen it in over 10 years programming Java).
EDIT
A common misconception with beginners in Java is that a class name is something like "MyClass". But that is not accurate; the nomenclature "MyClass" as seen in the declaration class MyClass is really a convenience for the programmer which the compiler combines with the package declaration to create what Java refers to as a qualified class name, which all class names really are to the runtime. (In C#, they use namespaces for this).
This becomes quite evident in many cases such as stack traces and method signatures which always contain, for example, java.lang.String. Because "String" is just a short form that is resolved to java.lang.String. You can prove this by making your own String in your own package... but beware doing so will require that you explicitly use java.lang.String or my.package.String everywhere that both packages or classes are imported.
Once you assimilate the fact that all class names are fully qualified, and that the compiler helps you avoid tedious work by using imports to resolve short forms to fully qualified forms, things become clearer.
It should then be evident why:
java -cp com/sun/test Commander
doesn't work. The cp option puts the directory ./com/sun/test (relative to the current directory) on the class path, but there is no class named Commander... it's com.sun.test.Commander. This implies two things: (a) the command line requires com.sun.test.Commander and (b) the classpath must contain an entry for the directory which contains "com" in order to resolve this class since a class named x.y.MyClass must be in x/y relative to some classpath element.
PS: You should not be using com.sun as a package name unless you are employed by Sun, since the domain name sun.com belongs to Sun. This convention exists to avoid class packaging and naming collisions.
PPS: There is such a thing as the default package, which is "specified" by omitting the package declaration -- but it should almost never be used. The one legitimate place I have found is with a self-contained "Launcher/Classloader" where it is desired to be able to do:
java -cp . Launcher com.xxx.yyy.TargetApp
with Launcher.class in the current directory... and that is only because JAR files are held locked while the app is running while class files are not, which means that Launcher.class can self-update, while Launcher.jar cannot.
Assuming CLASSPATH environment variable is not set (and thus current working directory is in the classpath by default), the answers are the following:
A. Does not work, there is no Commander class in the default package
B. This one works
C. This one works also, but B is preferred
D. Class path is foo/com.sun.test where there is no Commander class in the default package
E. Class path is foo/com/sun/test where there is no Commander class in the default package
A. Not working, as Java will not found the Commander class
B. Will work, as Java will not found the com.sun.test.Commander class
C. Will work, at least on a Windows plateform. That's why you must use . instead of /.
D and E. They will not work because we still ask Java to search for the class Commander and not com.sun.test.Commander
Related
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.
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.
The following statements seem to disturbingly function:
robert#neghvar:~/tmp> cat org/foo/Bar.java
public class Bar {
}
robert#neghvar:~/tmp> javac org/foo/Bar.java
robert#neghvar:~/tmp> javap org.foo.Bar
Compiled from "Bar.java"
public class org.something.Bar extends java.lang.Object{
public org.something.Bar();
}
Although the Bar class file is in the org/foo directory and declares the org.something package, the compiler does not complain. I was under the impression that java mandated a directory hierarchy which follows the package name. Was I mistaken? If so, what are the consequences of mixing up package names?
The source directory structure is not required to follow package naming (even though it almost always does by convention.)
I think the Sun/Oracle javac,javap,java,etc. tools (and all other Java implementations that I know of) are what mandate the subdirectory per package name component rule (along with the default class loaders). I couldn't find anything authoritative, but it doesn't seem to be a requirement of the Java language specification:
http://java.sun.com/docs/books/jls/third_edition/html/packages.html
It's purely convention. The compiler will use the package names.
Having said that, it's not usually a good idea to break with this convention. It'll cause inconsistency (the classes generated will be in directories following the package) and some confusion!
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 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
{
}
:-)