Is it bad practice to overload your main method? - java

I am aware of the limitations of it, but if I only intend on having a class, say, for example
public class GUIWindow
{
static JFrame theGUI = new JFrame();
public static void main(String[] args)
{
theGUI.setSize(900, 600);
theGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theGUI.setLocationRelativeTo(null);
}
public static void main(Object obj)
{
String[] array = new String[1];
main(array);
theGUI.setTitle(obj.getClass().getName());
}
public static void main()
{
String[] array = new String[1];
main(array);
theGUI.setTitle(null);
}
}
that I can call to create a default GUI window of a certain size for the testing of multiple applications is it an alright thing to do?

public static void main(Sting[] args) is the only entry point JVM would recognize.
You could add other overloads (not overrides) of main, but these will lack that special meaning. It feels inconsistent and thus misleading.
If you want polymorphic instantiation of your main class, just add an independent family of methods for this. Don't mix it up with one predefined special method.

The main method public static void main(String args[]) should be used to set up your program and verify that the incoming arguments to your program are valid. Anything else is usually considered bad practice. This includes "overloading" your main method.
That being said, if you are just doing toy examples, or testing, do whatever you want in your main methods.

Related

Java static instance VS get-method

I've been thinking about the difference between these code snippets. I understand that you can not set instance field if you are using getInstance (Second option below), but is there other differences?
public class MainClass {
public static MainClass instance;
public static void main(String[] args) {
instance = new MainClass();
}
public void HelloWorld() {
System.out.println("This is a test!");
}
}
VS
public class MainClass {
private static MainClass instance;
public static void main(String[] args) {
instance = new MainClass();
}
public MainClass getInstance() {
return instance;
}
public void HelloWorld() {
System.out.println("This is a test!");
}
}
What is the difference between using "MainClass.instance.HelloWorld();" (First) or "MainClass.getInstance().HelloWorld();" (Second)
TLDR: Which one, and why? What is the difference?
Thanks! :)
In the first example, you have declared instance as public making it vulnerable to accidental changes and therefore it is not recommended.
In the second example, you have declared instance as private making it invisible outside the class and thus ensuring that if required, it can be changed only through a public mutator/setter where you can put the desired logic how you want it to be changed.
Scalability
The difference is somewhere down the line if your program has many calls to the instance, and you want to change where the instance comes from or perform an additional action while retrieving the instance, you can modify the getInstance() method, instead of adding code in every location where you used instance.
Public
Current code is vulnerable by outsider who can change your instance with new one or even their own by subclassing. If you do not have need to change instance after first init then make it final and then public is good.
private
Saves you from above problem. Gives you more control to change instance if needed.

How is the Static method(main) able to grab hold of non static method(constructor) and execute it?

Seems like a very basic query but I was pondering how the static method main() below is able to execute a non static method(the constructor obviously) from it using the new keyword. Though I understand that new brings onto the table a few other things as well but how should I convince myself that this isn't an exception to the rule that static and non static methods can't using non static and static context respectively?
Below is the sample code:
public class ConstructorTest {
ConstructorTest(String str)
{
System.out.println("Constructor Printing "+str);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ConstructorTest cnst=new ConstructorTest("here");
}
}
The above code actually prints --> Constructor Printing here
or in other words executing the body of a Non static method from a Static method?
Any plausible explanations are welcome.
The Java Tutorial states that
[...] Constructors are not members.
Therefore, there is no problem in calling them, since they are not bound to instances of your class. This would not make sense - hence, you cannot do the following:
Thing thing = new Thing();
Thing anotherThing = thing.Thing();
A constructor is not a method, so you cannot apply "method logic" to them.
In case you want to know more, the whole instantiation process is very well documented in the JLS. See 12.5. Creation of New Class Instances.
Actually constructor is compiled into the static method, this is how JVM internally creates instances of classes.
You are executing non-static code, but you are not doing it in a static context.
for instance:
public class C1{
private int x;
public String do(){ System.out.println("x = " + x);}
public static void main(String[] args){
do();
}
}
This can not work, since do is an instance method, which might run code that is specific to the instance. So, how would the VM know which instance to use, or what value x should have?
Now, to first use a constructor, which is possible from any context:
public class C1{
private int x;
public String do(){ System.out.println("x = " + x);}
public static void main(String[] args){
C1 t = new C1();
t.do();
}
}
Here, even though you are calling the method from within a static method, you are using it through an instance, so not in a static context.
ConstructorTest is not a method.
its an constructor,and you can use the constructor for initialize class property.
you can also initialize the static variable from the constructor like that :-
public class XYZ
{
static int i=0;
public XYZ() {
i=1;//not an compile time error
}
public static void doSome(){}
public static void main(String[] args) {
}
}
On a formal language level you should read the line
ConstructorTest cnst = new ConstructorTest("here")
as a class instance creation expression. As a matter of fact, this is not a call to a constructor or any other method.
The instance creation does many steps, like allocating memory for the new object, initializing the fields, calling constructors and initializer blocks. See JLS §12.5 for a detailed step-by-step description. Thus being said, the constructor invocation is only a part of the instance creation.
Additionally, you might see constructors as being static parts of the class. In fact, constructor declaration are not members (see JLS §8.8) and thus they are not overridable (as static methods also). Beware: This is only half true. When being inside the constructor you already have the instance created, and you are able to call other instance methods and/or access instance fields.

