Extending the main class in Java - java

I need to extend the functionality of my main class, by overriding some of its methods. I was expecting that the class extending the main class would be able to be run. However, Eclipse doesn't recognize MyLauncher as a runnable class. In the following code, I have a setup() method that is overridden by the subclass. What I want is a way to run the main(..) from the super class but also the setup from the subclass.
// Launcher.java
public class Launcher {
Launcher instance;
public static void main (args[]) {
instance = new Launcher(); // This is likely the problem
instance.setup();
}
public void setup() {
System.out.println("Default agent setup.");
}
}
// MyLauncher.java
public class MyLauncher extends Launcher {
public void setup() {
System.out.println("New agent setup!");
}
}
I accept alternatives to this. I can't add a main method to the subclass, though. The Launcher class is inside an API i'm making, so it can't refer to the class MyLauncher that is using the API.
edit: I think this is to specific to my problem. I decided to search for a new approach. Since I'm working with JDT, I'm going to parse the Launcher and inject the class.

Static methods are not inherited, they're always bound to the class that defines them, and need to be called explicitely.
In you case, the MyLauncher needs a main() method too, and could then delegate to the main() method of Launcher:
public class MyLauncher extends Launcher {
public static void main (String[] args) {
Launcher.main(args);
}
protected void setup() {
System.out.println("New agent setup!");
}
}

Protected methods can not be called from outside. So the MyLauncher.setup() do not override Launcher.setup() and instance.setup(); calls the public method from Class Launcher.

There can only be one main method in your project, that is one entry point to the program. So let's assume you're going to be keeping the main method in the Launcher class.
Your main method signature should be:
public static void main (String args[])
And unless you want the setup() method from the launcher to be called you'd want to do:
instance = new MyLauncher();
That would call the setup() method from MyLauncher.
If you want to call setup() from the Launcher class you need to instantiate the launcher class:
instance = new Launcher();

If you want to be able to run MyLauncher.setup(), the variable must be a MyLauncher. You are initializing and storing a Launcher in the main() function.
If the two classes are in the same package, or Launcher.java imports the MyLauncher class, then the main() function in Launcher should be able to be:
public class Launcher {
Launcher instance;
public static void main(String[] args) {
instance = new MyLauncher();
if(instance instanceof MyLauncher) {
((MyLauncher) instance).setup();
} else
{
instance.setup();
}
}
}

As you say, the fact that you create an instance of Launcher directly in main means that no inheritance is available. Even if you could start MyLauncher easily from Eclipse, within the main method you wouldn't know which type had actually been used to start it. I can't see any easy solution that doesn't involve either creating a main method in each class or providing the class name as a command-line argument. I would probably separate the "running" from anything else:
public class Launcher {
public static void launch(LaunchConfiguration configuration) {
configuration.setup();
...
}
}
public class LaunchConfiguration {
public static void main(String[] args) {
Launcher.launch(new LaunchConfiguration());
}
public void setup() {
}
}
public class MyLaunchConfiguration {
public static void main(String[] args) {
Launcher.launch(new MyLaunchConfiguration());
}
#Override
public void setup() {
}
}

Related

Can we create an object of the class in which main function is defined in Java?

Is it possible to create object of class in which main method resides.I have been searching for this answer but I have been told that it depends on compiler some compiler will allow while others will not.Is that true?
Yes? The main method is just an entry point. The class is like any other, except it has an additional public static method. The main method is static and therefore not part of the instance of the object, but you shouldn't be using the main method anyway except for starting the program.
public class Scratchpad {
public static void main(String[] args) {
Scratchpad scratchpad = new Scratchpad();
scratchpad.someMethod();
}
public Scratchpad() {
}
private void someMethod() {
System.out.println("Non-static method prints");
}
}
Yes, you can create object for the class which has main method. There is no difference in this class and a class which don't have main method with respect to creating objects and using.

Main method empty?

