疑惑的产生
每一个Java学习者都知道程序的入口是public static void main(String[] args){}
注1,包括我自己,但是有C++基础的我对main产生了一些疑问
public class MainMethod {
final int a = 0;
private void print_a(){
System.out.println(a);
}
public static void main(String... args) {
MainMethod mObj = new MainMethod();
mObj.print_a();
}
}
我的疑惑来自于类似于上面代码的结构,无法理解为什么可以在main中实例化main所在类(MainMethod mObj = new MainMethod();
),
询问得到的结果是:“Java的规定罢了”,这样相当于没回答的回答无法解决问题,于是开始自己研究。
通过写法分析main方法
public static void main(String... args) {
//方法体
}
public
:访问权限修饰符,公共的,给main方法最高的访问权限。为了保证JVM在任何时候都可以访问main方法,所以使用public修饰。static
:静态的,方法被static修饰符修饰后不需要通过实例调用。这样在类加载的时候main方法就已经准备好了(存储在方法区而非堆内存中),换句话说,JVM想要调用main方法不需要实例化main所在类而只需要加载main所在类。这可以使调用更方便。void
:由于Java默认退出代码为0,所以不需要像C++一样返回int,无异常程序结束退出代码0,异常结束退出代码1main
:这个还真是*“Java的规定罢了”*- **
(String... args)
:程序的入口有参数列表的原因是通过命令行启动Java时是可以带参数启动的,比如java MainMethod aweee
这样的启动方式,aweee就会作为参数传入main方法。默认启动的时候args为空。
main方法的调用及main的本质理解
为什么程序可以执行?
main方法是程序的入口,就是说main方法可以被JVM识别并调用,可以理解为在程序一切的一切开始之前JVM先执行了类名.main(参数);
(这个说法并不严谨,事实上在main之前还有static代码块执行)而在JVM第一次调用之后,JVM便不会主动调用main方法,但是!程序员仍然可以调用main方法! 程序员也可以调用别的类的main方法!
这直接说明main本质上只是一个普通的静态方法,只不过被自动调用了一次。
public class MainMethod {
static { System.out.println("static代码块执行了!"); }
public static void main(String... args) {
System.out.println("main方法执行了");
}
/*输出:
static代码块执行了!
main方法执行了
*/
}
上面的例子体现main的自动调用和main与static代码块的执行顺序。
public class MainMethod {
public static void main(String... args) {
System.out.println("main方法执行了");
MainMethod.main("");
}
/*输出:
main方法执行了
main方法执行了
main方法执行了
......
*/
}
上面的例子展示了main作为普通静态方法调用,事实上上例形成了可怕的递归,理论上来说“main方法执行了”会无限输出,不过程序因异常结束了:(
/* TestClass.java */
public class TestClass {
public static void main(String... args) {
System.out.println("TestClass.main(String... args);调用");
}
}
/* MainMethod.java */
public class MainMethod {
public static void main(String... args) {
TestClass.main("");
}
}
//输出:TestClass.main(String... args);调用
上面的例子展示了调用其他类的main。
在main中实例化main当前类
import java.lang.reflect.Method;
public class MainMethod {
final int a = 0;
private void print_a(){
System.out.println(a);
}
public static void main(String... args) {
MainMethod mObj = new MainMethod();
mObj.print_a();
System.out.println("\nMainMethod类中定义的方法有:");
for(Method i :mObj.getClass().getDeclaredMethods()){
System.out.println(i.getName());
}
}
/* 输出:
0
MainMethod类中定义的方法有:
main
print_a*/
}
回到开头那个例子,通过调试发现main也只不过是MainMethod类中定义的一个方法罢了。
结论:
我把问题复杂化了,main就是个被自动调用一次的普通静态方法而已。
注:
注1:args
可以改名,String[] args
可以写成String args[]
←C-style,高版本Java可以写成String... args
参考资料(按日期排列)
Java main方法
解析java中main函数为什么是这样写
java中main方法的理解
Java-程序的入口main方法
详解Java的main函数
Java–主函数(main)