前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你确定能把main方法解释清楚?

你确定能把main方法解释清楚?

作者头像
田维常
发布2019-08-28 15:23:48
2.4K0
发布2019-08-28 15:23:48
举报
文章被收录于专栏:Java后端技术栈cwnait

引入

main方法是我们最熟悉的方法了。从最初的开始入门Java开始就接触它了,main方法是Java程序的入口点,由Java虚拟机自动调用。因此,在很多人眼里,将main方法当作为神秘的方法,认为该方法具有很多特殊性。那么,事实是否真如此呢?你有去想过么?

本文我们就一起来深挖一下main方法相关的知识。

main方法声明

JDK1.5前,声明方式

代码语言:javascript
复制
public class MainTest {
    public static void main(String[] args) {
        System.out.println("main");
    }
}

还可以另外一种方式:

代码语言:javascript
复制
public class MainTest {
    public static void main(String  args [] ) {
        System.out.println("main");
    }
}

其实上面的两种方式还是一种,区别在于Java中数组声明的方式不同罢了。

JDK5及以后

代码语言:javascript
复制
public class MainTest {
    public static void main(String ... args) {
        System.out.println("main");
    }
}

哈哈,很多人都没想到吧,其实就是可变参数吧。

请看以下代码:

代码语言:javascript
复制
public class MainTest {
    private static void main(String ... args) {
        System.out.println("main");
    }
}

把public换成private。有问题吗?代码能正常运行吗?

答案是不能正常运行,找不到程序入口。也就是在eclipse和IDEA中运行的时候找不到Run 和Debug了。

关键字和参数说明

public:main方法作为应用程序的入口,该方法是程序启动时候由Java虚拟机调用的,所以访问权限当然是需要设置为public。

static:如果不是静态的方法,就需要通过对象来调用。而当Java程序运行,虚拟机调用main方法的时候,没有必要创建含有main方法类的对象。例如:类A中声明了main方法,当运行类A的时候,虚拟机直接调用类A的main方法,没有必要创建A对象,然后通过对象调用main方法。

void:main方法在退出时,并没有给系统返回退出代码,而是在需要时候使用System.exit(int status);方法来返回,所以返回类型为void。

String [] args:该字符串数组用来运行时接收用户输入的参数,具体长度取决于用户输入的参数的长度,如果用户没有输入参数,则长度为0.

main方法解析

说到“特殊性”,main方法是Java虚拟机在程序启动的时候自动调用的,并且在命令行可以传递参数给main方法的args参数,从这点就可以说明,main方法和其他方法是不一样的。不过,在更多的表现上 ,main方法与普通的方法是一样的。

例如:

  1. main方法的重载,
  2. 调用main方法,
  3. 继承main方法,
  4. 隐藏main方法,
  5. main方法抛出异常,
  6. 带有类型参数,
main方法重载

关于重载的概念,这里就不提了,不清楚请自行学习。

如果没有按照上面所述的三种方式来声明main方法,会发生怎样的情况呢?

代码语言:javascript
复制
public class MainTest {
    public int main(int i) {
        System.out.println("main 2 " + i);
        return i;
    }
    public static void main(String arg) {
        System.out.println("main 3");
    }
    //如果没有下面这个方法,只有上面两个方法是没法启动程序的,
    //会提示:在类com.tian.swagger.advancedfeatures.thisandsuper.MainTest中
    //找不到主方法
    public static void main(String[] args) {
        System.out.println("main 1");
    }
}

也就是说,Java虚拟机要求的main方法必须是按照前面说的三种声明方式,否则,将认为你没有给程序定义好入口(main方法)。

调用main方法

我们都只是在main方法中调用其他方法,那么其他方法能不能调用main方法呢?

代码语言:javascript
复制
public class MainTest {
    private static boolean flag = true;

    public static void test() {
        if (flag) {
            flag = false;
            //调用main方法
            main(new String[]{""});
        }
    }
    public static void main(String[] args) {
        System.out.println("main");
        test();
    }
}

输出:

代码语言:javascript
复制
main
main

说明其他普通方法也是能调用main方法的。

继承main方法
代码语言:javascript
复制
public class Base {
    public static void main(String[] args) {
        System.out.println("base main");
    }
}
public class Sub extends Base {
}

在Sub类中Run也是可以的,并且输出:

代码语言:javascript
复制
base main

说明main方法是可以继承的。

隐藏main方法

如果子类继承了父类的main方法,并且在子类中重写声明新的main方法,也可以隐藏父类的main方法,这个与隐藏其他方法一样的。

代码语言:javascript
复制
public class Base {
    public static void main(String[] args) {
        System.out.println("base main");
    }
}
public class Sub extends Base {
    public static void main(String[] args) {
        System.out.println("sub main");
    }
}

在Sub中Run,输出:

代码语言:javascript
复制
sub main
main方法抛出异常
代码语言:javascript
复制
public class MainTest {
    public static void main(String[] args) throws ClassNotFoundException {
         Class.forName("com.tian.swagger.MainTest");
    }
}

说明main方法和普通方法一样,都可以抛出异常的。

带有类型参数
代码语言:javascript
复制
public class MainTest {
    private static boolean flag = false;
    public static <T> void main(String[] args) {
        if (flag) {
            System.out.println("main exit");
            System.exit(0);
        } else {
            test(args);
        }
    }
    private static void test(String[] args) {
        flag = true;
        MainTest.<String>main(args);
    }
}

MainTest可以Run,并且输出:

代码语言:javascript
复制
main exit

声明两个main方法

代码语言:javascript
复制
public class MainTest {
    public static   void main(String[] args) {
      
    }
    public static   void main(String ... args) {

    }
}

猜想上面这段代码有问题吗?

总结

Java语言中作为程序入口的main方法,需要将其声明为public,static,void,并且方法参数类型为String数组或可变String类型参数。在程序启动的时候,Java虚拟机自动调用main方法。

main方法在表现行为上,与其他普通方法基本相同,可以重载、由其他方法调用、继承、隐藏。也可以抛出异常、带有类型参数。

可以使用反射来调用main方法,(这里没实现,有兴趣的小伙伴自己去尝试)。

不能在同一个类中声明两个main方法(main三种正确声明方式中的两种),否则,抛异常:

代码语言:javascript
复制
Error:(14, 26) java:
无法在com.tian.swagger.MainTest中同时声明main(java.lang.String...)
    和main(java.lang.String[])
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java后端技术栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引入
  • main方法声明
  • 关键字和参数说明
  • main方法解析
    • main方法重载
      • 调用main方法
        • 继承main方法
          • main方法抛出异常
            • 带有类型参数
            • 总结
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档