Briefly, main function behavior - multiple classes in one source file - java

Given a Java source file named as TestMainFunction.java
1.) As most of us would know, a Java file name must be the class name which contains the main function
See the below simple code (in a single file named as mentioned above) which executes perfectly and prints ClassOne.
public class TestMainFunction {}
class ClassOne {
public static void main(String[] a) {
System.out.println("ClassOne");
}
}
2.) When there is more than one class with a main function in a single file, Eclipse prompts the user to choose the class to run.
See the below simple code (single file named as mentioned above) which executes perfectly and prints the class name as we have chosen from the Eclipse promt.
public class TestMainFunction {
public static void main(String[] a) {
System.out.println("TestMainFunction");
}
}
class ClassOne {
public static void main(String[] a) {
System.out.println("ClassOne");
}
}
class ClassTwo {
public static void main(String[] a) {
System.out.println("ClassTwo");
}
}
All the above will work as I mentioned. It will create separate .class file for every class. The same behavior applies even when using inner classes.
But what exactly is happening here? How does Eclipse know which class to launch when multiple classes are present in one source file? Can any one explain it? Explaining this would be greatly appreciated.

As most of you would know, a Java file name must be the class name
which contains the main function
This is incorrect, and I believe the source of your confusion. A Java source file is only allowed to have one public class, and it must have the same name (minus the extension) as it's containing file. A given Java source file though, may contain as many non-public class files as desired, with the only constraint being that their names are valid. Note that you can have a class with the same name as its containing source file (minus the extension) that is not public! Also note that it's generally considered bad practice to have multiple top-level (non-nested) classes in a single Java source file.
The second assumption you may have is that only one class in a source file is allowed to have a main function. This is simply untrue. You can add a main function to every single one of your class files - the only one that matters is the one you specify to the JVM when your application is being launched.
So given your scenario - a source file with multiple class files (one of them public), where each class has a main method, the following applies:
When you invoke the Run command in Eclipse on this file, Eclipse will detect that there is more than one eligible class to be run, and will prompt you to select one of those class. It will then build a 'Run Profile' for the selected class, that launches just that class. You can actually see the profile Eclipse builds via the Run->Debug Configurations menu.
When compiling this source file externally, it will generate multiple .class files (not just one). The classes had no relation to each other save being in the same source file, and you would explicitly select the .class you want to launch in the JVM.
i.e:
java TestMainFunction
java ClassOne
java ClassTwo

Related

Make two Java file separate from each other in one folder [duplicate]

This question already has answers here:
File name and class name different in java
(1 answer)
Can I compile a java file with a different name than the class?
(21 answers)
Closed 6 months ago.
I usually do my homework on a Java file and submit the file to complete my task, so I separate each file and contain them all in one folder. Sometimes there are two works that have the same class name, but different work. If I let two files have the same class name, they won't run properly. (I'm using vscode)
For example:
File1.java
public class File1{
public static void main(String[] args) {
...
}
}
class Fraction {...}
File2.java
public class File2{
public static void main(String[] args) {
...
}
}
class Fraction {...} //this is not the same with File1.java
Can I do anything keep two class names the same in two different files in one folder?
Do not define the same class name (whether the same script or not) in the same folder. This throws an error many times.
Largely all filenames are Operating System rules dependent.
Java source code files must be named by the main class name of the code in the file. After compiling, a file of the same name but different extension, extension of .class will be there. Dependent how the compiler command line flags are set it will simply by default overwrite any old version .class file.
type javac -h on the shell or prompt for compile command flags info.

Strange exception when implementing interface

I have Exception in thread "main" java.lang.NoClassDefFoundError: A (wrong name: a) and I dont't have any idea what this can caused by
public class Test
{
public static void main(String[] args)
{
new B();
}
}
interface a { }
class A implements a { }
class B extends A { }
Edit: in online compiler https://www.onlinegdb.com/online_java_compiler it compiles
When Java compiles your source code, it creates multiple .class files. For example, it creates Test.class for public class Test, a.class for interface a, and A.class for class A. The problem here is that file names in some operating systems are case-insensitive. This means that the operating system sees a.class and A.class as the same file so one will overwrite the other.
The online compiler most likely treats these file names as different due to case-sensitivity.
The solution here is to use different names so that you avoid these name collisions at the operating system level.
The established Java convention is to start all class and interface names with an upper case letter. If you follow this convention, then you will avoid this problem.
If you run javac path/to/your/file, you should see the list of .classfiles created by the java compiler in that dir. The problem with your approach is you have duplicate names for the interface and the class i.e A (case insensitive) and as a result only one .class gets created. Try again by changing the name of either interface or class and your problem should go away.

