关闭

Java main方法背后的故事?

478人阅读 评论(0) 收藏 举报
分类:

jvm java 看似一种语言,实则一个巨大的体系的王国,开发这么多年了,还是没有搞懂,我以为我懂了,可是过了一段时间又忘了,所以说还是没懂

1、main方法说起

编译完我们的java文件后,需要有个一含有main方法的类,java 命令将指示操作系统启动一个jvm进程

这个jvm进程启动后,寻找那个main地方开始执行程序

java [JVM_Options] ClassName_with_main [args_separate_space]

main方法的签名必须是 pubic static void main(String[] args) why?

简单点:

首先,main方法是JVM(java虚拟机)自动调用

JVM调用main方法的位置自然不会在某个类中、或某个包中,因此只有当main方法在公有级别上时,才对JVM可见,所以mian方法需要public修饰,

main方法所在的类也需要public修饰符。

由于main方法是所有程序的入口,也就是main被调用时没有任何对象创建,不通过对象调用某一方法,只有将该方法定义为静态方法,所以main方法是一个静态方法,既需要static修饰。

JVM对于java程序已经是最底层,由它调用的方法的返回值已经没有任何地方可去,因此,main方法返回值为空,既需用void修饰。

至于main方法的参数String[ ] arg我们现在已经很少有机会去用它了,它用于在接受命令行传入的参数

 2、执行main方法之前发生了神马

可以参看 jvm源码分析     

首先要明确 jvm进程 是操作系统的进程,该进程是多线程机制的

我们明确两种线程:

jvm线程:指jvm自行管理的线程,我们在程序中无法操控,多是守护类型的

java线程:指从java技术角度看 jvm、我们在程序中用Thread类或Runnable接口编写产生的线程,可操控的线程

至于 java线程 在 jvm里面是怎么实现的,怎么对应到os级别的线程的,请看  http://my.oschina.net/jingxing05/blog/275334

明确两类不同的线程之后,执行main方法之前: LoadJavaVM

jvm进程启动了多个jvm线程很可能是错的,如有,请赐教):

jvm线程:

  • 启动 VM Thread, 单例的,所有线程之始祖!这个线程自轮询loop从对一个队列中取操作任务,来产生其他线程

  • 根据jvm抽象规范,可能有执行引擎线程,GC线程,classloader线程

在jvm自身启动和初始化之后,会

ContinueInNewThread(JavaMain, threadStackSize, (void*)&args);

即启动一个叫main的线程来执行  入口的main方法,main线程虽然不是我们手动生出的线程,但ta还是一个非守护线程

3、main执行过程

  • 加载类

执行main方法时,jvm进程发现main所在类没有在方法区,于是开始进行classload

类加载完的最后一步是 根据情况决定  是不是要进行类的初始化

在main执行之前,必须先对类进行初始化。初始化类的变量,还有静态代码块。初始化的时候还要先初始化它的父类。每个类都有一个隐含的父类Object。 

初始化的顺序:类变量和静态块按序,先父后子

类的初始化过程发生时刻: 

1. T是一个类,当T的一个实例创建的时候,也就是T t = new T(); 

2. T的一个静态方法被调用的时候,也就是 T.staticField(); 

3. T的静态属性被赋值的时候,T.staticField = o; 

4. T的一个静态属性被使用的时候,也就是 Object o = T.staticField; 但是它不是常量。 

5. T is a top level class , and an assert statement  lexically nested 

within T  is executed. (不懂,求解) 

  • 执行main方法

将方法需要的参数,局部变量,本地方法,操作数等以 栈帧的结构 push到 main线程的堆栈区,然后执行引擎线程开始执行,执行完毕,将该栈帧 pop掉。main线程的堆栈区没有栈帧时,main线程消退。

  • 卸载类对象

这一步是个优化的步骤,释放一些方法区的内存,jvm自己决定要不要这一步,一般不会去卸载方法区的

  • 程序退出

1. 所有的非daemon线程都终止了 

2. 某个线程调用了类Runtime或者System的exit方法

main程序执行图


类加载详细过程



jvm中的一些线程可参看点击打开链接


原文转自:点击打开链接

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

放麦子 你一定听说过这个故事。国王对发明国际象棋的大臣很佩服,问他要什么报酬,大臣说:请在第1个棋盘格放1粒麦子,在第2个棋盘格放2粒麦子,

