views:

1543

answers:

5

Hi there. I've had quite a long discussion with a friend of mine about the correct and good use of the main method in Java. Basically we have a class like this:

public class AnImporter implements Runnable {
  // some methods, attributes, etc.
}

But where to put the main method? I concider it a good practice to "keep code where it belongs", thus turning the above code into

public class AnImporter implements Runnable {
  public static void main(String [] args){
    // Startup code for Importer App here
  }
  // some methods, attributes, etc.
}

While my buddy argues that "the startup code has nothing to do with the application itself", thus it should be placed in another class, like this:

public class AnImporter implements Runnable {
  // some methods, attributes, etc.
}

public class AnApplication {
  // Nothing here
  public static void main(String [] args){
    AnImporter a = new AnImporter();
    // Startup code here
  }
  // Nothing here
}

Despite the fact that we discussed the matter for some time we both ended up with no conclusion on which way is the better approach in Java. What's your oppinion on this topic? Where and most importantly, why, do you place your main method where you placed it?

+12  A: 

I agree with your friend. You're building up a potentially reusable service in AnImporter that could potentially be used in multiple programs with multiple main's. So, making one main special and embedding it in AnImporter doesn't make much sense.

Clint Miller
+4  A: 

I wouldn't pollute a Runnable class with a main method. The same goes for pretty much any class that does anything in your application. Generally I'll have a class like this:

public class App {
  public static void main(String args[]) {
    Thread t = new Thread(new Blah());
    t.start();
    t.wait();
  }
}

public class Blah implements Runnable {
  public void run() {
    // do normal stuff
  }
}

instead of:

public class Blah implements Runnable {
  public void run() {
    // do normal stuff
  }

  public static void main(String args[]) {
    Thread t = new Thread(new Blah());
    t.start();
    t.wait();
  }
}

It just feels cleaner.

cletus
+7  A: 

I'd probably go with your friend as I'd prefer to get out of the class with the main method as quickly as possible. It helps facilitate testing when you want to test atomically (just the runnable class) or you want to mock things out. The sooner you get out of the main method, the more options you have. If you have one class with the main method and other things in it, it could get messy quickly. (even if it might not seem that way with a simple example such as the one you describe)

But I'd say readability and testability are two good reasons for getting out of the main method (and its encompassing class) ASAP. But hey..that's just me ;)

digiarnie
Yes. I'd also get out of Applet/JApplet as soon as possible.
Tom Hawtin - tackline
+4  A: 

I always separate the main from the rest of the code, for several reasons:

1) A main is, in a way, a hack to let your program start from the command line. Any class that contains it should have a single responsibility: let the program start from the command line. By putting it with your primary runnable, you're polluting the runnable.

2) You could end up having multiple mains (e.g., with certain default parameters, with special modes, etc.)

3) You could end up running the program from a different environment (e.g., an Eclipse plugin or OGSI module, an applet, a web based tool, etc.). In those cases, you would want to restrict access to your main. Putting it with the functionality prevents that.

4) It is sometimes easier to leave your main in the default package to make run time execution faster (e.g., java myblabla par1 par2 par3), but you definitely don't want the rest of your code in the default package.

Uri
+1 for a good answer, but I would say that one should never put any class in the "default" package, not even the one with main.
Software Monkey
I've found that users who are not accustomed to Java or who use command line tools often prefer a C style invocation. They're willing to "absorb the JAR", but it's the long package sequence they dislike.
Uri
+2  A: 

The interface to main (a list of strings) is approximately useless, except for the OS shell.

Your main should have as little code as humanly possible in it.

Indeed, your public class ThisIsMyApp {...} should be nothing more than the OS interface to the real work, which is elsewhere.

S.Lott