we can declare only one public file in a source file and file name must match the public class name
is there any reason to this restriction....
Well, it's not a compulsory restriction in Java. It's one that the Java Language Specification mentions as an option. From 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.
But basically it's there to encourage you to make your source easier to navigate. If you know the name of a public class, it's usually pretty easy to find the source code for it.
Yes, it's the specification of the Java language...
The reason is, that this is the convention. Also the classloader expects a class in a specific file. You can write your own classloader to avoid this restriction, but there is no good reason to do this. Everyone looking on your code will get confused. ;)
However, you can create "multiple" classes in one file by creating inner classes. I know, its not the same, but usually you should think about more important things than why there is only one class in one file.
It's there so that the compiler can find the source code of dependent classes.
#saravanan. I have executed some simple programs which show that just a single default class(ie a class with no access specifier) having the main method works well in java when u save the file name with the default class name.
To add on to the reason of naming the file with public class name, in a document I went through the details into this state that the JVM looks for the public class (since no restrictions and can be accessible from any where) and also looks for public static void main() in the public class .
This public class acts as the initial class from where the JVM instance for the java application( program) is begun.So when u provide more than one public class in a program the compiler itself stops you by throwing an error.
This is because later you can't confuse the JVM as to which class to be its initial class because only one public class with the public static void main(String args[]) is the initial class for JVM.
HOPE I have helped you in understanding JAVA programming naming better.
simply remember only that class would be public which has the main other files dont be public
Related
First, please take a look at the following code.
package test;
class c_hi {
public static void method_hi(){
System.out.println("hi");
}
}
class c_bye {
public void method_hi(){
System.out.println("bye");
}
}
public class test {
public static void main(String[] args){
c_hi.method_hi();
c_bye c_hi = new c_bye();
c_hi.method_hi();
}
}
I've been using Java for several years, and I understand the general rules for naming class names and variable names.
However, I got a very interesting question. If the name of the reference variable of the "c_bye" class is "c_hi" (a class named "c_hi" already exists),
I can't access "method_hi" of class "c_hi" from inside class "test".
Of course, I know that this problem can be prevented or circumvented by not overlapping class names and variable names, package separation, and FQCN etc.
Apart from the usual way of avoiding duplicate names, is there a more grammatical way to solve this problem? Please tell me your opinion. (Or, I would appreciate any documentation, links, or other questions on Stack Overflow that I can refer to.)
This code works the same for both JDK versions 8 and 15.
This should "fix" the problem:
test.c_hi.method_hi(); // Using the fully qualified class name.
However, the correct solution would be:
Don't ignore Java style rules. The rules say Java method name should start with a lowercase letter, and a class name should start with an uppercase letter.
Avoid using the same name for a static method and an instance method.
(You actually can't do this in some cases. For example, if c_bye extends c_hi then you get a compilation error about an instance method not being allowed to override a static method.)
Don't attempt to call a static method using an instance variable. Use the class name. (Which cannot be confused with a variable name if you follow the style rules!)
It is legal Java to do that, but it tends to fool the reader into thinking that the method is an instance method and/or that there is dynamic dispatching of static methods happening.
For what it is worth the rules for name resolution are fully specified in the JLS. (See this answer for the JLS text and reference.) The implications are a bit complicated for edge cases like the one you are talking about, but the name resolution rules are not Java version specific, AFAIK.
Java is not designed to "play nice" when people willfully ignore the style rules.
The Java Language Specification deals with that. here the first paragraph of JLS 6.4.2 Obscuring:
A simple name may occur in contexts where it may potentially be interpreted as the name of a variable, a type, or a package. In these situations, the rules of §6.5.2 specify that a variable will be chosen in preference to a type, and that a type will be chosen in preference to a package. Thus, it is may sometimes be impossible to refer to a type or package via its simple name, even though its declaration is in scope and not shadowed. We say that such a declaration is obscured.
As you already mentioned, FQN must be used instead of the simple name.
I know that the name of the public class declared in a java file must be same as its file name. But I wonder how this is not giving me a compilation error, rather it is running successfully.
class Foo //<-- this can be any name...
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
I know that the default access is package private. For the above program, the class name and the file name need not be same. It is executing correctly, rather than a compiler error.
Can anyone throw some light? Thank you.
EDIT:
Now I get it! But another question struck me. What happens when there are two such classes in the same file?
Well, I thought a .class file will be generated out of the class that has implemented main method. There wasn't any compilation error, but to my surprise there wasn't any .class file generated either. Why is that so?
Yes, that's absolutely fine. Even for public classes, this is a compiler-specific optional restriction.
From section 7.6 of the JLS:
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).
Note the second bullet point - when your class isn't public, this restriction isn't applicable.
EDIT: From the updated question...
What happens when there are two such classes in the same file?
Class files are generated based on class names. The presence of a main method is completely irrelevant to this, as is the original source file name. A class file certainly should have been generated if compilation succeeded. Without sample code to reproduce the problem, we can't tell what happened really.
Your observation is correct. If the class is not public, the name of the class does not need to match the file name. When you don't have a public class in your file, you can name your file as you like.
If you say have a source file Test003.java and you define in it
two non-public classes AAA and BBB, there are no compilation
errors and two class files are generated: AAA.class and BBB.class.
So all is good.
01/20/2014 06:27 AM 238 AAA.class
01/20/2014 06:27 AM 238 BBB.class
As the title already says, I would like to know if it is somehow possible to give a class a different filename in Java with Eclipse ?
Edit: I only want to know if its possible with Eclipse. If you don't know the answer, please resist the urge to respond with condescending answers.
Edit2: It's hilarious what kind of responses I get here. All I wanted to know is if it is possible to have a class with a different filename (and I meant the public class) and nothing else. I thought this is the kind of forum to ask these questions, but the second response I got was already an insult. Is this some kind of taboo question or what is going on ?
Your filename should always match your class name, end of story. Although the JLS doesn't specifically state that it HAS to be done, they leave it up to the implementation of the compiler to make that decision. I'm pretty sure most (if not all) will not allow you to differ from that standard.
The JLS states:
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.
So while you may be able to rename the file itself in eclipse, or your filesystem - you will more than likely hit a compile error.
I don't know why you would like to do that but it is possible if you compile files from command line with help of symbolic links.
Let's say you have class YourClass saved in a file OtherName.java. If you create a symbolic link to that file like this:
UNIX system: (for sure doesn't work on Solaris - other system aren't verified)
ln -s OtherName.java YourClass.java
javac YourClass.java
WINDOWS system: (works on Windows Vista/2008+)
mklink YourClass.java OtherName.java
javac YourClass.java
the compiler finds the type and compilation works...
This solution is not verified on Unix systems, but works for sure on Windows Vista/2008+..
What does Eclipse have with the naming conventions or rules of Java Programming Language?
Eclipse is just an IDE, and if you are working with Java you have to obey its rules.
Lets's say you have X.java file. This means that you can have only one public / abstract / final class named X in this file. There is no limitation on the number of classes and their names and also their nesting relations with each other as far as no more than one class holds the filename as its class name. If a class takes the filename, then it should have one or more of these modifiers: public, static, final. That's the story.
No, the Java a public class and the file must have the same name.
If you try to give the class another name, the compiler will fail with
class YourClass is public, should be declared in a file named YourClass.java
But you can declare additional private classes in a file which contains a public class.
below are the situations where you can have different class name.
1.class is not public class and exists in a java file where atleast one public class is defined
class notpublic{
}
public class PublicClass {
}
2.Class is a InnerClass .
public class PublicClass {
class InnerClass{
}
}
I have file TestClass.java
package com.fido.android.sample.dsm.SoftPin.Core;
public class TestClass
{
public int mValue1;
public String mValue2;
}
Now in this file (TestClass.java) I want to declare one more class, but when I write for example:
public class SecondClass
{
// Class members goes here.
}
Compiler do not allow me to do that, if I remove public everything is Okay, but I can use SecondClass only in the TestClass.java, I can't write
SecondClass sc = new SecondClass();
out of TestClass.java class. Now I want to know if there is a way to do such thing, to have two classes in the same file and to use them from everywhere (not inner classes).
Question is: Why would you want to declare a second public class within the same Java class file? It is a rule in Java that each public class must be declared in a single class file - except for nested classes like Graham Borland pointed out.
Short answer: You can't.
That's how Java works.
You can only declare a single public class per file, with the class name the same as the file name.
You can use inner-classing as Graham suggested, or better yet, move the second class in a new file.
If you have SecondClass inside TestClass (i.e. nested inside the class definition), with public visibility, then you can refer to TestClass.SecondClass everywhere.
No, you can't, if the compiler chooses to enforce this rule from the Java Language Specification, section 7.6:
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.
So this is optional in that it's still "legal Java" to include more than one public top-level class in a single source file - but it's also valid for the compiler to reject it. In practice, I think every file-based Java compiler I've ever used enforces this rule.
Now you could try to find a different compiler if you really wanted, but there's a reason for this: Java programmers are used to finding the source code for a public top-level type (and usually any top-level type) in a source file with the same name.
To ask a return question provocatively: why do you want to make your source code hard to navigate?
You cannot.
What you can do is to have inner classes.
According to java conventions, A public class should be created in a separate file having same name as of class name.
So you cannot make two public classes in same file.
you can try either removing public from one class or making inner class.
Since public classes must have the same name as the source file , there can only one pulbic class inside a java file.
The error I get is exactly the error specified in:
http://java.syntaxerrors.info/index.php?title=Own_file
(class must be defined in its own file.)
but they don't give a solution there how to solve it, other than just having a file per public class.
Thank you, eclipse, for making me do this, but this is not mandatory in Java. Is there a way to get rid of this error?
Yes, it is mandatory in Java. Each public class has to be in a separate file named exactly the same way as the class.
See this question about it. The Java language specification writes that this is not 100% mandatory for compilers, but they usually do that. And since it is a good thing, and is noted in the spec, all compilers do 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 you want to have multiple classes in the same file, that's a different story. You can do it in two ways:
declare them as package-private classes with class Foo after the body of the main class. You can have any number of non-public classes in the same file
declare them as static inner classes: public static class InnerFoo inside the main class body. That way they will be visible to other classes by FooClass.InnerFoo