How to reference Java Object classes in separate folders

I have a Main class. I also have another class I have made (call it the "Runner" class). I would like to, however, have more Runner classes (the difference between them being modifications to each respective Runner class by other people). Would it be possible to have each Runner class in separate folders and have the folders in the same directory as the Main class, and then reference the Runner objects in the Main class as if they were a class in the same directory as the Main class?
Yes, this question strikes me like you're viewing Java like php or ruby, etc which isn't quite accurate. With Java, each class has what's called a "Fully Qualified Name" which is derived from the folder it's stored in (like Python). Because Java is compiled, you tell the compiler where to find the code needed to compile a java file, rather than putting a reference to those needed files in the top of the file (like a require statement in php) which would be an instruction to the interpreter.
Say for instance you had a structure like this:
src/
Main.java
/runner1
SomeRunner.java
/runner2
SomeOtherRunner.java
Main.java
public class Main{
public static void main(String[] args){
//use SomeRunner
runner1.SomeRunner.run();
//use SomeOtherRunner
runner2.SomeOtherRunner.run();
}
}
SomeRunner.java
package runner1;
public class SomeRunner{
public void run(){ ... }
}
SomeOtherRunner.java
package runner2;
public class SomeOtherRunner{
public void run(){ ... }
}
Alternatively, you can use imports:
Main.java
import runner1.SomeRunner;
import runner2.SomeOtherRunner;
public class Main{
public static void main(String[] args){
//use SomeRunner
SomeRunner.run();
//use SomeOtherRunner
SomeOtherRunner.run();
}
}
In this example, I chose arbitrary package names (runner1 and runner) which is technically fine. However, best practices state that your package names should be the reverse domain name of your project (i.e. com.myproject) to avoid collisions with other libraries etc. You can read more about that here. When you compile your Main class, you will need to supply the SomeRunner and SomeOtherRunner files to the compiler so it knows where to find them.

Java class files with $ symbol

I have a class with name StreamGo. It has 4 more class files with the same name like - StreamGo$1, StreamGo$2 etc. All these class files have different set of code. How do I merge them? And why does these class files get created with $1 and $2 etc?
Please help.
Those class files are automatically generated for anonymous inner classes defined inside StreamGo.java. For example, if you have something like this:
final Runnable runnable = new Runnable() {
public void run() {
// ...
}
};
then you'll have a StreamGo$1.class for the anonymous implementation of Runnable that you've defined here.
Named nested classes will do much the same, except that you'll get their names instead of the number part.
These are compiler-generated classes for anonymous classes that you create in your class.
Since Java bytecode requires a separate .class file for each class, you cannot merge them.
You may want to put all of your .class files into a .jar.
If there is an inner class in your java file, then the compiler will create a class file with name of Java file along with $. You cannot combine these class files. But if you are copying these class files, make sure you are copying all the class files starting with $ symbol! else it will not work

How to run Java .class file from another .class file? (java newb)

I've been running different individual Java .java files in the Netbeans IDE by right-clicking the .java files themselves in the Project Explorer of Netbeans (the portion normally at the upper left part of Netbeans).
However, i've been googling on how to make a class file run another class file using code, but to no avail.
I have a project named "loadanotherfile" with 2 files, namely: Loadanotherfile.java and otherfile.java
I'm trying to make Loadanotherfile.java run otherfile.java, but I'm not exactly sure how. I read about Classloaders and URLClassloaders however these methods don't seem suitable for my purpose of running another .java file.
Below is the code of the 2 files i mentioned.
Loadanotherfile.java
package loadanotherfile;
public class Loadanotherfile {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Hello World!");
// TODO code application logic here
}
}
otherfile.java
package loadanotherfile;
public class otherfile {
public static void main(String args[])
{
System.out.println("This is the other file.");
}
}
I have a feeling that the task has something to do with using the "import" syntax (namely something like import loadanotherfile.* but even if my guess is correct, I'm still not sure on how to make my Loadanotherfile.java run otherfile.java using code.
How can I load otherfile.java using Loadanothefile.java?
Cheers
In Loadanotherfile.java
otherfile.main(args);
Compile the two together, and then from Loadanotherfile,
otherfile.main(args);
will do the trick. You don't need to import since you're in the same package. Note the linked tutorial.
I would investigate (however) class instantiation, and creating an instance of a new class to invoke upon. Invoking static methods from static methods isn't very OO.
Try This:
className.main(Args){
}
This works! ive tested it myself.
Check the public void main line. If there IOException and not there then insert
in Loadanotherfile.java
use this
otherfile.main(args);{
}

Categories

Resources