首先说明一下,本文使用了几年前的JDK(版本是1.4.2)来演示程序的运行。
1、奇怪的Java程序
源代码
程序的编译和运行
D:>jdk1.4.2binjavac Strange.javaD:>jdk1.4.2binjava StrangeHello, this is Strange.javaI will exit.D:>
可以看到,这个Strange类,没有main方法,完全正常地运行了!
2、分析
我们分析上面的Strange.java程序,发现它有一行代码是我们平常不怎么用的:
System.exit(0);
其实上面的奇怪代码能够正常运行的原因就在这一行代码上,现在我们去掉这一行代码,程序变为:
public class Strange{ static{ System.out.println("Hello, this is Strange.java"); System.out.println("I will exit."); }}
代码编译和运行的情况就变为:
D:>jdk1.4.2binjavac Strange.javaD:>jdk1.4.2binjava StrangeHello, this is Strange.javaI will exit.Exception in thread "main" java.lang.NoSuchMethodError: mainD:>
现在,程序刚开始正常打印两句提示语,但是接着就出现异常了,JDK发现Strange类没有定义main方法!
3、原因解释
根据上面代码运行的情况,我们可以对这个没有main方法的程序的运行进行解释:
(1)java命令执行程序时,先执行static块代码,然后才执行main方法;
(2)由于在static块中有System.exit(0)语句,会退出java命令的执行逻辑,所以系统还没来得及执行main方法,来不及抛出异常,就退出了。
4、号外!新JDK已经不允许这样的程序正常运行
上面的程序虽然逻辑上正常,但一个没有main方法的程序正常运行,总会给人带来费解。
因此新的JDK不允许这样做了。这是JDK1.8.0执行该程序时的显示:
root@VM-0-8-ubuntu:~/java# javac Strange.javaroot@VM-0-8-ubuntu:~/java# java StrangeError: Main method not found in class Strange, please define the main method as: public static void main(String[] args)or a JavaFX application class must extend javafx.application.Application
虽然在JDK1.8.0中会给出错误提示,但我们依然可以通过加入一个空的main方法,来规避JDK的检查:
public class Strange{ static{ System.out.println("Hello, this is Strange.java"); System.out.println("I will exit."); System.exit(0); } public static void main(String[] args){ }}
这时候再编译和运行Strange.java程序,一切正常:
root@VM-0-8-ubuntu:~/java# javac Strange.javaroot@VM-0-8-ubuntu:~/java# java StrangeHello, this is Strange.javaI will exit.root@VM-0-8-ubuntu:~/java#
5、补充说明
特别说明一下,本文只是为了解释Java虚拟机执行程序的规律,并不建议大家这样开发程序。谢谢!