/* 放麦子 你一定听说过这个故事。国王对发明国际象棋的大臣很佩服,问他要什么报酬 ,大臣说:请在第1个棋盘格放1粒麦子,在第2个棋盘格放2粒麦子, 在第3个棋盘格放4粒麦子,在第4个棋盘格放8粒麦子,...... 后一格的数字是前一格的两倍,直到放完所有棋盘格(国...
  • hanshileiai
  • hanshileiai
  • 2013-04-14 12:10
  • 9359

再谈 内存对齐补齐--提高cpu检索周期效率

首先我们先看看下面的C语言的结构体: [cpp] view plain copy   typedef struct MemAlign   {    ...
  • vevenlcf
  • vevenlcf
  • 2016-06-30 15:13
  • 556

Java程序利用main函数中args参数实现参数的传递

1.运行Java程序的同时,可以通过输入参数给main函数中的接收参数数组args[],供程序内部使用!即当你在Java命令行后面带上参数,Java虚拟机就直接把它们存放到了main方法中的参数String数组里了。 2..args是Java命令行参数,因为参数可以为多个,所以要用数组来存我们...
  • salonhuang
  • salonhuang
  • 2017-07-06 16:05
  • 1323

java main方法调用类的实例化方法疑问

public class Example { void idea() { } public static void main(String args[]) { new Example().idea();//这里居然不报错. main方法是个静态方法,j...
  • z_dianjun
  • z_dianjun
  • 2016-03-24 21:20
  • 6154

经典的 Java main方法面试题

1.不用main方法如何定义一个类?     不行,没有main方法我们不能运行Java类。      在Java 7之前,你可以通过使用静态初始化运行Java类。但是,从Java 7开始就行不通了。 2.m...
  • Care_about
  • Care_about
  • 2015-08-24 22:54
  • 1183

如何在Eclipse中快速添加main方法

如何在Eclipse中快速添加main方法  Eclipse软件开发 专业回答 JAVA时空 团队  819793859 2015-10-16 17:08 方法一,在创建类时自动添加,只需要勾选“public stat...
  • evilcry2012
  • evilcry2012
  • 2016-04-18 10:14
  • 2529

java的主方法为什么定义成main

在讲这个之前,我先讲一些关于java关键字static的吧。 (1)在类中,变量的前面有修饰符static称为静态变量(类变量),方法的前面有修饰符static称为静态方法(类方法)。静态方法和静态变量是属于某一个类,而不属于类的对象。 (2)静态方法和静态变量的引用直接通过类名引用。 例如:...
  • wuxinliulei
  • wuxinliulei
  • 2013-11-02 11:17
  • 1097

在java中为什么要把main方法定义为一个static方法?

在java中为什么要把main方法定义为一个static方法?在讲这个之前,我先讲一些关于java关键字static的吧。 (1)在类中,变量的前面有修饰符static称为静态变量(类变量),方法的前面有修饰符static称为静态方法(类方法)。静态方法和静态变量是属于某一个类,而不属于类的对...
  • u013826776
  • u013826776
  • 2016-03-17 10:42
  • 1504

用Maven跑Java main的3种方法

概述Maven exec plugin可以使我们运行自己工程的Java类的main方法,并在classpath里自动包含工程的dependencies。本文用示例代码展示了使用maven exec plugin来运行java main方法的3种方法。1) 在命令行(Command line)运行用这...
  • qiyueqinglian
  • qiyueqinglian
  • 2016-01-28 12:35
  • 4352

java main方法参数传递

一般情况下 我们的main方法是不需要参数传入的 但是如果在工作中需要我们写一些小的应用程序 并且以jar包的方式发给其他人员直接在dos界面使用 并且需要输入参数的时候就需要用到main的参数传递 首先main方法中传递的参数是String数组 我们直接打印这个数组是没有值得空数组 所以...
  • docuxu
  • docuxu
  • 2017-06-22 14:35
  • 3615
    个人资料
    • 访问:561374次
    • 积分:5424
    • 等级:
    • 排名:第5802名
    • 原创:102篇
    • 转载:33篇
    • 译文:0篇
    • 评论:353条
    个人简介
    我只是一个简单的Coder,为了兴趣和理想奋斗在生活的道路上
    希望大家多多交流,共同进步,有疑问或想法请留言或者私信,也可以加群:157797573

    博客专栏
    最新评论
    你还在一个人孤独的奋斗吗?
    其实,你并不寂寞,欢迎加入CSDN Java群,这里是你的另一个家!    点击加入:CSDN Java群