what is wrong with this code public class Hello { public static void main() { System.out.println("Doesn't execute");

I typed this code into Eclipse
public class Hello
{
public static void main()
{
System.out.println("Doesn't execute");
}
// .....
}
When I press run it says that it does not contain a main type.
I don't know what I'm doing wrong , and I am new to java.
It should be:
public static void main(String[] args)
This is what your code should look like:
public class Hello {
public static void main(String[] args) {
System.out.println("Doesn't execute");
}
}
Notice the closing parenthesis, also I have properly changed your main method.
Here's another hint:
When you create a new Java class in Eclipse, there is an option to auto-generate the main method stub for you (this option would have fixed your error without you even knowing).
It is the first checked checkbox in the following screenshot.
main method without the string array arguments is not the method that JVM looks for to start the execution of a class.
After completion of the initialization for a class (during which other consequential loading, linking, and initializing may have occurred), the method main of class is invoked.
The method main must be declared public, static, and void. It must specify a formal parameter whose declared type is array of String. Therefore, either of the following declarations is acceptable:
public static void main(String[] args)
public static void main(String... args)
Read more about JVM startup, loading, linking and intilization of class here:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.1.4

I have trouble with static main method and inputting non-static values [duplicate]

This question already has answers here:
Cannot make a static reference to the non-static method
(8 answers)
Closed 8 years ago.
I am working on a school project, building a Chess-game. I have my board which creates the arrays and fill the board with pieces.
Now, I want to instantiate a new board in a game class and use the console to input player moves. To make this as simple as possible, my trouble is inputting non-static variables.
For instance:
public class Test extends ConsoleProgram{
public static double a1;
public static void main(String[] args) {
a1 = readLine("Insert value of a1");
System.out.println(a1);
}
}
more info on readLine() here
As you probably see, this won't work as java is complaining cannot make static reference to the non-static method readLine()
How do I work around this? Maybe there is something really basic I just don't understand..
As always, thank you very much for your quick and insightful answers!
If you don't want to make your readLine method static, do a call on an instance:
public static void main(String[] args) {
Test me = new Test();
a1 = me.readLine("Insert value of a1");
System.out.println(a1);
}
either define readline as static or
make an object of class and then call the method, new Test().readline();
Make readLine()` as static.Then you can access
If you make method as static then you can use that in main() method
otherwise create an object for Test class then use it
The simplest work around I've found is simply instantiate the object in the main method, and call the relevant methods from the constructor.
public static void main(String[] args)
{
new ClassThing();
}
public ClassThing()
{
// Make your method calls here.
}
This means you can access instance methods, and you don't need to call everything from a static context.
Create Test instance in main and call it's instance method.
public class Test extends ConsoleProgram {
public double a1;
public void run() {
a1 = readLine("Insert value of a1");
System.out.println(a1);
}
public static void main(String[] args) {
Test main = new Test();
main.run();
}
}
You should instantiate an object of the class that has the method readLine().
If that class' name is i.e. Reader you should do something like:
Reader r= new Reader();
a1 = r.readLine("Insert...");`

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