I have a class that implements Runnable, but Eclipse needs a public static void main method in it. Is it ok if the main is completly empty?
public class Launcher implements Runnable{
private String message;
public Launcher(String message) {
this.message= message;
}
public static void main(String[] args) {
}
#Override
public void run() {
//My implementations
}
If you intend Launcher to be the main class of the application, the one you use to start it, the main method is needed and must do whatever should be done to start work.
If not, delete the main method. Eclipse does not require a main method unless you start the application by telling it to run the class. It will optionally generate one when creating a class, but that can be edited out if not needed.
No, the main method is the only method the compiler is searching for when looking where to start. Hence if you're main method is empty, nothing gets executed. At the very least add:
new Launcher("some string").run();
in the main method.

Calling main inside the code

Can we call main() function inside any other function? I tried but did not come up with it.
If we can't call it then why?
Why main() is not like ordinary methods?
Yes why not try something like:
public class Main {
public static void main(String args[]) {
System.out.println("Hello World");
}
}
public class NewMain {
public static void main(String args[]) {
Main.main(args);
}
}
If you run:
java NewMain
the output is:
Hello World
Why main() is not like ordinary methods
Not like ordinary methods in what sense? It is like any other method. I'll try to explain why main looks like this, maybe it'll help you to understand what's going on.
It's void because when it finishes, it doesn't mean that the program finished. If it spawns a new thread it might be that these threads are still running.
It's public because it's called by the JVM, which is outside the scope of the project.
And of course it has to be static because when the JVM calls it, there's no object existing for the class being called.
Nothing special about it when you understand it, so yes.. it can be called like any other static method.
Sure you can, main() is like nay other method in that area.
public class A {
public static void main(String[] args) {
System.out.println("a's main()");
B.main(new String[0]);
}
}
public class B {
public static void main(String[] args) {
System.out.println("B's main()");
}
}
Running A's main() will produce:
a's main()
B's main()
All the actions that you do one other methods can also be done on the main method
The only difference between main method and other methods is that the main method servers as the starting point for running a class
The java command launches a Java application. It does this by starting a Java runtime environment, loading a specified class, and invoking that class's main method.
Except for this reason, there is nothing else.

Issues while trying to get another class

I wrote the getPlugin() method to be able to get the main class from another class.
public class Main extends JavaPlugin {
public Main getPlugin() {
return this;
}
}
But when I try to call it...
public class Arena {
private Main plugin = Main.getPlugin();
}
...Eclipse gives me the following error:
Cannot make a static reference to the non-static method getPlugin() from the type Main
I have used static, but static gives me issue's in a lot of different places, and I've seen that static is usually a bad way of doing stuff. Causes memory leaks and stuff.
I have tried using getters and setters, but those need to be static too?
The code I've been using is very messy and I'd like to find a cleaner way of accessing another class.
If you want to avoid using static methods, you need to pass variables as a parameter to the constructor of objects. In your example, it would work like this:
public class Arena {
private final Main plugin;
public Arena(Plugin plugin) {
this.plugin = plugin;
}
}
And then you can create an Arena from your main plugin class, and pass in this as a parameter:
public class Main extends JavaPlugin {
#Override
public void onEnable() {
Arena arena = new Arena(this);
}
}
This problem occurs because there already is a getPlugin() method in the JavaPlugin superclass, so when you do Main.getPlugin() you are trying to call the non-static one.
Also, your own method is non-static.
Here is how I do.
You have to use a different name and make it static. Also, you should initialize its value on onEnable().
public final class Example extends JavaPlugin {
private static Plugin main;
public static Plugin getMain() {
return main;
}
#Override
public void onEnable() {
main = this;
}
}

Multiple main() methods in java

I was wondering what the effect of creating extra main methods would do to your code.
For example,
public class TestClass {
public static void main (String[] args){
TestClass foo = new TestClass();
}
}
After the program initially starts up, foo will be created and it would have another public main method inside it. Will that cause any errors?
It will cause no errors. Just because you initialize an object, doesn't mean the main method gets executed. Java will only initially call the main method of the class passed to it, like
>java TestClass
However, doing something like:
public class TestClass
{
public static void main (String[] args)
{
TestClass foo = new TestClass();
foo.main(args);
}
}
Or
public class TestClass
{
public TestClass()
{
//This gets executed when you create an instance of TestClass
main(null);
}
public static void main (String[] args)
{
TestClass foo = new TestClass();
}
}
That would cause a StackOverflowError, because you are explicitly calling TestClass's main method, which will then call the main method again, and again, and again, and....
When in doubt, just test it out :-)
The main method is static, which means it belongs to the class rather than the object. So the object won't have another main method inside it at all.
You could call the main method on instances of the object, but if you do that it's literally just another way of calling TestClass.main() (and it's frowned upon by many, including me, to call a static method on an instance of an object anyway.)
If you're referring to multiple main methods in the same program, then this isn't a problem either. The main class is simply specified and its main method is executed to start the program (in the case of a jar file this is the main-class attribute in the manifest file.)
It won't have an additional main-method, as main is static. So it's once per class.
If you have multiple main-methods in your project, you will specify which one to launch when starting your application.
This is perfectly fine. Having multiple main methods doesn't cause any problems. When you first start a Java program, execution begins in some function called main in a class specified by the user or by the .jar file. Once the program has started running, all the other functions called main are essentially ignored or treated like other functions.
After searching for a Java Class with multiple main() methods or in plain words, overloaded main() methods, I came up with an example of my own. Please have a look
public class MultipleMain{
public static void main(String args[]){
main(1);
main('c');
main("MyString");
}
public static void main(int i){
System.out.println("Inside Overloaded main()");
}
public static void main(char i){
System.out.println("Inside Overloaded main()");
}
public static void main(String str){
System.out.println("Inside Overloaded main()");
}
}
I tested this Java Code on JDK 1.7 and works like a charm !
You need "public static void main(String args[])" to start with and then you can call overloaded main methods inside this main and it should work for sure.
Any comments and suggestion are highly appreciated. I am just a novice Java Developer willing to develop my Java skills.
Thanks,
PK
No, you can have any number of main-methods in a project. Since you specify which one you want to use when you launch the program it doesn't cause any conflicts.
You can have only one main method in one class, But you can call one main method to the another explicitly
class Expmain
{
public static void main(String[] ar)
{
System.out.println("main 1");
}
}
class Expmain1
{
public static void main(String[] ar)
{
System.out.println("main 2");
Expmain.main(ar);
}
}
when you run your Java class it will always look for the signature public static void main(String args[]) in the class. So suppose if you invoking by command line argument, it will look for the method Signature in the class and will not invoke other until if u explicitly inoke it by its class name.
class MainMethod1{
public static void main(String[] ags){
System.out.println("Hi main 1");
testig2 y = new testig2();
//in this case MainMethod1 is invoked/.......
// String[] a = new String[10];
// testig2.main(a);
}
}
class MainMethod2{
public static void main(String[] ags){
System.out.println("Hi main 2");
}
}
But when you try the same from eclipse it will ask for which class to compile. Means MainMethod1 or Mainmethod2. So if te class has the exact signature they can be used as individual entry point to start the application.
Coming to your question, If you remove the signature as u did above by changing the argument if main method. It will act as a normal method.
It is all about the execution engine of JVM. Remember, you write >java com.abc.MainClass on cmd prompt.
It explains everything. If main method is not found here it throws a run time Error:Main Method Not Found in class MainClass.
Now if main method is found here, it acts as the first point when Program Counters have to map and start executing the instructions. Referred classes are loaded then, referred methods may be called using the instances created inside. So, main is class specific though one class can have only one main method.
Please note, main method's signature never changes. You can have two overloaded main methods in same class, like
public static void main(String[] args) {}
public static void main() {} //overloaded in same class.
During Static binding, the original main is resolved and identified by execution engine.
Another interesting point to consider is a case where you have two different classes in of java file.
For example, you have Java file with two classes:
public class FirstClassMultiply {
public static void main (String args[]){
System.out.println("Using FirstClassMultiply");
FirstClassMultiply mult = new FirstClassMultiply();
System.out.println("Multiple is :" + mult.multiply(2, 4));
}
public static void main (int i){
System.out.println("Using FirstClassMultiply with integer argument");
FirstClassMultiply mult = new FirstClassMultiply();
System.out.println("Multiply is :" + mult.multiply(2, 5));
}
int multiply(int a, int b) {
return (a * b);
}
}
class SecondClass {
public static void main(String args[]) {
System.out.println("Using SecondClass");
FirstClassMultiply mult = new FirstClassMultiply();
System.out.println("Multiply is :" + mult.multiply(2, 3));
FirstClassMultiply.main(null);
FirstClassMultiply.main(1);
}
}
Compiling it with javac FirstClassMultiply.java will generate two .class files, first one is FirstClassMultiply.class and second one is SecondClass.class
And in order to run it you will need to do it for the generated .class files: java FirstClassMultiply and java SecondClass, not the original filename file.
Please note a couple of additional points:
You will be able to run SecondClass.class although it's class wasn't public in the original file!
FirstClassMultiply overloading of the main method
of is totally fine, but, the only entry point to your prog
will be the main method with String args[] argument.

Categories